Skip to content

darwin: installBinaryPackage init and refactoring of darwin apps#293498

Draft
afh wants to merge 4 commits intoNixOS:masterfrom
afh:init-darwin-install-binary
Draft

darwin: installBinaryPackage init and refactoring of darwin apps#293498
afh wants to merge 4 commits intoNixOS:masterfrom
afh:init-darwin-install-binary

Conversation

@afh
Copy link
Member

@afh afh commented Mar 5, 2024

Description of changes

ℹ️ In order to tackle this work @dwt and I decided to split the work between this PR introducing the darwin.installBinaryPackage function and packages making use of it, see #440894

  • Add darwin.installBinaryPackage unifying and simplifying how binary darwin applications are installed.
  • Refactor a few packages to use darwin.installBinaryPackage
  • Clean-up of packages, e.g. ensure phase pre- and post-hooks are run

NOTA BENE: This is a draft PR to get the conversation going on whether this is headed into the right direction and folks see this as beneficial and helpful.

💭 A Few Thoughts

  • There are several ../os-specific/darwin/ packages declared in pkgs/top-level/all-packages.nix do folks agree that these are better declared in pkgs/top-level/darwin-packages.nix?
  • TODO: Migrate os-specific/darwin packages from all-packages.nix to darwin-packages.nix if the general sentiment is positive on the previous question.
grep os-specific/darwin pkgs/top-level/all-packages.nix | awk -F'[=]' '/ *#/{next} {print $1}'
  • asitop
  • goku
  • grandperspective
  • hexfiend
  • kwm
  • khd
  • m-cli
  • pam-reattach
  • reattach-to-user-namespace
  • skhd
  • qes
  • pngpaste
  • sketchybar
  • spacebar
  • swiftbar
  • airbuddy
  • aldente
  • coconutbattery
  • defaultbrowser
  • karabiner-elements
  • osx-cpu-temp
  • macfuse-stubs
  • osxsnarf
  • plistwatch
  • noah
  • rectangle
  • shortcat
  • smimesign
  • swiftdefaultapps
  • sensible-side-buttons
  • raycast
  • dockutil
  • mas
  • mysides
  • yabai
  • ghc-standalone-archive
  • duti
  • wifi-password
  • TODO: Refactor packages using undmg or _7zz as their nativeBuildInput to unpack a prebuilt darwin binary, if this PR is generally viewed positively.
