另外在执行脚本的过程中需要用到超级用户的权限,因此在脚本中添加了检查当前用户权限的功能:
def is_root(): if hasattr(os, "getuid"): return os.getuid() == 0 return False该 Python 脚本的主要功能是添加和删除仓库(目录),添加仓库的操作如下,分别是创建目录,执行 git init --bare --shared 命令,更改文件属主和属组的操作(实际的脚本中包含一些日志记录和异常处理的代码):
from pathlib import Path def createRepo(repo: Path): if repo.exists(): return repo.mkdir(parents=True) subprocess.run(["git", "init", "--bare", "--shared", str(repo.absolute())]) shutil.chown(repo, config["user"], config["group"])删除仓库的操作更加简单,调用 shutil 递归删除文件夹即可,不能使用 repo.rmdir() 函数,因为一般仓库文件夹是非空的:
import shutil def deleteRepo(repo: Path): if not repo.exists(): return shutil.rmtree(str(repo))罗列所有仓库使用 Path.iterdir() 函数即可。
这样一个可以使用的脚本就制作完成了,如果只是单纯的编写一个脚本的话,可以在文件的开头加上 #!/usr/bin/python3 这样的标记,表明这是一个可执行的 Python3 脚本,在 linux 系统上给它加上 x 权限,比如这个文件的名称为 gitrepo.py,我们可以在终端中输入 gitrepo.py -h 或者 python3 gitrepo.py -h 查看这个命令的帮助信息。
详细的代码可以在 [Github 上的 gitrepo.py][https://github.com/BriFuture/myfacilities/blob/master/myfacilities/gitrepo.py] 文件中查看。
以 wheel 包的形式发布前面说过,我们可以把写好的 Python 文件当做脚本执行,但是每次都要敲 gitrepo.py -h 这样的命令,能不能就像平时用 ls 这些命令一样直接敲 gitrepo -h 呢?最简单的是用 ln 建立软链接:sudo ln -s /path/to/gitrepo.py /usr/bin/gitrepo,但是这里我们可以借助 pypi 发布我们已经写好的命令,将我们的脚本发布到 pypi 上,那么还可以在没有该脚本的机器上利用 pip 进行安装。
以 brifuture-facilities 这个项目为例,在项目的根目录下面新建一个 setup.py 文件,输入以下内容:
# -*- coding: utf-8 -*- from setuptools import setup, find_packages with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read() with open('requirements.txt', "r", encoding="utf-8") as f: requires = f.read().splitlines() from myfacilities import __version__ setup( name = "brifuture-facilities", packages = find_packages(where='.'), version = __version__, entry_points = { "console_scripts": [ 'bf_broadcast = myfacilities.broadcast:main', 'bf_gitrepo = myfacilities.gitrepo:main', ] }, description = "BriFuture's scripts set, all scripts will be written with Python3", author = "BriFuture", author_email = "jw.brifuture@gmail.com", license = "GPLv3", url = "http://github.com/brifuture/", install_requires = requires, include_package_data = True, zip_safe=True, exclude_package_data = {'': ['__pycache__']}, # download_url = "", keywords = [ "webserver", "shadowsocks-manager" ], classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3" , "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: OS Independent" ], long_description = long_description, long_description_content_type="text/markdown", )我们需要利用的是 setuptools,从这个模块中导入 setup,它的参数都很直观,我们想要添加一个可执行的脚本时,在 entry_points 关键字参数中添加即可,如:
entry_points = { "console_scripts": [ 'bf_broadcast = myfacilities.broadcast:main', 'bf_gitrepo = myfacilities.gitrepo:main', ] },由于这个项目中的文件是包的一部分,所以我没法直接使用 python 运行其中的某个脚本,像 python3 myfacilities.gitrepo -h 是无法运行的,但是借助于 setuptools,我们可以将写好的程序安装到机器中,python3 setup.py install 可以通过 setup.py 文件进行安装,也可以使用 pip install . 进行安装,详细的教程可以在 文档 中找到。
接下来制作 wheel 包,命令很简单:
python3 setup.py sdist bdist_wheel这样会将我们的代码打包到 dist/ 目录下。
我们需要将制作好的程序发布到 pypi 上,安装好 twine: pip install twine, 在 $HOME 目录(linux) 或者 C:\Users\yourname\ 目录(windows)下新建一个 .pypirc 文件,输入下面的内容:
[distutils] index-servers= pypi testpypi [pypi] repository: https://upload.pypi.org/legacy/ username: yourname password: yourpasswd [testpypi] repository: https://test.pypi.org/legacy/ username: yourname password: yourpasswd接下来就可以发布了,但是不要着急,正式发布前都请将制作好的包发布到 testpypi 上:
python3 -m twine upload -r testpypi dist/* --skip-exsiting等你确认一切无误后,在将 -r testpypi 参数换成 -r pypi 以便正式发布。
小结