手把手教你组件化开发Python命令行工具

手把手教你组件化开发Python命令行工具

布景

作为研制,假定你想进步开发效率、解放出产力、CI/CD,必定离不开脚本。跟着功用不断完善,脚本体量越来越大,一起一门脚本语言,解耦复用模块,组件化开发脚本变得愈加重要。

所以,一起继续运用一门适宜的脚本语言对错常有必要的。

作为移动端研制,我推荐运用Python,比较Shell,Ruby,Gradle,JS,Swift等等,优势如下:

  1. 入门简略,社区巨大,生态完善,许多坑别人都踩过,许多功用都有人完结过(这点很重要,否则你或许会因为一些大坑带来的挫折感停滞不前);

  2. 各端都有各自常用的脚本语言,而Python形似愈加的途径不相关,开发多端复用的东西或许Python更适宜;

  3. 运用广泛,或许你后期能够拓展学习人工智能,大数据等;

废话不多说,下面详细介绍下组件化开发一套Python指令行东西需求用到的东西链及相关装备。(本文以MacOS为例)

设备Python3.x

Mac体系自带Python,或许会被体系东西依托,假定玩坏了影响规划较大。一般版别较旧,且不便当处理,这儿我建议自己再设备一套,推荐用Homebrew设备。(或许官网下载)

# 设备3.x版别
brew install python3 
# 体系自带的Python在 /usr/bin/python3 
# 运用Homebrew设备的Python一般在 /usr/local/bin/python3 
# 查看设备方位,设备后会打印brew设备的途径 
which python3 
# python包处理东西,下面介绍 
which pip3 

# 假定途径不对,一般是PATH没有记载新途径,增加一下即可 
echo $PATH 
# 卸载 
brew uninstall python3

关于pip3

相似iOS的Cocoapods,Java的Maven,前端的npm,pip3是官方自带的包处理东西,从PyPI或私有源上你能够轻松找到可供你运用的轮子(以下都称package)。

# 下载package
python3 -m pip install <package> 
# 或许 
pip3 install <package> 

# 查看已设备package 
pip3 show <package> 
# 查看下载到本地的全部package 
pip3 list [-v] 

# 卸载 
pip3 uninstall <package>

关于pip3导入包的效果域

全局效果域

一般来说,pip3 install默许导入到全局效果域,即模块导入到/usr/local/lib/python3.x/site-packages途径下,可实施文件导入到/usr/local/bin/。

在体系目录下,可被全部用户同享。

用户效果域

增加–user选项,导入到用户效果域,即模块导入到/Users/lyon/Library/Python/3.x/ lib/python/site-packages,可实施文件导入到/Users/lyon/Library/Python/3.11/bin/。

在其时用户目录下,不可被其他用户同享。

注:/Users/lyon/Library/此途径一般不在环境变量PATH中,也就是说,假定pip3 install导入到用户效果域下或许因指令不可见导致调用失利。

设备pipx

pip3设备package以用户为最小阻隔单位,即同一个用户设备的package在同一目录下。并且不支持同一个package的多版别共存,假定用户开发或运用的多个工程(以下称applicationorapp)依托的同一个package版别抵触时将无法处理。

pipx是python package,封装并优化了pip的设备逻辑,对多个app依托的packages阻隔处理,处理了上述问题。

# 设备
brew install pipx 
# 增加pipx的工作目录到PATH变量中 
pipx ensurepath

设备poetry

pip3/pipx精确说是针对东西运用者的包处理东西,比如要下载名为AppUploader的东西,运用者经过pip install设备时会主动下载该东西依托的packages。

关于东西开发者,至少需求增加及处理依托、阻隔开发和出产环境、装备指令行进口的功用,可选东西有Pipenv、venv、setuptools、Poetry等,这些东西也都能够看作是对pip功用的封装。

推荐poetry,供给了从开发、依托、编译、发布一整套的工程化处理方案,比较setuptools运用体会更好。

# 设备
pipx install poetry 
# 创立新工程 
poetry new YOUR_PROJ_NAME 
# 初始化已有工程 
poetry init 
# 增加依托 
poetry add requests 
# 导入/对齐依托 
poetry install 
# 更新依托 
poetry update requests 
# 激活虚环境(追加PATH,掩盖出产环境目录) 
poetry shell

poetry初始化之后,主要装备pyproject.toml文件,样例如下:

