Skip to main content

快速构建一个干净整洁的命令行工具包。Quickly develop your command line interface(CLI) toolkit.

Project description

likeshell

PyPI version Supported Versions Apache License

Actions Status codecov

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

可变长参数(*args)

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')

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

likeshell-1.1.5.tar.gz (24.4 kB view hashes)

Uploaded Source

Built Distribution

likeshell-1.1.5-py3-none-any.whl (22.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page