diff --git a/scripts/profile_sync.py b/scripts/profile_sync.py index 818e7bb54..a61f5b05f 100644 --- a/scripts/profile_sync.py +++ b/scripts/profile_sync.py @@ -4158,9 +4158,10 @@ def build_parser() -> argparse.ArgumentParser: help="the profiles the branch adds against --base, as CI checks them", ) parser.add_argument( - "--base", default="origin/main", + "--base", help="revision --changed and --added compare with, through its merge " - "base with HEAD (default: %(default)s)", + "base with HEAD (default: the project's main line, upstream/main or " + "origin/main when that remote names the project, fetched otherwise)", ) parser.add_argument( "--emulators-dir", default="emulators", @@ -4327,14 +4328,33 @@ def branch_profiles(emulators_dir: str, base: str, added_only: bool) -> list[str }) +def project_base() -> str: + """The project's main line, the base --changed compares with by default. + + In a fork's clone origin/main is the fork: once the branch is pushed it + is HEAD, and --changed --strict found nothing and passed while the PR's + CI then failed. validate_pr.py resolves the same line the same way. + """ + from validate_pr import _git_lines as git_lines, _project_main_line + + line = _project_main_line() + if line: + return line + for remote in ("upstream", "origin"): + if git_lines("rev-parse", "--verify", "--quiet", f"{remote}/main"): + return f"{remote}/main" + return "HEAD" + + def select_profiles(profiles: dict, args: argparse.Namespace) -> dict: """Profiles matching the selection flags.""" if args.changed or args.added: - names = branch_profiles(args.emulators_dir, args.base, args.added) + base = args.base or project_base() + names = branch_profiles(args.emulators_dir, base, args.added) selected = {name: profiles[name] for name in names if name in profiles} if not selected: verb = "adds" if args.added else "adds or edits" - print(f"the branch {verb} no profile against {args.base}", file=sys.stderr) + print(f"the branch {verb} no profile against {base}", file=sys.stderr) return selected if args.emulator: names = [args.emulator] if isinstance(args.emulator, str) else args.emulator diff --git a/tests/test_profile_sync.py b/tests/test_profile_sync.py index 843d85fe4..8bb0e78db 100644 --- a/tests/test_profile_sync.py +++ b/tests/test_profile_sync.py @@ -5896,6 +5896,24 @@ class TestBranchProfiles(unittest.TestCase): ["draft", "edited", "new"], ) + def test_a_fork_clone_compares_with_the_project(self): + """origin is the fork, pushed: origin/main is HEAD, and the default + base found nothing to check while the PR's CI failed.""" + base = subprocess.run( + ["git", "rev-parse", "main"], cwd=self.root, capture_output=True, + text=True, check=True, + ).stdout.strip() + self._git("remote", "add", "origin", "https://github.com/someone/retrobios") + self._git("remote", "add", "upstream", "https://github.com/Abdess/retrobios") + self._git("update-ref", "refs/remotes/origin/main", "HEAD") + self._git("update-ref", "refs/remotes/upstream/main", base) + args = profile_sync.build_parser().parse_args(["--changed"]) + profiles = {"kept": {}, "edited": {}, "new": {}, "draft": {}} + self.assertEqual( + list(profile_sync.select_profiles(profiles, args)), + ["draft", "edited", "new"], + ) + class TestBranchCheckIsWired(unittest.TestCase): """CONTRIBUTING and CI name the branch's profiles through the flag.""" diff --git a/wiki/tools.md b/wiki/tools.md index 1aa6aef87..214920b78 100644 --- a/wiki/tools.md +++ b/wiki/tools.md @@ -447,8 +447,10 @@ to show one cited file and `--context N` lines around each hunk. `--strict` exits 1 when a profile has refs to review, and CI runs it on every profile a change adds. `--offline` answers from `--cache-dir` alone. `--changed` selects the profiles the branch adds or edits, uncommitted ones included, and `--added` -the ones it adds, both against the merge base of `--base` (`origin/main` by -default) and HEAD. +the ones it adds, both against the merge base of `--base` and HEAD. By +default `--base` is the project's main line: `upstream/main` or `origin/main` +when that remote is the project, fetched from the project in a fork's clone, +where `origin/main` is the fork. ```bash python scripts/profile_sync.py --all --system sega-saturn --changed-only