Set answer upstream for task branches

This commit is contained in:
mpabi
2026-04-29 02:51:56 +02:00
parent f59c761d86
commit 3f83620342
4 changed files with 45 additions and 4 deletions
+3 -2
View File
@@ -356,8 +356,9 @@ inf bss task3_stack_unused ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss
inf bss task4_stack_strlen ~/dev/workspace/rv/series/inf/lab-rv32i-strlen-bss-data-stack/src/tasks
```
Przełącz się na wybrane zadanie. `rvctl` bierze login ucznia ze store tokenów i
tworzy branch pracy w formacie `<login>T<numer_zadania>a`:
Przełącz się na wybrane zadanie. `rvctl` bierze login ucznia ze store tokenów,
tworzy branch pracy w formacie `<login>T<numer_zadania>a` i ustawia mu upstream
na `r1a/<branch>`:
```bash
./rvctl series cards tasks switch inf bss 4
+1 -1
View File
@@ -480,7 +480,7 @@ Przełączniki:
Domyślna nazwa brancha powstaje z użytkownika w `tokens.json`, numeru zadania i
końcówki `a`. Dla użytkownika `u1` i zadania `task4_stack_strlen` będzie to
`u1T4a`.
`u1T4a`. Komenda ustawia też upstream brancha na `r1a/u1T4a`.
```bash
./rvctl series cards tasks switch inf bss 4
+2 -1
View File
@@ -168,7 +168,8 @@ u1T4a
```
Jeżeli branch już istnieje, `rvctl` przełącza na niego repo. Jeżeli go nie ma,
tworzy go od aktualnego commita karty.
tworzy go od aktualnego commita karty. Branch dostaje upstream `r1a/<branch>`,
na przykład `r1a/u1T4a`.
Na tym poziomie nie wprowadzamy osobnego `fetch`: zadania są pobierane razem z
kartą przez `series cards fetch` albo razem z całą serią przez `series fetch`.
+39
View File
@@ -2718,6 +2718,19 @@ def submission_branch_name(user_name: str, task_name: str) -> str:
return branch_value(f"{slug_value(user_name, 'student user')}{task_branch_part(task_name)}a")
def set_branch_upstream(repo_path: Path, branch_name: str, remote_name: str, dry_run: bool = False) -> str:
expected_merge = f"refs/heads/{branch_name}"
current_remote = git_capture(repo_path, ["config", "--get", f"branch.{branch_name}.remote"])
current_merge = git_capture(repo_path, ["config", "--get", f"branch.{branch_name}.merge"])
if current_remote == remote_name and current_merge == expected_merge:
return "unchanged"
if dry_run:
return "dry-run"
subprocess.run(["git", "-C", str(repo_path), "config", f"branch.{branch_name}.remote", remote_name], check=True)
subprocess.run(["git", "-C", str(repo_path), "config", f"branch.{branch_name}.merge", expected_merge], check=True)
return "updated" if current_remote or current_merge else "set"
def print_card_tasks(config: WorkspaceConfig, series_name: str, card_name: str) -> None:
card_path = resolve_workspace_card_path(config, series_name, card_name)
for task_name in task_names(card_path):
@@ -2761,6 +2774,25 @@ def switch_card_task(
check=False,
).returncode == 0
token_status = "dry-run"
answer_remote_status = "dry-run"
if not dry_run:
token_status, source_token = ensure_answer_token_from_source(
config,
config.git.source_remote,
config.git.answer_remote,
answer_url,
)
answer_remote_status = set_git_remote(
card_path,
config.git.answer_remote,
credentialed_remote_url(
answer_url,
str(source_token.get("user", "")),
str(source_token.get("value", "")),
),
)
if dry_run:
status = "dry-run"
elif current_branch == branch_name:
@@ -2771,6 +2803,7 @@ def switch_card_task(
else:
subprocess.run(["git", "-C", str(card_path), "switch", "-c", branch_name], check=True)
status = "created"
upstream_status = set_branch_upstream(card_path, branch_name, config.git.answer_remote, dry_run=dry_run)
return {
"series": series_name,
@@ -2778,6 +2811,12 @@ def switch_card_task(
"task": task_name,
"student_user": student_user,
"branch": branch_name,
"answer_remote": config.git.answer_remote,
"answer_url": answer_url,
"token_status": token_status,
"answer_remote_status": answer_remote_status,
"upstream": f"{config.git.answer_remote}/{branch_name}",
"upstream_status": upstream_status,
"workspace": str(card_path),
"status": status,
}