動機
以前、「可搬的なpythonツールのためのスケルトン作成ユーティリティ」というのを作成した。これは、もともとpythonスクリプトを色々な環境に持って行ってに使うのを楽にするため作成した「比較的小規模で可搬的なPython toolのスケルトン」というのが元になっている。
本体はbash
のシェルスクリプトで、主な機能としては、
- Pythonの必要なモジュールを
pip
でローカルなディレクトリにインストールする - 環境変数
PYTHONPATH
にそのローカルディレクトリを加えてpythonスクリプトを実行するラッパースクリプト - ローカルディレクトリに
python
スクリプトなどのテンプレートを作成する - 自分で作成したpythonスクリプトなど他の環境にコピーするファイルは残して、
pip
でローカルにインストールしたモジュールファイルをまとめて消去する。 (配布物の作成を楽にする。)
の4つがある。個人的には大変使い勝手がよく、いろいろな環境にもっていって使うpythonスクリプトを書くさいに多用するようになった。しかしながら、さらに毎回ルーチンワーク的にやっている作業があることに気づいたので、より省力化がはかれるのではないか、と思うようになった。
また、少し前に「よく使うシェルスクリプト(bash)のツールの保守性/汎用性を高める試み。」というのを作成した。これは、bashスクリプトをsource
(.
)しても副作用がないようなものにする工夫である。この工夫をすればbash
スクリプトをalias
的にすることもできるのでないか、と思えてきた。
(個人的には、作業用にログインシェル的にはtcsh
を使っているので、その恩恵はないと思うが......)
これらのため、シェルスクリプトとしては大幅に書き換えることになったので、名前を変えて新しいツールとすることにした。pythonツールやそれに必要なものがまとめて入った小型容器ということで、py_canister
と命名した。
ファイル置き場
基本的な動作 (従前とおなじ)
まず初めに--manage
オプションをつけて、py_canister.sh
をinit
サブコマンドで実行すると、python
スクリプトのスケルトンを作成できます。 下記の例だと、 新規ディレクトリ~/tmp/py_working_tool
以下に、show_status3.py
という名のpython3
スクリプトのスニペットが準備されるとともに、これを実行するためのラッパースクリプト(へのシンボリックリンク)が作成されます。
% ~/somewhere/py_canister.sh --manage \
-p ~/tmp/py_working_tool -g -r -3 \
-t 'Working tool by Python' init show_status
できたファイルを確認すると、下記のようになっています。
% find ~/tmp/py_working_tool/ -ls
.... ~/tmp/py_working_tool/
.... ~/tmp/py_working_tool/bin
.... ~/tmp/py_working_tool/bin/py_canister.sh
.... ~/tmp/py_working_tool/bin/mng_pyenv -> py_canister.sh
.... ~/tmp/py_working_tool/bin/show_status -> py_canister.sh
.... ~/tmp/py_working_tool/bin/mng_pyenv2 -> py_canister.sh
.... ~/tmp/py_working_tool/bin/mng_pyenv3 -> py_canister.sh
.... ~/tmp/py_working_tool/bin/show_status3 -> py_canister.sh
.... ~/tmp/py_working_tool/README.md
.... ~/tmp/py_working_tool/.gitignore
.... ~/tmp/py_working_tool/lib
.... ~/tmp/py_working_tool/lib/python
.... ~/tmp/py_working_tool/lib/python/show_status3.py
.... ~/tmp/py_working_tool/lib/python/show_status.py -> show_status3.py
.... ~/tmp/py_working_tool/lib/python/site-packages
.... ~/tmp/py_working_tool/lib/python/site-packages/.gitkeep
ここで作成されたshow_status3.py
ですが、
% head ~/tmp/py_working_tool/lib/python/show_status3.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
...
import pytz
import tzlocal
...
非標準のモジュールpytz
,tzlocal
を読み込んでいますので、このままでは実行できませんが、mng_pyenv3
でpip
を使ってローカルにモジュールをインストールできます。
% ~/tmp/py_working_tool/bin/mng_pyenv3 install pytz tzlocal
Collecting pytz
Using cached pytz-2024.1-py2.py3-none-any.whl.metadata (22 kB)
Collecting tzlocal
Using cached tzlocal-5.2-py3-none-any.whl.metadata (7.8 kB)
Using cached pytz-2024.1-py2.py3-none-any.whl (505 kB)
Using cached tzlocal-5.2-py3-none-any.whl (17 kB)
Installing collected packages: pytz, tzlocal
Successfully installed pytz-2024.1 tzlocal-5.2
ファイルを確認すると、ローカルフォルダにインストールされてます。
% find ~/tmp/py_working_tool/ -ls
......
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12/pytz-2024.1.dist-info
......
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12/pytz
......
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12/tzlocal-5.2.dist-info
......
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12/tzlocal
......
bin/show_status3
はbin/py_canister.sh
へのシンボリックリンクですが、ここではpy_canister.sh
は、--manage
オプションがない場合には、シンボリック名もしくはコマンドライン第一引数のファイルをPYTHONPATH
を設定して実行するラッパースクリプトとして動作します。
% ~/tmp/py_working_tool/bin/show_status3 -d
Hello, World! ......
Python : 3.12.1 (..../bin/python3)
.... (PYTHONPATH一覧を表示)
これで準備が完了したので、py_working_tool/lib/python/show_status3.py
を所望の動作をするようにバリバリ書き換え、また必要に応じてpy_working_tool/bin/mng_pyenv3 install ...
として、さらに追加で必要となるpythonモジュールを追加していく、というのが作業になります。ここまでは、以前の「可搬的なpythonツールのためのスケルトン作成ユーティリティ」と同じです。
追加した機能
「可搬的なPythonスクリプトツール」を作っている時にほとんど場合に必要となることは、スクリプトやその実行に必要なモジュールファイルだけでなく、データファイルや設定ファイルの可搬性を確保することが必要になる。その際には、要は必要なファイルを一つのディレクトリ以下に収めるというドクトリンになるわけであるが、そのために毎回同じような機能を書いていることに気づいた。そのため、py_canister.sh
にはよく使うpython
コードをテンプレートとして埋め込んでおけるようなに実装した。例として、自分が常用するコードから、ローカルディレクトリの構造をハンドルするpkg_structure.py
というファイルと、データキャッシュを使うpkg_cache.py
というのを入れてみた。
使い方としては、
% ~/somewhere/py_canister.sh --manage -3 -p ~/tmp/py_working_tool -g -r -t 'Working tool by Python' \
-s pkg_structure init show_status
のように-s
オプションで、埋め込んだテンプレートから実ファイル作成することを指示すると、
% find ~/tmp/py_working_tool/ -ls
.......
.... ~/tmp/py_working_tool/lib/python/pkg_structure.py
.......
と、追加でpython
のモジュール的に使用できるファイルが作成される。
ローカルディレクトリの構造の定型化(pkg_structure.py
)
前述のとおり、pythonスクリプトやモジュールだけでなく、なんらかのデータファイルや設定ファイルなどもまとめて他の環境にもっていく必要があることも少なくない。「可搬的なスクリプトツール」を目指す、という観点からは、
- 1つのディレクトリ以下に必要なファイルが収まっている。
- そのフォルダがどこの場所に置いても必要なファイルを読み込んで動作する
- そのファイル以外の場所に意図せずファイルを作らない
の3点を満たしたい。とくに2点目や3点目に関して、実行スクリプトの親ディレクトリを調べて相対的にデータファイルや中間ファイルや出力ファイルのpathを決める、というコードを毎回書くことになっていた。このためのpkg_structure.py
というコードを用意した。
py_canister.sh
では、トップディレクトリ(上記実行例では~/tmp/py_working_tool
)以下のbin
ディレクトリ以下に実行ファイルを、lib/python
以下にPythonスクリプトを配置している。
pkg_structure.py
はこれを発展させて、トップディレクトリ以下にvar
, share
,etc
,...といったGNU Coding StandardやFilesystem Hierarchy Standardに準じたディレクトリ構造を持たせるのをサポートする。
pkg_structure.py
の利用例
具体的な例として、GUIライブラリの一つであるkivy
を使ったpythonスクリプトの例を挙げる。見た目のよいマルチタッチアプリケーションが作成可能ということでkivy
を使っている方もいると思いますが、可搬的にスクリプトにする、という点では下記の点が問題になります。
- Wigetの配置などをpythonスクリプトとは別の独自言語(
kv
)のファイルに記述する。 - 最初に起動したとき、(
~/.kivy
)という隠しディレクトリを作って、その下に設定ファイルを作成する。 - さらに
~/.kivy/log
以下に実行ログを残していく。(ユーザーが気づかない場所で静かにディスク容量が食われていく) - これに加えて、デフォルトでは、kivyで作成したアプリ(
kivy.app.App
を継承したクラス)毎の設定ファイルを、~/.config
(macOSの場合は~/Library/Application Support/
)以下に作成する。
作成したpkg_structure.py
を使って、これらを回避する例を作ってみました。全体像は最後につけますが,上記ポイントに関係する部分を抽出して説明します。
pkg_structure.py
の使用
まず、モジュールをimport
して、それを使うPkgStructure
クラスのエンティティを定義します。コンストラクタの引数であたえたスクリプトから親ディレクトリを推測します。
import pkg_structure
...
pkg_info = pkg_structure.PkgStructure(script_path=sys.argv[0])
# pkg_info.dump(relpath=False, with_seperator=True)
...
pkg_info.make_subdirs('pkg_sysconfdir', 0o755, True, 'kivy')
os.environ['KIVY_HOME'] = pkg_info.concat_path('pkg_sysconfdir', 'kivy')
....
それによりどんなサブディレクトリが定義されるかは、メンバ関数dump()
で表示できます。引数に与えたスクリプトのパス('base_script')が、~/tmp/py_working_tool/lib/python/show_status3.py
の場合には、
上位のlib/python/
のさらに親ディレクトリが、このパッケージのディレクトリと類推して、
-
そのディレクトリ名
py_working_tool
をこのパッケージの名前:'pkg_name' -
そのディレクトリの場所
~/tmp/py_working_tool
がディレクトリ構造のトップ('prefix')
と決めます。それいかに、GNU Coding StandardやFHSで定義されている。 -
'bindir':
~/tmp/py_working_tool/bin
-
'datadir':
~/tmp/py_working_tool/share
-
'sysconfdir':
~/tmp/py_working_tool/etc
-
'localstatedir':
~/tmp/py_working_tool/var
-
'runstatedir':
~/tmp/py_working_tool/var/run
-
'tmpdir':
~/tmp/py_working_tool/tmp
などのサブディレクトリや、これらのディレクトリ名の直下のパッケージの名前('pkg_name')のサブディレクトリ
- 'pkg_datadir':
~/tmp/py_working_tool/share/py_working_tool
- 'pkg_sysconfdir':
~/tmp/py_working_tool/etc/py_working_tool
- 'pkg_cachedir':
~/tmp/py_working_tool/var/cache/py_working_tool
- 'pkg_statedatadir':
~/tmp/py_working_tool/var/lib/py_working_tool
- 'pkg_logdir':
~/tmp/py_working_tool/var/log/py_working_tool
- 'pkg_spooldir':
~/tmp/py_working_tool/var/spool/py_working_tool
に相当する文字列が定義され、PkgStructureクラスのプロパティとしてアクセスできるようになります。
どのようなプロパティ(サブディレクトリ名)が定義されるかは、lib/python/pkg_structure.py
を単体で直接実行することでも確認できます。(********
は実行ユーザー名になります)
'pkg_name': py_working_tool
'pkg_path': ~/tmp/py_working_tool
----------------------------------------------------------------------
'base_script': ~/tmp/py_working_tool/lib/python/pkg_structure.py
----------------------------------------------------------------------
'script_mnemonic': pkg_structure
'script_path': ~/tmp/py_working_tool/lib/python/pkg_structure.py
'script_location': ~/tmp/py_working_tool/lib/python
'script_basename': pkg_structure.py
----------------------------------------------------------------------
'prefix': ~/tmp/py_working_tool
----------------------------------------------------------------------
'exec_user': ********
----------------------------------------------------------------------
'exec_prefix': '${prefix}'
'bindir': '${prefix}'/bin
'datarootdir': '${prefix}'/share
'datadir': '${prefix}'/share
'sysconfdir': '${prefix}'/etc
'sharedstatedir': '${prefix}'/com
'localstatedir': '${prefix}'/var
'include': '${prefix}'/include
'libdir': '${prefix}'/lib
'srcdir': '${prefix}'/src
'infodir': '${prefix}'/share/info
'runstatedir': '${prefix}'/var/run
'localedir': '${prefix}'/share/locale
'lispdir': '${prefix}'/emacs/lisp
'docdir': '${prefix}'/doc/py_working_tool
'htmldir': '${prefix}'/doc/py_working_tool
'dvidir': '${prefix}'/doc/py_working_tool
'pdfdir': '${prefix}'/doc/py_working_tool
'psdir': '${prefix}'/doc/py_working_tool
'mandir': '${prefix}'/share/man
'man0dir': '${prefix}'/share/man/man0
'man1dir': '${prefix}'/share/man/man1
'man2dir': '${prefix}'/share/man/man2
'man3dir': '${prefix}'/share/man/man3
'man4dir': '${prefix}'/share/man/man4
'man5dir': '${prefix}'/share/man/man5
'man6dir': '${prefix}'/share/man/man6
'man7dir': '${prefix}'/share/man/man7
'man8dir': '${prefix}'/share/man/man8
'man9dir': '${prefix}'/share/man/man9
'manndir': '${prefix}'/share/man/mann
'sbindir': '${prefix}'/sbin
'bootdir': '${prefix}'/boot
'devdir': '${prefix}'/dev
'mediadir': '${prefix}'/media
'mntdir': '${prefix}'/mnt
'optdir': '${prefix}'/opt
'tmpdir': '${prefix}'/tmp
'xmldir': '${prefix}'/etc/xml
'etcoptdir': '${prefix}'/etc/opt
'cachedir': '${prefix}'/var/cache
'statedatadir': '${prefix}'/var/lib
'lockdir': '${prefix}'/var/lock
'logdir': '${prefix}'/var/log
'spooldir': '${prefix}'/var/spool
'statetmpdir': '${prefix}'/var/tmp
'user_home': '${prefix}'/Users/********
'home': '${prefix}'/Users/********
'homedir': '${prefix}'/Users
----------------------------------------------------------------------
'pkg_datadir': '${prefix}'/share/py_working_tool
'pkg_sysconfdir': '${prefix}'/etc/py_working_tool
'pkg_runstatedir': '${prefix}'/var/run/py_working_tool
'pkg_include': '${prefix}'/include/py_working_tool
'pkg_libdir': '${prefix}'/lib/py_working_tool
'pkg_srcdir': '${prefix}'/src/py_working_tool
'pkg_tmpdir': '${prefix}'/tmp/py_working_tool
'pkg_xmldir': '${prefix}'/etc/xml/py_working_tool
'pkg_cachedir': '${prefix}'/var/cache/py_working_tool
'pkg_statedatadir': '${prefix}'/var/lib/py_working_tool
'pkg_lockdir': '${prefix}'/var/lock/py_working_tool
'pkg_logdir': '${prefix}'/var/log/py_working_tool
'pkg_spooldir': '${prefix}'/var/spool/py_working_tool
'pkg_statetmpdir': '${prefix}'/var/tmp/py_working_tool
----------------------------------------------------------------------
さらに、これらの下に別のディレクトリ/ファイル名の文字列を作成するメンバ関数concat_path()
を実装しました。実際にディレクトリを作成するためのメンバ関数make_subdirs()
も実装しました。前記の例の最後の2行
pkg_info.make_subdirs('pkg_sysconfdir', 0o755, True, 'kivy')
os.environ['KIVY_HOME'] = pkg_info.concat_path('pkg_sysconfdir', 'kivy')
が、~/tmp/py_working_tool/etc/py_working_tool/kivy
というディレクトリを作成して、環境変数KIVY_HOME
にこのディレクトリを設定するコードになります。これで、~/.kivy
という隠しファイルが作られるのを避けられます。これらの環境変数設定は、kivy関係のモジュールをインポートする前に実行される必要があります
kivy
のログファイル出力先の変更
次に他のkivy関係のモジュールを読み込む前にログファイルの置き場をしておきます。kivy.config
関係の設定をおこなってからkivyのメインのモジュールを読み込む順番になります。
import kivy.config
kivy.config.Config.set("kivy","log_dir", pkg_info.pkg_logdir)
pkg_info.pkg_logdir
というところがPkgStructure
のプロパティとしてサブディレクトリの場所を取得する例となっています。
kivyのアプリケーション設定フォルダの指定
前述のとおりkivyの作法として、kivy.App
のを継承してアプリケーションのクラスを構築すると、~/.config
(macOSの場合は~/Library/Application Support/
)以下に非明示的にディレクトリが作成されます。このディレクトリの場所を変えるには、kivy.App
クラスのコンストラクタの引数kv_directory
で指定します。
class MainApp(kivy.app.App):
def __init__(self, pkg_info, **kwargs):
super().__init__(kv_directory=pkg_info.pkg_runstatedir, **kwargs)
self.pkg_info = pkg_info
この例では、作成するMainApp
のコンストラクタにPkgStructureクラス
のエンティティを渡しておき、そのプロパティpkg_info.pkg_runstatedir
を親クラス(kivy.app.App
)のコンストラクタに引数で渡します。また、このクラスでPkgStructureクラス
のエンティティを参照できるように、メンバ変数に保持しておきます。
kivyのGUI画面設定ファイルの指定
main.App
のGUIウィンドウ画面の定義などは別途.kv
ファイルに記述して読み込みます。これもkivy.app.App
のコンストラクタの引数(kv_file
)で指定できます。あらかじめ~/tmp/py_working_tool/share/py_working_tool/main.kv
というファイルを作成しておき、MainApp
クラスのコンストラクタ経由でkivy.app.App
クラスのコンストラクタに渡します。
kv_file=pkg_info.concat_path('pkg_datadir', 'main.kv')
...
main_app = MainApp(kv_file=kv_file, pkg_info=pkg_info)
この例での作成ファイル。
スクリプトの全体像としてはあとにつけますが、これを実行すると非明示的に作成されるファイルは下記の通り、トップディレクトリ以下に限られ、またログファイルもより明示的な場所に作られるので、めざしていた「可搬性」が達成できました。
% ~/somewhere/py_canister.sh --manage -3 -p ~/tmp/py_working_tool \
-g -r -t 'Working tool by Python' -s pkg_structure init show_status
% (edit) emacs ~/tmp/py_working_tool/lib/python/show_status3.py
% (edit) emacs ~/tmp/py_working_tool/share/py_working_tool/main.kv
% ~/tmp/py_working_tool/bin/mng_pyenv3 install pytz tzlocal psutil kivy
% ~/tmp/py_working_tool/bin/show_status3
% find ~/tmp/py_working_tool/
...
~/tmp/py_working_tool/etc/py_working_tool/kivy/config.ini
~/tmp/py_working_tool/etc/py_working_tool/kivy/mods
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-32.png
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-24.png
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-64.ico
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-256.png
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-48.png
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-512.png
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-64.png
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-128.png
~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-16.png
...
~/tmp/py_working_tool/var/log/py_working_tool/kivy_24-07-26_0.txt
スクリプト全体像
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Standard modules
import argparse
import datetime
import sys
import os
# Publicly Distributed modules
import pytz
import tzlocal
import psutil
# Custom-made modules
import pkg_structure
def main():
argpsr = argparse.ArgumentParser(description='Example: showing status')
argpsr.add_argument('-q', '--quiet', action='store_true', help='Supress kivy log to stderr')
cmdargs = argpsr.parse_args()
pkg_info = pkg_structure.PkgStructure(script_path=sys.argv[0])
#pkg_info.dump(relpath=False, with_seperator=True)
os.environ['KIVY_NO_ARGS'] = '1'
pkg_info.make_subdirs('pkg_sysconfdir', 0o755, True, 'kivy')
os.environ['KIVY_HOME'] = pkg_info.concat_path('pkg_sysconfdir', 'kivy')
if cmdargs.quiet:
os.environ['KIVY_NO_CONSOLELOG'] = '1'
import kivy.config
kivy.config.Config.set("kivy","log_dir", pkg_info.pkg_logdir)
import kivy.app
import kivy.uix.widget
import kivy.properties
class MainApp(kivy.app.App):
def __init__(self, pkg_info, **kwargs):
super().__init__(kv_directory=pkg_info.pkg_runstatedir, **kwargs)
self.pkg_info = pkg_info
class MainWidget(kivy.uix.widget.Widget):
KEYWORDS = ['pkg_name', 'pkg_path', 'base_script',
'prefix', 'bindir', 'datadir', 'sysconfdir',
'localstatedir', 'runstatedir', 'tmpdir',
'pkg_datadir', 'pkg_sysconfdir', 'pkg_runstatedir', 'pkg_tmpdir']
status_text = { x: kivy.properties.StringProperty() for x in KEYWORDS }
status_text['MECH'] = kivy.properties.StringProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
tz_local = tzlocal.get_localzone()
self.status_text['MECH'] = (f'CPU Usage: {psutil.cpu_percent(interval=1)} %'
f', Load Avg. = {psutil.getloadavg()[0]:.2f}'
f' @ {datetime.datetime.now(tz=tz_local).strftime("%c")}')
for x in self.KEYWORDS:
self.status_text[x] = kivy.app.App.get_running_app().pkg_info[x]
for x in MainWidget.KEYWORDS:
print (f"{x+':':18s} {pkg_info[x]}")
kv_file=pkg_info.concat_path('pkg_datadir', 'main.kv')
print ("--------------------")
print (f"{'kv_file:':18s} {kv_file}")
print ("--------------------")
main_app = MainApp(kv_file=kv_file, pkg_info=pkg_info)
main_app.run()
if __name__ == '__main__':
main()
MainWidget:
<MainWidget>:
BoxLayout:
orientation: 'vertical'
size: self.parent.size
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_MECH
size_hint: 0.2, 0.01
text: 'MECH'
Label:
id: status_text_MECH
size_hint: 0.8, 0.01
text: root.status_text['MECH']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_pkg_name
size_hint: 0.2, 0.01
text: 'pkg_name'
Label:
id: status_text_pkg_name
size_hint: 0.8, 0.01
text: root.status_text['pkg_name']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_pkg_path
size_hint: 0.2, 0.01
text: 'pkg_path'
Label:
id: status_text_pkg_path
size_hint: 0.8, 0.01
text: root.status_text['pkg_path']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_base_script
size_hint: 0.2, 0.01
text: 'base_script'
Label:
id: status_text_base_script
size_hint: 0.8, 0.01
text: root.status_text['base_script']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_prefix
size_hint: 0.2, 0.01
text: 'prefix'
Label:
id: status_text_prefix
size_hint: 0.8, 0.01
text: root.status_text['prefix']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_bindir
size_hint: 0.2, 0.01
text: 'bindir'
Label:
id: status_text_bindir
size_hint: 0.8, 0.01
text: root.status_text['bindir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_datadir
size_hint: 0.2, 0.01
text: 'datadir'
Label:
id: status_text_datadir
size_hint: 0.8, 0.01
text: root.status_text['datadir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_sysconfdir
size_hint: 0.2, 0.01
text: 'sysconfdir'
Label:
id: status_text_sysconfdir
size_hint: 0.8, 0.01
text: root.status_text['sysconfdir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_localstatedir
size_hint: 0.2, 0.01
text: 'localstatedir'
Label:
id: status_text_localstatedir
size_hint: 0.8, 0.01
text: root.status_text['localstatedir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_runstatedir
size_hint: 0.2, 0.01
text: 'runstatedir'
Label:
id: status_text_runstatedir
size_hint: 0.8, 0.01
text: root.status_text['runstatedir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_tmpdir
size_hint: 0.2, 0.01
text: 'tmpdir'
Label:
id: status_text_tmpdir
size_hint: 0.8, 0.01
text: root.status_text['tmpdir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_pkg_datadir
size_hint: 0.2, 0.01
text: 'pkg_datadir'
Label:
id: status_text_pkg_datadir
size_hint: 0.8, 0.01
text: root.status_text['pkg_datadir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_pkg_sysconfdir
size_hint: 0.2, 0.01
text: 'pkg_sysconfdir'
Label:
id: status_text_pkg_sysconfdir
size_hint: 0.8, 0.01
text: root.status_text['pkg_sysconfdir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_pkg_runstatedir
size_hint: 0.2, 0.01
text: 'pkg_runstatedir'
Label:
id: status_text_pkg_runstatedir
size_hint: 0.8, 0.01
text: root.status_text['pkg_runstatedir']
BoxLayout:
size_hint: 1.0, 0.01
Label:
id: status_label_pkg_tmpdir
size_hint: 0.2, 0.01
text: 'pkg_tmpdir'
Label:
id: status_text_pkg_tmpdir
size_hint: 0.8, 0.01
text: root.status_text['pkg_tmpdir']
Button:
size_hint: 1.0, 0.01
text: "Quit"
on_press: app.stop()
(参考) py_canister.sh
の使い方
ヘルプのダンプ画面をつけておきます。
% ~/somewhere/py_canister.sh --manage -h
% py_canister.sh --manage [options] sub-command [arguments]
---- Shell script for providing Portable 'Contained' Python environment
[sub-commands]
% py_canister.sh --manage [options] init [scriptnames] ... setup directory tree,
and prepare templates if arguments are given.
% py_canister.sh --manage [options] add script_names ... prepare python script templates.
% py_canister.sh --manage [options] addlib [script_names] ... prepare python script templates.
% py_canister.sh --manage install module_names ... Install python module with pip locally.
% py_canister.sh --manage download module_names ... Download python module with pip locally.
% py_canister.sh --manage clean ... Delete local python module for corresponding python version.
% py_canister.sh --manage distclean/cleanall/allclean ... Delete local python module for all python version.
% py_canister.sh --manage info ... Show information.
[Options]
-h : Show this message
-P arg : specify python command / path
-v : Show verbose messages
-q : Supress verbose messages (default)
-n : Dry-run mode.
-2 : Prioritize Python2 than Python3
-3 : Prioritize Python3 than Python2
[Options for sub-command: setup/init ]
-p : prefix of the directory tree. (Default: Grandparent directory if the name of parent directory of
py_canister.sh is bin, otherwise current working directory.)
-M : moving this script body into instead of copying
-g : setup files for git
-G : do not setup files for git (default)
-r : setup/update README.md
-R : do not setup/update README.md (default)
-k : keep backup file of README.md when it is updated.
-K : do not keep backup file of README.md when it is updated. (default)
-t arg : Project title
-m arg : install module by pip
-s arg : install library script from template.
-S : install standard library scripts. (equivalent to '-s pkg_structure -s pkg_cache')
[Options for sub-command: install/download ]
-i arg : specify pip command