--- a/scripts/repository-candidate-gate +++ b/scripts/repository-candidate-gate @@ -388,7 +388,7 @@ def main() -> int: parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) - parser.add_argument("--config", required=True) + parser.add_argument("--config", help="repository gate policy (required for the main process)") parser.add_argument("--candidate", default=".", help="candidate tree (default: working directory)") parser.add_argument("--baseline", help="baseline tree (default: config baseline, the published tree)") parser.add_argument("--worker", nargs="+", help=argparse.SUPPRESS) @@ -397,6 +397,9 @@ kind, root, out, *atoms = args.worker worker_packages(root, out) if kind == "packages" else worker_resolve(root, atoms, out) return 0 + + if not args.config: + parser.error("--config is required for the main gate process") # Portage sources ebuilds as the portage user: the work tree must be traversable. os.umask(0o022) --- /dev/null +++ b/tests/test_candidate_gate.py @@ -0,0 +1,21 @@ +from importlib.machinery import SourceFileLoader +from importlib.util import module_from_spec, spec_from_loader +from pathlib import Path +from unittest.mock import patch +import unittest + + +class CandidateGateCommandTests(unittest.TestCase): + def test_worker_protocol_does_not_require_main_process_policy(self): + script = Path(__file__).resolve().parents[1] / 'scripts/repository-candidate-gate' + loader = SourceFileLoader('candidate_gate_test', str(script)) + module = module_from_spec(spec_from_loader(loader.name, loader)) + loader.exec_module(module) + with patch.object(module.sys, 'argv', [str(script), '--worker', 'packages', '/isolated/root', '/isolated/out']), \ + patch.object(module, 'worker_packages') as worker: + self.assertEqual(module.main(), 0) + worker.assert_called_once_with('/isolated/root', '/isolated/out') + + +if __name__ == '__main__': + unittest.main()