Auto-rename origin during token sync

This commit is contained in:
mpabi
2026-04-29 02:21:59 +02:00
parent af96388f6a
commit 46f2f44118
4 changed files with 79 additions and 36 deletions
+29 -35
View File
@@ -191,15 +191,6 @@ git clone http://77.90.8.171:3001/edu-tools/rv-launcher.git
cd rv-launcher cd rv-launcher
``` ```
Etap 3: zmień nazwę remota z `origin` na `r1`:
```bash
git remote rename origin r1
```
`tokens.json` jest mapowany na nazwy git remotes, dlatego repo launchera ma
używać remota `r1`.
Po `git clone` workspace wygląda tak: Po `git clone` workspace wygląda tak:
```text ```text
@@ -210,7 +201,7 @@ Po `git clone` workspace wygląda tak:
└── tokens.json └── tokens.json
``` ```
Etap 4: sprawdź store i wpisz credentials ze store do remota `r1`: Etap 3: sprawdź store i wpisz credentials ze store do remota `r1`:
```bash ```bash
./rvctl tokens list store ./rvctl tokens list store
@@ -220,6 +211,8 @@ Etap 4: sprawdź store i wpisz credentials ze store do remota `r1`:
`tokens list store` sprawdza, czy skopiowany `tokens.json` zawiera wpis dla `tokens list store` sprawdza, czy skopiowany `tokens.json` zawiera wpis dla
remota `r1`. `tokens sync store r1` bierze token ze store i wpisuje credentials remota `r1`. `tokens sync store r1` bierze token ze store i wpisuje credentials
do git remota `r1`, tak aby kolejne operacje Git mogły używać tego tokena. do git remota `r1`, tak aby kolejne operacje Git mogły używać tego tokena.
Jeżeli po `git clone` repo ma tylko remote `origin` wskazujący to samo repo,
`rvctl` automatycznie przemianuje go na `r1`.
`list store` powinien pokazać token ze store: `list store` powinien pokazać token ze store:
@@ -235,6 +228,7 @@ item source kind server proto host org repo use
```text ```text
repo_root /home/user/dev/workspace/rv/tools/rv-launcher repo_root /home/user/dev/workspace/rv/tools/rv-launcher
remote r1 remote r1
renamed_from origin
server http://77.90.8.171:3001 server http://77.90.8.171:3001
user u1 user u1
id r1 id r1
@@ -242,7 +236,7 @@ status updated
url http://77.90.8.171:3001/edu-tools/rv-launcher.git url http://77.90.8.171:3001/edu-tools/rv-launcher.git
``` ```
Etap 5: odśwież metadane tokena i porównaj store z remote: Etap 4: odśwież metadane tokena i porównaj store z remote:
```bash ```bash
./rvctl tokens update r1 ./rvctl tokens update r1
@@ -263,7 +257,7 @@ item server proto host org repo user remote tok
1 gitea http 77.90.8.171:3001 edu-tools rv-launcher u1 r1 r1 * e59cc...13be forever 1 gitea http 77.90.8.171:3001 edu-tools rv-launcher u1 r1 r1 * e59cc...13be forever
``` ```
Etap 6: po operacjach Git możesz usunąć sekret z `.git/config`, zostawiając Etap 5: po operacjach Git możesz usunąć sekret z `.git/config`, zostawiając
token tylko w store: token tylko w store:
```bash ```bash
@@ -281,6 +275,29 @@ item server proto host org repo user remote tok
1 gitea http 77.90.8.171:3001 edu-tools rv-launcher u1 r1 r1 S e59cc...13be forever 1 gitea http 77.90.8.171:3001 edu-tools rv-launcher u1 r1 r1 S e59cc...13be forever
``` ```
## Szybki start
Najpierw zobacz konfigurację i dostępne komendy:
```bash
./rvctl
./rvctl show-config
```
Typowy przepływ pracy:
```bash
./rvctl tokens compare
./rvctl list-series
./rvctl list-cards inf
./rvctl tmux-container inf 03 --dry-run
./rvctl tmux-container inf 03 --session rv-inf03 --attach
./rvctl submission inf 03 --class 4i --nick u1
```
`--dry-run` jest przydatny przy sprawdzaniu planu uruchomienia lub konfiguracji
repo, zanim narzędzie coś zmieni.
### Po pobraniu kart pracy ### Po pobraniu kart pracy
Karty trafiają do `series` w workspace: Karty trafiają do `series` w workspace:
@@ -320,29 +337,6 @@ Repozytoria źródłowe poza workspace, na przykład `~/dev/edu/repos/rv`, są
zapleczem dla autora materiałów albo fallbackiem dla narzędzi. Nie są wymagane zapleczem dla autora materiałów albo fallbackiem dla narzędzi. Nie są wymagane
do zwykłej pracy w workspace. do zwykłej pracy w workspace.
## Szybki start
Najpierw zobacz konfigurację i dostępne komendy:
```bash
./rvctl
./rvctl show-config
```
Typowy przepływ pracy:
```bash
./rvctl tokens compare
./rvctl list-series
./rvctl list-cards inf
./rvctl tmux-container inf 03 --dry-run
./rvctl tmux-container inf 03 --session rv-inf03 --attach
./rvctl submission inf 03 --class 4i --nick u1
```
`--dry-run` jest przydatny przy sprawdzaniu planu uruchomienia lub konfiguracji
repo, zanim narzędzie coś zmieni.
## Dokumentacja ## Dokumentacja
- `doc/rvctl.md` - techniczna dokumentacja CLI: wszystkie komendy, argumenty - `doc/rvctl.md` - techniczna dokumentacja CLI: wszystkie komendy, argumenty
+3
View File
@@ -447,6 +447,9 @@ Zapisuje dane auth z rekordu `REMOTE_ID` w `tokens.json` do git remote o tej
samej nazwie. Jeśli remote jeszcze nie istnieje, URL jest budowany z pól samej nazwie. Jeśli remote jeszcze nie istnieje, URL jest budowany z pól
`server.endpoint`, `org` i `repo` w `tokens.json`. `server.endpoint`, `org` i `repo` w `tokens.json`.
Jeżeli repo ma tylko remote `origin` wskazujący ten sam URL, `sync store`
automatycznie przemianuje `origin` na `REMOTE_ID` przed wpisaniem credentials.
Przełączniki: Przełączniki:
- `--repo PATH` - `--repo PATH`
+3
View File
@@ -136,6 +136,9 @@ Jeśli remote `r1` nie istnieje, `rvctl` buduje URL z pól `server.endpoint`,
http://77.90.8.171:3001/edu-tools/rv-launcher.git http://77.90.8.171:3001/edu-tools/rv-launcher.git
``` ```
Jeżeli w repo istnieje tylko `origin` wskazujący ten sam URL, `sync store r1`
automatycznie przemianuje `origin` na `r1`, a potem wpisze credentials.
Opcjonalnie można podać URL ręcznie: Opcjonalnie można podać URL ręcznie:
```bash ```bash
+44 -1
View File
@@ -1939,6 +1939,35 @@ def remote_url_from_token_record(token_record: dict) -> str:
return f"{endpoint}/{quote(owner, safe='')}/{quote(repo_name, safe='')}" return f"{endpoint}/{quote(owner, safe='')}/{quote(repo_name, safe='')}"
def remote_urls_point_to_same_repo(left_url: str, right_url: str) -> bool:
try:
left_sanitized, _ = sanitize_remote_url(left_url)
right_sanitized, _ = sanitize_remote_url(right_url)
except SystemExit:
return False
return left_sanitized.rstrip("/") == right_sanitized.rstrip("/")
def find_origin_rename_candidate(
config: WorkspaceConfig,
repo_root: Path,
target_remote: str,
target_url: str,
) -> tuple[str, str] | None:
origin_remote = config.git.origin_remote
if not origin_remote or origin_remote == target_remote:
return None
if git_capture(repo_root, ["remote", "get-url", target_remote]) is not None:
return None
origin_url = git_capture(repo_root, ["remote", "get-url", origin_remote])
if not origin_url:
return None
if not remote_urls_point_to_same_repo(origin_url, target_url):
return None
return origin_remote, origin_url
def resolve_repo_argument(repo_arg: str | None) -> Path: def resolve_repo_argument(repo_arg: str | None) -> Path:
return Path(repo_arg).expanduser().resolve() if repo_arg else Path.cwd().resolve() return Path(repo_arg).expanduser().resolve() if repo_arg else Path.cwd().resolve()
@@ -2171,6 +2200,7 @@ def run_tokens_sync(config: WorkspaceConfig, args: argparse.Namespace) -> None:
args.repo = str(repo_path) args.repo = str(repo_path)
args.remote = args.remote_id args.remote = args.remote_id
args.token_name = args.remote_id args.token_name = args.remote_id
args.auto_rename_origin = True
run_tokens_write(config, args) run_tokens_write(config, args)
return return
raise SystemExit(f"Unsupported tokens sync direction: {args.direction}") raise SystemExit(f"Unsupported tokens sync direction: {args.direction}")
@@ -2255,11 +2285,17 @@ def run_tokens_write(config: WorkspaceConfig, args: argparse.Namespace) -> None:
f"Missing target remote URL and tokens.json has no org/repo for: {server_endpoint}:{remote_id}" f"Missing target remote URL and tokens.json has no org/repo for: {server_endpoint}:{remote_id}"
) )
rename_candidate = None
if getattr(args, "auto_rename_origin", False) and existing_remote_url is None:
rename_candidate = find_origin_rename_candidate(config, repo_root, args.remote, target_url)
if rename_candidate:
_, existing_remote_url = rename_candidate
final_url = credentialed_remote_url(target_url, user_name, token_value) final_url = credentialed_remote_url(target_url, user_name, token_value)
status = "added" if existing_remote_url is None else "updated" status = "added" if existing_remote_url is None else "updated"
existing_credentials = remote_credentials(existing_remote_url) if existing_remote_url else None existing_credentials = remote_credentials(existing_remote_url) if existing_remote_url else None
if existing_credentials == (user_name, token_value): if existing_credentials == (user_name, token_value):
status = "unchanged" status = "renamed" if rename_candidate else "unchanged"
elif existing_credentials is not None and not args.replace: elif existing_credentials is not None and not args.replace:
raise SystemExit( raise SystemExit(
f"Remote '{args.remote}' already has different credentials. " f"Remote '{args.remote}' already has different credentials. "
@@ -2268,6 +2304,8 @@ def run_tokens_write(config: WorkspaceConfig, args: argparse.Namespace) -> None:
print(f"repo_root\t{repo_root}") print(f"repo_root\t{repo_root}")
print(f"remote\t{args.remote}") print(f"remote\t{args.remote}")
if rename_candidate:
print(f"renamed_from\t{rename_candidate[0]}")
print(f"server\t{server_endpoint}") print(f"server\t{server_endpoint}")
print(f"user\t{user_name}") print(f"user\t{user_name}")
print(f"id\t{remote_id}") print(f"id\t{remote_id}")
@@ -2277,6 +2315,11 @@ def run_tokens_write(config: WorkspaceConfig, args: argparse.Namespace) -> None:
if args.dry_run or status == "unchanged": if args.dry_run or status == "unchanged":
return return
if rename_candidate:
subprocess.run(
["git", "-C", str(repo_root), "remote", "rename", rename_candidate[0], args.remote],
check=True,
)
set_git_remote(repo_root, args.remote, final_url) set_git_remote(repo_root, args.remote, final_url)