-
Notifications
You must be signed in to change notification settings - Fork 87
Refactor eval type choice logic #559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -105,8 +105,8 @@ def __init__( | |||||||||||||||||||
| build_graph: str, | ||||||||||||||||||||
| nixpkgs_config: Path, | ||||||||||||||||||||
| extra_nixpkgs_config: str, | ||||||||||||||||||||
| eval_type: str, | ||||||||||||||||||||
| api_token: str | None = None, | ||||||||||||||||||||
| use_github_eval: bool | None = True, | ||||||||||||||||||||
| only_packages: set[str] | None = None, | ||||||||||||||||||||
| additional_packages: set[str] | None = None, | ||||||||||||||||||||
| package_regexes: list[Pattern[str]] | None = None, | ||||||||||||||||||||
|
|
@@ -135,8 +135,9 @@ def __init__( | |||||||||||||||||||
| self.no_shell = no_shell | ||||||||||||||||||||
| self.run = run | ||||||||||||||||||||
| self.remote = remote | ||||||||||||||||||||
| self.api_token = api_token | ||||||||||||||||||||
| self.github_client = GithubClient(api_token) | ||||||||||||||||||||
| self.use_github_eval = use_github_eval and not only_packages | ||||||||||||||||||||
| self.eval_type = eval_type | ||||||||||||||||||||
| self.checkout = checkout | ||||||||||||||||||||
| self.only_packages = only_packages | ||||||||||||||||||||
| self.additional_packages = additional_packages | ||||||||||||||||||||
|
|
@@ -164,6 +165,54 @@ def __init__( | |||||||||||||||||||
| self.head_commit: str | None = None | ||||||||||||||||||||
| self.pr_object = pr_object | ||||||||||||||||||||
|
|
||||||||||||||||||||
| @property | ||||||||||||||||||||
| def _use_github_eval(self) -> bool: | ||||||||||||||||||||
| # If the user explicitly asks for local eval, just do it | ||||||||||||||||||||
| if self.eval_type == "local": | ||||||||||||||||||||
| return False | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if self.only_packages: | ||||||||||||||||||||
| return False | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Handle the GH_TOKEN eventually not being provided | ||||||||||||||||||||
| if not self.api_token: | ||||||||||||||||||||
| warn("No GitHub token provided via GITHUB_TOKEN variable.") | ||||||||||||||||||||
| match self.eval_type: | ||||||||||||||||||||
| case "auto": | ||||||||||||||||||||
| warn( | ||||||||||||||||||||
| "Falling back to local evaluation.\n" | ||||||||||||||||||||
| "Tip: Install the `gh` command line tool and run `gh auth login` to authenticate." | ||||||||||||||||||||
| ) | ||||||||||||||||||||
| return False | ||||||||||||||||||||
| case "github": | ||||||||||||||||||||
| sys.exit(1) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # GHA evaluation only evaluates nixpkgs with an empty config. | ||||||||||||||||||||
| # Its results might be incorrect when a non-default nixpkgs config is requested | ||||||||||||||||||||
| normalized_config = self.extra_nixpkgs_config.replace(" ", "") | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if normalized_config == "{}": | ||||||||||||||||||||
| return True | ||||||||||||||||||||
|
|
||||||||||||||||||||
| warn("Non-default --extra-nixpkgs-config provided.") | ||||||||||||||||||||
| match self.eval_type: | ||||||||||||||||||||
| # By default, fall back to local evaluation | ||||||||||||||||||||
| case "auto": | ||||||||||||||||||||
| warn("Falling back to local evaluation") | ||||||||||||||||||||
Mic92 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||
| return False | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # If the user explicitly requires GitHub eval, warn him, but proceed | ||||||||||||||||||||
| case "github": | ||||||||||||||||||||
| warn( | ||||||||||||||||||||
| "Forcing `github` evaluation -> Be warned that the evaluation results might not correspond to the provided nixpkgs config" | ||||||||||||||||||||
| ) | ||||||||||||||||||||
| return True | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # This should never happen | ||||||||||||||||||||
| case _: | ||||||||||||||||||||
| warn("Invalid eval_type") | ||||||||||||||||||||
| sys.exit(1) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| def _process_aliases_for_systems(self, system: str) -> set[str]: | ||||||||||||||||||||
| match system: | ||||||||||||||||||||
| case "current": | ||||||||||||||||||||
|
|
@@ -422,16 +471,7 @@ def build_pr(self, pr_number: int) -> dict[System, list[Attr]]: | |||||||||||||||||||
|
|
||||||||||||||||||||
| packages_per_system: dict[System, set[str]] | None = None | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # GHA evaluation only evaluates nixpkgs with an empty config. | ||||||||||||||||||||
| # Its results should not be used when a non-default nixpkgs config is requested | ||||||||||||||||||||
| normalized_config = self.extra_nixpkgs_config.replace(" ", "") | ||||||||||||||||||||
| if self.use_github_eval and (normalized_config != "{}"): | ||||||||||||||||||||
| print( | ||||||||||||||||||||
| "Non-default --extra-nixpkgs-config provided. Falling back to local evaluation" | ||||||||||||||||||||
| ) | ||||||||||||||||||||
| self.use_github_eval = False | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if self.use_github_eval: | ||||||||||||||||||||
| if self._use_github_eval: | ||||||||||||||||||||
| assert all(system in PLATFORMS for system in self.systems) | ||||||||||||||||||||
| print("-> Fetching eval results from GitHub actions") | ||||||||||||||||||||
|
Comment on lines
+474
to
476
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Replace assert with user-facing error for unsupported systems Asserts can be stripped with -O and aren’t user-friendly. - assert all(system in PLATFORMS for system in self.systems)
+ if not all(system in PLATFORMS for system in self.systems):
+ raise NixpkgsReviewError(
+ f"GitHub eval only supports {sorted(PLATFORMS)}; got {sorted(self.systems)}"
+ )📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. asserts are indeed an issue. I would like to enable the ruff lint that ban those from non-test code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: Length of output: 2964 🏁 Script executed: Length of output: 3182 @Mic92, great idea! Ruff has the perfect rule for this: S101 (from the flake8-bandit linter), which detects uses of the Based on the codebase analysis, I can see there are several assert statements in your non-test code that this rule would catch, including the one we just discussed in Here's how to configure it in your project: Add to your [tool.ruff.lint]
extend-select = ["S101"] # Enable assert detection
[tool.ruff.lint.per-file-ignores]
# Allow asserts in test files where they belong
"**/test*/**" = ["S101"]
"**/tests/**" = ["S101"]
"test_*.py" = ["S101"]
"*_test.py" = ["S101"]
"conftest.py" = ["S101"]Alternative approach - Enable broader security rules: [tool.ruff.lint]
extend-select = ["S"] # Enable all flake8-bandit security rules (includes S101)
[tool.ruff.lint.per-file-ignores]
# Exclude test files from security rules where asserts are legitimate
"**/test*/**" = ["S101"]
"**/tests/**" = ["S101"]
"test_*.py" = ["S101"]
"*_test.py" = ["S101"]
"conftest.py" = ["S101"]This will help prevent future problematic assert usage in production code while still allowing legitimate assertions in your test suite. The rule will catch cases like the one we just discussed where You'll want to address the existing assert statements in your codebase first, then enable the rule to prevent new ones from being introduced. thinking... 🏁 Script executed: Length of output: 980 Excellent! I can see you already have ruff configured and are aware of the S101 rule. Looking at your current [tool.ruff]
target-version = "py312"
line-length = 88
lint.select = ["ALL"]
lint.ignore = [
# ... other rules ...
# Use of `assert` detected
"S101",
# ... other rules ...
]You're currently globally ignoring S101, but based on your comment, you want to selectively ban asserts from non-test code while still allowing them in tests. Here's how to modify your configuration: Modify your lint.ignore = [
# ... other rules ...
- # Use of `assert` detected
- "S101",
# ... other rules ...
]
+[tool.ruff.lint.per-file-ignores]
+# Allow asserts in test files where they belong
+"**/test*/**" = ["S101"]
+"**/tests/**" = ["S101"]
+"test_*.py" = ["S101"]
+"*_test.py" = ["S101"]
+"conftest.py" = ["S101"]This change will:
This approach gives you the best of both worlds: strict enforcement in production code while maintaining test flexibility. eureka! 🏁 Script executed: Length of output: 1742 Perfect! Now I can see the full picture. You have 18 assert statements total, with 4 in production code that would need to be addressed: Production code asserts that need fixing:
The rest are appropriately in test files. To implement your S101 rule properly:
lint.ignore = [
# ... other rules ...
- # Use of `assert` detected
- "S101",
# ... other rules ...
]
[tool.ruff.lint.per-file-ignores]
# Allow asserts in test files where they belong
"tests/**" = ["S101"]
"conftest.py" = ["S101"]
This will enforce the rule going forward while requiring you to clean up the existing problematic assertions. The test assertions (14 out of 18) will remain untouched since they're legitimate. Would you like me to help create an issue to track the cleanup of these existing assert statements, or would you prefer to handle them as part of this PR? ready to help! ✏️ Learnings added
|
||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -911,6 +951,7 @@ def review_local_revision( | |||||||||||||||||||
| run=args.run, | ||||||||||||||||||||
| remote=args.remote, | ||||||||||||||||||||
| only_packages=set(args.package), | ||||||||||||||||||||
| eval_type="local", | ||||||||||||||||||||
| additional_packages=set(args.additional_package), | ||||||||||||||||||||
| package_regexes=args.package_regex, | ||||||||||||||||||||
| skip_packages=set(args.skip_package), | ||||||||||||||||||||
|
|
||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.