gabriel / muse public
attributes.py python
74 lines 2.2 KB
bda49bdb feat: redesign .museignore as TOML with domain-scoped sections (#100) Gabriel Cardona <cgcardona@gmail.com> 5d ago
1 """muse attributes — display the ``.museattributes`` merge-strategy rules.
2
3 Reads and pretty-prints the ``.museattributes`` file from the current
4 repository, showing the ``[meta]`` domain (if set) and each rule's path
5 pattern, dimension, and strategy.
6
7 Usage::
8
9 muse attributes # tabular display
10 muse attributes --json # JSON object with meta + rules array
11 """
12
13 from __future__ import annotations
14
15 import json
16
17 import typer
18
19 from muse.core.attributes import load_attributes, read_attributes_meta
20 from muse.core.repo import require_repo
21
22 app = typer.Typer()
23
24
25 @app.callback(invoke_without_command=True)
26 def attributes(
27 ctx: typer.Context,
28 output_json: bool = typer.Option(False, "--json", help="Output rules as JSON."),
29 ) -> None:
30 """Display the ``.museattributes`` merge-strategy rules."""
31 root = require_repo()
32 meta = read_attributes_meta(root)
33 rules = load_attributes(root)
34
35 if output_json:
36 payload: dict[str, str | list[dict[str, str | int]]] = {}
37 domain_val = meta.get("domain")
38 if domain_val is not None:
39 payload["domain"] = domain_val
40 payload["rules"] = [
41 {
42 "path_pattern": r.path_pattern,
43 "dimension": r.dimension,
44 "strategy": r.strategy,
45 "source_index": r.source_index,
46 }
47 for r in rules
48 ]
49 typer.echo(json.dumps(payload, indent=2))
50 return
51
52 if not rules:
53 typer.echo("No .museattributes file found (or file is empty).")
54 typer.echo(
55 "Create one at the repository root to declare per-path merge strategies."
56 )
57 return
58
59 # Header: domain from [meta] if present
60 domain_val = meta.get("domain")
61 if domain_val is not None:
62 typer.echo(f"Domain: {domain_val}")
63 typer.echo("")
64
65 # Compute column widths for aligned output.
66 pat_w = max(len(r.path_pattern) for r in rules)
67 dim_w = max(len(r.dimension) for r in rules)
68
69 typer.echo(f"{'Path pattern':<{pat_w}} {'Dimension':<{dim_w}} Strategy")
70 typer.echo(f"{'-' * pat_w} {'-' * dim_w} --------")
71 for rule in rules:
72 typer.echo(
73 f"{rule.path_pattern:<{pat_w}} {rule.dimension:<{dim_w}} {rule.strategy}"
74 )