Skip to content

stats: refactor build to data-driven Nix functions - #542371

Open
TyceHerrman wants to merge 6 commits into
NixOS:masterfrom
TyceHerrman:stats-3.0.8
Open

stats: refactor build to data-driven Nix functions#542371
TyceHerrman wants to merge 6 commits into
NixOS:masterfrom
TyceHerrman:stats-3.0.8

Conversation

@TyceHerrman

@TyceHerrman TyceHerrman commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Refactors the existing Stats 3.0.13 build around a shared, data-driven module configuration. The package attribute, app bundle, and $out/bin/stats interface are unchanged.

The rewrite addresses the maintainer review by:

  • building every module, including Sensors' Objective-C source, through one shared builder;
  • scoping IOReport linkage to CPU, GPU, and Sensors;
  • preserving upstream's Info.plist, merging actool metadata, and removing the unused privileged-helper declaration;
  • requiring all module config.plist files at build time; and
  • using makeBinaryWrapper so Bash is not retained in the runtime closure.

Additional verification:

  • Ran targeted treefmt, git diff --check, and nix-build -A stats --no-out-link before each of the six commits.
  • nixpkgs-review rev HEAD -p stats --systems aarch64-darwin --no-shell: 1 package built (stats).
  • Verified CFBundleShortVersionString = 3.0.13, upstream CFBundleVersion = 835, NSAppleEventsUsageDescription is present, and SMPrivilegedExecutables is absent.
  • Verified all 11 frameworks and all 10 module configs are installed.
  • Verified only CPU, GPU, and Sensors link IOReport.
  • Verified $out/bin/stats is a Mach-O binary wrapper, the runtime closure contains no Bash, and closure size falls from 14.0 MiB to 11.2 MiB.
  • Verified codesign --verify --deep --strict.
  • Interactive launch testing could not be confirmed from the Codex sandbox: the rewritten build, the untouched master build, and the installed Home Manager app all fail through this session's LaunchServices boundary in the same way. x86_64-darwin was not tested locally.

Automation disclosure: This contribution, including the code changes and pull request summary, was prepared with assistance from Codex (GPT-5).

Things done

@nixpkgs-ci nixpkgs-ci Bot added 8.has: package (update) This PR updates a package to a newer version 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux. 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. labels Jul 15, 2026
@TyceHerrman
TyceHerrman marked this pull request as ready for review July 15, 2026 21:47
@nixpkgs-ci
nixpkgs-ci Bot requested review from 4evy, emilytrau and kinnrai July 15, 2026 22:11
@kinnrai

kinnrai commented Jul 20, 2026

Copy link
Copy Markdown
Member

nixpkgs-review result

Generated using nixpkgs-review.

Command: nixpkgs-review pr 542371
Commit: 8755d789bbc42d60299b2860b7e2089816175816


aarch64-darwin

✅ 1 package built:
  • stats

@kinnrai kinnrai left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Built and tested on aarch64-darwin. LGTM.

@nixpkgs-ci nixpkgs-ci Bot added 12.approvals: 1 This PR was reviewed and approved by one person. 12.approved-by: package-maintainer This PR was reviewed and approved by a maintainer listed in any of the changed packages. llm-assisted Contributions that include code generation with LLMs labels Jul 20, 2026
@TyceHerrman TyceHerrman changed the title stats: 3.0.6 -> 3.0.8, refactor build stats: 3.0.6 -> 3.0.9, refactor build Jul 20, 2026
@TyceHerrman

Copy link
Copy Markdown
Contributor Author

@emilytrau, can you take a look at this when you get a chance?

@TyceHerrman TyceHerrman changed the title stats: 3.0.6 -> 3.0.9, refactor build stats: 3.0.6 -> 3.0.11, refactor build Aug 20, 2026
@nixpkgs-review-gha

Copy link
Copy Markdown

nixpkgs-review result

Generated using nixpkgs-review-gha (b0ab82d)

Command: nixpkgs-review pr 542371
Commit: b9b3832f58248f8dac35c6b11f9799029205fa40 (subsequent changes)
Merge: 4b5bae196dc05a6c37e26b4b0efd19dd633e694d

Triggered by @TyceHerrman (22066434)
Logs: https://github.com/TyceHerrman/nixpkgs-review-gha/actions/runs/32528169491/attempts/1


x86_64-linux

No rebuilds


aarch64-linux

No rebuilds


x86_64-darwin

No rebuilds


aarch64-darwin (sandbox = relaxed)

✅ 1 package built:
  • stats

@4evy

4evy commented Aug 23, 2026

Copy link
Copy Markdown
Member

Could you rebase this onto master once #555873 is merged and drop the redundant version bump?

Also, this is partly a review note to myself since the refactor commit was cherry-picked from my earlier PR (lol): I think it'd be better to split it into smaller, independently reviewable commits

Right now the module model, build commands, plist generation, asset handling, and install logic all change together, which makes it hard to distinguish structural cleanup from behavior changes

Comment thread pkgs/by-name/st/stats/package.nix Outdated
"CoreBluetooth"
];
}
{ name = "Sensors"; } # custom build (ObjC + Swift)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we fold Sensors into the same module table instead of keeping a second build path?

{
  name = "Sensors";
  bridgingHeader = "Modules/Sensors/bridge.h";
  frameworks = [ "IOKit" ];
  libraries = [ "IOReport" ];
  objcSource = "reader.m";
}

Then the shared builder can compile objcSource when present.

@TyceHerrman TyceHerrman Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 7c96ad8. Sensors is now a moduleConfigs entry with its bridging header, IOKit, IOReport, and Objective-C source. The shared builder compiles objcSource when present