nix run nixpkgs#silver-searcher -- -G '\.nix' -l '(undmg|_7zz)' | rev | cut -d/ -f2 | rev
  • prl-tools
  • install-binary-package
  • aldente
  • macfuse
  • airbuddy
  • rectangle
  • raycast
  • grandperspective
  • hexfiend
  • sensible-side-buttons
  • caffeine
  • archi
  • 7zz
  • undmg
  • peazip
  • realvnc-vnc-viewer
  • unnaturalscrollwheels
  • disk-inventory-x
  • jprofiler
  • composer
  • mkl
  • fpc
  • fpc
  • top-level
  • spotube
  • spacedrive
  • mos
  • iina
  • suspicious-package
  • rectangle-pro
  • warp-terminal
  • kbreakout
  • libkmahjongg
  • knights
  • killbots
  • bomber
  • knetwalk
  • kpat
  • kdiamond
  • granatier
  • libkdegames
  • kapman
  • kgoldrunner
  • kigo
  • notesnook
  • sequelpro
  • 1password-gui
  • joplin-desktop
  • tableplus
  • keeweb
  • obsidian
  • losslesscut-bin
  • roam-research
  • darwin
  • localsend
  • lens
  • discord
  • vk-messenger
  • slack
  • caprine-bin
  • breitbandmessung
  • synology-drive-client
  • bin
  • scilab-bin
  • yesplaymusic
  • spotify
  • reaper
  • p4v
  • radicle-upstream
  • pika
  • pkgs
  • zandronum
  • katawa-shoujo
  • anki
  • What needs to be documented where, so contributors can discover darwin.installBinaryPackage and learn about its details?
  • If initial review feedback is positive loop in maintainers of refactored packages and ask for their input
  • @reviewers Please see inline comments and questions, especially on pkgs/os-specific/install-binary-package/*

ℹ️ All treewide: refactor to use darwin.installBinaryPackage* commits will be squashed into one. For now it's easier for me to work on this with individual commits.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.05 Release Notes (or backporting 23.05 and 23.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

Copy link
Member Author

@afh afh Mar 5, 2024

Choose a reason for hiding this comment

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

  • Is this the best way to set sensible defaults, but allow customisation for packages that need it?
  • Are there any other dont* flags that are relevant here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Does this implementation allow for enough flexibility for uncommon use-cases (see karabiner-elements) while still making "good" assumptions about the general layout/content of DMGs and PKGs, e.g. unpack any Payload* using bsdtar contained in a .pkg file?

@ofborg ofborg bot added the 6.topic: darwin Running or building packages on Darwin label Mar 5, 2024
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/proposal-for-installing-prebuilt-binaries-on-darwin/40843/1

@afh afh self-assigned this Mar 5, 2024
@afh afh added 0.kind: enhancement Add something new or improve an existing system. 8.has: clean-up This PR removes packages or removes other cruft labels Mar 5, 2024
@afh afh requested review from DataHearth, Enzime and emilytrau and removed request for Enzime and emilytrau March 5, 2024 14:12
@DataHearth
Copy link
Contributor

I like the abstraction made by the dynamic unpack hook for DMG and PKG. Package complexity will drop (IMO) and package's lines reduced by a good margin.

But I think we should make sure every possible option is covered. As for some specific behavior, this might even add more complexity inside the package and possibly inside the hook.

If this solution is chosen, we should create a detailed documentation to avoid looking everywhere to find options, default behaviors, etc.

Love it 👍

@afh
Copy link
Member Author

afh commented Mar 5, 2024

Thank you for taking the time to have a look at this and your comment, @DataHearth, very much appreciated!

In your mind what is a good way to ensure that "every possible option is covered"? My first approach would be to refactor the packages in pkgs/os-specific/darwin and the ones that have undmg or _7zz as a build input.

Where would be a good place for such documentation? Somewhere in docs or rather pkgs/os-specific/darwin/README.md?

@afh
Copy link
Member Author

afh commented Mar 5, 2024

Looking at fetchzip I wonder if that could be changed or creating a similar fetcher, e.g. fetchdmgpkg would be more? helpful than the unpack-dmg-pkg hook? 🤔

@afh afh force-pushed the init-darwin-install-binary branch from 38620a5 to 9dd6490 Compare March 5, 2024 20:52
@ShamrockLee
Copy link
Contributor

I love the idea of having a unified way to package binaries for MacOS.

Regarding the treewide change,

  1. hello: refactor to use darwin.installBinaryPackage would be easier to read comparing to treewide: refactor to use darwin.installBinaryPackage (hello).
  2. It would make this PR easier to review if we change only some packages for demonstration and testing purpose, and split others into subsequent PRs.

@afh
Copy link
Member Author

afh commented Mar 6, 2024

Thanks for your input, @ShamrockLee, much appreciated!

  1. Yes, that is a working title and when this draft PR is promoted to a PR I'll squash all those commits into one with an updated commit message

  2. Agreed 🙂

Any opinion or advice you may have on the "💭 A Few Thoughts" I listed in the initial description?

@DataHearth
Copy link
Contributor

Hey! Regarding creating a fetcher, I'm not a big fan of. As the "universal" way seems to fetch then unpack for most scenarios, I would keep it as a new package helper.

I think the best way to find out if you missed something, it's to check other packages which are using an unpack like 7z or unzip, etc... list all available options, and see if they're applicable to dmg and pkg files. And of course, test it on packages ^^.

I agree with @ShamrockLee , I think this would me much easier to review for a code maintainer with only 1 or 2 packages as examples.

@afh
Copy link
Member Author

afh commented Mar 6, 2024

Thanks for the feedback, @DataHearth, that's helpful.

I'll do some code level analysis and prepare some notes. In addition to that I'll split this PR into two: one for the install binary package changes and one for the treewide package changes (with a possible follow-up).

@afh
Copy link
Member Author

afh commented Mar 7, 2024

As requested this PR now affects fewer files and the majority of the actual package rewrites to use the changes proposed in this PR will be in #293961.
Please allow for some more time for a more methodical analysis and summarising the findings in a few notes (posted here later).

@ofborg ofborg bot added the 8.has: package (new) This PR adds a new package label Mar 7, 2024
@ofborg ofborg bot requested review from joelburget, marsam and stepbrobd March 7, 2024 05:34
@ofborg ofborg bot added the 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. label Mar 7, 2024
@nixpkgs-ci nixpkgs-ci bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Aug 10, 2025
}@args:

let
unpackDmgPkg = makeSetupHook {
Copy link
Member

Choose a reason for hiding this comment

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

Also why not using undmg to un-package dmgs and then creating a separate hook like unpkg that use the both hooks? This would give more flexibility if a user wanted to use outside of install-binary-package.

Copy link
Member

Choose a reason for hiding this comment

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

You probably should look into #147567 this had the implementation of unpkg.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would be easy to use passthru to expose this. I kind of like the fact this is not spread all over nixpgks.

@Eveeifyeve
Copy link
Member

Also isn't this a copy of #147567

@afh
Copy link
Member Author

afh commented Aug 11, 2025

Thanks for taking a look at this, @Eveeifyeve, I've lost some context since last working on this, but I remember this PR going beyond what #147567 did, if I remember correctly undmg does not handle disk image using APFS.

Happy to have another look at #147567 to combine the best of the two.

@afh afh force-pushed the init-darwin-install-binary branch from 4619d35 to 4bb4370 Compare September 5, 2025 10:54
@nixpkgs-ci nixpkgs-ci bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label Sep 5, 2025
@afh afh force-pushed the init-darwin-install-binary branch 2 times, most recently from 4429904 to b13ef19 Compare September 7, 2025 11:31
Comment on lines 17 to 22
pushd "${2:-$pname}"
# Extract files from Payload or Payload~ file contained in given pkg if any
# Depending on how apps are packaged maxdepth might need to be adjusted
# or made adjustable
find . -name 'Payload*' -maxdepth 2 -print0 | xargs -0 -t -I % bsdtar -xf %
popd
Copy link
Contributor

Choose a reason for hiding this comment

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

I kind of would like to use a sub shell with cd ... here to avoid leaking a directory change in case of errors`

@dwt
Copy link
Contributor

dwt commented Sep 9, 2025

I really like this approach and have started to try and write some nixos tests based on this pull request #441396 to

a. better understand how this would work and
b. allow us to ensure that further evolutions of this feature do not break existing packages.

This seems especially relevant to me, as installBinaryPackage tries to guess what actions are required to install a given binary package, which I suspect we will only be able to make work in about 90 to 98 % of cases.

Still, more is probably not required to make binary installers on macOS / Darwin much easier to create and maintain.

Some further developments I would like:

  • AppCast support for automated updates using an update script to ease the maintenance burden
  • Some Documentation on how this is supposed to be evolved, how much complications we want to absorb into the guessing script and at what point we draw the line and direct people to using mkDerivation again.
  • More documentation on how this works.

All of these should probably happen in their own pull request later on, perhaps except the docs on. how we want this to evolve.

@dwt
Copy link
Contributor

dwt commented Sep 9, 2025

@afh I would like to add something like this to make it easier to debug why a build is failing:

diff --git a/pkgs/os-specific/darwin/install-binary-package/default.nix b/pkgs/os-specific/darwin/install-binary-package/default.nix
index d1c9b2a8f238..339a464187ec 100644
--- a/pkgs/os-specific/darwin/install-binary-package/default.nix
+++ b/pkgs/os-specific/darwin/install-binary-package/default.nix
@@ -43,6 +43,14 @@ stdenvNoCC.mkDerivation (
         runHook preInstall
 
         mkdir -p $out/Applications
+
+        if [ ! -d "${appName}" ]; then
+          echo "ERROR: Application '${appName}' not found in the current directory"
+          echo "Contents of the current directory:"
+          find .
+          exit 1
+        fi
+
         cp -R "${appName}" $out/Applications
 
         runHook postInstall

What do you think, is that too un nix like to spit out so much information on a build failure?

@afh
Copy link
Member Author

afh commented Sep 9, 2025

At first glance this feels more suitable for the checkPhase and either if ls -lsa isn't suitable enough I'd like to suggest to add -depth 2 to the find command and/or pipe it to head -100 to limit the error output somewhat.

What do you think?

@dwt
Copy link
Contributor

dwt commented Sep 9, 2025

At first glance this feels more suitable for the checkPhase and either if ls -lsa isn't suitable enough I'd like to suggest to add -depth 2 to the find command and/or pipe it to head -100 to limit the error output somewhat.

What do you think?

Both sounds great. Just a bit of output to get an orientation what's going on and why it is failing.

@afh afh force-pushed the init-darwin-install-binary branch 2 times, most recently from 1c87ea9 to c8aaa30 Compare September 14, 2025 09:31
@dwt
Copy link
Contributor

dwt commented Sep 15, 2025

@afh and me had a bit of a conversation thinking about wether an alternative approach would be to provide darwin.fetchPKG and darwin.fetchDMG functions to provide almost the same drop in package complexity, but without having to explain darwin.installBinaryPackage to everyone. Still just a thought experiment, but never the less an interesting idea. Feedback welcome.

@auscyber
Copy link
Contributor

@afh and me had a bit of a conversation thinking about wether an alternative approach would be to provide darwin.fetchPKG and darwin.fetchDMG functions to provide almost the same drop in package complexity, but without having to explain darwin.installBinaryPackage to everyone. Still just a thought experiment, but never the less an interesting idea. Feedback welcome.

that would be really good, however, how do we deal with maintaining notarization though? as fixup can break many packages

@afh afh force-pushed the init-darwin-install-binary branch 2 times, most recently from 9591326 to 8eecaf5 Compare September 22, 2025 20:17
@dwt
Copy link
Contributor

dwt commented Sep 22, 2025

@auscyber I just had a talk with @afh and the preliminary conclusion is, that we probably want both, fetchers and install binaryPackage as it allows us to expose arguments with the fetchers that give us a very uniform result, while removing much of the magic this module currently has, while still giving us enough control to provide a really short derivation.

@afh afh force-pushed the init-darwin-install-binary branch from 8eecaf5 to 7a473d3 Compare September 23, 2025 08:30
@nixpkgs-ci nixpkgs-ci bot added the 6.topic: fetch Fetchers (e.g. fetchgit, fetchsvn, ...) label Sep 23, 2025
@nixpkgs-ci nixpkgs-ci bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Oct 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

0.kind: enhancement Add something new or improve an existing system. 2.status: merge conflict This PR has merge conflicts with the target branch 6.topic: darwin Running or building packages on Darwin 6.topic: fetch Fetchers (e.g. fetchgit, fetchsvn, ...) 8.has: clean-up This PR removes packages or removes other cruft 8.has: package (new) This PR adds a new package 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.