git subcommand with --help arg, not working - python

Having this example code:
#!/usr/bin/env python3
import argparse
def main():
parser = argparse.ArgumentParser(description="Some Description")
parser.add_argument('some-arg')
args = parser.parse_args()
print(args)
if __name__ == '__main__':
main()
I add this code to file called git-mycommand, made it executable and copied it to /usr/bin.
Now trying to run command with --help, gives me this unintended output:
user#user:~$ git mycommand --help
No manual entry for git-mycommand
See 'man 7 undocumented' for help when manual pages are not available.
If I run command normally without --help, It works properly, like:
oerp#oerp:~$ git mycommand some_val
Namespace(**{'some-arg': 'some_val'})
Or if I dont use it as git subcommand and run it directly, like:
oerp#oerp:~$ git-mycommand --help
usage: git-mycommand [-h] some-arg
Some Description
positional arguments:
some-arg
optional arguments:
-h, --help show this help message and exit
Does anyone know why custom git subcommand does not work properly with --help argument? Or maybe there is something else, I need to do, so it would show intended output?

The git command is receiving the --help option, not your subcommand.
Note that git --help ... is identical to git help ... because the former is internally converted into the latter.
https://git-scm.com/docs/git-help
git help invokes git-help which opens the man page for the given command.

Related

How would I run command lines in Python?

I am playing around with this Instagram ID tracker because my friends are constantly changing usernames so I can never keep up. The code is from here. The only way I am aware of, is that you have to go to any sort of terminal and type a command in this format
$ usage: t.py [-h] -u USERNAME [-p] [-s] [-t]
I've already tried to do some on my own and I recently saw other people running command lines in the Python text editor but it doesn't seem to work for me. This is what I did
import os
import main
import api
os.system('python3 main.py -u <USERNAME>')
There are 2 files, main.py and api.py. I imported both but when I run it, it still says
usage: t.py [-h] -u USERNAME [-p] [-s] [-t]
t.py: error: the following arguments are required: -u/--username
Is there an easier way to go about this?

How require options for CLI app based on Python and Click

