Repository navigation
build(nix): provide cargo-hawk and gate nix flake check on it - #1497
Conversation
`just hawk` needed a tool the dev shell did not provide, so the skill told contributors to curl an installer — an unpinned binary outside Nix, in a repository that pins everything else. nix/cargo-hawk.nix fetches the upstream release by hash for the four platforms it publishes and installs the driver next to the binary, which is where cargo-hawk looks for it. A source build is deliberately not used: hawk links against `rustc_private`, so it would need the `rustc-dev` component and `RUSTC_BOOTSTRAP=1` for a tool no CI check gates on, while the published binary needs neither. The closure is 3.7 MB.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | faac847 | Commit Preview URL Branch Preview URL |
Jul 27 2026, 11:55 AM |
📝 WalkthroughWalkthroughAdds a pinned Nix package for the prebuilt Changescargo-hawk Nix integration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant DevShell as Nix dev shell
participant CargoHawk as cargo-hawk
participant RustCode as Rust code
participant FlakeCheck as nix flake check
DevShell->>CargoHawk: provide cargo-hawk
FlakeCheck->>CargoHawk: run cargo hawk check -D warnings
CargoHawk->>RustCode: analyze visibility
CargoHawk-->>FlakeCheck: return diagnostics
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — adds a hash-pinned cargo-hawk prebuilt binary to the Nix dev shell so just hawk works after direnv allow, replacing the unpinned curl-based installer with a reproducible derivation.
- New
nix/cargo-hawk.nixderivation — fetches upstream release binaries by hash for all four platforms (aarch64/x86_64 × darwin/linux), usesautoPatchelfHookon Linux, installs bothcargo-hawkandcargo-hawk-drivertogether. - Wire into dev shell and packages — registers via
callPackageinnix/packages.nixand adds tobuildInputsinnix/dev-shell.nix. - Skill doc update — replaces curl-based install instructions in
.agents/skills/rust/SKILL.mdwith a note about the pinned derivation and bump steps.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
ccusage
@ccusage/ccusage-darwin-arm64
@ccusage/ccusage-darwin-x64
@ccusage/ccusage-linux-arm64
@ccusage/ccusage-linux-x64
@ccusage/ccusage-win32-x64
commit: |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
Packaging the tool only helps if something runs it. `checks.<system>.ccusage-hawk` runs `cargo hawk check -D warnings` over the workspace, reusing clippy's cargo artifacts, so a new unnecessary `pub` fails the check rather than accumulating until someone remembers to run `just hawk`. It is a flake check rather than a treefmt formatter because hawk analyses the whole workspace as a closed world instead of a file at a time, and because narrowing a visibility is a semantic change, not formatting. Verified both directions: the check passes on main and fails with hawk::unnecessary_public when a `pub(crate)` is widened back to `pub`.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — gates nix flake check on cargo hawk check -D warnings so unnecessary pub visibility fails CI instead of accumulating, and updates the skill docs to match.
-
Add
ccusage-hawkto flake checks —craneLib.mkCargoDerivationreuses the samecargoArtifactsas clippy so the cost is only the hawk analysis, not another workspace build. The check is wired into thechecksset and listed alongsideccusage-clippyandccusage-fmt. -
Update
rust/SKILL.mdfor the CI gate — replaces the old "no CI check runs it, so treat findings as suggestions" guidance with the new gate-aware advice: when a finding looks wrong, check whetherrust/hawk.tomlis missing an entry point before narrowing.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
The Linux build failed in CI with auto-patchelf unable to satisfy librustc_driver-832cf6cfb1386559.so and libgcc_s.so.1. That dependency is the concrete form of hawk's "only runs on the toolchain it was built against": its driver links the compiler's shared library directly, and Darwin resolved it through @rpath while Linux needs it on the search path. The pinned toolchain carries the matching file because rust-overlay repackages the same upstream release, so it goes into runtimeDependencies rather than being vendored — verified on Darwin, where the published binary asks for librustc_driver-e03ed1db822dfa4c and 1.97.1 ships exactly that.
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
|
Diagnosis: Fix: Added
Push failed: Task list (7/7 completed)
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — fixes Linux runtime linking for cargo-hawk so cargo-hawk-driver can resolve librustc_driver on Linux, which the prior Nix derivation inadvertently omitted.
-
Add
rustToolchainas a runtime dependency on Linux — passesrustToolchain(derived fromrust-toolchain.tomlviapkgs.rust-bin.fromRustupToolchainFile) to thecargo-hawkderivation asruntimeDependenciesso the binary can loadlibrustc_driverat runtime. -
Add
stdenv.cc.cc.libas a build input on Linux — letsautoPatchelfHooklink against glibc symbols during the build phase. -
Thread
rustToolchainthrough fromnix/packages.nix— already bound there at line 19 and used by every other Nix module (checks.nix,dev-shell.nix,git-hooks.nix), now passed topkgs.callPackageforcargo-hawk.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
runtimeDependencies put the toolchain on the RUNPATH but left the dependency reported as unsatisfied, because auto-patchelf resolves against the library set derived from buildInputs and only writes runtimeDependencies into the RUNPATH. The pinned toolchain does carry the exact file the published binary asks for: the upstream rustc 1.97.1 archive for x86_64-unknown-linux-gnu ships librustc_driver-832cf6cfb1386559.so, the name in the CI failure, so moving the toolchain into buildInputs makes the search find it instead of ignoring it.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@nix/checks.nix`:
- Line 59: Update the nativeBuildInputs expression in the relevant checks
configuration to parenthesize the `commonArgs.nativeBuildInputs` fallback before
appending `config.packages.cargo-hawk`, ensuring the `or [ ]` default applies
only to nativeBuildInputs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4914d58f-61ea-4d0d-9e62-abff4c00885f
📒 Files selected for processing (4)
.agents/skills/rust/SKILL.mdnix/cargo-hawk.nixnix/checks.nixnix/packages.nix
🚧 Files skipped from review as they are similar to previous changes (3)
- nix/packages.nix
- nix/cargo-hawk.nix
- .agents/skills/rust/SKILL.md
| sourceRoot = "source/rust"; | ||
| cargoLock = root + /rust/Cargo.lock; | ||
| inherit cargoArtifacts; | ||
| nativeBuildInputs = commonArgs.nativeBuildInputs or [ ] ++ [ config.packages.cargo-hawk ]; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
direnv allow
just --list
nix eval --json --expr '
let
commonArgs = { nativeBuildInputs = [ "existing-input" ]; };
in
commonArgs.nativeBuildInputs or [ ] ++ [ "cargo-hawk" ]
'
nix eval --json --expr '
let
commonArgs = { nativeBuildInputs = [ "existing-input" ]; };
in
(commonArgs.nativeBuildInputs or [ ]) ++ [ "cargo-hawk" ]
'Repository: ccusage/ccusage
Length of output: 197
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "== files =="
git ls-files nix/
echo "== nix/checks.nix around 47-62 and 160-172 =="
cat -n nix/checks.nix | sed -n '45,70p;158,174p'
echo "== searches for ccusage-hawk / cargo-hawk native inputs =="
rg -n "cargo-hawk|ccusage-hawk|nativeBuildInputs.*or|nativeBuildInputs = commonArgs" nix .github README.md 2>/dev/null | head -120
echo "== nix parser probe if nix is available =="
if command -v nix >/dev/null 2>&1; then
nix eval --json --expr '
let
commonArgs = { nativeBuildInputs = [ "existing-input" ]; };
in
commonArgs.nativeBuildInputs or [ ] ++ [ "cargo-hawk" ]
' || true
nix eval --json --expr '
let
commonArgs = { nativeBuildInputs = [ "existing-input" ]; };
in
(commonArgs.nativeBuildInputs or [ ]) ++ [ "cargo-hawk" ]
' || true
else
echo "nix not available"
fi
echo "== locate Nix evaluator for parsing if commonArgs can be omitted =="
if command -v nix >/dev/null 2>&1; then
cat >/tmp/nix-or-probe.nix <<'NIX'
let
commonArgs = { };
cfg = commonArgs.nativeBuildInputs or [ ];
inputs = cfg ++ [ "cargo-hawk" ];
in { cfg = cfg; inputs = inputs; }
NIX
nix eval --json --file /tmp/nix-or-probe.nix || true
fiRepository: ccusage/ccusage
Length of output: 4686
🌐 Web query:
Nix attribute selection operators precedence dot or concat list or [ ] ++ concatenation
💡 Result:
In the Nix expression language, operators follow a specific precedence order that determines how expressions are evaluated. Attribute selection and list concatenation occupy different tiers in this hierarchy, meaning attribute selection binds more tightly than list concatenation [1][2]. The precedence levels for the requested operators are as follows (where 1 is the highest precedence/strongest binding): 1. Attribute Selection (.): This operator has a precedence of 1, making it one of the highest-binding operations in the language [1][3]. It is used to select an attribute from an attribute set (e.g., attrset.attrpath) [1][4]. 2. List Concatenation (++): This operator has a precedence of 5 [1][2]. It is used to join two lists together (e.g., list1 ++ list2) [1][5]. Because attribute selection (precedence 1) binds more tightly than list concatenation (precedence 5), an expression like a.b ++ c is parsed as (a.b) ++ c [1][2]. Summary of relevant operator precedence (from strongest to weakest): - Attribute Selection (.): 1 [1][3] - Function Application: 2 [1][2] - Arithmetic Negation (-): 3 [1][6] - Has Attribute (?): 4 [1][2] - List Concatenation (++): 5 [1][4] For comprehensive details, you can refer to the official Nix language documentation regarding operators [1][2].
Citations:
- 1: https://github.com/NixOS/nix/blob/master/doc/manual/source/language/operators.md
- 2: https://nix.dev/manual/nix/2.32/language/operators
- 3: https://releases.nixos.org/nix/nix-2.34.0/manual/language/operators.html
- 4: https://releases.nixos.org/nix/nix-2.33.1/manual/language/operators.html
- 5: https://hydra.nixos.org/build/153568733/download/1/manual/expressions/language-operators.html
- 6: https://nix.dev/manual/nix/2.33/language/operators.html
🌐 Web query:
Nix syntax or operator binding associativity in attrpath fallback or syntax A or B
💡 Result:
In the Nix language, the attribute selection operator (also known as the fallback syntax when the or keyword is used) is defined as having "none" for its associativity [1][2][3]. The formal syntax for this operation is: attrset. attrpath [or expr] When the or keyword is used, it provides a fallback value if the specified attribute path (attrpath) does not exist in the attribute set (attrset). If the attribute is missing and no or expression is provided, Nix will abort evaluation [1][2][3]. Regarding associativity, the attribute selection operator's "none" designation signifies that chaining behaves in a specific way: while multiple selections can be chained (e.g., a.b.c), the or fallback expression extends as far as possible to the right [4]. This means that in an expression like a.b or c.d or e, the parser interprets the or as applying to the entire preceding selection chain [4]. Because the or clause binds to the entire preceding expression, it effectively acts as a fallback for the entire lookup operation rather than just the final segment of a chained path [4].
Citations:
- 1: https://nix.dev/manual/nix/2.33/language/operators
- 2: https://github.com/NixOS/nix/blob/master/doc/manual/source/language/operators.md
- 3: https://nix.dev/manual/nix/2.33/language/operators.html
- 4: https://discourse.nixos.org/t/assosiativity-of-none-for-certain-operators/29967
🌐 Web query:
"commonArgs.nativeBuildInputs or [ ] ++" "Nix" "or []"
💡 Result:
The expression commonArgs.nativeBuildInputs or [] ++ ... is a common pattern in Nix flake configurations, particularly when using builders like crane, to safely extend an existing list of build dependencies [1][2][3]. Breakdown of the expression: 1. commonArgs.nativeBuildInputs or []: This part uses the OR operator (or). It attempts to access the nativeBuildInputs attribute from the commonArgs attribute set. If nativeBuildInputs is missing from commonArgs, it defaults to an empty list [], preventing an evaluation error [1][4]. 2. ++: This is the list concatenation operator in the Nix language. It combines the list obtained in the first step with the list on the right-hand side [1][5][6]. 3....: This represents the new dependencies you wish to add to the derivation (e.g., with pkgs; [ git cmake ]) [1][3]. Why this is used: In Nix, defining derivation arguments often involves merging attribute sets. If you simply use // to override nativeBuildInputs, you will completely replace the original list, effectively "dropping" any default dependencies (like build hooks or standard tools) that were defined in commonArgs [1]. Using (commonArgs.nativeBuildInputs or []) ++ [...] ensures that you are extending the existing list rather than overwriting it, which is crucial for maintaining necessary build tools across different parts of a project [1][4]. It is important to note the order of operations and grouping. Because the or operator has higher precedence than ++, you should generally group the first part in parentheses if you want the or to apply to the retrieval of the attribute before the concatenation occurs: (commonArgs.nativeBuildInputs or []) ++ [...] [1][4]. Without proper grouping, the expression might be parsed as commonArgs.nativeBuildInputs or ([] ++ [...]), which may not be the intended behavior.
Citations:
- 1: fix: hApps that are fetched from URL are not packaged with Nix build holochain/wind-tunnel#526
- 2: https://github.com/njbrake/agent-of-empires/blob/main/flake.nix
- 3: https://github.com/max-sixty/worktrunk/blob/main/flake.nix
- 4: https://deepwiki.com/akirak/flake-templates/6.1-nix-development-shells
- 5: utensils/nxv@09f160e
- 6: https://gitea.hillion.co.uk/JakeHillion/personal-agent/commit/ef712a42dbf9ea08dae57082753353b41a4296a3
🌐 Web query:
"Nix language operators" "or" "None"
💡 Result:
The Nix language does not have a None type or a specific None operator. Instead, it provides a null value, which represents the absence of a value [1][2][3]. The null value is a distinct primitive type in Nix [3][4]. It can be accessed as the literal null or via the built-in attribute set as builtins.null [1][3][5]. Regarding operators, Nix features a variety of arithmetic, logical, and structural operators, such as attribute selection (.), attribute update (//), and equality tests (==,!=), but there is no None operator [6][7][8]. Notably, the attribute selection operator does support a default value mechanism using the or keyword (e.g., attrset.attrpath or default_expr), which is often used in scenarios where one might use an option or null-coalescing operator in other languages [6][7][9].
Citations:
- 1: https://nix.dev/manual/nix/2.30/language/types
- 2: https://releases.nixos.org/nix/nix-2.33.1/manual/language/types.html
- 3: https://github.com/NixOS/nix/blob/master/doc/manual/source/language/types.md
- 4: https://nix.dev/manual/nix/2.34/language/types
- 5: https://nix.dev/manual/nix/2.19/language/values
- 6: https://nix.dev/manual/nix/2.34/language/operators
- 7: https://nix.dev/manual/nix/2.34/language/index.html
- 8: https://github.com/NixOS/nix/blob/master/doc/manual/source/language/operators.md
- 9: https://nix.dev/manual/nix/2.31/language/index.html
🌐 Web query:
github nixos/nix "or" attrpath precedence "++" language/operators.md
💡 Result:
In the Nix expression language, attribute selection (.) and the ++ (list concatenation) operator have different precedence levels, which determine the order in which expressions are evaluated [1][2]. According to the official Nix reference documentation, attribute selection has the highest precedence (1), while list concatenation (++) has a lower precedence (5) [1][3]. Because lower precedence numbers indicate "stronger" binding (the operations performed first), attribute selection binds more tightly than the ++ operator [4]. Summary of precedence levels for these operators: 1. Attribute selection (attrset.attrpath): Precedence 1 [1][2]. 2. List concatenation (list ++ list): Precedence 5 [1][2]. Because of this, an expression like a.b ++ c is parsed as (a.b) ++ c rather than a.(b ++ c). In Nix, an "attribute path" is defined as a dot-separated list of attribute names (e.g., a.b.c) and is used specifically with the attribute selection operator [4][5].
Citations:
- 1: https://nix.dev/manual/nix/2.33/language/operators.html
- 2: https://releases.nixos.org/nix/nix-2.34.0/manual/language/operators.html
- 3: https://github.com/NixOS/nix/blob/master/doc/manual/source/language/operators.md
- 4: https://hydra.nixos.org/build/153568733/download/1/manual/expressions/language-operators.html
- 5: https://nix.dev/manual/nix/2.18/language/operators
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
# Read-only static probe: parse Nix attr-or syntax using a small tokenizer from the
# language/operator precedent described by the Nix manual for attribute selection vs
# list concatenation.
#
# Relevance: we do not run repository code or tools, but this mirrors deterministic
# parsing by respecting precedence/associativity facts from the referenced Nix semantics.
import re
def tokenize(s):
state = 'start'
i = 0
while i < len(s):
ch = s[i:i+1]
if ch.isspace():
i += 1
continue
if ch == '.':
yield 'DOT'
i += 1
elif ch == '+':
if s[i:i+2] == '++':
yield 'CONCAT'
i += 2
else:
raise SystemExit("unknown token ++")
elif ch == '[':
yield 'LBRACKET'
i += 1
elif ch == ']':
yield 'RBRACKET'
elif s[i:i+2] == 'or':
yield 'OR'
i += 2
else:
m = re.match(r'[A-Za-z0-9_-]+', s[i:])
if not m:
raise SystemExit(f"unexpected token at {i!r}")
yield m.group(0)
i += len(m.group(0))
def parse_attr_or_concat(s):
tokens = list(tokenize(s))
# Tokens relevant to expression `commonArgs.nativeBuildInputs or [] ++ [ cargo-hawk ]`
# with hyphen names tokenized.
expr = tokens
if tokens == ['commonArgs','nativeBuildInputs','OR','LBRACKET','RBRACKET','CONCAT','LBRACKET','cargo hawk','RBRACKET']:
# Model precedence/order: dot binds attrpath; or is part of attr-or syntax for
# missing attrpath with fallback expression. Concat is a separate later list
# operator with lower precedence.
attr_path = ('commonArgs','nativeBuildInputs')
fallback = []
extra = ['cargo hawk']
return {'parsed': f'attr_or(attr_path={attr_path}, fallback={fallback}) ++ extra={extra}',
'would_concat_if_exists': True}
attr = []
i = 0
if expr[0] not in ['commonArgs','nativeBuildInputs']:
return {}
# Parse leading attrpath with attributes.
while i < len(expr) and expr[i].isidentifier():
attr.append(expr[i])
i += 1
if i < len(expr) and expr[i] == 'DOT':
if len(attr) < 2 or expr[i+1] != 'nativeBuildInputs':
raise SystemExit("unexpected attrpath")
attr.append('nativeBuildInputs')
i += 2
if i < len(expr) and expr[i] == 'OR':
if len(attr) != 2 or expr[i+1:i+3] != ['LBRACKET','RBRACKET']:
raise SystemExit("unexpected or")
attrs = tuple(attr)
i += 3
result_exists = attrs == ('commonArgs','nativeBuildInputs')
fallback = []
if i < len(expr) and expr[i] == 'CONCAT':
if expr[i+1:i+3] != ['LBRACKET','cargo hawk','RBRACKET']:
raise SystemExit("unexpected concat")
print("Parsed expression has later CONCAT after attr-or, so concat is a separate operator.")
print("If commonArgs.nativeBuildInputs exists, eval-result = existing ++ ['cargo hawk'].")
print("If commonArgs.nativeBuildInputs is missing, eval-result = [] ++ ['cargo hawk'].")
raise SystemExit(0)
else:
raise SystemExit("missing concat after or")
raise SystemExit("bad expression")
parse_attr_or_concat('commonArgs.nativeBuildInputs or [ ] ++ [ cargo hawk ]')
PYRepository: ccusage/ccusage
Length of output: 145
🌐 Web query:
"commonArgs.nativeBuildInputs or [ ] ++" "Nix"
💡 Result:
In Nix, the expression commonArgs.nativeBuildInputs or [ ] is a common pattern used to safely access a list of dependencies from an attribute set (commonArgs), providing an empty list [ ] as a fallback if the attribute is missing [1][2][3]. The syntax x or y is a built-in Nix language feature used to access an attribute x from a set if it exists, otherwise returning the default value y. This pattern is frequently used in Nix derivations—particularly when building Rust projects with tools like Crane—to incrementally extend or override build arguments [1][2][4]. For example, when creating a new derivation based on a set of common arguments, you can extend the nativeBuildInputs while ensuring you do not encounter an error if the base set lacks that specific attribute: nativeBuildInputs = (commonArgs.nativeBuildInputs or [ ]) ++ [ pkgs.some-tool ]; This allows for modular and DRY (Don't Repeat Yourself) configurations, where common dependencies are defined once and then augmented as needed for specific targets or test environments [1][2]. It is particularly valuable in complex Flake configurations where arguments are passed through multiple layers of derivation overrides [4][5].
Citations:
- 1: https://crane.dev/examples/sqlx.html
- 2: https://github.com/apibara/dna/blob/1740bb3a/nix/build.nix
- 3: https://docs.rs/crate/es-entity/latest/source/flake.nix
- 4: https://deepwiki.com/akirak/flake-templates/6.1-nix-development-shells
- 5: https://github.com/jamesbrink/nxv/blob/main/flake.nix
🌐 Web query:
docs.rs nix-parser "or" operator precedence list concatenation "++"
💡 Result:
In the Nix expression language, the list concatenation operator (++) has a precedence level of 5 [1][2][3]. It is right-associative [1][2][3]. For context, this places it between the "has attribute" operator (precedence 4) and multiplication/division (precedence 6) [1][2][3]. Regarding the mention of "docs.rs nix-parser," the primary Rust-based parser for the Nix language is rnix (often referred to as rnix-parser) [4][5][6]. While it provides tools for parsing and manipulating the Nix abstract syntax tree (AST) [4][5][6], authoritative technical details regarding language-level operator precedence are defined by the official Nix reference manual [1][2][3] and implemented in the language's core source code (e.g., parser.y) [7].
Citations:
- 1: https://nix.dev/manual/nix/2.30/language/operators
- 2: https://nix.dev/manual/nix/2.33/language/operators.html
- 3: https://releases.nixos.org/nix/nix-2.34.0/manual/language/operators.html
- 4: https://docs.rs/crate/rnix/0.12.0
- 5: https://github.com/nix-community/rnix-parser/
- 6: https://crates.io/crates/rnix
- 7: https://github.com/NixOS/nix/blob/b4de9738/src/libexpr/parser.y
Parenthesize the fallback before appending cargo-hawk.
commonArgs.nativeBuildInputs or [ ] ++ [ config.packages.cargo-hawk ] uses precedence that can make the fallback apply to the lookup result after concatenation instead of before. Move the default list outside the or syntax instead of leaving or [ ] ++ ... as the fallback target.
Proposed fix
- nativeBuildInputs = commonArgs.nativeBuildInputs or [ ] ++ [ config.packages.cargo-hawk ];
+ nativeBuildInputs = (commonArgs.nativeBuildInputs or [ ]) ++ [ config.packages.cargo-hawk ];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| nativeBuildInputs = commonArgs.nativeBuildInputs or [ ] ++ [ config.packages.cargo-hawk ]; | |
| nativeBuildInputs = (commonArgs.nativeBuildInputs or [ ]) ++ [ config.packages.cargo-hawk ]; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@nix/checks.nix` at line 59, Update the nativeBuildInputs expression in the
relevant checks configuration to parenthesize the `commonArgs.nativeBuildInputs`
fallback before appending `config.packages.cargo-hawk`, ensuring the `or [ ]`
default applies only to nativeBuildInputs.
There was a problem hiding this comment.
False positive: in Nix the or fallback is an expr_select and binds tighter than the lower-precedence ++, so the line already parses as (commonArgs.nativeBuildInputs or [ ]) ++ [ config.packages.cargo-hawk ]. CI confirms this — commonArgs defines nativeBuildInputs, yet the check still builds cargo-hawk, which only happens under the correct parse. The suggested parens are a no-op.
There was a problem hiding this comment.
Skipped: comment is from another GitHub bot.
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |

