mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
Module moves (with imports, paths, argv literals, scripts, docs, and
parents[N] formulas updated in lockstep):
- cli/deploy -> cli/administration/deploy
- cli/validate/inventory -> cli/administration/inventory/validate
- cli/vault -> cli/administration/secrets/vault
- cli/administration/inventory/encrypt -> cli/administration/secrets/seal
- cli/mirror -> cli/contributing/mirror
The new cli/administration/secrets cluster collocates the whole-file
ansible-vault wrapper next to the inventory-aware per-field sealer.
The user-facing CLI subcommand paths follow the package layout, e.g.
"infinito administration deploy dedicated <inv>" and
"infinito administration inventory validate <inv>".
Help system redesign in cli/core/{discovery,help,app}.py:
- Discovery now distinguishes runnable commands (directories with
__main__.py) from category folders (directories that only group
further commands). Empty support packages are filtered out.
- Each category folder MAY carry a README.md; its H1 heading is used
as the title and its first paragraph as the one-line description in
the help output.
- "infinito" / "infinito --help" prints only the top-level entries
(one level deep). "infinito <category>" navigates into a folder and
shows its sub-folders and commands one level deep, with the README
title as the page heading and the invocation as a dim subtitle.
- New "--tree [N]" flag walks the tree under the (optional) path
prefix recursively. N caps the depth (1-based); omit N for an
unbounded walk. The output uses Unicode tree connectors, an emoji
per entry (folder for categories, gear for commands), a globally
aligned description column, and multi-line wrapped descriptions
with tree-continuity bars on continuation lines.
- Category and command listings use the full invocation
("infinito meta callorder") rather than the bare leaf name, so the
output is copy-pasteable.
Convention doc + 17 CLI READMEs:
- New docs/contributing/artefact/files/cli/readme_md.md describes the
H1+paragraph layout the help system reads, and how it differs from
role/docs READMEs.
- README.md added for cli/{administration, build, contributing, meta}
and their immediate sub-folders, plus cli/meta/roles/applications
and its resolution sub-folder. Each follows the "title with trailing
emoji + single descriptive paragraph" convention.
Mirror resolver/sync description strings (the help system reads them
from argparse --help output) added so they no longer surface as
"options:" in the global index. cli/mirror/cleanup already had a
description and is unchanged.
Fixes uncovered by the move:
- import unittest.mock added to four dedicated-deploy tests so
unittest.mock.patch resolves under stdlib unittest discovery
(Python 3.13 no longer surfaces unittest.mock through "import
unittest" alone).
- parents[N] index in the new
cli/administration/inventory/validate/__init__.py corrected from
3 to 4 to match the deeper layout.
- test_paths.INVENTORY_VALIDATOR_PATH assertion and test_runner
substring assertions updated to match the new validator path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
87 lines
2.8 KiB
Python
87 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
from typing import TYPE_CHECKING
|
|
|
|
from . import PROJECT_ROOT
|
|
from .common import resolve_distro
|
|
|
|
if TYPE_CHECKING:
|
|
import argparse
|
|
|
|
|
|
def add_parser(sub: argparse._SubParsersAction) -> None:
|
|
p = sub.add_parser(
|
|
"build", help="Build infinito image using scripts/image/build.sh (SPOT)."
|
|
)
|
|
p.add_argument("--missing", action="store_true", help="Build only if missing.")
|
|
p.add_argument("--no-cache", action="store_true", help="Build with --no-cache.")
|
|
p.add_argument("--target", help="Dockerfile target (e.g. virgin).", default="")
|
|
p.add_argument("--tag", help="Override output tag.", default="")
|
|
p.add_argument("--push", action="store_true", help="Push image (buildx).")
|
|
p.add_argument(
|
|
"--publish", action="store_true", help="Publish semantic tags (implies --push)."
|
|
)
|
|
p.add_argument("--registry", default="", help="Registry (e.g. ghcr.io).")
|
|
p.add_argument("--owner", default="", help="Owner/namespace (e.g. org/user).")
|
|
p.add_argument(
|
|
"--repo-prefix",
|
|
default="",
|
|
help="Repo prefix (default: current repository name).",
|
|
)
|
|
p.add_argument("--version", default="", help="Version (required for --publish).")
|
|
p.add_argument(
|
|
"--stable", choices=["true", "false"], default="", help="Publish stable tags."
|
|
)
|
|
|
|
p.set_defaults(_handler=handler)
|
|
|
|
|
|
def handler(args: argparse.Namespace) -> int:
|
|
repo_root = PROJECT_ROOT
|
|
script = repo_root / "scripts" / "image" / "build.sh"
|
|
repository_name_script = (
|
|
repo_root / "scripts" / "meta" / "resolve" / "repository" / "name.sh"
|
|
)
|
|
|
|
env = dict(os.environ)
|
|
env["INFINITO_DISTRO"] = resolve_distro()
|
|
if not args.repo_prefix and not env.get("INFINITO_IMAGE_REPOSITORY"):
|
|
resolved_repo = subprocess.run(
|
|
[str(repository_name_script)],
|
|
cwd=repo_root,
|
|
env=env,
|
|
check=True,
|
|
capture_output=True,
|
|
text=True,
|
|
).stdout.strip()
|
|
env["INFINITO_IMAGE_REPOSITORY"] = resolved_repo
|
|
|
|
cmd: list[str] = [str(script)]
|
|
if args.missing:
|
|
cmd.append("--missing")
|
|
if args.no_cache:
|
|
cmd.append("--no-cache")
|
|
if args.target:
|
|
cmd += ["--target", args.target]
|
|
if args.tag:
|
|
cmd += ["--tag", args.tag]
|
|
if args.push:
|
|
cmd.append("--push")
|
|
if args.publish:
|
|
cmd.append("--publish")
|
|
if args.registry:
|
|
cmd += ["--registry", args.registry]
|
|
if args.owner:
|
|
cmd += ["--owner", args.owner]
|
|
if args.repo_prefix:
|
|
cmd += ["--repo-prefix", args.repo_prefix]
|
|
if args.version:
|
|
cmd += ["--version", args.version]
|
|
if args.stable:
|
|
cmd += ["--stable", args.stable]
|
|
|
|
r = subprocess.run(cmd, cwd=repo_root, env=env, check=False)
|
|
return int(r.returncode)
|