From a9d0d0117a3adb171464113f0f3e28bf4119f1a7 Mon Sep 17 00:00:00 2001 From: mpabi Date: Sun, 26 Apr 2026 20:08:12 +0200 Subject: [PATCH] Mark token source of truth in scan output --- README.md | 8 ++++---- doc/rvctl.md | 11 ++++++----- doc/tokens.md | 8 +++++++- rvctl.py | 33 ++++++++++++++++++++------------- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index cf8a39f..83f7738 100644 --- a/README.md +++ b/README.md @@ -159,10 +159,10 @@ Podstawowe komendy tokenow: `tokens scan` wypisuje waska tabele. Dla jednego endpointu zobaczysz osobny wiersz `source=repo` oraz osobny wiersz `source=tokens.json`. Ten sam numer `item` laczy oba wiersze w pare dla jednego endpointu. -Kolumny `token` i `sync` pokazuja, gdzie jest token i czy repo zgadza sie -z `tokens.json`. Kolumna `id` pokazuje `r1` dla tokena w repo albo `t1` dla -tokenu w `tokens.json`, bez pokazywania sekretu. Endpoint jest rozbity na -`server`, `scheme`, `host` i `port`. +Kolumna `token` pokazuje, gdzie jest token, a `sync` stawia `*` przy zrodle +prawdy. Kolumna `id` pokazuje `r1` dla tokena w repo albo `t1` dla tokena w +`tokens.json`, bez pokazywania sekretu. Endpoint jest rozbity na `server`, +`scheme`, `host` i `port`. ## Fetch i switch diff --git a/doc/rvctl.md b/doc/rvctl.md index 47648ad..e83aab7 100644 --- a/doc/rvctl.md +++ b/doc/rvctl.md @@ -307,8 +307,8 @@ Typowy wynik: items item source id server scheme host port credential repo_user store_user token sync ---- ----------- ---------- ------ ------ --------------- ----- ---------- --------- ---------- ----- ---- -1 repo r1 gitea http 77.90.8.171 3001 auth u1 u1 yes yes -1 tokens.json t1 gitea http 77.90.8.171 3001 store u1 u1 yes yes +1 repo r1 gitea http 77.90.8.171 3001 auth u1 u1 yes +1 tokens.json t1 gitea http 77.90.8.171 3001 store u1 u1 yes * ``` Jesli remote istnieje, ale ma URL bez `LOGIN:TOKEN@`, wynik bedzie mial @@ -318,7 +318,8 @@ endpoint istnieje w `tokens.json`, drugi wiersz tego samego `item` pokaze Ten sam numer `item` oznacza jedna pare logiczna dla jednego endpointu. Wiersz `source=repo` pokazuje stan remote, a wiersz `source=tokens.json` pokazuje stan -lokalnego store. Kolumna `sync` jest flaga zgodnosci calej pary repo/store. +lokalnego store. Kolumna `sync` pokazuje `*` przy aktualnym zrodle prawdy dla +pary repo/store. Przy konflikcie pokazuje `!`. Kolumna `id` pokazuje identyfikator miejsca przechowywania tokena: dla repo jest to nazwa remota, na przyklad `r1`, a dla store nazwa tokenu, na przyklad `t1`. Endpoint jest rozbity na `server`, `scheme`, `host` i `port`. @@ -387,8 +388,8 @@ token_path... items item source id server scheme host port credential repo_user store_user token sync ---- ----------- ---------- ------ ------ --------------- ----- ---------- --------- ---------- ----- ---- -1 repo r1 gitea http 77.90.8.171 3001 plain u1 no no -1 tokens.json t1 gitea http 77.90.8.171 3001 store u1 u1 yes no +1 repo r1 gitea http 77.90.8.171 3001 plain u1 no +1 tokens.json t1 gitea http 77.90.8.171 3001 store u1 u1 yes * status itemvalue diff --git a/doc/tokens.md b/doc/tokens.md index 96e0136..f9d7390 100644 --- a/doc/tokens.md +++ b/doc/tokens.md @@ -113,12 +113,18 @@ Kolumny w tabeli `items`: - `repo_user` - login odczytany z remote URL-i repo - `store_user` - login odczytany z `tokens.json` - `token` - `yes` albo `no`, czyli czy dane zrodlo ma token dla endpointu -- `sync` - `yes` albo `no`, czyli czy para repo/store jest zgodna +- `sync` - `*` przy zrodle prawdy albo `!` przy konflikcie Tabela nie wypisuje sekretu tokena. Jezeli token jest w remote, `id` pokazuje nazwe remota, na przyklad `r1`. Jezeli token jest w `tokens.json`, `id` pokazuje nazwe tokenu, na przyklad `t1`. +Zasada znacznika `sync`: + +- `in_sync`, `store_only`, `store_ahead` - `*` przy `tokens.json` +- `repo_only`, `repo_ahead` - `*` przy `repo` +- `diverged` - `!`, bo nie ma jednoznacznego zrodla prawdy + Przyklad: ```bash diff --git a/rvctl.py b/rvctl.py index 50ae9ed..0d89e2d 100644 --- a/rvctl.py +++ b/rvctl.py @@ -693,14 +693,22 @@ def fit_cell(value: str, width: int) -> str: def print_token_item_table(rows: list[dict[str, str]]) -> None: print("items") - print(" ".join(fit_cell(name, width) for name, width in TOKEN_ITEM_COLUMNS)) - print(" ".join("-" * width for _, width in TOKEN_ITEM_COLUMNS)) + print(" ".join(fit_cell(name, width) for name, width in TOKEN_ITEM_COLUMNS).rstrip()) + print(" ".join("-" * width for _, width in TOKEN_ITEM_COLUMNS).rstrip()) for row in rows: - print(" ".join(fit_cell(row.get(name, ""), width) for name, width in TOKEN_ITEM_COLUMNS)) + print(" ".join(fit_cell(row.get(name, ""), width) for name, width in TOKEN_ITEM_COLUMNS).rstrip()) -def sync_flag(status_name: str) -> str: - return "yes" if status_name == "in_sync" else "no" +def sync_mark(status_name: str, source: str) -> str: + if status_name == "diverged": + return "!" + if status_name in {"in_sync", "store_only", "store_ahead"}: + truth_source = "tokens.json" + elif status_name in {"repo_only", "repo_ahead"}: + truth_source = "repo" + else: + truth_source = "" + return "*" if source == truth_source else "" def users_label(server_entry: dict | None) -> str: @@ -758,7 +766,6 @@ def print_token_item_rows( endpoint_values = endpoint_column_values(endpoint, repo_entry, store_entry) repo_users_label = users_label(repo_entry) store_users_label = users_label(store_entry) - sync_value = sync_flag(status_name) repo_rows = scan_rows_by_endpoint.get(endpoint, []) if repo_rows: @@ -774,7 +781,7 @@ def print_token_item_rows( "repo_user": row["user"], "store_user": store_users_label, "token": "yes" if token_label else "no", - "sync": sync_value, + "sync": sync_mark(status_name, "repo"), } ) elif repo_entry is None: @@ -786,7 +793,7 @@ def print_token_item_rows( "credential": "missing", "store_user": store_users_label, "token": "no", - "sync": sync_value, + "sync": sync_mark(status_name, "repo"), } ) else: @@ -806,7 +813,7 @@ def print_token_item_rows( "repo_user": user_name, "store_user": store_users_label, "token": "yes" if token_label else "no", - "sync": sync_value, + "sync": sync_mark(status_name, "repo"), } ) else: @@ -819,7 +826,7 @@ def print_token_item_rows( "credential": repo_kind, "store_user": store_users_label, "token": "yes" if repo_result == "present" else "no", - "sync": sync_value, + "sync": sync_mark(status_name, "repo"), } ) @@ -832,7 +839,7 @@ def print_token_item_rows( "credential": "missing", "repo_user": repo_users_label, "token": "no", - "sync": sync_value, + "sync": sync_mark(status_name, "tokens.json"), } ) continue @@ -847,7 +854,7 @@ def print_token_item_rows( "credential": "store", "repo_user": repo_users_label, "token": "no", - "sync": sync_value, + "sync": sync_mark(status_name, "tokens.json"), } ) continue @@ -863,7 +870,7 @@ def print_token_item_rows( "repo_user": repo_users_label, "store_user": user_name, "token": "yes" if token_name else "no", - "sync": sync_value, + "sync": sync_mark(status_name, "tokens.json"), } )