diff --git a/generator.py b/generator.py index b4c224ce5..328e1ccdf 100755 --- a/generator.py +++ b/generator.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -from os import listdir -from os.path import isfile, isdir, join +from pathlib import Path +import argparse import subprocess import sys @@ -10,29 +10,29 @@ NOTHING_TO_BE_DONE = 0 NEED_UPDATE = 1 FAILURE = 2 +DEFAULT_GIR_FILES_DIRECTORY = Path('./gir-files') +DEFAULT_GIR_DIRECTORY = Path('./gir/') +DEFAULT_GIR_PATH = DEFAULT_GIR_DIRECTORY / 'target/release/gir' + def run_command(command, folder=None): if folder is None: folder = "." - child = subprocess.Popen(command, cwd=folder) - child.communicate() - if child.returncode != 0: - print("Command `{}` failed with return code `{}`...".format(command, child.returncode)) + ret = subprocess.run(command, cwd=folder) + if ret.returncode != 0: + print("Command `{}` failed with `{}`...".format(command, ret)) return False return True def update_workspace(): - try: - return run_command(['cargo', 'build', '--release'], 'gir') - except: - return False + return run_command(['cargo', 'build', '--release'], 'gir') def ask_yes_no_question(question, conf): question = '{} [y/N] '.format(question) - if conf["yes"] is True: - print(question) + if conf.yes: + print(question + 'y') return True if sys.version_info[0] < 3: line = raw_input(question) @@ -42,18 +42,18 @@ def ask_yes_no_question(question, conf): def def_check_submodule(submodule_path, conf): - if len(listdir(submodule_path)) != 0: + if any(submodule_path.iterdir()): return NOTHING_TO_BE_DONE - print('=> Initializing gir submodule...') - if not run_command(['git', 'submodule', 'update', '--init']): + print('=> Initializing {} submodule...'.format(submodule_path)) + if not run_command(['git', 'submodule', 'update', '--init', submodule_path]): return FAILURE print('<= Done!') - if ask_yes_no_question('Do you want to update gir submodule?', conf): - print('=> Updating gir submodule...') - if not run_command(['git', 'reset', '--hard', 'HEAD'], 'gir'): + if ask_yes_no_question('Do you want to update {} submodule?'.format(submodule_path), conf): + print('=> Updating submodule...') + if not run_command(['git', 'reset', '--hard', 'HEAD'], submodule_path): return FAILURE - if not run_command(['git', 'pull', '-f', 'origin', 'master'], 'gir'): + if not run_command(['git', 'pull', '-f', 'origin', 'master'], submodule_path): return FAILURE print('<= Done!') return NEED_UPDATE @@ -64,7 +64,7 @@ def build_gir_if_needed(updated_submodule): if updated_submodule == FAILURE: return False print('=> Building gir...') - if update_workspace() is True: + if update_workspace(): print('<= Done!') else: print('<= Failed...') @@ -72,106 +72,88 @@ def build_gir_if_needed(updated_submodule): return True -def regen_crates(path, conf, level=0): - for entry in listdir(path): - entry_file = join(path, entry) - if isdir(entry_file): - if level < 2 and not regen_crates(entry_file, conf, level + 1): +def regen_crates(path, conf): + if path.is_dir(): + for entry in path.rglob("Gir*.toml"): + if not regen_crates(entry, conf): return False - elif entry.startswith("Gir") and entry.endswith(".toml"): - print('==> Regenerating "{}"...'.format(entry_file)) + elif path.match("Gir*.toml"): + print('==> Regenerating "{}"...'.format(path)) - args = [conf["gir_path"], '-c', entry_file, '-o', path, '-d', conf["gir_files"]] - if level > 1: - args.append('-m') - args.append('sys') - error = False - try: - error = run_command(args) is False - except Exception as err: - print('The following error occurred: {}'.format(err)) - error = True - if error is True: - if not ask_yes_no_question('Do you want to continue?', conf): - return False - print('<== Done!') + args = [conf.gir_path, '-c', path, '-o', path.parent, '-d', conf.gir_files_path] + if path.parent.name.endswith("sys"): + args.extend(['-m', 'sys']) + error = False + try: + error = not run_command(args) + except Exception as err: + print('The following error occurred: {}'.format(err)) + error = True + if error: + if not ask_yes_no_question('Do you want to continue?', conf): + return False + print('<== Done!') + else: + print('==> {} is not a valid Gir*.toml file'.format(path)) + return False return True -def print_help(): - print("generator.py Helper to regenerate gtk-rs crates using gir.") - print("") - print("[OPTIONS]") - print(" -h | --help Display this message") - print(" --gir-path [PATH] Sets the path of the gir executable to run") - print(" (`./gir/target/release/gir` by default)") - print(" --gir-files [PATH] Sets the path of the gir-files folder") - print(" (`gir-files` by default)") - print(" --yes Always answer `yes` to any question asked by the script") - print(" --no-fmt If set, this script won't run `cargo fmt`") +def valid_path(path): + path = Path(path) + if not path.exists(): + raise argparse.ArgumentTypeError("`{}` no such file or directory".format(path)) + return path -def parse_args(args): - conf = { - "gir_path": None, - "gir_files": None, - "yes": False, - "run_fmt": True, - } - i = 0 +def directory_path(path): + path = Path(path) + if not path.is_dir(): + raise argparse.ArgumentTypeError("`{}` directory not found".format(path)) + return path - while i < len(args): - arg = args[i] - if arg == "-h" or arg == "--help": - print_help() - return None - elif arg == "--gir-path": - i += 1 - if i >= len(args): - print("Expected argument after `--gir-path` option...") - return None - if not isfile(args[i]): - print("`{}` file doesn't exist. Aborting...".format(args[i])) - return None - conf["gir_path"] = args[i] - elif arg == "--gir-files": - i += 1 - if i >= len(args): - print("Expected argument after `--gir-files` option...") - return None - if not isdir(args[i]): - print("`{}` folder doesn't exist. Aborting...".format(args[i])) - return None - conf["gir_files"] = args[i] - elif arg == "--yes": - conf["yes"] = True - elif arg == "--no-fmt": - conf["run_fmt"] = False - else: - print("Unknown argument `{}`.".format(arg)) - return None - i += 1 - return conf + +def file_path(path): + path = Path(path) + if not path.is_file(): + raise argparse.ArgumentTypeError("`{}` file not found".format(path)) + return path + + +def parse_args(): + parser = argparse.ArgumentParser(description='Helper to regenerate gtk-rs crates using gir.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument('path', nargs="*", default=[Path('.')], + type=valid_path, + help='Paths in which to look for Gir.toml files') + parser.add_argument('--gir-files-directory', dest="gir_files_path", default=DEFAULT_GIR_FILES_DIRECTORY, + type=directory_path, + help='Path of the gir-files folder') + parser.add_argument('--gir-path', default=DEFAULT_GIR_PATH, + type=file_path, + help='Path of the gir executable to run') + parser.add_argument('--yes', action='store_true', + help=' Always answer `yes` to any question asked by the script') + parser.add_argument('--no-fmt', action='store_true', + help='If set, this script will not run `cargo fmt`') + + return parser.parse_args() def main(): - gir_path = None + conf = parse_args() - conf = parse_args(sys.argv[1:]) - if conf is None: - return 1 - - if conf["gir_files"] is None: - conf["gir_files"] = "gir-files" - if conf["gir_path"] is None: - if not build_gir_if_needed(def_check_submodule("gir", conf)): + if conf.gir_path == DEFAULT_GIR_PATH: + if not build_gir_if_needed(def_check_submodule(DEFAULT_GIR_DIRECTORY, conf)): return 1 - conf["gir_path"] = "./gir/target/release/gir" print('=> Regenerating crates...') - if not regen_crates(".", conf): - return 1 - if conf["run_fmt"] is True and not run_command(['cargo', 'fmt']): + for path in conf.path: + print('=> Looking in path `{}`'.format(path)) + if not regen_crates(path, conf): + return 1 + if not conf.no_fmt and not run_command(['cargo', 'fmt']): return 1 print('<= Done!') print("Don't forget to check if everything has been correctly generated!")