From 12403eccf9ff4b503b04eb6863146813a02fbb5e Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Mon, 6 Nov 2023 15:13:17 -0500 Subject: [PATCH] basic basejump script --- configs/scripts/basejump | 37 +++++++++++++++++ configs/scripts/basejump-fetch | 58 ++++++++++++++++++++++++++ configs/scripts/basejump-init | 75 ++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100755 configs/scripts/basejump create mode 100755 configs/scripts/basejump-fetch create mode 100755 configs/scripts/basejump-init diff --git a/configs/scripts/basejump b/configs/scripts/basejump new file mode 100755 index 0000000..9f07900 --- /dev/null +++ b/configs/scripts/basejump @@ -0,0 +1,37 @@ +#! /usr/bin/env python +import argparse +import sys +import logging +import subprocess + + +logger = logging.getLogger(__name__) + + +def main() -> int: + # Handle program arguments + ap = argparse.ArgumentParser(prog="basejump") + ap.add_argument( + "subcommand", help="The subcommand to run", choices=["init", "fetch"] + ) + ap.add_argument("arguments", nargs=argparse.REMAINDER) + args = ap.parse_args() + + # Configure logging + logging.basicConfig( + level=logging.INFO, + format="%(levelname)s: %(message)s", + ) + + # Execute the appropriate subcommand + real_command_name = f"basejump-{args.subcommand}" + try: + return subprocess.run([real_command_name] + args.arguments).returncode + except FileNotFoundError: + logger.error(f"Unknown subcommand: {args.subcommand}") + logger.error(f"Could not find `{real_command_name}` in $PATH") + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/configs/scripts/basejump-fetch b/configs/scripts/basejump-fetch new file mode 100755 index 0000000..ce050b1 --- /dev/null +++ b/configs/scripts/basejump-fetch @@ -0,0 +1,58 @@ +#! /usr/bin/env python +import argparse +import sys +import logging +import json +import subprocess +import os +from pathlib import Path + +logger = logging.getLogger(__name__) + + +def main() -> int: + # Handle program arguments + ap = argparse.ArgumentParser( + prog="basejump fetch", description="Fetches all changes for a whole codebase" + ) + ap.add_argument("name", help="The name of the codebase") + ap.add_argument("--pull", help="Perform a full pull", action="store_true") + ap.add_argument( + "-v", "--verbose", help="Enable verbose logging", action="store_true" + ) + args = ap.parse_args() + + # Configure logging + logging.basicConfig( + level=logging.DEBUG if args.verbose else logging.INFO, + format="%(levelname)s: %(message)s", + ) + + # Ensure that the basejump config dir exists + bj_config_dir = Path.home() / ".config" / "basejump" + bj_config_dir.mkdir(parents=True, exist_ok=True) + + # Read the codebase config + codebase_config_path = bj_config_dir / f"{args.name}.codebase.json" + if not codebase_config_path.exists(): + logger.error(f"Codebase `{args.name}` does not exist") + return 1 + config = json.loads(codebase_config_path.read_text()) + + # Handle each repository + for repo in config["repos"]: + logger.info(f"Fetching {repo['path']}") + + # If we are in pull mode, do a git pull + if args.pull: + subprocess.run(["git", "pull"], cwd=repo["path"]) + + # Otherwise fetch all + else: + subprocess.run(["git", "fetch", "--all"], cwd=repo["path"]) + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/configs/scripts/basejump-init b/configs/scripts/basejump-init new file mode 100755 index 0000000..0013ea7 --- /dev/null +++ b/configs/scripts/basejump-init @@ -0,0 +1,75 @@ +#! /usr/bin/env python +import argparse +import sys +import logging +import json +import subprocess +import os +from pathlib import Path + +logger = logging.getLogger(__name__) + + +def main() -> int: + # Handle program arguments + ap = argparse.ArgumentParser( + prog="basejump init", description="Creates a new basejump codebase" + ) + ap.add_argument("name", help="The name of the codebase") + ap.add_argument( + "-v", "--verbose", help="Enable verbose logging", action="store_true" + ) + args = ap.parse_args() + + # Configure logging + logging.basicConfig( + level=logging.DEBUG if args.verbose else logging.INFO, + format="%(levelname)s: %(message)s", + ) + + # Ensure that the basejump config dir exists + bj_config_dir = Path.home() / ".config" / "basejump" + bj_config_dir.mkdir(parents=True, exist_ok=True) + + # Create a new codebase definition + codebase_config_path = bj_config_dir / f"{args.name}.codebase.json" + + # If the path already exists, abort + if codebase_config_path.exists(): + logger.error(f"Codebase `{args.name}` already exists") + logger.info(f"Config file at: {codebase_config_path}") + return 1 + + # Create a template codebase config + template_config = { + "name": args.name, + "repos": [ + { + "path": "/tmp/example", + "upstream": "https://github.com/octocat/Hello-World", + } + ], + } + + # Write the template config to disk + codebase_config_path.write_text(json.dumps(template_config, indent=4)) + + # Open $EDITOR (or vim) to edit the config + subprocess.run([os.environ.get("EDITOR", "vim"), str(codebase_config_path)]) + + # Iterate through every repo and clone it + config = json.loads(codebase_config_path.read_text()) + for repo in config["repos"]: + if Path(repo["path"]).exists(): + logger.info(f"Skipping {repo['path']}, already exists") + continue + + # Do a clone + logger.info(f"Cloning {repo['upstream']} into {repo['path']}") + subprocess.run(["git", "clone", repo["upstream"], repo["path"]]) + + return 0 + + +if __name__ == "__main__": + sys.exit(main())