Google 開源的 Python 命令行庫(kù):fire 實(shí)現(xiàn) git 命令
掃描二維碼
隨時(shí)隨地手機(jī)看文章
一、前言
在前面三篇介紹 fire的文章中,我們?nèi)媪私饬?fire強(qiáng)大而不失簡(jiǎn)潔的能力。按照慣例,我們要像使用 argparse、docopt和 click一樣使用 fire來(lái)實(shí)現(xiàn) git 命令。
本文的關(guān)注點(diǎn)并不在 git的各種命令是如何實(shí)現(xiàn)的,而是怎么使用 fire去打造一個(gè)實(shí)用命令行程序,代碼結(jié)構(gòu)是怎樣的。因此,和 git相關(guān)的操作,將會(huì)使用 gitpython庫(kù)來(lái)簡(jiǎn)單實(shí)現(xiàn)。
為了讓沒讀過(guò) 使用 xxx 實(shí)現(xiàn) git 命令(xxx指 argparse、docopt和 click) 的小伙伴也能讀明白本文,我們?nèi)詴?huì)對(duì) git常用命令和 gitpython做一個(gè)簡(jiǎn)單介紹。
本系列文章默認(rèn)使用 Python 3 作為解釋器進(jìn)行講解。
若你仍在使用 Python 2,請(qǐng)注意兩者之間語(yǔ)法和庫(kù)的使用差異哦~
二、git 常用命令
當(dāng)你寫好一段代碼或增刪一些文件后,會(huì)用如下命令查看文件狀態(tài):
git status
確認(rèn)文件狀態(tài)后,會(huì)用如下命令將的一個(gè)或多個(gè)文件(夾)添加到暫存區(qū):
git add [pathspec [pathspec ...]]
然后使用如下命令提交信息:
git commit -m "your commit message"
最后使用如下命令將提交推送到遠(yuǎn)程倉(cāng)庫(kù):
git push
我們將使用 fire和 gitpython庫(kù)來(lái)實(shí)現(xiàn)這 4 個(gè)子命令。
三、關(guān)于 gitpython
gitpython[1] 是一個(gè)和 git倉(cāng)庫(kù)交互的 Python 第三方庫(kù)。我們將借用它的能力來(lái)實(shí)現(xiàn)真正的 git邏輯。
安裝:
pip install gitpython
四、思考
在實(shí)現(xiàn)前,我們不妨先思考下會(huì)用到 fire的哪些功能?整個(gè)程序的結(jié)構(gòu)是怎樣的?
fire
git的 4 個(gè)子命令的實(shí)現(xiàn)其實(shí)對(duì)應(yīng)于四個(gè)函數(shù),我們可以都放到一個(gè)類中,實(shí)現(xiàn)四個(gè)實(shí)例方法。而對(duì)于 git add命令,需要接受任意個(gè)參數(shù),在實(shí)例方法中用 *pathspecs參數(shù)來(lái)表達(dá)。對(duì)于 git commit命令,需要接受 -m選項(xiàng),在實(shí)例方法中用 m參數(shù)來(lái)表達(dá)。
程序結(jié)構(gòu)
程序結(jié)構(gòu)上:
-
實(shí)例化 Git對(duì)象,供全局使用
-
在 GitCli類中定義四個(gè)命令對(duì)應(yīng)的實(shí)例方法 status、add、commit、push
則基本結(jié)構(gòu)如下:
import os import fire from git.cmd import Git
git = Git(os.getcwd()) class GitCli: def status(self): """
處理 status 命令
""" pass def add(self, *pathspecs): """
處理 add 命令
""" pass def commit(self, m): """
處理 -m命令
""" pass def push(self): """
處理 push 命令
""" pass if __name__ == '__main__':
fire.Fire(GitCli())
下面我們將一步步地實(shí)現(xiàn)我們的 git程序。
五、實(shí)現(xiàn)
假定我們?cè)?fire-git.py[2] 文件中實(shí)現(xiàn)我們的 git程序。
5.1 status 子命令
status子命令不接受任何參數(shù)和選項(xiàng),因此 status方法無(wú)需任何入?yún)ⅰ?
class GitCli: def status(self): """
處理 status 命令
""" cmd = ['git', 'status']
output = git.execute(cmd) return output
不難看出,我們最后調(diào)用了真正的 git status來(lái)實(shí)現(xiàn),并打印了輸出。
5.2 add 子命令
add子命令相對(duì)于 status子命令,需要接受任意個(gè) pathspec 參數(shù),因此 add方法需要增加 *pathspecs入?yún)?。fire 最終傳入的是一個(gè)元組,我們需要將其轉(zhuǎn)換成 list 以便后續(xù)處理。
class GitCli: def add(self, *pathspecs): """
處理 add 命令
""" cmd = ['git', 'add'] + list(pathspecs)
output = git.execute(cmd) return output
當(dāng)我們執(zhí)行 python3 fire-git.py add --help時(shí),結(jié)果如下:
INFO: Showing help with the command 'fire-git.py add -- --help'.
NAME
fire-git.py add - 處理 add 命令
SYNOPSIS
fire-git.py add [PATHSPECS]...
DESCRIPTION
處理 add 命令
POSITIONAL ARGUMENTS
PATHSPECS
5.3 commit 子命令
commit子命令相對(duì)于 status子命令,需要接受 -m選項(xiàng),因此 commit方法需要增加 m入?yún)ⅰ?
class GitCli: def commit(self, m): """
處理 -m命令
""" cmd = ['git', 'commit', '-m', m]
output = git.execute(cmd) return output
5.4 push 子命令
push子命令同 status子命令一樣,不接受任何參數(shù)和選項(xiàng),因此 push方法無(wú)需任何入?yún)ⅰ?
class GitCli: def push(self): """
處理 push 命令
""" cmd = ['git', 'push']
output = git.execute(cmd) return output
至此,我們就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的 git命令行,使用 python fire-git.py status便可查詢項(xiàng)目狀態(tài)。
非常方便的是,每個(gè)命令函數(shù)的 docstring都將作為這個(gè)命令的幫助信息,因此,當(dāng)我們執(zhí)行 python3 fire-git.py --help會(huì)自動(dòng)生成如下幫助內(nèi)容:
INFO: Showing help with the command 'fire-git.py -- --help'.
NAME
fire-git.py
SYNOPSIS
fire-git.py COMMAND
COMMANDS
COMMAND is one of the following:
add
處理 add 命令
commit
處理 -m命令
push
處理 push 命令
status
處理 status 命令
想看整個(gè)源碼,請(qǐng)戳 fire-git.py[3] 。
六、小結(jié)
本文簡(jiǎn)單介紹了日常工作中常用的 git命令,然后提出實(shí)現(xiàn)它的思路,最終一步步地使用 fire和 gitpython實(shí)現(xiàn)了 git程序。
對(duì)比 argparse、docopt和 click的實(shí)現(xiàn)版本,你會(huì)發(fā)現(xiàn)使用 fire來(lái)實(shí)現(xiàn)是最簡(jiǎn)單的:
-
相較于 argparse,子解析器、參數(shù)類型什么的統(tǒng)統(tǒng)不需要關(guān)心
-
相較于 docopt,參數(shù)解析和命令調(diào)用處理也不需要關(guān)心
-
相較于 click,裝飾器所定義的命令行參數(shù)信息也必須要關(guān)心
無(wú)疑,fire把能簡(jiǎn)化的都簡(jiǎn)化了,簡(jiǎn)直就是懶人福音。
關(guān)于 fire的講解將告一段落,回顧下 fire的至簡(jiǎn)之道,你會(huì)深愛上它。這也體現(xiàn)出了 Python 之美。
現(xiàn)在,你已學(xué)會(huì)了四個(gè)特點(diǎn)各異的主流命令行解析庫(kù)的使用了,再也不需要為命令行程序的實(shí)現(xiàn)而煩惱了。





