@@ -115,21 +115,8 @@ def run(self, cmd: list[str], *, check: bool, capture_output: bool, text: bool)
115115 )
116116
117117 if cmd [:3 ] == ["gh" , "repo" , "view" ]:
118- return FakeCompletedProcess (
119- json .dumps (
120- {
121- "nameWithOwner" : "PaddlePaddle/Paddle" ,
122- "description" : "PaddlePaddle core framework" ,
123- "homepageUrl" : "https://www.paddlepaddle.org.cn/" ,
124- "isFork" : False ,
125- "parent" : None ,
126- "url" : "https://github.com/PaddlePaddle/Paddle" ,
127- "sshUrl" : "git@github.com:PaddlePaddle/Paddle.git" ,
128- "viewerPermission" : "READ" ,
129- "defaultBranchRef" : {"name" : "develop" },
130- }
131- )
132- )
118+ repo = cmd [3 ] if len (cmd ) > 3 else "PaddlePaddle/Paddle"
119+ return FakeCompletedProcess (json .dumps (_repo_view_payload (repo )))
133120
134121 if cmd [:3 ] == ["gh" , "api" , "user" ]:
135122 return FakeCompletedProcess (json .dumps ({"login" : "ShigureNyako" }))
@@ -138,7 +125,7 @@ def run(self, cmd: list[str], *, check: bool, capture_output: bool, text: bool)
138125 return FakeCompletedProcess (json .dumps (_pull_files_payload (cmd [2 ])))
139126
140127 if cmd [:2 ] == ["gh" , "api" ] and len (cmd ) >= 3 and "/git/trees/" in cmd [2 ]:
141- return FakeCompletedProcess (json .dumps (_repo_tree_payload ()))
128+ return FakeCompletedProcess (json .dumps (_repo_tree_payload (cmd [ 2 ] )))
142129
143130 if cmd [:2 ] == ["gh" , "api" ] and len (cmd ) >= 3 and "/branches/" in cmd [2 ]:
144131 payload = _repo_branch_payload (cmd [2 ])
@@ -2345,6 +2332,27 @@ def run_with_truncated_tree(
23452332 assert "gh browse -R PaddlePaddle/Paddle --branch develop 'CONTRIBUTING_GUIDE.md'" in out
23462333
23472334
2335+ def test_repo_preflight_surfaces_parent_repo_and_targets_upstream_pr_for_forks (
2336+ monkeypatch : pytest .MonkeyPatch ,
2337+ tmp_path : Path ,
2338+ capsys : pytest .CaptureFixture [str ],
2339+ ) -> None :
2340+ responder = GhResponder ()
2341+ monkeypatch .setattr (github_api .subprocess , "run" , responder .run )
2342+ monkeypatch .setenv ("XDG_CACHE_HOME" , str (tmp_path ))
2343+
2344+ code = cli .run (["repo" , "preflight" , "--repo" , "ShigureNyako/gh-llm" ])
2345+ assert code == 0
2346+
2347+ out = capsys .readouterr ().out
2348+ assert "repo: ShigureNyako/gh-llm" in out
2349+ assert "is_fork: true" in out
2350+ assert "parent_repo: ShigureLab/gh-llm" in out
2351+ assert "Parent repo: `ShigureLab/gh-llm`" in out
2352+ assert "gh pr create --repo ShigureLab/gh-llm --base main" in out
2353+ assert "gh pr create --repo ShigureNyako/gh-llm --base main" not in out
2354+
2355+
23482356def _branch_protection_rules_payload (after : str | None ) -> dict [str , Any ]:
23492357 del after
23502358 return {
@@ -2378,7 +2386,45 @@ def _branch_protection_rules_payload(after: str | None) -> dict[str, Any]:
23782386 }
23792387
23802388
2381- def _repo_tree_payload () -> dict [str , Any ]:
2389+ def _repo_view_payload (repo : str ) -> dict [str , Any ]:
2390+ if repo == "ShigureNyako/gh-llm" :
2391+ return {
2392+ "nameWithOwner" : "ShigureNyako/gh-llm" ,
2393+ "description" : "Forked gh-llm workspace" ,
2394+ "homepageUrl" : "" ,
2395+ "isFork" : True ,
2396+ "parent" : {
2397+ "name" : "gh-llm" ,
2398+ "owner" : {"login" : "ShigureLab" },
2399+ },
2400+ "url" : "https://github.com/ShigureNyako/gh-llm" ,
2401+ "sshUrl" : "git@github.com:ShigureNyako/gh-llm.git" ,
2402+ "viewerPermission" : "ADMIN" ,
2403+ "defaultBranchRef" : {"name" : "main" },
2404+ }
2405+ return {
2406+ "nameWithOwner" : "PaddlePaddle/Paddle" ,
2407+ "description" : "PaddlePaddle core framework" ,
2408+ "homepageUrl" : "https://www.paddlepaddle.org.cn/" ,
2409+ "isFork" : False ,
2410+ "parent" : None ,
2411+ "url" : "https://github.com/PaddlePaddle/Paddle" ,
2412+ "sshUrl" : "git@github.com:PaddlePaddle/Paddle.git" ,
2413+ "viewerPermission" : "READ" ,
2414+ "defaultBranchRef" : {"name" : "develop" },
2415+ }
2416+
2417+
2418+ def _repo_tree_payload (path : str ) -> dict [str , Any ]:
2419+ if "repos/ShigureNyako/gh-llm/" in path :
2420+ return {
2421+ "sha" : "mock-tree-sha" ,
2422+ "truncated" : False ,
2423+ "tree" : [
2424+ {"path" : "README.md" , "type" : "blob" },
2425+ {"path" : "skills/github-conversation/SKILL.md" , "type" : "blob" },
2426+ ],
2427+ }
23822428 return {
23832429 "sha" : "mock-tree-sha" ,
23842430 "truncated" : False ,
@@ -2396,6 +2442,19 @@ def _repo_tree_payload() -> dict[str, Any]:
23962442def _repo_branch_payload (path : str ) -> dict [str , Any ] | None :
23972443 if "/branches/" not in path :
23982444 return None
2445+ if "repos/ShigureNyako/gh-llm/branches/main" in path :
2446+ return {
2447+ "name" : "main" ,
2448+ "protected" : False ,
2449+ "protection" : {
2450+ "enabled" : False ,
2451+ "required_status_checks" : {
2452+ "enforcement_level" : "off" ,
2453+ "contexts" : [],
2454+ "checks" : [],
2455+ },
2456+ },
2457+ }
23992458 return {
24002459 "name" : "develop" ,
24012460 "protected" : True ,
0 commit comments