[tool.poetry]
name = "metis-ios-workflow"
version = "1.0.2"
description = "CLI tools for Metis."
authors = ["xxx"]
readme = "README.md"
packages = [
    {include = "metis_ios_workflow", from = "src"},
]
license = "MIT"
homepage = "xxx"
[tool.poetry.scripts]
metis = "metis_ios_workflow.cli.entry:metis"
[tool.poetry.dependencies]
python = "^3.11"
requests = "^2.31.0"
jira = {version = "^3.5.2", extras = ["cli"]}
appstoreconnect = {git = "https://github.com/xxx/xxx.git", branch = "xxx"}
[tool.poetry.group.dev.dependencies]
flake8 = "^6.0.0"
flake8-quotes = "*"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

代码风格查看

干流的代码风格查看东西有flake8,black,isort,其间black和isort供给格式化代码的进口。

关于代码风格建议详见《PEP 8 – Style Guide for Python Code》,根据标准拟定的错误码详见pycodestyle。

# 设备(仅开发环境)
poetry add flake8 isort black --group=dev

设备及装备pre-commit

pre-commit能够集中处理git hooks各个阶段的脚本,并且供给丰厚的插件及自定义插件的才干,flake8和isort均供给了相关插件,代码查看机遇可经过装备pre-commit结束,在git pre-commit时主动查看,查看不经过则commit失利。

# step1:设备
pipx install pre-commit 
# step2:经过`.pre-commit-config.yaml`装备pre-commit(git库房根目录) 
# step3:导入git hook插件(git库房根目录实施) 
pre-commit install

其间.pre-commit-config.yaml文件装备如下:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.2.0
    hooks:
      - id: end-of-file-fixer
      - id: trailing-whitespace
  - repo: https://github.com/pycqa/flake8
    rev: 4.0.1
    hooks:
      - id: flake8
        additional_dependencies: [flake8_commas, flake8_quotes]
  - repo: https://github.com/pycqa/isort
    rev: 5.12.0
    hooks:
      - id: isort

设备及装备PyCharm CE

比较VSCode,PyCharm默许集成了代码提示,风格查看,查看API,Debug东西,主动导入poetry依托,主动激活虚环境等一系列健壮功用,并且与IDEA交互风格非常相似,了解以上IDE的研制能够无缝切换,推荐运用PyCharm。

JetBrains推出了许多优异的开发东西,其间IDEA、WebStorm等是现在业界最受欢迎的IDE,PyCharm是旗下专业的Python IDE,能够下载社区免费版。

主动格式化代码

“cmd+,”进入偏好设置,找到External Tools,点击+号,这儿分别增加black和isort外部东西。

手把手教你组件化开发Python命令行东西

black装备如下,其间:

$PyInterpreterDirectory$是python3解说器途径,在poetry虚环境下便是其可实施文件目录,保证black cli在此目录下即可。

$FilePath$是其时选中的文件/目录,作为black cli入参,指定需求格式化的文件/目录。

手把手教你组件化开发Python命令行东西

isort装备如下:

手把手教你组件化开发Python命令行东西

选中文件/目录后,可在菜单栏中点击调用对应的指令结束代码格式化。

手把手教你组件化开发Python命令行东西

也能够如下装备快捷键。(或许监听文件改动主动实施,参看:Automate linting & formatting in PyCharm with your favourite tools)

手把手教你组件化开发Python命令行东西

定制指令进口

关于一套功用较杂乱的CLI,如git指令,以git [options] <command> [<args>]的方式组合了clone/commit/push等功用,便当一起查看帮忙信息,也能够结构化复用相关参数,需求定制层级分明、可组合式的指令行进口。

推荐运用click三方库辅佐规划,经过poetry add click设备。

定制一套形如metis <command> <subcommand> [<args>]的CLI,可如下规划:

metis作为指令进口,增加各子功用模块。

import click
from metis_ios_workflow.cli.cmds.app import app
from metis_ios_workflow.cli.cmds.gitlab import gitlab
from metis_ios_workflow.cli.cmds.jira import jira
from metis_ios_workflow.cli.cmds.notify import notify
from metis_ios_workflow.cli.cmds.pod import pod
from metis_ios_workflow.cli.cmds.release import release
from metis_ios_workflow.cli.cmds.scrum import scrum
from metis_ios_workflow.cli.cmds.sentry import sentry
from metis_ios_workflow.cli.cmds.xcrc import xcrc
CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]}
@click.group(context_settings=CONTEXT_SETTINGS)
@click.version_option(None, "-v", "-V", "--version")
def metis():
    pass
