From 6e497fdfd2368e1cb57578a48aee969c639a39c1 Mon Sep 17 00:00:00 2001 From: Janis Hutz Date: Tue, 7 Apr 2026 18:13:03 +0200 Subject: [PATCH] Notes, improve args, some UX --- archmgr.py | 2 +- cli/args.py | 12 +++--------- commands/commit.py | 13 +++++++------ commands/init.py | 14 +++++++++++++- commands/util/choice.py | 30 ++++++++++++++++++++++++++++++ commands/util/diff.py | 13 +++++++++++++ commands/util/git.py | 5 +++++ notes.md | 8 ++++++++ 8 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 commands/util/choice.py create mode 100644 commands/util/diff.py create mode 100644 notes.md diff --git a/archmgr.py b/archmgr.py index 6135ea1..4e7b3de 100644 --- a/archmgr.py +++ b/archmgr.py @@ -27,7 +27,7 @@ print( ) if args.cmd == "commit": - commit.commit(args.dry_run, args.force, args.no_apply, args.no_commit) + commit.commit(args.dry_run, args.force, args.no_commit) elif args.cmd == "config": config.config() elif args.cmd == "init": diff --git a/cli/args.py b/cli/args.py index 9952bdb..2f4f314 100644 --- a/cli/args.py +++ b/cli/args.py @@ -5,10 +5,10 @@ import argcomplete def add_cli_args(): ap = argparse.ArgumentParser( "archmgr", - description="A nixos-like declarative config and package manager for Arch Linux (or any other cdistro, with some tweaks)", + description="A nixos-like declarative config and package manager for Arch Linux (or any other distro, with some tweaks)", usage="archmgr [command] [options]", ) - ap.add_argument("--version", "-v", action="version", version="%(prog)s V0.0.1") + ap.add_argument("-v", "--version", action="version", version="%(prog)s V0.0.1") sp = ap.add_subparsers( title="commands", metavar="Use 'archmgr [command] --help' to see help for each command", @@ -21,13 +21,7 @@ def add_cli_args(): commit = sp.add_parser( "commit", help="apply pending changes and commit to git repo" ) - commit.add_argument("--force", "-f", help="force apply", action="store_true") - commit.add_argument( - "--no-apply", "-n", help="do not apply to local system", action="store_true" - ) - commit.add_argument( - "--no-commit", "-N", help="do not commit changes to repo", action="store_true" - ) + commit.add_argument("-f", "--force", help="force apply", action="store_true") commit.add_argument( "--no-render", "-r", help="do not re-render renderables", action="store_true" ) diff --git a/commands/commit.py b/commands/commit.py index a518cb2..659325f 100644 --- a/commands/commit.py +++ b/commands/commit.py @@ -1,7 +1,8 @@ -def commit( - dry_run: bool = False, - force: bool = False, - no_apply: bool = False, - no_commit: bool = False, -): +from commands.util.choice import confirm_overwrite + + +def commit(dry_run: bool = False, force: bool = False): + if dry_run: + pass print("Commit, force:", force) + print(confirm_overwrite()) diff --git a/commands/init.py b/commands/init.py index 5cc5cb4..3a31102 100644 --- a/commands/init.py +++ b/commands/init.py @@ -1,2 +1,14 @@ +import os +import commands.util.git as git + + def init(force: bool = False): - print("Init") + dir = os.getcwd() + if force: + [os.remove(dir) for dir in os.listdir(dir)] + git.init(dir) + os.mkdir(dir + "/config") + os.mkdir(dir + "/etc") + with open(dir + "/config.yaml") as file: + file.write("") + print("Initialized a new archmgr repository") diff --git a/commands/util/choice.py b/commands/util/choice.py new file mode 100644 index 0000000..a03d73f --- /dev/null +++ b/commands/util/choice.py @@ -0,0 +1,30 @@ +from typing import Optional + + +def choice(default: str, options: str, msg: str) -> str: + default = default.lower() + formatted_options = "".join( + [(opt + "/" if opt != default else default.upper() + "/") for opt in options] + )[:-1] + choice = input(msg + " [" + formatted_options + "] ") + if choice == "": + return default + else: + return choice.lower() + + +def confirm(is_true_default: bool, msg: Optional[str] = ""): + return ( + choice( + "y" if is_true_default else "n", + "yn", + (msg if msg != "" and msg != None else "Do you really want to continue?"), + ) + == "y" + ) + + +def confirm_overwrite(msg: Optional[str] = ""): + return confirm( + False, (msg if msg != "" else "Do you really want to overwrite your changes?") + ) diff --git a/commands/util/diff.py b/commands/util/diff.py new file mode 100644 index 0000000..6bfaee2 --- /dev/null +++ b/commands/util/diff.py @@ -0,0 +1,13 @@ +from typing import List + + +def compute_diff(paths: List[str]): + pass + + +def file_diff(path: str): + pass + + +def pkg_diff(): + pass diff --git a/commands/util/git.py b/commands/util/git.py index e69de29..d46bda8 100644 --- a/commands/util/git.py +++ b/commands/util/git.py @@ -0,0 +1,5 @@ +import subprocess + + +def init(dirname: str): + subprocess.call("git init", cwd=dirname) diff --git a/notes.md b/notes.md new file mode 100644 index 0000000..1f50eb0 --- /dev/null +++ b/notes.md @@ -0,0 +1,8 @@ +# Concept for tracking changes +- Create new commit (if possible) +- If force is unset: Diff system's files against current state by copying them into the current state branch +- Then, diff the package state against the state branch by dumping it +- Else, or if no diff, continue +- Copy normal config files into correct directories +- Render and copy renderables +- Retrieve explicitly installed packages and remove those that are not present in goal and install those that are not present in current state