Coder Social home page Coder Social logo

clime's Introduction

DEPRECATION

This project is deprecated and is not maintained anymore. You may like Click or Typer. Thank you for the years. ❤️

Clime

Clime lets you convert any module into a multi-command CLI program with zero configuration.

The main features:

  1. It works well with zero configuration. Free you from the configuration hell.
  2. Docstring (i.e., help text) is just configuration. When you finish your docstring, the configuration of aliases and metavars is also finished.
  3. It generates usage for each command automatically.

It is a better choice than the heavy optparse or argparse for most of the CLI tasks.

CLI-ize ME!

Let me show you Clime with an example.

We have a simple script with a docstring here: :

# file: repeat.py

def repeat(message, times=2, count=False):
    '''It repeats the message.

    options:
        -m=<str>, --message=<str>  The description of this option.
        -t=<int>, --times=<int>
        -c, --count
    '''

    s = message * times
    return len(s) if count else s

After we add this line: :

import clime.now

Our CLI program is ready! :

$ python repeat.py twice
twicetwice

$ python repeat.py --times=3 thrice
thricethricethrice

It also generates a pretty usage for this script: :

$ python repeat.py --help
usage: [-t <int> | --times=<int>] [-c | --count] <message>
   or: repeat [-t <int> | --times=<int>] [-c | --count] <message>

If you have a docstring in your function, it also shows up in usage manual with --help. :

$ python repeat.py repeat --help
usage: [-t <int> | --times=<int>] [-c | --count] <message>
   or: repeat [-t <int> | --times=<int>] [-c | --count] <message>

It repeats the message.

options:
    -m=<str>, --message=<str>  The message.
    -t=<int>, --times=<int>
    -c, --count

You can find more examples in the clime/examples.

Command describes more about how it works.

Installation

Clime is hosted on two different platforms, PyPI and GitHub.

Install from PyPI

Install Clime from PyPI for a stable version: :

$ sudo pip install clime

If you don't have pip, execute :

$ sudo apt-get install python-pip

to install pip on Debian-base Linux distribution.

Get Clime from GitHub

If you want to follow the latest version of Clime, use :

$ git clone git://github.com/moskytw/clime.git

to clone a Clime repository, or download manually from GitHub.

clime's People

Contributors

absolutelynowarranty avatar moskytw avatar naereen avatar pjw91 avatar takano32 avatar uranusjr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clime's Issues

generator output error

in core.py 543 :: 548

    if not self.ignore_return and return_val is not None:
        if inspect.isgenerator(return_val):
            for return_val in return_val:
                print result
        else:
            print return_val

for return_val in return_val:
o.O

Varargs aren't dispatched correctly

With this example function:

def repeat(message, times=2, count=False, *additional_lines):
    '''It repeats the message.

    options:
        -m=<str>, --message=<str>  The description of this option.
        -t=<int>, --times=<int>
        -c, --count
    '''
    s = message * times + '\n'.join(additional_lines)
    return len(s) if count else s

import clime.now

The help works (not -h):

$ python repeat.py -h
repeat.py: repeat() got an unexpected keyword argument '-
$ python repeat.py --help
usage: [-t<int> | --times=<int>] [-c | --count] <message> [<additional-lines>...]
   or: repeat [-t<int> | --times=<int>] [-c | --count] <message> [<additional-lines>...]

It repeats the message.

options:
    -m=<str>, --message=<str>  The description of this option.
    -t=<int>, --times=<int>
    -c, --count

But this does not work:

$ python repeat.py msg addit # This should be repeat('msg', 2, False, 'addit')
repeat.py: invalid literal for int() with base 10: 'addit'
$ python repeat.py msg -t4 addit # repeat('msg', 4, False, 'addit')
msg 4 addit ()
12
$ python repeat.py msg -t4 addit1 addit2 #  repeat('msg', 4, False, 'addit1', 'addit2')
msg 4 addit1 ('addit2',)
18

Because clime passes arguments as they are given on the command line without preserving the default ones. In the above examples -c, --count is never given on the command line, so it should always be False. Instead clime passes the additional arguments to the function as they are given on the command line.
I think clime should merge the default arguments with the ones given on the command line; if there are any arguments left, they go into varargs (if present).

support multi-value of an option

The option which has multi-value should be defined in a help text and in the following formats:

--point X Y
--list ELEMENT...

Here is a simple test case:

# file: vector.py
from operator import mul

def dot(x, y):
    '''calculate a dot product for vectors

    options:
        -x SCALARS...  x vector
        -y SCALARS...  y vector
    '''
    return sum(map(mul, x, y))

if __name__ == '__main__':
    from clime import now

On shell:

$ python vector.py dot -x 2 3 1 -y -1 2 0
4

It is supported by most of CLI frameworks.

note: Actually, Clime has supported it in another syntax (not in GNU standard?), -x 2 -x 3 -x 1 -y.... See the smartlyadd in clime.helpers.

Give option to display docstring description for commands

def draw(story, squash=1):
    '''It draws a pyramid.

    -s <int>, --squash=<int>
    '''

    ground_len = 1 + (story-1) * squash * 2

    for i in range(1, ground_len+1, squash*2):
        print ('*'*i).center(ground_len)

It would be nice to show It draws a pyramid. somewhere.

It would also be nice if it was possible to get detailed help for a single command. Something like: ./test.py help draw
The docstring description would fit nicely in there.

data flow

恩..套關係失敗~ 直接發好了

linux 指令特性, 流程
command1 && command2
command1 的exit code == 0 才會繼續command2

core.py
531...
try:
# execute the command with the raw arguments.
return_val = cmd.execute(raw_args)
except Exception, e:
if self.debug:
from traceback import print_exception
print_exception(*sys.exc_info())
return
else:
self.complain(e)
return
可以明顯的看到 你在cli程式出錯後 接到exception 沒有送exit code.. 所以流程&&沒用..

483...
def complain(self, msg):
'''Print an error message msg with the name of this program to stderr.'''
print >> sys.stderr, '%s: %s' % (self.name, msg)
可是這邊又有把錯誤訊息送到stderr

我想應該是你漏掉了...

generator output error

in core.py 543 :: 548

    if not self.ignore_return and return_val is not None:
        if inspect.isgenerator(return_val):
            for return_val in return_val:
                print result
        else:
            print return_val

for return_val in return_val:
o.O

pipeline

linux 部分指令有的令一個特性~
看你喜不喜歡而已..

cmd1|cmd2
會把cmd1 的stdout 當cmd2 的stdin輸入~

看起來和你的clime好像沒太大關係XD

不過加入pipeline 的概念後就可以達成像是

add.py 1 2|add.py 1|add.py 1|sub.py 1
這種感覺的命令~

另外就是, 如果你想要批次處理命令~
像是整個檔案每一行都是資料要經過某函式做處理的話~

說的不太好.. 反正就是可以用python做到類似sed的功能就是..... 當然我想大多會想要支援pipeline 的命令都會直接接stdin 不過總會有一些每行都是獨立的資料的~

make parsing behavior like GNU toolkit

Clime parses the options by the way which I favor, but I think it is not good.

It will avoid misunderstand to use the way people have known, such as the behavior of GNU toolkit.

Maybe it should let user select the style her want to use.

support the nest sub-commands

At first, I had considered the nest sub-commands, but it doesn't work well at the current version. So I want to make it work if I have spare time.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.