Show token repo and store rows per item
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user