涉及的示例代碼和歷史文章,已同步更新到 HelloGitHub-Team 倉庫html
在前面三篇介紹 fire
的文章中,咱們全面瞭解了 fire
強大而不失簡潔的能力。按照慣例,咱們要像使用 argparse
、docopt
和 click
同樣使用 fire
來實現 git 命令。python
本文的關注點並不在 git
的各類命令是如何實現的,而是怎麼使用 fire
去打造一個實用命令行程序,代碼結構是怎樣的。所以,和 git
相關的操做,將會使用 gitpython
庫來簡單實現。git
爲了讓沒讀過 使用 xxx 實現 git 命令
(xxx
指 argparse
、docopt
和 click
) 的小夥伴也能讀明白本文,咱們仍會對 git
經常使用命令和 gitpython
作一個簡單介紹。github
本系列文章默認使用 Python 3 做爲解釋器進行講解。
若你仍在使用 Python 2,請注意二者之間語法和庫的使用差別哦~
複製代碼
當你寫好一段代碼或增刪一些文件後,會用以下命令查看文件狀態:編程
git status
複製代碼
確認文件狀態後,會用以下命令將的一個或多個文件(夾)添加到暫存區:bash
git add [pathspec [pathspec ...]]
複製代碼
而後使用以下命令提交信息:函數
git commit -m "your commit message"
複製代碼
最後使用以下命令將提交推送到遠程倉庫:ui
git push
複製代碼
咱們將使用 fire
和 gitpython
庫來實現這 4 個子命令。spa
gitpython 是一個和 git
倉庫交互的 Python 第三方庫。 咱們將借用它的能力來實現真正的 git
邏輯。命令行
安裝:
pip install gitpython
複製代碼
在實現前,咱們不妨先思考下會用到 fire
的哪些功能?整個程序的結構是怎樣的?
fire
git
的 4 個子命令的實現其實對應於四個函數,咱們能夠都放到一個類中,實現四個實例方法。 而對於 git add
命令,須要接受任意個參數,在實例方法中用 *pathspecs
參數來表達。 對於 git commit
命令,須要接受 -m
選項,在實例方法中用 m
參數來表達。
程序結構
程序結構上:
Git
對象,供全局使用GitCli
類中定義四個命令對應的實例方法 status
、add
、commit
、push
則基本結構以下:
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 <msg> 命令 """
pass
def push(self):
""" 處理 push 命令 """
pass
if __name__ == '__main__':
fire.Fire(GitCli())
複製代碼
下面咱們將一步步地實現咱們的 git
程序。
假定咱們在 fire-git.py 文件中實現咱們的 git
程序。
status
子命令不接受任何參數和選項,所以 status
方法無需任何入參。
class GitCli:
def status(self):
""" 處理 status 命令 """
cmd = ['git', 'status']
output = git.execute(cmd)
return output
複製代碼
不難看出,咱們最後調用了真正的 git status
來實現,並打印了輸出。
add
子命令相對於 status
子命令,須要接受任意個 pathspec 參數,所以 add
方法須要增長 *pathspecs
入參。 fire 最終傳入的是一個元組,咱們須要將其轉換成 list 以便後續處理。
class GitCli:
def add(self, *pathspecs):
""" 處理 add 命令 """
cmd = ['git', 'add'] + list(pathspecs)
output = git.execute(cmd)
return output
複製代碼
當咱們執行 python3 fire-git.py add --help
時,結果以下:
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
複製代碼
commit
子命令相對於 status
子命令,須要接受 -m
選項,所以 commit
方法須要增長 m
入參。
class GitCli:
def commit(self, m):
""" 處理 -m <msg> 命令 """
cmd = ['git', 'commit', '-m', m]
output = git.execute(cmd)
return output
複製代碼
push
子命令同 status
子命令同樣,不接受任何參數和選項,所以 push
方法無需任何入參。
class GitCli:
def push(self):
""" 處理 push 命令 """
cmd = ['git', 'push']
output = git.execute(cmd)
return output
複製代碼
至此,咱們就實現了一個簡單的 git
命令行,使用 python fire-git.py status
即可查詢項目狀態。
很是方便的是,每一個命令函數的 docstring
都將做爲這個命令的幫助信息,所以,當咱們執行 python3 fire-git.py --help
會自動生成以下幫助內容:
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 <msg> 命令
push
處理 push 命令
status
處理 status 命令
複製代碼
想看整個源碼,請戳 fire-git.py 。
本文簡單介紹了平常工做中經常使用的 git
命令,而後提出實現它的思路,最終一步步地使用 fire
和 gitpython
實現了 git
程序。
對比 argparse
、docopt
和 click
的實現版本,你會發現使用 fire
來實現是最簡單的:
argparse
,子解析器、參數類型什麼的通通不須要關心docopt
,參數解析和命令調用處理也不須要關心click
,裝飾器所定義的命令行參數信息也必需要關心無疑,fire
把能簡化的都簡化了,簡直就是懶人福音。
關於 fire
的講解將告一段落,回顧下 fire
的至簡之道,你會深愛上它。這也體現出了 Python 之美。
如今,你已學會了四個特色各異的主流命令行解析庫的使用了,不再須要爲命令行程序的實現而煩惱了。
什麼,你爲要使用哪個庫而發愁?在下一篇也是最後一篇文章中,咱們將對這些庫作一個橫向對比,以對什麼場景下使用什麼樣的命令行庫瞭然於胸~
『講解開源項目系列』——讓對開源項目感興趣的人再也不畏懼、讓開源項目的發起者再也不孤單。跟着咱們的文章,你會發現編程的樂趣、使用和發現參與開源項目如此簡單。歡迎留言聯繫咱們、加入咱們,讓更多人愛上開源、貢獻開源~