cgcardona / muse public
attributes.py python
73 lines 2.2 KB
45fd2148 fix: config and versioning audit — TOML attributes, v0.1.1, no Phase N labels Gabriel Cardona <cgcardona@gmail.com> 2d 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 from __future__ import annotations
13
14 import json
15
16 import typer
17
18 from muse.core.attributes import load_attributes, read_attributes_meta
19 from muse.core.repo import require_repo
20
21 app = typer.Typer()
22
23
24 @app.callback(invoke_without_command=True)
25 def attributes(
26 ctx: typer.Context,
27 output_json: bool = typer.Option(False, "--json", help="Output rules as JSON."),
28 ) -> None:
29 """Display the ``.museattributes`` merge-strategy rules."""
30 root = require_repo()
31 meta = read_attributes_meta(root)
32 rules = load_attributes(root)
33
34 if output_json:
35 payload: dict[str, str | list[dict[str, str | int]]] = {}
36 domain_val = meta.get("domain")
37 if domain_val is not None:
38 payload["domain"] = domain_val
39 payload["rules"] = [
40 {
41 "path_pattern": r.path_pattern,
42 "dimension": r.dimension,
43 "strategy": r.strategy,
44 "source_index": r.source_index,
45 }
46 for r in rules
47 ]
48 typer.echo(json.dumps(payload, indent=2))
49 return
50
51 if not rules:
52 typer.echo("No .museattributes file found (or file is empty).")
53 typer.echo(
54 "Create one at the repository root to declare per-path merge strategies."
55 )
56 return
57
58 # Header: domain from [meta] if present
59 domain_val = meta.get("domain")
60 if domain_val is not None:
61 typer.echo(f"Domain: {domain_val}")
62 typer.echo("")
63
64 # Compute column widths for aligned output.
65 pat_w = max(len(r.path_pattern) for r in rules)
66 dim_w = max(len(r.dimension) for r in rules)
67
68 typer.echo(f"{'Path pattern':<{pat_w}} {'Dimension':<{dim_w}} Strategy")
69 typer.echo(f"{'-' * pat_w} {'-' * dim_w} --------")
70 for rule in rules:
71 typer.echo(
72 f"{rule.path_pattern:<{pat_w}} {rule.dimension:<{dim_w}} {rule.strategy}"
73 )