Author: HelloGitHub- Prodesire
HelloGitHub of "explain open source projects" series, Project Address: https://github.com/HelloGitHub-Team/Article
Foreword
Introduced in the previous three argparse
articles, we fully understand the argparse
capabilities, we believe that many small partners have been gearing up, you want to build one of their own command-line tool.
This will be our daily work in the most common git
commands, for example, explain how to use the argparse
library to implement a real command line program available.
本系列文章默认使用 Python 3 作为解释器进行讲解。
若你仍在使用 Python 2,请注意两者之间语法和库的使用差异哦~
git commonly used commands
You may recall, usually the most commonly used git
sub-command has what?
When you write a piece of code or add or delete some files, you will use the following command to view the status file:
git status
After confirming the state of the file, the following command will use one or more files (clips) to the staging area:
git add [pathspec [pathspec ...]]
Then use the following command to submit information:
git commit -m "your commit message"
Finally, use the following command to submit push to a remote repository:
git push
We will use argparse
and gitpython
libraries to implement these four sub-command.
About gitpython
gitpython is a and git
warehouse interactive Python third party libraries.
We will borrow its ability to achieve true git
logic.
installation:
pip install gitpython
Think
Before implementation, we might think at first will use argparse
what function? Structure of the entire program is like?
argparse
- To achieve sub-command, before the introduction to the
嵌套解析器
essential - When a user types the command sub-sub-sub-command corresponding to the parser needs to respond, we need to use sub-parser
set_defaults
functions - For
git add [pathspec [pathspec ...]]
that we need to achieve positional parameters, and the number is an arbitrary number - For
git commit --message msg
orgit commit -m msg
that we need to implement the option parameters and options can be long, but also short options
Program Structure
- A command-line program needs to
cli
function as a unified entrance, which is responsible for building parser and parse command line arguments - We also need four
handle_xxx
functions in response to the corresponding sub-command
The basic structure is as follows:
import os
import argparse
from git.cmd import Git
def cli():
"""
git 命名程序入口
"""
pass
def handle_status(git, args):
"""
处理 status 命令
"""
pass
def handle_add(git, args):
"""
处理 add 命令
"""
pass
def handle_commit(git, args):
"""
处理 -m <msg> 命令
"""
pass
def handle_push(git, args):
"""
处理 push 命令
"""
pass
if __name__ == '__main__':
cli()
Below we will step by step to achieve our git
program.
achieve
We assume argparse-git.py achieve our file git
program.
Construction of the parser
We need to build a parent parser, as the root parser program, the program name as git
. Then add in the above sub-parser, resolve to prepare for subsequent sub-command:
def cli():
"""
git 命名程序入口
"""
parser = argparse.ArgumentParser(prog='git')
subparsers = parser.add_subparsers(
title='These are common Git commands used in various situations',
metavar='command')
add_subparsers
In title
and metavar
is mainly used in command-line help information, the final effect is as follows:
usage: git [-h] command ...
optional arguments:
-h, --help show this help message and exit
These are common Git commands used in various situations:
command
...
status subcommand
We need cli
to add a function for resolving status
the sub-command parser status_parser
, and specify the corresponding processing function handle_status
.
def cli():
...
# status
status_parser = subparsers.add_parser(
'status',
help='Show the working tree status')
status_parser.set_defaults(handle=handle_status)
It should be noted that, in status_parser.set_defaults
function, can receive any name keyword argument, the value will be stored in the variable parent parser command line arguments.
For example, in this sample program, we define a parser for each child up handle
, then args = parser.parse_args()
the args
will have handle
property, we pass different sub-commands, then this handle
is a different response function.
Defines status
the sub-parser, and then we realized the next handle_status
can be realized status
in response to the command:
def handle_status(git, args):
"""
处理 status 命令
"""
cmd = ['git', 'status']
output = git.execute(cmd)
print(output)
Easy to see that we finally call the real git status
to achieve, and print output.
You might be handle_status
a function signature confused, where git
and args
how is it passed? This is actually by our own control, we will explain at the end of this article.
add subcommand
Similarly, we need cli
to add a function for resolving add
the sub-command parser add_parser
, and specify the corresponding processing function handle_add
.
Extra to do is, in the sub-parser to add_parser
add on a pathspec
location parameter, and the number is arbitrary:
def cli():
...
# add
add_parser = subparsers.add_parser(
'add',
help='Add file contents to the index')
add_parser.add_argument(
'pathspec',
help='Files to add content from',
nargs='*')
add_parser.set_defaults(handle=handle_add)
Then, is to realize the handle_add
function, we need to use indicates that the file path args.pathspec
:
def handle_add(git, args):
"""
处理 add 命令
"""
cmd = ['git', 'add'] + args.pathspec
output = git.execute(cmd)
print(output)
commit subcommand
Similarly, we need cli
to add a function for resolving commit
the sub-command parser commit_parser
, and specify the corresponding processing function handle_commit
.
Extra to do it is, in the sub-parser to commit_parser
add an on -m
/ --message
option parameters, and require mandatory:
def cli():
...
# commit
commit_parser = subparsers.add_parser(
'commit',
help='Record changes to the repository')
commit_parser.add_argument(
'--message', '-m',
help='Use the given <msg> as the commit message',
metavar='msg',
required=True)
commit_parser.set_defaults(handle=handle_commit)
Then, is to realize the handle_commit
function, we need to use express submission of information args.message
:
def handle_commit(git, args):
"""
处理 -m <msg> 命令
"""
cmd = ['git', 'commit', '-m', args.message]
output = git.execute(cmd)
print(output)
push subcommand
Similarly, we need cli
to add a function for resolving push
the sub-command parser push_parser
, and specify the corresponding processing function handle_push
.
It is the same status
consistent implementation of the sub-command:
def cli():
...
# push
push_parser = subparsers.add_parser(
'push',
help='Update remote refs along with associated objects')
push_parser.set_defaults(handle=handle_push)
Then, it is to realize the handle_push
function, and handle_status
similar:
def handle_push(git, args):
cmd = ['git', 'push']
output = git.execute(cmd)
print(output)
Analytical parameters
After his son in the definition of the parser, and add parameters, we need to do to resolve the parameters, this work is implemented in the cli
function:
def cli():
...
git = Git(os.getcwd())
args = parser.parse_args()
if hasattr(args, 'handle'):
args.handle(git, args)
else:
parser.print_help()
- By
git.cmd.Git
instantiating thegit
objects, and forgit
warehouse interaction - By
parser.parse_args()
parsing the command line - By
hasattr(args, 'handle')
judging whether the input sub-command.- Since each sub-parsers are defined
handle
, then if when the user does not enter any command line command,args
there is nohandle
property, then we help information output - If the user enters subcommand, then calls
args.handle
, incominggit
andargs
object used to process the corresponding command
- Since each sub-parsers are defined
So far, we have implemented a simple git
command line, use the python argparse-git.py -h
View Help as follows:
usage: git [-h] command ...
optional arguments:
-h, --help show this help message and exit
These are common Git commands used in various situations:
command
status Show the working tree status
add Add file contents to the index
commit Record changes to the repository
push Update remote refs along with associated objects
Then we can happily use personally designed git
program it!
Want to see the entire source code, please poke argparse-git.py .
summary
This paper briefly describes the daily work commonly used git
commands, and then implement it proposed the idea of using the final step by step argparse
and gitpython
implement a git
program. Is not it great sense of accomplishment?
About argparse
explanation will come to an end, the next review argparse
Four Steps, plus the contents of today, I feel it is quite clear and simple.
However, this is just the command line opens the door to door.
Have you ever thought argparse
of four steps, while understanding the simple, but a little trouble. Is there an easier way?
If I am familiar with the command-line syntax help, I can help write a string to put all the command line to define the meta-information out? Then directly relaxed and happy to get parameter information parsed it?
In the next article, we will explain another stand on a new idea, but very powerful library docopt
.