I am building a CLI app with Python and the Click library.
How do I achieve the following use case:
First I only want the subcommand to be followed by an argument no options are required:
$ myapp subcommand argument
This is straight forward.
But how can I write the code that if argument2 is set that also some options are required?
$ myapp subcommand argument2 -o1 abc -o2 def
For example:
no options are required:
$ ./myapp.py install basic
options are required:
$ ./myapp.py install custom -o1 abc -o2 def
Furthermore I do not know how to make choice for arguments, that means that the user must choose between "basic" or "custom". In case he chooses "custom", he needs to add some options.
I have achieved this successfully by making your argument2 be a click.Command.
Running through the code below, my main way of interacting with the CLI application is via the cli group. That cli group has another group, install, added as a command. So we have a CLI with nested groups.
install has 2 commands, basic and custom, as in your example.
basic takes no parameters, while custom takes 2 required Options.
Calls would look like this:
❯ myapp install custom -o1 arg1 -o2 def
This is a custom install with option1: arg1 and option2: def
❯ myapp install basic
Executing a basic install
You can see the nested group install acts as a command inside the help message:
❯ myapp
Usage: myapp [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
install
And if you were to invoke install, this is the help output you'd get.
❯ myapp install
Usage: myapp install [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
basic
custom
This is the code:
import click
#click.group()
def cli():
pass
#click.group()
def install():
pass
#install.command()
def basic():
print('Executing a basic install')
#install.command()
#click.option("-o1", "--option1", required=True)
#click.option("-o2", "--option2", required=True)
def custom(option1, option2):
print(f'This is a custom install with option1: {option1} and option2: {option2}')
def main():
cli.add_command(install)
cli()
if __name__ == '__main__':
main()

slow response of CLI written with Python Click

I'm experiencing slow responses of my CLI written with Click 7.0 on Python 3.6.6 (under conda environment).
It takes time to print the help message when calling the CLI when the package has been installed with pip (using setuptools):
$ time cli
Usage: cli [OPTIONS] COMMAND [ARGS]...
Welcome in the CLI!
Options:
--version Show the version and exit.
--help Show this message and exit.
real 0m0,523s
user 0m0,482s
sys 0m0,042s
However, I don't get this lag when calling the CLI directly from the source:
$ time python myproject/cli.py
Usage: cli.py [OPTIONS] COMMAND [ARGS]...
Welcome in the CLI!
Options:
--version Show the version and exit.
--help Show this message and exit.
real 0m0,088s
user 0m0,071s
sys 0m0,016s
Here is the content of myproject/cli.py:
import click
#click.group('cli', invoke_without_command=True)
#click.pass_context
#click.version_option(version='0.0.1', prog_name="test")
def cli(ctx):
"""
Welcome in the CLI!
"""
if ctx.invoked_subcommand is None:
# show help if no option passed to cli
if all(v==False for v in ctx.params.values()):
click.echo(ctx.get_help())
if __name__ == '__main__':
cli()
And setup.py is configured like this:
setup(
name=name,
version=__version__,
packages=find_packages(),
install_requires=install_requires,
author=author,
author_email=author_email,
description=description,
entry_points='''
[console_scripts]
cli=myproject.cli:cli
''',
keywords=keywords,
cmdclass=cmdclass,
include_package_data=True,
)
Could someone help me with this? This is really inconvenient to get such lag for a CLI.
For small Python CLIs this delay is very noticable. It has to do with the wrapper that setuptools creates around your CLI endpoint.
It implements some auxiliary functionality with your endpoint, like checking that your (virtual) python environment has all required dependencies.
People have created solutions to circumvent these auxilary functionalities with tools like fast-entry_points. Check it out, it might suite your use-case.
Note: This speed improvement is mostly noticeable for small CLIs. If you have a larger CLI/Project, you will need to structure your imports as local imports to prevent all imports being loaded when you perform a specific action. Especially when using auto-complete on your CLI, it might be worth to also change your imports.

How to change the -h response on a Django Management Command

If I run my command as python manage.py foo --help
It returns:
Usage: manage.py load_cartridge_types_delivery_windows [options]
Options:
-v VERBOSITY, --verbosity=VERBOSITY
Verbosity level; 0=minimal output, 1=normal output,
2=verbose output, 3=very verbose output
...
-h, --help show this help message and exit
At the bottom, it shows -h and the standard help message, "show this help message and exit". How do I change that help message to describe my command?
Just define the help attribute on the class.

ipython not showing argparse help message

In my python script myscript.py I use argparse to pass command-line arguments. When I want to display the help information about the input arguments, I just do:
$ python myscript.py --help
If instead I want to use ipython to run my script, the help message won't be displayed. Ipython will display its own help information:
$ ipython -- myscript.py -h
=========
IPython
=========
Tools for Interactive Computing in Python
=========================================
A Python shell with automatic history (input and output), dynamic object
introspection, easier configuration, command completion, access to the
system shell and more. IPython can also be embedded in running programs.
Usage
ipython [subcommand] [options] [files]
It's not so annoying, but is there a way around it?
You need to run your .py script inside the ipython. Something like that:
%run script.py -h
This is an IPython bug, corrected in https://github.com/ipython/ipython/pull/2663.
My 0.13 has this error; it is corrected in 0.13.2. The fix is in IPthyon/config/application.py Application.parse_command_line. This function looks for help and version flags (-h,-V) in sys.argv before passing things on to parse_known_args (hence the custom help formatting). In the corrected release, it checks sys.argv only up to the first --. Before it looked in the whole array.
earlier:
A fix for earlier releases is to define an alternate help flag in the script:
simple.py script:
import argparse, sys
print(sys.argv)
p = argparse.ArgumentParser(add_help=False) # turn off the regular -h
p.add_argument('-t')
p.add_argument('-a','--ayuda',action=argparse._HelpAction,help='alternate help')
print(p.parse_args())
Invoke with:
$ ./ipython3 -- simple.py -a
['/home/paul/mypy/argdev/simple.py', '-a']
usage: simple.py [-t T] [-a]
optional arguments:
-t T
-a, --ayuda alternate help
$ ./ipython3 -- simple.py -t test
['/home/paul/mypy/argdev/simple.py', '-t', 'test']
Namespace(t='test')

Categories

Resources