Skip to content

API Reference

This page is auto-generated from Python docstrings.

pup_up

pup-up package.

__main__

Run pup-up as a module.

cli

Command-line interface for pup-up.

This module parses arguments and dispatches update behavior.

Commands: uv run pup-up uv run pup-up --write

Equivalent uvx usage after release: uvx pup-up uvx pup-up@latest uvx pup-up --write

build_parser

build_parser() -> argparse.ArgumentParser

Build the argument parser.

Source code in src/pup_up/cli.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def build_parser() -> argparse.ArgumentParser:
    """Build the argument parser."""
    parser = argparse.ArgumentParser(
        prog="pup-up",
        description=(
            "Bring the current repository up to the current Denise Case "
            "managed baseline from canonical templates."
        ),
    )

    parser.add_argument(
        "--root",
        type=Path,
        default=None,
        help=(
            "Repository root to update. Defaults to the nearest parent "
            "directory containing .git, or the current directory."
        ),
    )
    parser.add_argument(
        "--write",
        action="store_true",
        help=(
            "Apply managed baseline changes. Without this flag, pup-up performs "
            "a dry run and reports what would change."
        ),
    )
    parser.add_argument(
        "--diff",
        action="store_true",
        help="Show unified diffs for managed files that would change.",
    )
    parser.add_argument(
        "paths",
        nargs="*",
        type=Path,
        help=(
            "Optional repository-relative managed file paths. "
            "When provided with --write, only these files are written."
        ),
    )
    parser.add_argument(
        "--templates",
        default="pup-pack/templates",
        help=(
            "GitHub owner/repo for canonical templates. Defaults to pup-pack/templates."
        ),
    )
    parser.add_argument(
        "--ref",
        default="main",
        help="Git ref, branch, or tag to fetch templates from. Defaults to main.",
    )
    parser.add_argument(
        "--templates-path",
        type=Path,
        default=None,
        help=(
            "Optional local templates repository path. If provided, templates "
            "are read from disk instead of GitHub raw URLs."
        ),
    )

    return parser

main

main(argv: Sequence[str] | None = None) -> int

Run the command-line interface.

Parameters:

Name Type Description Default
argv Sequence[str] | None

Optional command-line arguments. If None, uses sys.argv.

None

Returns:

Type Description
int

Exit code from the update command.

Source code in src/pup_up/cli.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def main(argv: Sequence[str] | None = None) -> int:
    """Run the command-line interface.

    Args:
        argv: Optional command-line arguments. If None, uses sys.argv.

    Returns:
        Exit code from the update command.
    """
    parser = build_parser()
    args = parser.parse_args(argv)

    return update.run(
        root=args.root,
        write=args.write,
        show_diff=args.diff,
        selected_paths=args.paths,
        templates=args.templates,
        ref=args.ref,
        templates_path=args.templates_path,
    )

commands

Command modules for pup-up.

Each command module exposes a stable run(...) -> int entry point.

The CLI parser lives in pup_up.cli. Behavior lives here.

update

Apply or preview the managed repository baseline.

run
run(
    *,
    root: Path | None = None,
    write: bool = False,
    show_diff: bool = False,
    selected_paths: Sequence[Path] = (),
    templates: str = 'pup-pack/templates',
    ref: str = 'main',
    templates_path: Path | None = None,
) -> int

Preview or apply managed baseline updates.

Parameters:

Name Type Description Default
root Path | None

Repository root. If None, pup-up detects the current repo root.

None
write bool

Whether to write changes. False means dry-run only.

False
show_diff bool

Whether to print unified diffs for changed managed files.

False
selected_paths Sequence[Path]

Optional repository-relative managed files to process.

()
templates str

GitHub owner/repo for canonical templates.

'pup-pack/templates'
ref str

Git ref, branch, or tag.

'main'
templates_path Path | None

Optional local templates repo path.

None

Returns:

Type Description
int

Process exit code.

Source code in src/pup_up/commands/update.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def run(
    *,
    root: Path | None = None,
    write: bool = False,
    show_diff: bool = False,
    selected_paths: Sequence[Path] = (),
    templates: str = "pup-pack/templates",
    ref: str = "main",
    templates_path: Path | None = None,
) -> int:
    """Preview or apply managed baseline updates.

    Args:
        root: Repository root. If None, pup-up detects the current repo root.
        write: Whether to write changes. False means dry-run only.
        show_diff: Whether to print unified diffs for changed managed files.
        selected_paths: Optional repository-relative managed files to process.
        templates: GitHub owner/repo for canonical templates.
        ref: Git ref, branch, or tag.
        templates_path: Optional local templates repo path.

    Returns:
        Process exit code.
    """
    repository = detect_repository(root)
    layers = tuple(
        infer_layers(
            repo_root=repository.root,
            repo_name=repository.repo_name,
            files=set(repository.files),
        )
    )
    source = TemplateSource(
        repository=templates,
        ref=ref,
        local_path=templates_path,
    )

    with fetch_template_snapshot(source=source) as snapshot:
        plan = build_update_plan(
            target=repository,
            layers=layers,
            snapshot=snapshot,
            protected_paths=frozenset({"docs/api.md", "README.md"}),
        )

    if selected_paths:
        plan = filter_update_plan(plan, selected_paths)

    print_update_plan(plan, write=write)

    if show_diff:
        print_update_diffs(plan)

    if write:
        write_update_plan(plan)

    return 0