likeshell 快速构建自己的命令行工具,扩展性强、可配置、开箱即用、干净整洁,只需一步构建自己的CLI。
likeshell通过定义类中方法的形式定义CLI中的命令,极少有任务逻辑外的代码,使用简单,使开发的CLI程序简洁易用可读性强。
Python >= 3.6
使用pip安装
$ pip install likeshell
1.创建一个python文件,这里命名为demo.py。
import likeshell
class MyTasks(likeshell.Shell): # 定义类并继承likeshell.Shell,类名并不影响程序。
def task1( # 命令名默认为方法名称
self, # 默认按顺序输入参数,self被忽略
s1, # 不指定类型则不校验
i1: int, # 指定类型会校验参数类型
f1: float
):
print('run test1')
print(f's1 is {s1}')
print(f'i1 is {i1}')
print(f'f1 is {f1}')
def task2(self):
print('run test2')
2.在终端中输入。
>> python demo.py task1 str1 100 10.01
<< run test1
s1 is str1
i1 is 100
f1 is 10.01
>> python demo.py task1
<< likeshell.exceptions.ParameterError: MissingParameter: s1.
>> python demo.py task1 str1 str2 str3
<< likeshell.exceptions.ParameterError: ParameterTypeError: "str2" is not a int
>> python demo.py task2
<< run test2
基础使用可完全使用Python语法,除继承操作外不需要使用likeshell
中的任何方法。
1.创建命令类并继承likeshell.Shell
2.创建相应的命令任务(命令默认为方法名)
3.定义参数
# 导入likeshell包
import likeshell
# 创建类并继承likeshell.Shell
class MyTasks(likeshell.Shell):
# 创建相应的命令任务
def task1(self, s1, i1, f1):
print('run test1')
print(f's1 is {s1}')
print(f'i1 is {i1}')
print(f'f1 is {f1}')
def task2(self):
print('run test2')
任务中的参数定义
通过type annotation语法增加类型校验
import likeshell
class MyTasks(likeshell.Shell):
def task1(self, s1):
print(f's1 is {s1}')
def task2(self, i1: int):
print(f'i1 is {i1}')
>> python demo.py task1 100
<< s1 is 100
>> python demo.py task2 str1
<< likeshell.exceptions.ParameterError: ParameterTypeError: "str1" is not a int
import likeshell
class MyTasks(likeshell.Shell):
def task1(self, *args):
print(f'args: {args}')
>> python demo.py task1 a1 a2 a3
<< args: ['a1', 'a2', 'a3']
import likeshell
class MyTasks(likeshell.Shell):
def task1(
self,
s1: str,
*, # 通过*分割必要参数与非必要参数
s2: str = 'string'
):
print(f's1: {s1}')
print(f's2: {s2}')
>> python demo.py task1 str1
<< s1: str1
s2: string
>> python demo.py task1 str1 str2
<< s1: str1
s2: str2
import likeshell
class GitShell(likeshell.Shell):
# 在命令执行之前生效
def __before__(self):
print('run before')
# 在命令执行之后生效
def __after__(self):
print('run after')
通过-h
或--help
获得方法相关的提示
import likeshell
class MyTasks(likeshell.Shell):
@likeshell.desc('This is task1') # likeshell.desc定义命令的简要说明 在-h中打印 不定义默认打印comment多行注释中的有效内容第一行
def task1(self, s1, i1, f1):
"""
定义多行注释,help会将其作为命令说明打印
task1说明:
task1 takes 3 arguments
"""
print('run test1')
print(f's1 is {s1}')
print(f'i1 is {i1}')
print(f'f1 is {f1}')
def task2(self):
"""
task is a method
"""
print('run test2')
>> python demo.py
<< 帮助:
<shell> -h
<shell> -h <action>
用法:
<shell> <action> [options...]
命令:
task1 This is task1
task2 task is a method
>> python demo.py -h task1
<< 定义多行注释,help会将其作为命令说明打印
task1说明:
task1 takes 3 arguments
在程序中命令默认去匹配方法名, 当希望使用的命令名为python中关键字、包含特殊字符或希望定义的更加简短时,可以通过定义别名的方式实现。
likeshell提供两种方式来实现。
使用likeshell.alias
装饰器实现别名定义
import likeshell
class MyTasks(likeshell.Shell):
# 定义方法task1的别名为lambda
@likeshell.alias('lambda')
def task1(self):
print('run task1')
>> python demo.py lambda
<< run task1
在方法中定义:alias
开头的多行注释
通过空格
或:
分割实现别名定义
import likeshell
class MyTasks(likeshell.Shell):
def task1(self):
"""
定义方法task1的别名为lambda
:alias: lambda
"""
print('run task1')
>> python demo.py lambda
<< run task1
让指定任务命令不再被识别,也无法再调用
使用likeshell.ignore
装饰器无视指定的方法
import likeshell
class MyTasks(likeshell.Shell):
@likeshell.ignore
def task1(self):
print('run task1')
>> python demo.py task1
<< RuntimeError: task1 is not found.
实现用户输入
import likeshell
class MyTasks(likeshell.Shell):
def task1(
self,
a: likeshell.Input # 定义类型为 likeshell.Input
):
print('run task1')
print(a)
>> python demo.py task1
>> a:
>> a: hello world
<< run task1
hello world
import likeshell
def valid(arg):
arg += '!'
return arg
class MyTasks(likeshell.Shell):
def task1(
self,
a: str,
b: likeshell.Input(prompt='username:', default='default', hide=False, callback=valid),
c: str
):
"""
参数说明
:prompt: 输入时显示的提示字符串
:default: 输入为空时 使用默认值 也可以通过定义参数默认值实现
:hide: 隐藏输入内容 默认为False
:callback: 回调函数 要求接收一个参数 返回一个参数
"""
print('run task1')
print(a)
print(b)
print(c)
>> python demo.py task1 astr cstr
>> username: joker
<< run task1
astr
joker!
cstr
支持以-a
、--arg
绑定标签的形式定义参数
import likeshell
class MyTasks(likeshell.Shell):
def task1(
self,
a1,
a2: likeshell.Options(tag='--a2', arglen=2),
):
"""
参数说明
:tag: 可识别的标签名 多个使用元组或列表例如['-a', '--arg']
:arglen: 指定接收的参数个数
"""
print(a1, a2[0], a2[1])
assert a1 == 'hello'
assert a2 == ['world', '!']
>> python demo.py task1 hello --a2 world !
<< hello world !
import likeshell
class MyTasks(likeshell.Shell):
@likeshell.Options(arg='a1', tag='--a1')
@likeshell.Options(arg='a2', tag='--a2')
def task1(
self,
a1,
a2,
):
"""
参数说明
:arg: 可选参数对应的位置参数名称
:tag: 可识别的标签名 要定义多个标签则使用元组或列表 例如['-a', '--arg']
:arglen: 指定接收的参数个数
定义为0 将会接收到为'exist'的字符串或默认值
默认定义为1 接收指定的字符串或默认值
定义为大于1的数组 接收多个参数的列表或默认值
"""
print(a1, a2)
assert a1 == 'hello'
assert a2 == 'world'
>> python demo.py task1 --a2 world -a1 hello
<< hello world
import likeshell
class MyTasks(likeshell.Shell):
def task1(self):
self.cmd('git branch')
# likeshell.cmd('git branch') # 两者效果一样
# p = self.cmd('git branch', popen=True) # 通过子进程执行命令
# print(p.pid)
>> python demo.py task1
>> * master
当CLI程序需要配置入口时
import likeshell
from likeshell.shell import run_cls
class MyTasks(likeshell.Main): # 继承 likeshell.Main
def task1(self):
print('run task1')
def run():
# 调用run_cls方法
run_cls(MyTasks, MyTasks.__dict__)
import likeshell
class MyTasks(likeshell.Shell):
__default_bash__ = 'git' # 命令未击中时 可以使用其他cli (默认为None)
__options_handler__ = likeshell.SimpleOptionsHandler() # 参数处理器
def task1(self):
print('run task1')