Comment thread pkgs/by-name/st/stats/package.nix Outdated
${lib.optionalString (mod ? bridgingHeader) ''-import-objc-header "${mod.bridgingHeader}"''} \
-I "$buildDir" -L "$buildDir" \
-Xlinker -install_name -Xlinker "@rpath/${mod.name}.framework/${mod.name}" \
-lKit ${lib.concatMapStringsSep " " (f: "-framework ${f}") (mod.sysFrameworks or [ ])} \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we scope -lIOReport to CPU, GPU, and Sensors? Those are the only modules that use it; NIX_LDFLAGS currently links it into everything.

libraries = [ "IOReport" ];

linkFlags = [ "-lKit" ]
  ++ map (library: "-l${library}") (module.libraries or [ ]);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 2b0756b. The global NIX_LDFLAGS is gone and IOReport is expressed through the per-module libraries field. otool -L on the final bundle shows IOReport only in CPU, GPU, and Sensors.

Comment thread pkgs/by-name/st/stats/package.nix Outdated
--platform macosx \
--minimum-deployment-target 14.0 \
${lib.optionalString (appIcon != null) "--app-icon ${appIcon}"} \
--output-partial-info-plist /dev/null \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This drops upstream plist keys, including NSAppleEventsUsageDescription. I'd keep the upstream plist as the source of truth and merge the actool output into it:

cp "Stats/Supporting Files/Info.plist" "$appInfo"
# substitute the Xcode build variables here
actool ... --output-partial-info-plist "$assetInfo" ...
${lib.getExe' re-plistbuddy "PlistBuddy"} -c "Merge $assetInfo" "$appInfo"
${lib.getExe' re-plistbuddy "PlistBuddy"} -c 'Delete :SMPrivilegedExecutables' "$appInfo"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in a2b8526. The build now copies and substitutes upstream's plist, merges actool's partial plist with re-plistbuddy, and removes SMPrivilegedExecutables. The final plist retains NSAppleEventsUsageDescription, reports version 3.0.13/build 835, and has no privileged-helper entry.

Comment thread pkgs/by-name/st/stats/package.nix Outdated
if [ -f "Modules/$mod/config.plist" ]; then
cp "Modules/$mod/config.plist" "$app/Contents/Frameworks/$mod.framework/Resources/config.plist"
${lib.concatMapStrings (name: ''
if [ -f "Modules/${name}/config.plist" ]; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These configs are force-unwrapped at runtime, so this should fail during the build instead of crashing at launch:

for name in ${lib.escapeShellArgs moduleNames}; do
  cp "Modules/$name/config.plist" \
    "$app/Contents/Frameworks/$name.framework/Resources/config.plist"
done

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in dc807d7. Every module config is now copied unconditionally, so a missing input fails the build. The derivation succeeds and the final app contains all ten module config.plist files.

done
'') moduleNames}

makeWrapper "$app/Contents/MacOS/Stats" "$out/bin/stats"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makeWrapper pulls Bash into the closure even though we pass no wrapper args. makeBinaryWrapper keeps the call unchanged and took the closure from 14.0 to 11.2 MiB:

nativeBuildInputs = [ makeBinaryWrapper ];
makeWrapper "$app/Contents/MacOS/Stats" "$out/bin/stats"

@TyceHerrman TyceHerrman Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in add26be. The input is now makeBinaryWrapper while the existing makeWrapper call is unchanged. $out/bin/stats is a Mach-O wrapper. the runtime closure contains only Stats, LevelDB, and Snappy (no Bash) and measures 11.2 MiB versus 14.0 MiB.

@nixpkgs-ci nixpkgs-ci Bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Aug 24, 2026
@TyceHerrman TyceHerrman changed the title stats: 3.0.6 -> 3.0.11, refactor build stats: refactor build to data-driven Nix functions Aug 24, 2026
@TyceHerrman

TyceHerrman commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

@4evy Rebased onto master at aab1f6e after #555873 merged. The obsolete version bump and temporary LLD workaround are no longer in the branch.

I split the changes into six commits:

  1. add26bef597c — binary wrapper
  2. a2b852608606 — preserve/merge upstream application plist
  3. dc807d76127a — require module config plists
  4. 2b0756b5dd8b — scope IOReport linkage
  5. 7c96ad83b54f — data-driven shared module builder, including Sensors
  6. 32f776c9c584 — derive framework names from the module configuration

Each commit passed formatting, git diff --check, and an aarch64-darwin Stats build. also passed nixpkgs-review

@nixpkgs-ci nixpkgs-ci Bot removed 8.has: package (update) This PR updates a package to a newer version 2.status: merge conflict This PR has merge conflicts with the target branch llm-assisted Contributions that include code generation with LLMs labels Aug 24, 2026
@TyceHerrman

Copy link
Copy Markdown
Contributor Author

@ofborg build stats

@nixpkgs-review-gha

Copy link
Copy Markdown

nixpkgs-review result

Generated using nixpkgs-review-gha (b0ab82d)

Command: nixpkgs-review pr 542371
Commit: 32f776c9c5844ddf766d0a6ec9a8823ef2a17846 (subsequent changes)
Merge: 29a1b70acb4d662fc6551dc79db86ff4f47f883e

Triggered by @TyceHerrman (22066434)
Logs: https://github.com/TyceHerrman/nixpkgs-review-gha/actions/runs/32732764369/attempts/1


x86_64-linux

No rebuilds


aarch64-linux

No rebuilds


x86_64-darwin

No rebuilds


aarch64-darwin (sandbox = relaxed)

✅ 1 package built:
  • stats

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux. 12.approvals: 1 This PR was reviewed and approved by one person. 12.approved-by: package-maintainer This PR was reviewed and approved by a maintainer listed in any of the changed packages.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants