feat(setup): add -f/--filter to install a subset of profile paths

This commit is contained in:
2026-05-10 00:07:48 +02:00
parent cd6024b578
commit 1a84ea933e
+38 -1
View File
@@ -206,6 +206,26 @@ class Resolved:
system_installs: list[str] system_installs: list[str]
def apply_filter(ctx: Context, resolved: Resolved, filters: list[str]) -> Resolved:
wanted = set(filters)
symlinks = [p for p in resolved.symlinks if p in wanted]
symlink_map = {s: d for s, d in resolved.symlink_map.items() if s in wanted}
copies = [p for p in resolved.copies if p in wanted]
system_installs = [p for p in resolved.system_installs if p in wanted]
matched = set(symlinks) | set(symlink_map) | set(copies) | set(system_installs)
for f in wanted - matched:
ctx.error(f"--filter path not in selected profiles: {f!r}")
return Resolved(
pkgs=[],
symlinks=symlinks,
symlink_map=symlink_map,
copies=copies,
system_installs=system_installs,
)
def resolve_profiles(ctx: Context, profile_names: list[str]) -> Resolved: def resolve_profiles(ctx: Context, profile_names: list[str]) -> Resolved:
pkgs: list[Pkg] = [] pkgs: list[Pkg] = []
symlinks: list[str] = [] symlinks: list[str] = []
@@ -461,7 +481,7 @@ def parse_args() -> argparse.Namespace:
description="Install dotfiles and system configuration.", description="Install dotfiles and system configuration.",
) )
parser.add_argument( parser.add_argument(
"-f", "-F",
"--force", "--force",
action="store_true", action="store_true",
help="Overwrite any existing links or files", help="Overwrite any existing links or files",
@@ -491,6 +511,19 @@ def parse_args() -> argparse.Namespace:
metavar="PROFILE", metavar="PROFILE",
help=f"Extra profiles to apply on top of base (available: {', '.join(extras)})", help=f"Extra profiles to apply on top of base (available: {', '.join(extras)})",
) )
parser.add_argument(
"-f",
"--filter",
action="append",
metavar="PATH",
default=[],
dest="filters",
help=(
"Restrict the run to a single repo-relative path from the "
"selected profiles. Repeat to allow multiple paths. Skips "
"package and terminfo checks."
),
)
return parser.parse_args() return parser.parse_args()
@@ -499,9 +532,13 @@ def main() -> int:
ctx = Context(args) ctx = Context(args)
resolved = resolve_profiles(ctx, ["base", *args.profiles]) resolved = resolve_profiles(ctx, ["base", *args.profiles])
if args.filters:
resolved = apply_filter(ctx, resolved, args.filters)
if args.remove_existing: if args.remove_existing:
remove_all_symlinks(ctx, resolved.symlinks, resolved.symlink_map) remove_all_symlinks(ctx, resolved.symlinks, resolved.symlink_map)
else: else:
if not args.filters:
check_terminfo(ctx) check_terminfo(ctx)
check_packages_installed(ctx, resolved.pkgs) check_packages_installed(ctx, resolved.pkgs)
create_all_symlinks(ctx, resolved.symlinks, resolved.symlink_map) create_all_symlinks(ctx, resolved.symlinks, resolved.symlink_map)