-
-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: change CLI backend to typer #78
Changes from all commits
3652717
b61fa8d
4c1f8c3
b09fb11
fff9026
0453a4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,199 +1,150 @@ | ||
"""Cli functions to define the arguments and to call Makim.""" | ||
import argparse | ||
""" | ||
Makim CLI module. | ||
|
||
This module defines the command-line interface for the Makim tool. | ||
""" | ||
import os | ||
import sys | ||
|
||
from pathlib import Path | ||
|
||
from makim import Makim, __version__ | ||
|
||
|
||
class CustomHelpFormatter(argparse.RawTextHelpFormatter): | ||
"""Formatter for generating usage messages and argument help strings. | ||
|
||
Only the name of this class is considered a public API. All the methods | ||
provided by the class are considered an implementation detail. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
prog, | ||
indent_increment=2, | ||
max_help_position=4, | ||
width=None, | ||
**kwargs, | ||
): | ||
"""Define the parameters for the argparse help text.""" | ||
super().__init__( | ||
prog, | ||
indent_increment=indent_increment, | ||
max_help_position=max_help_position, | ||
width=width, | ||
**kwargs, | ||
) | ||
from typer import Argument, Option, Typer, echo | ||
from typing_extensions import Annotated | ||
|
||
from makim import Makim, __version__ | ||
|
||
makim = Makim() | ||
|
||
|
||
def _get_args(): | ||
""" | ||
Define the arguments for the CLI. | ||
|
||
note: when added new flags, update the list of flags to be | ||
skipped at extract_makim_args function. | ||
""" | ||
makim_file_default = str(Path(os.getcwd()) / '.makim.yaml') | ||
|
||
parser = argparse.ArgumentParser( | ||
prog='Makim', | ||
description=( | ||
'Makim is a tool that helps you to organize ' | ||
'and simplify your helper commands.' | ||
), | ||
epilog=( | ||
'If you have any problem, open an issue at: ' | ||
'https://github.com/osl-incubator/makim' | ||
), | ||
add_help=False, | ||
formatter_class=CustomHelpFormatter, | ||
) | ||
parser.add_argument( | ||
app = Typer( | ||
name='Makim', | ||
epilog=( | ||
'If you have any problem, open an issue at: ' | ||
'https://github.com/osl-incubator/makim' | ||
), | ||
) | ||
makim_file_default = str(Path(os.getcwd()) / '.makim.yaml') | ||
|
||
|
||
@app.callback(invoke_without_command=True) | ||
def main( | ||
# Common Options | ||
help: bool = Option( | ||
None, | ||
'--help', | ||
'-h', | ||
action='store_true', | ||
help='Show the help menu', | ||
) | ||
|
||
parser.add_argument( | ||
is_flag=True, | ||
help='Show the version and exit', | ||
), | ||
version: bool = Option( | ||
None, | ||
'--version', | ||
action='store_true', | ||
help='Show the version of the installed Makim tool.', | ||
) | ||
|
||
parser.add_argument( | ||
'-v', | ||
is_flag=True, | ||
help='Show the version and exit', | ||
), | ||
verbose: bool = Option( | ||
None, | ||
'--verbose', | ||
action='store_true', | ||
is_flag=True, | ||
help='Show the commands to be executed.', | ||
) | ||
|
||
parser.add_argument( | ||
), | ||
dry_run: bool = Option( | ||
None, | ||
'--dry-run', | ||
action='store_true', | ||
is_flag=True, | ||
help="Show the commands but don't execute them.", | ||
) | ||
), | ||
# Makim-specific Options | ||
makim_file: Annotated[ | ||
str, | ||
Option( | ||
'--makim-file', | ||
help='Specify a custom location for the makim file.', | ||
is_flag=True, | ||
), | ||
] = makim_file_default, | ||
target: Annotated[ | ||
str, | ||
Argument( | ||
..., | ||
help='Specify the target command to be performed.', | ||
), | ||
] = '', | ||
): | ||
""" | ||
Makim is a tool. | ||
|
||
that helps you to organize and simplify your helper commands. | ||
""" | ||
if version: | ||
return show_version() | ||
|
||
if help or not target: | ||
return create_help_text(makim_file) | ||
|
||
args = { | ||
'dry_run': dry_run, | ||
'help': help, | ||
'makim_file': makim_file, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you also probably don't need to use help here |
||
'target': target, | ||
'verbose': verbose, | ||
'version': version, | ||
} | ||
|
||
makim.load(makim_file) | ||
return makim.run(args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure if that is the write way to work with makim and typer together in this main function you probably should allow makim-file, and version. for the other commands you will need to implement (for each one) verbose, dry-run and makim-file the target you can set manually for each one, because each command will trigger just one function does it make sense? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw, let me know if this one is too complex for you ... and I can work on this one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me try one more time, then I will report to you. |
||
|
||
|
||
def create_help_text(makim_file): | ||
"""Display help text with details about Makim commands and options.""" | ||
usage = """makim [--help] [--version] [--verbose] [--dry-run] [--makim-file | ||
MAKIM_FILE] [target]""" | ||
|
||
parser.add_argument( | ||
'--makim-file', | ||
type=str, | ||
default=makim_file_default, | ||
help='Specify a custom location for the makim file.', | ||
) | ||
description = """Makim is a tool that helps you to organize and simplify | ||
your helper commands.""" | ||
|
||
try: | ||
idx = sys.argv.index('--makim-file') | ||
makim_file = sys.argv[idx + 1] | ||
except ValueError: | ||
makim_file = makim_file_default | ||
epilog = """If you have any problem, open an issue at: | ||
https://github.com/osl-incubator/makim""" | ||
|
||
makim.load(makim_file) | ||
target_help = [] | ||
|
||
# Iterate through groups and targets to generate help text | ||
groups = makim.global_data.get('groups', []) | ||
for group in groups: | ||
target_help.append('\n' + group + ':') | ||
target_help.append('-' * (len(group) + 1)) | ||
target_help.append('\n' + group + ':' + '\n') | ||
target_help.append('-' * (len(group) + 1) + '\n') | ||
for target_name, target_data in groups[group]['targets'].items(): | ||
target_name_qualified = f'{group}.{target_name}' | ||
help_text = target_data['help'] if 'help' in target_data else '' | ||
target_help.append(f' {target_name_qualified} => {help_text}') | ||
target_help.append(f' {target_name_qualified} => {help_text}\n') | ||
|
||
if 'args' in target_data: | ||
target_help.append(' ARGS:') | ||
target_help.append(' ARGS:\n') | ||
|
||
for arg_name, arg_data in target_data['args'].items(): | ||
target_help.append( | ||
f' --{arg_name}: ({arg_data["type"]}) ' | ||
f'{arg_data["help"]}' | ||
f'{arg_data["help"]}\n' | ||
) | ||
|
||
parser.add_argument( | ||
'target', | ||
nargs='?', | ||
default=None, | ||
help=( | ||
'Specify the target command to be performed. Options are:\n' | ||
+ '\n'.join(target_help) | ||
), | ||
) | ||
|
||
return parser | ||
help_text = format_help_text(description, usage, epilog, target_help) | ||
echo(help_text) | ||
|
||
|
||
def show_version(): | ||
"""Show version.""" | ||
print(__version__) | ||
|
||
|
||
def extract_makim_args(): | ||
"""Extract makim arguments from the CLI call.""" | ||
makim_args = {} | ||
index_to_remove = [] | ||
for ind, arg in enumerate(list(sys.argv)): | ||
if arg in [ | ||
'--help', | ||
'--version', | ||
'--verbose', | ||
'--makim-file', | ||
'--dry-run', | ||
]: | ||
continue | ||
def format_help_text(description, usage, epilog, target_help): | ||
"""Format help text with usage, description, and target details.""" | ||
return f"""{usage} | ||
|
||
if not arg.startswith('--'): | ||
continue | ||
{description} | ||
|
||
index_to_remove.append(ind) | ||
Positonal Arguments: | ||
{"".join(target_help)} | ||
{epilog}""" | ||
|
||
arg_name = None | ||
arg_value = None | ||
|
||
next_ind = ind + 1 | ||
|
||
arg_name = sys.argv[ind] | ||
|
||
if ( | ||
len(sys.argv) == next_ind | ||
or len(sys.argv) > next_ind | ||
and sys.argv[next_ind].startswith('--') | ||
): | ||
arg_value = True | ||
else: | ||
arg_value = sys.argv[next_ind] | ||
index_to_remove.append(next_ind) | ||
|
||
makim_args[arg_name] = arg_value | ||
|
||
# remove exclusive makim flags from original sys.argv | ||
for ind in sorted(index_to_remove, reverse=True): | ||
sys.argv.pop(ind) | ||
|
||
return makim_args | ||
|
||
|
||
def app(): | ||
"""Call the makim program with the arguments defined by the user.""" | ||
makim_args = extract_makim_args() | ||
args_parser = _get_args() | ||
args = args_parser.parse_args() | ||
|
||
if args.version: | ||
return show_version() | ||
|
||
if not args.target or args.help: | ||
return args_parser.print_help() | ||
def show_version(): | ||
"""Show version.""" | ||
echo(__version__) | ||
|
||
if args.help: | ||
return args_parser.print_help() | ||
|
||
makim.load(args.makim_file) | ||
makim_args.update(dict(args._get_kwargs())) | ||
return makim.run(makim_args) | ||
if __name__ == '__main__': | ||
app() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you probably don't need to specify help manually.