Package: likeshell
likeshelllikeshell 快速构建自己的命令行工具，扩展性强、可配置、开箱即用、干净整洁，只需一步构建自己的CLI。likeshell通过定义类中方法的形式定义CLI中的命令，极少有任务逻辑外的代码，使用简单，使开发的CLI程序简洁易用可读性强。要求Python >= 3.6安装使用pip安装$pipinstalllikeshell简单使用1.创建一个python文件，这里命名为demo.py。importlikeshellclassMyTasks(likeshell.Shell):# 定义类并继承likeshell.Shell，类名并不影响程序。deftask1(# 命令名默认为方法名称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}')deftask2(self):print('run test2')2.在终端中输入。>>pythondemo.pytask1str110010.01<< run test1s1 is str1i1 is 100f1 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<< runtest2功能文档基础功能基本使用参数钩子帮助高级功能任务别名无视任务输入(input)可选参数命令执行程序入口配置基本使用基础使用可完全使用Python语法，除继承操作外不需要使用likeshell中的任何方法。1.创建命令类并继承likeshell.Shell2.创建相应的命令任务(命令默认为方法名)
3.定义参数# 导入likeshell包importlikeshell# 创建类并继承likeshell.ShellclassMyTasks(likeshell.Shell):# 创建相应的命令任务deftask1(self,s1,i1,f1):print('run test1')print(f's1 is{s1}')print(f'i1 is{i1}')print(f'f1 is{f1}')deftask2(self):print('run test2')参数任务中的参数定义参数类型通过type annotation语法增加类型校验importlikeshellclassMyTasks(likeshell.Shell):deftask1(self,s1):print(f's1 is{s1}')deftask2(self,i1:int):print(f'i1 is{i1}')>>pythondemo.pytask1100<< s1 is100>>pythondemo.pytask2str1<< likeshell.exceptions.ParameterError:ParameterTypeError:"str1"isnotaint可变长参数(*args)importlikeshellclassMyTasks(likeshell.Shell):deftask1(self,*args):print(f'args:{args}')>>pythondemo.pytask1a1a2a3<< args: ['a1', 'a2', 'a3']非必要参数与默认值importlikeshellclassMyTasks(likeshell.Shell):deftask1(self,s1:str,*,# 通过*分割必要参数与非必要参数s2:str='string'):print(f's1:{s1}')print(f's2:{s2}')>>pythondemo.pytask1str1<< s1: str1s2: string>> python demo.py task1 str1 str2<< s1:str1s2:str2钩子importlikeshellclassGitShell(likeshell.Shell):# 在命令执行之前生效def__before__(self):print('run before')# 在命令执行之后生效def__after__(self):print('run after')帮助通过-h或--help获得方法相关的提示importlikeshellclassMyTasks(likeshell.Shell):@likeshell.desc('This is task1')# likeshell.desc定义命令的简要说明 在-h中打印 不定义默认打印comment多行注释中的有效内容第一行deftask1(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}')deftask2(self):"""task is a method"""print('run test2')>>pythondemo.py
<<帮助:<shell>-h<shell>-h<action>用法:<shell><action>[options...]命令:task1Thisistask1task2taskisamethod


>>pythondemo.py-htask1
<<定义多行注释，help会将其作为命令说明打印task1说明:task1takes3arguments任务别名在程序中命令默认去匹配方法名，
当希望使用的命令名为python中关键字、包含特殊字符或希望定义的更加简短时，可以通过定义别名的方式实现。likeshell提供两种方式来实现。通过装饰器使用likeshell.alias装饰器实现别名定义importlikeshellclassMyTasks(likeshell.Shell):# 定义方法task1的别名为lambda@likeshell.alias('lambda')deftask1(self):print('run task1')>>pythondemo.pylambda
<<runtask1通过多行注释在方法中定义:alias开头的多行注释
通过空格或:分割实现别名定义importlikeshellclassMyTasks(likeshell.Shell):deftask1(self):"""定义方法task1的别名为lambda:alias: lambda"""print('run task1')>>pythondemo.pylambda
<<runtask1无视任务让指定任务命令不再被识别，也无法再调用通过装饰器使用likeshell.ignore装饰器无视指定的方法importlikeshellclassMyTasks(likeshell.Shell):@likeshell.ignoredeftask1(self):print('run task1')>>pythondemo.pytask1
<<RuntimeError:task1isnotfound.输入实现用户输入使用importlikeshellclassMyTasks(likeshell.Shell):deftask1(self,a:likeshell.Input# 定义类型为 likeshell.Input):print('run task1')print(a)>>pythondemo.pytask1
>>a:
>>a:helloworld<< run task1hello world参数说明importlikeshelldefvalid(arg):arg+='!'returnargclassMyTasks(likeshell.Shell):deftask1(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)>>pythondemo.pytask1astrcstr
>>username:joker<< run task1astrjoker!cstr可选参数支持以-a、--arg绑定标签的形式定义参数通过类型定义importlikeshellclassMyTasks(likeshell.Shell):deftask1(self,a1,a2:likeshell.Options(tag='--a2',arglen=2),):"""参数说明:tag: 可识别的标签名 多个使用元组或列表例如['-a', '--arg']:arglen: 指定接收的参数个数"""print(a1,a2[0],a2[1])asserta1=='hello'asserta2==['world','!']>>pythondemo.pytask1hello--a2world!
<<helloworld!通过装饰器importlikeshellclassMyTasks(likeshell.Shell):@likeshell.Options(arg='a1',tag='--a1')@likeshell.Options(arg='a2',tag='--a2')deftask1(self,a1,a2,):"""参数说明:arg: 可选参数对应的位置参数名称:tag: 可识别的标签名 要定义多个标签则使用元组或列表 例如['-a', '--arg']:arglen: 指定接收的参数个数定义为0 将会接收到为'exist'的字符串或默认值默认定义为1 接收指定的字符串或默认值定义为大于1的数组 接收多个参数的列表或默认值"""print(a1,a2)asserta1=='hello'asserta2=='world'>>pythondemo.pytask1--a2world-a1hello
<<helloworld命令执行使用importlikeshellclassMyTasks(likeshell.Shell):deftask1(self):self.cmd('git branch')# likeshell.cmd('git branch')  # 两者效果一样# p = self.cmd('git branch', popen=True)  # 通过子进程执行命令# print(p.pid)>>pythondemo.pytask1
>>*master程序入口当CLI程序需要配置入口时importlikeshellfromlikeshell.shellimportrun_clsclassMyTasks(likeshell.Main):# 继承 likeshell.Maindeftask1(self):print('run task1')defrun():# 调用run_cls方法run_cls(MyTasks,MyTasks.__dict__)配置importlikeshellclassMyTasks(likeshell.Shell):__default_bash__='git'# 命令未击中时 可以使用其他cli (默认为None)__options_handler__=likeshell.SimpleOptionsHandler()# 参数处理器deftask1(self):print('run task1')