metis.add_command(app)
metis.add_command(notify)
metis.add_command(release)
metis.add_command(jira)
metis.add_command(gitlab)
metis.add_command(scrum)
metis.add_command(pod)
metis.add_command(sentry)
metis.add_command(xcrc)

metis release pre-release指令为例,将pre-release指令增加到release组下。

import click
from metis_ios_workflow.app_release_assist.app_review_monitor import app_review_monitor
from metis_ios_workflow.app_release_assist.post_build import post_build_cli
from metis_ios_workflow.app_release_assist.post_release import post_release_cli
from metis_ios_workflow.app_release_assist.pre_release import pre_release_cli
from metis_ios_workflow.utils.macro import BuildConfiguration
@click.group(help="发版辅佐")
def release():
    pass
@release.command(help="「预发版」任务处理")
@click.option("--target_list", type=click.STRING, required=True, help="App Target列表,以,距离")
@click.option("-v", "--version", type=click.STRING, required=True, help="App三位版别号")
@click.option(
    "--ref",
    type=click.STRING,
    required=False,
    help="设置从特定的ref(branch/tag/commitSHA)开分支,不传时默许从master分支的最新提交开分支",
)
@click.option(
    "--pbxproj_path",
    type=click.STRING,
    required=True,
    help="project.pbxproj文件途径,用于主动更新对应App的版别号",
)
def pre_release(target_list, version, ref, pbxproj_path):
    pre_release_cli(target_list, version, ref, pbxproj_path)

运用者视点能够明晰metis东西集的功用规划及运用介绍。

metis --help
Usage: metis [OPTIONS] COMMAND [ARGS]...
Options:
  -v, -V, --version  Show the version and exit.
  -h, --help         Show this message and exit.
Commands:
  app      app相关东西
  gitlab   gitlab东西
  jira     jira东西
  notify   企微告诉东西
  pod      Cocoapods东西
  release  发版辅佐
  scrum    scrum辅佐
  sentry   sentry东西
  xcrc     XCRemoteCache相关

指令入参详细介绍。

metis release pre-release --help
Usage: metis release pre-release [OPTIONS]
  「预发版」任务处理
Options:
  --target_list TEXT   App Target列表,以,距离  [required]
  -v, --version TEXT   App三位版别号  [required]
  --ref TEXT           设置从特定的ref(branch/tag/commitSHA)开分支,不传时默许从master分支的最新提交开
                       分支
  --pbxproj_path TEXT  project.pbxproj文件途径,用于主动更新对应App的版别号  [required]
  -h, --help           Show this message and exit.

发布

发布途径有三种:PyPI、私有源、git库房,对应运用方三种设备方法。

# PyPI
# 发布
poetry publish
# 设备
pip3 install <PACKAGE_NAME>

# 私有源
# 初次需装备私有源
poetry config repo.REPO_NAME REPO_INDEX_URL
# 发布
poetry publish --repository=<REPO_NAME>
# 设备
pip3 install <PACKAGE_NAME> --extra-index-url <REPO_INDEX_URL> --trusted-host <DOMAIN_OF_REPO_INDEX_URL>

# Git库房
# 发布:提交到远端分支即视为发布
# 设备
pip3 install git+ssh://git@github.com/xxx/xxx.git@BRANCH_NAME

总结

  1. 设备Python3开发包;
  2. pipx:阻隔依托packages,防止版别抵触;
  3. poetry:适用开发者的工程装备、依托处理东西集;
  4. 代码风格查看:flake8/black/isort + pre-commit,主动实施代码查看;
  5. PyCharm:自带完善功用的IDE,装备主动格式化代码;
  6. click:三方开发库,定制可组合式的指令行东西集;
  7. 三种发布及设备方法;

以上是组件化开发一套指令行东西,需求运用的东西链及装备。

工欲善其事必先利其器,或许你完结过以调用py文件的方法实施脚本,不过跟着功用逐步完善,脚本文件逐步增多,树立一套相对标准的组件化工程将助力你更高效开发高可用的东西集。

参看

pipx

poetry

PEP 8 – Style Guide for Python Code

flake8

black

isort

pre-commit

click