文中涉及的示例代碼,已同步更新到 HelloGitHub-Team 倉庫html
在前面兩篇介紹 docopt
的文章中,咱們全面瞭解了 docopt
的能力。按照慣例,咱們要像使用 argparse
同樣使用 docopt
來實現 git 命令。python
爲了讓沒讀過 使用 argparse 實現 git 命令
的小夥伴也能讀明白本文,咱們仍會對 git 經常使用命令和 gitpython 作一個簡單介紹。git
本系列文章默認使用 Python 3 做爲解釋器進行講解。
若你仍在使用 Python 2,請注意二者之間語法和庫的使用差別哦~
複製代碼
當你寫好一段代碼或增刪一些文件後,會用以下命令查看文件狀態:github
git status
複製代碼
確認文件狀態後,會用以下命令將的一個或多個文件(夾)添加到暫存區:編程
git add [pathspec [pathspec ...]]
複製代碼
而後使用以下命令提交信息:bash
git commit -m "your commit message"
複製代碼
最後使用以下命令將提交推送到遠程倉庫:函數
git push
複製代碼
咱們將使用 docopt
和 gitpython
庫來實現這 4 個子命令。spa
gitpython 是一個和 git
倉庫交互的 Python 第三方庫。 咱們將借用它的能力來實現真正的 git
邏輯。命令行
安裝:code
pip install gitpython
複製代碼
在實現前,咱們不妨先思考下會用到 docopt
的哪些功能?整個程序的結構是怎樣的?
docopt
不一樣於使用 argparse
時須要考慮嵌套解析器、各種參數等問題,在使用 docopt
只需將咱們要實現的 git 命令用接口描述先定義清楚便可。
程序結構
程序結構上,除了開頭處定義接口描述外,其他和使用 argparse
實現 git 命令的結構是同樣的:
cli
函數來做爲統一的入口,它負責構建解析器,並解析命令行參數handle_xxx
函數響應對應的子命令則基本結構以下:
import os
import docopt
from git.cmd import Git
def cli():
""" git 命名程序入口 """
pass
def handle_status(git):
""" 處理 status 命令 """
pass
def handle_add(git, pathspec):
""" 處理 add 命令 """
pass
def handle_commit(git, msg):
""" 處理 -m <msg> 命令 """
pass
def handle_push(git):
""" 處理 push 命令 """
pass
if __name__ == '__main__':
cli()
複製代碼
下面咱們將一步步地實現咱們的 git
程序。
假定咱們在 docopt-git.py 文件中實現咱們的 git
程序。
根據咱們的要求,能夠很容易的定義出接口描述:
Usage:
git status
git add [<pathspec>...]
git commit -m msg
git push
Options:
-h --help Show help.
-m --message msg Commit with message.
複製代碼
進而就能夠在 cli()
中解析命令行:
def cli():
""" git 命名程序入口 """
args = docopt(__doc__)
git = Git(os.getcwd())
複製代碼
若是 args['status']
爲 True
,說明輸入了 status 子命令,那麼就調用 handle_status
函數進行處理。
def cli():
...
if args['status']:
handle_status(git)
def handle_status(git):
""" 處理 status 命令 """
cmd = ['git', 'status']
output = git.execute(cmd)
print(output)
複製代碼
不難看出,咱們最後調用了真正的 git status
來實現,並打印了輸出。
若是 args['add']
爲 True
,說明輸入了 add 子命令,那麼就調用 handle_add
函數進行處理,須要傳入 args['<pathspec>']
表示添加的路徑。
def cli():
...
elif args['add']:
handle_add(git, args['<pathspec>'])
def handle_add(git, pathspec):
""" 處理 add 命令 """
cmd = ['git', 'add'] + pathspec
output = git.execute(cmd)
print(output)
複製代碼
若是 args['commit']
爲 True
,說明輸入了 commit 子命令,那麼就調用 handle_commit
函數進行處理,須要傳入 args['--message']
表示提交的信息。
def cli():
...
elif args['commit']:
handle_commit(git, args['--message'])
def handle_commit(git, msg):
""" 處理 -m <msg> 命令 """
cmd = ['git', 'commit', '-m', msg]
output = git.execute(cmd)
print(output)
複製代碼
若是 args['push']
爲 True
,說明輸入了 commit 子命令,那麼就調用 handle_push
函數進行處理。
def cli():
...
elif args['push']:
handle_push(git)
def handle_push(git):
""" 處理 push 命令 """
cmd = ['git', 'push']
output = git.execute(cmd)
print(output)
複製代碼
至此,咱們就實現了一個簡單的 git
命令行,使用 python docopt-git.py status
即可查詢項目狀態。
想看整個源碼,請戳 docopt-git.py 。
本文簡單介紹了平常工做中經常使用的 git
命令,而後提出實現它的思路,最終一步步地使用 docopt
和 gitpython
實現了 git
程序。
對比 argparse
的實現版本,你會發現使用 docopt
來實現變得很是簡單,子解析器、參數類型什麼的通通不須要關心!這能夠說是 docopt
最大的優點了。
關於 docopt
的講解將告一段落,回顧下 docopt
的三步曲,加上今天的內容,感受它的使用方式仍是比 argparse
簡單很多的。
如今,你已學會了兩個命令行解析庫的使用了。但你覺得這就夠了嗎?
但人類的智慧是多麼璀璨呀,有些人並不喜歡這兩個庫的使用方式,因而他們有開闢了一個全新的思路。
在下篇文章中,將爲你們介紹一個在 Python 界十分流行的命令行庫 —— click
。
『講解開源項目系列』——讓對開源項目感興趣的人再也不畏懼、讓開源項目的發起者再也不孤單。跟着咱們的文章,你會發現編程的樂趣、使用和發現參與開源項目如此簡單。歡迎留言聯繫咱們、加入咱們,讓更多人愛上開源、貢獻開源~