Summary
just hawklanded in #1428 without the tool behind it, so therustskill toldcontributors to
curl | shan installer — an unpinned binary outside Nix, in arepository that pins everything else. This adds
nix/cargo-hawk.nixand puts it inthe dev shell, so
just hawkworks afterdirenv allowlike every other recipe.Why the published binary rather than a source build
hawk links against
rustc_private. Building it from source needs therustc-devcomponent in the toolchain and
RUSTC_BOOTSTRAP=1, which is a lot of machinery tocarry for a lint that no CI check gates on and that upstream calls experimental
("not intended for public consumption"). Upstream's own docs note that a prebuilt
release requires neither.
The derivation pins the release by hash for the four platforms upstream publishes
(aarch64/x86_64 × darwin/linux), marks
sourceProvenance = binaryNativeCode, andinstalls
cargo-hawk-drivernext tocargo-hawkbecause the binary execs the driverfrom its own directory. Closure is 3.7 MB. A version bump is
versionplus the foursha256values, which upstream publishes beside each archive.If a source build is preferred later, the
rustc-devtoolchain can be materialisedinside this derivation through rust-overlay without touching the shared
rust-toolchain.tomlpin — the file is the only thing that would change.Testing
nix build .#cargo-hawk— both binaries land in$out/bincargo hawk check --manifest-path rust/Cargo.tomlwith the Nix-built binary: 0 findings onmainnix build .#ccusagestill builds, so the dev-shell addition does not perturb the package setjust fmtThe skill section now describes the pinned derivation and how to bump it instead of
the installer script.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is enabled.Summary by cubic
Pins
cargo-hawkin the Nix dev shell and gates CI withnix flake checkso unnecessarypubfails fast. Fixes Linux linking by moving the pinned toolchain intobuildInputs, making the binary work across macOS/Linux on arm64 and x86_64.New Features
nix/cargo-hawk.nixto installcargo-hawkwithcargo-hawk-driver.packages.cargo-hawkand included in the dev shell.checks.<system>.ccusage-hawkto runcargo hawk check -D warnings, reusing clippy artifacts..agents/skills/rust/SKILL.mdwith pinning and bump steps.Bug Fixes
rustToolchainintobuildInputs(withstdenv.cc.cc.lib) soautoPatchelfresolveslibrustc_driver; macOS continues to resolve via@rpath.Written for commit faac847. Summary will update on new commits.
Summary by CodeRabbit
cargo-hawkto the development environment as a visibility lint tool.cargo-hawkso it’s available consistently across systems.hawk/cargo-hawkworkflow to reflect the Nix-pinned dev shell setup and how toolchain versioning affects results.nix flake checkto run an additionalcargo hawk checkwith warnings treated as errors.