# HG changeset patch # User Raphaël Gomès <rgomes@octobus.net> # Date 1678880075 -3600 # Wed Mar 15 12:34:35 2023 +0100 # Node ID 8e4c05833113d9f6fe4ec45d976f8edfc54a827c # Parent 07297ef82aa5f7752e3955c3ee9c1c8f71508a2d bin: rewrite `bin-env-util` with `click` This is much simpler and more powerful than rolling it by hand. diff --git a/python-libs/poulpe/bin/bin-env-util b/python-libs/poulpe/bin/bin-env-util --- a/python-libs/poulpe/bin/bin-env-util +++ b/python-libs/poulpe/bin/bin-env-util @@ -1,10 +1,9 @@ #!/usr/bin/env python3 -# -# Small tool to manipulate bin-envs -import argparse import os +import sys import subprocess -import sys + +import click import poulpe @@ -18,7 +17,7 @@ err = poulpe.err -def create_empty(env_path, method="manual"): +def _create_empty(env_path, method="manual"): """create a new environ (in a non-ready state)""" os.makedirs(env_path, exist_ok=True) base_data = { @@ -32,28 +31,67 @@ file_path = poulpe.bin_env_file(env_path) if os.path.exists(file_path): err('This is already a bin-env, aborting') - return ERR_CODE_EXISTS + sys.exit(ERR_CODE_EXISTS) poulpe.write_data(file_path, base_data) - return 0 + + +def _mark_ready(path): + shell_path = os.path.join(path, poulpe.SHELL_FILE) + if not os.access(shell_path, os.X_OK): + err(f'cannot find an executable file at: "{shell_path}"') + sys.exit(ERR_CODE_NO_BIN_ENV_SHELL) + + path = poulpe.bin_env_file(path) + data = poulpe.get_data(path) + if data is None: + err(f'missing file: "{path}"') + sys.exit(ERR_CODE_NO_BIN_ENV_DESC) + data['ready'] = True + poulpe.write_data(path, data) + + +@click.group(no_args_is_help=True) +def bin_env_util(): + """Tool to manipulate binary environments""" -def setup_one(env_path, script): +@bin_env_util.command(no_args_is_help=True) +@click.argument("path") +def create_empty(path): + """Create a new empty bin-env at a given path + + \b + ARGS: + <PATH> is the path of the environment to create + """ + _create_empty(path) + + +@bin_env_util.command(no_args_is_help=True) +@click.argument("path") +@click.argument("script") +def setup_one(path, script): + """Create a new bin-env with a setup script. + + \b + ARGS: + <PATH> is the path of the environment to create + <SCRIPT> is the path to the script to setup the environment + """ if not os.access(script, os.X_OK): err(f'no executable setup script at: "{script}"') - return ERR_CODE_NO_SETUP_SCRIPT - ret = create_empty(env_path, method="script") - if ret != 0: - return ret + sys.exit(ERR_CODE_NO_SETUP_SCRIPT) + _create_empty(path, method="script") script = os.path.abspath(script) try: - subprocess.check_call(script, cwd=env_path) + subprocess.check_call(script, cwd=path) except subprocess.CalledProcessError as exc: err(f'script returned with status {exc.returncode}: {script}') - return ERR_CODE_SETUP_SCRIPT_FAILED + sys.exit(ERR_CODE_SETUP_SCRIPT_FAILED) - env_file = poulpe.bin_env_file(env_path) + env_file = poulpe.bin_env_file(path) data = poulpe.get_data(env_file) - vars_file = os.path.join(env_path, "POULPE-VARS") + vars_file = os.path.join(path, "POULPE-VARS") if os.path.exists(vars_file): with open(vars_file) as f: for line in f: @@ -63,174 +101,99 @@ k = f'bin-env-vars.{k}' poulpe.set_one_value(data, k, v) poulpe.write_data(env_file, data) - return mark_ready(env_path) + _mark_ready(path) -def mark_ready(env_path): - shell_path = os.path.join(env_path, poulpe.SHELL_FILE) - if not os.access(shell_path, os.X_OK): - err(f'cannot find an executable file at: "{shell_path}"') - return ERR_CODE_NO_BIN_ENV_SHELL +@bin_env_util.command(no_args_is_help=True) +@click.argument("path") +def mark_ready(path): + """Mark a bin-env as ready. - path = poulpe.bin_env_file(env_path) - data = poulpe.get_data(path) - if data is None: - err(f'missing file: "{path}"') - return ERR_CODE_NO_BIN_ENV_DESC - data['ready'] = True - poulpe.write_data(path, data) - return 0 + \b + ARGS: + <PATH> is the path of the environment to mark as ready + """ + _mark_ready(path) -def show(env_path): - path = poulpe.bin_env_file(env_path) +@bin_env_util.command(no_args_is_help=True) +@click.argument("path") +def show(path): + """Show all data we have about this environment. + + \b + ARGS: + <PATH> is the path of the environment to show + """ + path = poulpe.bin_env_file(path) data = poulpe.get_data(path) if data is None: err(f'missing file: "{path}"') - return ERR_CODE_NO_BIN_ENV_DESC + sys.exit(ERR_CODE_NO_BIN_ENV_DESC) poulpe.show(data) - return 0 + + +@bin_env_util.command("get", no_args_is_help=True) +@click.argument("path") +@click.argument("key") +def get_value(path, key): + """Show a specific bin-env variable. + + \b + ARGS: + <PATH> is the path of the environment + <KEY> is the path to the variable + """ + f = poulpe.bin_env_file(path) + data = poulpe.get_data(f) + if data is None: + err(f'missing file: "{f}"') + sys.exit(ERR_CODE_NO_BIN_ENV_DESC) + k = f'bin-env-vars.{key}' + value = poulpe.get_one_value(data, k) + if value is None: + sys.exit(ERR_CODE_NO_KEY) + print(value) -def _parsers(): - top_parser = argparse.ArgumentParser(prog='poulpe-bin-env-util') - subparsers = top_parser.add_subparsers( - help='available sub-command', dest='command', required=True - ) - - # XXX having PATH everywhere is not great - - ### bin-env-util create-empty PATH - cmd_parser = subparsers.add_parser( - 'create-empty', help='create a new empty bin-env' - ) - cmd_parser.add_argument( - 'PATH', - help="the path to the (future) environment", - ) - - ### bin-env-util setup-one-sh PATH SCRIPT - cmd_parser = subparsers.add_parser( - 'setup-one', help='create a new bin-env with a setup script' - ) - cmd_parser.add_argument( - 'PATH', - help="the path of the environment", - ) - cmd_parser.add_argument( - 'SCRIPT', - help="the path to the script to setup the env", - ) - - ### bin-env-util mark-ready PATH - cmd_parser = subparsers.add_parser( - 'mark-ready', help='mark a bin-env as ready' - ) - cmd_parser.add_argument( - 'PATH', - help="the path to the environment", - ) +@bin_env_util.command("set", no_args_is_help=True) +@click.argument("path") +@click.argument("key") +@click.argument("value") +def set_value(path, key, value): + """Set the value of a specific bin-env variable. - ### bin-env-util show PATH - cmd_parser = subparsers.add_parser( - 'show', help='Show all data we have about this environment' - ) - cmd_parser.add_argument( - 'PATH', - help="the path to the environment", - ) - - ### bin-env-util get PATH KEY - cmd_parser = subparsers.add_parser( - 'get', help='Show a specific bin-env variable' - ) - cmd_parser.add_argument( - 'PATH', - help="the path to the environment", - ) - cmd_parser.add_argument( - 'KEY', - help="the path to the variable", - ) - - ### bin-env-util set PATH KEY VALUE - cmd_parser = subparsers.add_parser( - 'set', help='Set the value of a specific bin-env variable' - ) - cmd_parser.add_argument( - 'PATH', - help="the path to the environment", - ) - cmd_parser.add_argument( - 'KEY', - help="the path to the variable", - ) - cmd_parser.add_argument( - 'VALUE', - help="the value to set", - ) - - ### bin-env-util del PATH KEY - cmd_parser = subparsers.add_parser( - 'del', help='Delete a specific bin-env variable' - ) - cmd_parser.add_argument( - 'PATH', - help="the path to the environment", - ) - cmd_parser.add_argument( - 'KEY', - help="the path to the variable", - ) - - return top_parser + \b + ARGS: + <PATH> is the path of the environment + <KEY> is the path to the variable + <VALUE> is the value to be set + """ + f = poulpe.bin_env_file(path) + k = f'bin-env-vars.{key}' + data = poulpe.get_data(f) + if data is None: + err(f'creating new file: "{f}"') + data = {} + poulpe.set_one_value(data, k, value) + poulpe.write_data(f, data) -def main(args): - parser = _parsers() - param = parser.parse_args(args) - if param.command == 'create-empty': - ret = create_empty(param.PATH) - elif param.command == 'setup-one': - ret = setup_one(param.PATH, param.SCRIPT) - elif param.command == 'mark-ready': - ret = mark_ready(param.PATH) - elif param.command == 'show': - ret = show(param.PATH) - elif param.command == 'get': - f = poulpe.bin_env_file(param.PATH) - data = poulpe.get_data(f) - if data is None: - err(f'missing file: "{f}"') - ret = ERR_CODE_NO_BIN_ENV_DESC - else: - k = f'bin-env-vars.{param.KEY}' - value = poulpe.get_one_value(data, k) - if value is None: - ret = ERR_CODE_NO_KEY - else: - print(value) - ret = 0 - elif param.command == 'set': - f = poulpe.bin_env_file(param.PATH) - k = f'bin-env-vars.{param.KEY}' - data = poulpe.get_data(f) - if data is None: - err(f'creating new file: "{f}"') - data = {} - poulpe.set_one_value(data, k, param.VALUE) - poulpe.write_data(f, data) - return 0 - elif param.command == 'del': - f = poulpe.bin_env_file(param.PATH) - k = f'bin-env-vars.{param.KEY}' - ret = poulpe.del_value(f, k) - else: - assert False - return ret +@bin_env_util.command("del", no_args_is_help=True) +@click.argument("path") +@click.argument("key") +def del_value(path, key): + """Delete a specific bin-env variable. + + \b + ARGS: + <PATH> is the path of the environment + <KEY> is the path to the variable to delete + """ + f = poulpe.bin_env_file(path) + k = f'bin-env-vars.{key}' + poulpe.del_value(f, k) if __name__ == "__main__": - ret = main(sys.argv[1:]) - assert ret is not None - sys.exit(ret) + bin_env_util() diff --git a/tests/test-bin-env-util.t b/tests/test-bin-env-util.t --- a/tests/test-bin-env-util.t +++ b/tests/test-bin-env-util.t @@ -4,23 +4,21 @@ Check basic invocation $ poulpe bin-env-util --help - usage: poulpe-bin-env-util [-h] - {create-empty,setup-one,mark-ready,show,get,set,del} - ... + Usage: bin-env-util [OPTIONS] COMMAND [ARGS]... + + Tool to manipulate binary environments + + Options: + --help Show this message and exit. - positional arguments: - {create-empty,setup-one,mark-ready,show,get,set,del} - available sub-command - create-empty create a new empty bin-env - setup-one create a new bin-env with a setup script - mark-ready mark a bin-env as ready - show Show all data we have about this environment - get Show a specific bin-env variable - set Set the value of a specific bin-env variable - del Delete a specific bin-env variable - - option*s: (glob) - -h, --help show this help message and exit + Commands: + create-empty Create a new empty bin-env at a given path + del Delete a specific bin-env variable. + get Show a specific bin-env variable. + mark-ready Mark a bin-env as ready. + set Set the value of a specific bin-env variable. + setup-one Create a new bin-env with a setup script. + show Show all data we have about this environment. Check repository creation