Show token repo and store rows per item

This commit is contained in:
mpabi
2026-04-26 15:54:09 +02:00
parent f13b09c317
commit b4e638ef4f
4 changed files with 187 additions and 101 deletions
+141 -70
View File
@@ -619,6 +619,122 @@ def compare_server_entries(repo_entry: dict | None, store_entry: dict | None) ->
return "diverged", len(repo_only_pairs), len(store_only_pairs)
def token_name_rows(users_data: dict) -> list[tuple[str, str]]:
rows: list[tuple[str, str]] = []
for user_name in sorted(users_data):
user_entry = users_data[user_name]
if not isinstance(user_entry, dict):
continue
tokens = user_entry.get("tokens", {})
if not tokens:
rows.append((str(user_name), ""))
continue
for token_name in sorted(tokens):
rows.append((str(user_name), str(token_name)))
return rows
def repo_result_for_entry(repo_entry: dict | None) -> tuple[str, str]:
if repo_entry is None:
return "missing", "missing"
if repo_entry.get("auth_urls", 0):
return "auth", "present"
if repo_entry.get("plain_urls", 0):
return "plain", "no_credentials"
return "empty", "no_credentials"
def print_token_context(
repo_root: Path | None,
config: WorkspaceConfig,
repo_servers: dict[str, dict],
store_servers: dict[str, dict],
endpoint_count: int,
) -> None:
print("context")
print("item\tvalue")
print(f"repo_root\t{repo_root or ''}")
print(f"token_path\t{config.token_path}")
print(f"repo_endpoints\t{len(repo_servers)}")
print(f"tokens_endpoints\t{len(store_servers)}")
print(f"items\t{endpoint_count}")
def print_status_counts(status_counts: dict[str, int]) -> None:
print("status")
print("item\tvalue")
for status_name in ["in_sync", "repo_only", "store_only", "repo_ahead", "store_ahead", "diverged"]:
print(f"{status_name}\t{status_counts[status_name]}")
def print_token_item_rows(
endpoint_names: list[str],
repo_servers: dict[str, dict],
store_servers: dict[str, dict],
scan_rows: list[dict[str, str]] | None = None,
) -> dict[str, int]:
status_names = ["in_sync", "repo_only", "store_only", "repo_ahead", "store_ahead", "diverged"]
status_counts = {status_name: 0 for status_name in status_names}
scan_rows_by_endpoint: dict[str, list[dict[str, str]]] = {}
for row in scan_rows or []:
endpoint = row.get("endpoint", "")
if endpoint:
scan_rows_by_endpoint.setdefault(endpoint, []).append(row)
print("items")
print("item\tsource\tendpoint\tremote\tkind\tuser\ttoken\tresult\tstatus")
for index, endpoint in enumerate(endpoint_names, start=1):
item_id = str(index)
repo_entry = repo_servers.get(endpoint)
store_entry = store_servers.get(endpoint)
status_name, _, _ = compare_server_entries(repo_entry, store_entry)
if status_name in status_counts:
status_counts[status_name] += 1
repo_rows = scan_rows_by_endpoint.get(endpoint, [])
if repo_rows:
for row in repo_rows:
token_label = "remote" if row["url_kind"] == "auth" else ""
print(
f"{item_id}\trepo\t{endpoint}\t{row['remote']}\t{row['url_kind']}\t"
f"{row['user']}\t{token_label}\t{row['result']}\t{status_name}"
)
elif repo_entry is None:
print(f"{item_id}\trepo\t{endpoint}\t\tmissing\t\t\tmissing\t{status_name}")
else:
repo_kind, repo_result = repo_result_for_entry(repo_entry)
remote_names = ",".join(sorted(repo_entry.get("remotes", set())))
repo_users = token_name_rows(repo_entry.get("users", {}))
if repo_users:
for user_name, _ in repo_users:
print(
f"{item_id}\trepo\t{endpoint}\t{remote_names}\t{repo_kind}\t"
f"{user_name}\tremote\t{repo_result}\t{status_name}"
)
else:
print(
f"{item_id}\trepo\t{endpoint}\t{remote_names}\t{repo_kind}\t\t\t"
f"{repo_result}\t{status_name}"
)
if store_entry is None:
print(f"{item_id}\ttokens.json\t{endpoint}\t\tmissing\t\t\tmissing\t{status_name}")
continue
store_users = token_name_rows(store_entry.get("users", {}))
if not store_users:
print(f"{item_id}\ttokens.json\t{endpoint}\t\tstore\t\t\tempty\t{status_name}")
continue
for user_name, token_name in store_users:
print(
f"{item_id}\ttokens.json\t{endpoint}\t\tstore\t{user_name}\t"
f"{token_name}\tpresent\t{status_name}"
)
return status_counts
def resolve_server_from_store(token_data: dict, endpoint: str | None) -> tuple[str, dict]:
servers = token_data.get("servers", {})
if endpoint:
@@ -707,27 +823,28 @@ def resolve_repo_argument(repo_arg: str | None) -> Path:
def run_tokens_scan(config: WorkspaceConfig, args: argparse.Namespace) -> None:
report = sync_tokens_from_repo(config, resolve_repo_argument(args.repo))
repo_root = report["repo_root"]
print("summary")
print(
"repo_root\tremotes\turls\tscanned\tauth_urls\tplain_urls\t"
"unsupported_urls\tfound\tadded\tservers\ttoken_path"
)
print(
f"{repo_root or ''}\t{report['remotes']}\t{report['urls']}\t"
f"{report['scanned']}\t{report['auth_urls']}\t{report['plain_urls']}\t"
f"{report['unsupported_urls']}\t{report['found']}\t{report['added']}\t"
f"{report['servers']}\t{config.token_path}"
)
repo_path = resolve_repo_argument(args.repo)
report = sync_tokens_from_repo(config, repo_path)
repo_root, repo_servers = collect_repo_server_entries(config, repo_path)
token_data = load_token_store(config)
store_servers = token_data.get("servers", {})
endpoint_names = sorted(set(repo_servers) | set(store_servers))
print_token_context(repo_root, config, repo_servers, store_servers, len(endpoint_names))
print()
print("remotes")
print("remote\tendpoint\ttype\turl_kind\tuser\tresult")
for row in report["remote_rows"]:
print(
f"{row['remote']}\t{row['endpoint']}\t{row['type']}\t"
f"{row['url_kind']}\t{row['user']}\t{row['result']}"
)
print("scan")
print("item\tvalue")
print(f"remotes\t{report['remotes']}")
print(f"urls\t{report['urls']}")
print(f"scanned\t{report['scanned']}")
print(f"auth_urls\t{report['auth_urls']}")
print(f"plain_urls\t{report['plain_urls']}")
print(f"unsupported_urls\t{report['unsupported_urls']}")
print(f"found\t{report['found']}")
print(f"added\t{report['added']}")
print(f"servers\t{report['servers']}")
print()
print_token_item_rows(endpoint_names, repo_servers, store_servers, report["remote_rows"])
def run_tokens_read(config: WorkspaceConfig, args: argparse.Namespace) -> None:
@@ -774,57 +891,11 @@ def run_tokens_stats(config: WorkspaceConfig, args: argparse.Namespace) -> None:
raise SystemExit(f"Missing server endpoint in repo/store: {args.server}")
endpoint_names = [args.server]
status_names = ["in_sync", "repo_only", "store_only", "repo_ahead", "store_ahead", "diverged"]
status_counts = {status_name: 0 for status_name in status_names}
print(f"repo_root\t{repo_root or ''}")
print(f"token_path\t{config.token_path}")
print(f"repo_endpoints\t{len(repo_servers)}")
print(f"store_endpoints\t{len(store_servers)}")
print(f"union_endpoints\t{len(endpoint_names)}")
table_rows: list[list[str]] = []
for endpoint in endpoint_names:
repo_entry = repo_servers.get(endpoint)
store_entry = store_servers.get(endpoint)
status_name, repo_only_count, store_only_count = compare_server_entries(repo_entry, store_entry)
if status_name in status_counts:
status_counts[status_name] += 1
sample_entry = repo_entry or store_entry or {}
repo_users = repo_entry.get("users", {}) if repo_entry else {}
store_users = store_entry.get("users", {}) if store_entry else {}
table_rows.append(
[
endpoint,
str(sample_entry.get("type", "unknown")),
",".join(sorted(repo_entry.get("remotes", set()))) if repo_entry else "",
str(repo_entry.get("urls", 0) if repo_entry else 0),
str(repo_entry.get("auth_urls", 0) if repo_entry else 0),
str(repo_entry.get("plain_urls", 0) if repo_entry else 0),
str(count_users(repo_users)),
str(count_server_tokens(repo_entry) if repo_entry else 0),
str(count_users(store_users)),
str(count_server_tokens(store_entry) if store_entry else 0),
str(repo_only_count),
str(store_only_count),
status_name,
]
)
for status_name in status_names:
print(f"{status_name}\t{status_counts[status_name]}")
print_token_context(repo_root, config, repo_servers, store_servers, len(endpoint_names))
print()
print(
"endpoint\ttype\trepo_remotes\trepo_urls\trepo_auth_urls\trepo_plain_urls\t"
"repo_users\trepo_tokens\tstore_users\tstore_tokens\trepo_only_tokens\t"
"store_only_tokens\tstatus"
)
for row in table_rows:
print(
"\t".join(row)
)
status_counts = print_token_item_rows(endpoint_names, repo_servers, store_servers)
print()
print_status_counts(status_counts)
def run_tokens_write(config: WorkspaceConfig, args: argparse.Namespace) -> None: