Live data from Hacker News

Nix solves the package manager ejection problem

zeroindexed.com

21–30 of 50 posts

Re: Nix solves the package manager ejection problem

#21
post #9

Read the NPM doc but I still don't understand what "ejection" is. What are we ejecting? Can someone explain this please?

I believe the confusing bit is that it's not an NPM thing, it's a create-react-app thing. create-react-app is a helper tool for, as the name says, creating React applications and doing a bunch of things out of the box. Occasionally you reach the point where you need to do something more complex than create-react-app can handle for you. In that case, you run the "eject" script in the generated app (using "npm run" as…

> I don't think it's a perfect analogy, but I see what the author is getting at - you need to break the abstraction of some packaging tool, but you want the functionality it provided to still work as well as possible.

You got it. I don't think it's the best analogy either but it is pithy and works if you squint.

The essence is:

1. create-react-app is a monolithic transformation of a bunch of disparate tools into a managed workflow.

2. You can update create-react-app like any other dependency and get updates to the workflow.

3. At any point, you can break the abstraction via `npm run eject`, which drops you down a level into the raw configuration for the "disparate tools" that create-react-app was acting as a veneer over. This ejection is a point in time transformation, you no longer get the managed workflow updates from (2).

The analogy was:

1. The Linux kernel package on $DISTRO is a monolithic transformation of Linux kernel source code to Linux kernel binaries.

2. You can get updates from the package manager.

3. At any point, you can break the abstraction by dropping down a level and forking the current packaging script to adjust the transformation (like applying a patch). This fork is a point in time transformation, you no longer get the package updates from (2).

Re: Nix solves the package manager ejection problem

#22

Read the NPM doc but I still don't understand what "ejection" is. What are we ejecting? Can someone explain this please?

It’s not a common package manager or NPM thing, but a create-react-app thing that a few other things have copied. A detailed description of what it involves in CRA is here: https://create-react-app.dev/docs/available-scripts/

Re: Nix solves the package manager ejection problem

#23
post #12

Off-topic question about Nix. I understand it works by redirecting symlinks from, say, one version of a package's files to another. Isn't there a race-condition here -- like if I invoke a program at the wrong time while it's in the process of changing symlinks, could it pick up the wrong libraries or something? Does Linux OS allow a "changeset" of files to be locked and altered together in a batch, or anything like t…

After the profile is built, there is only one link that needs to be changed to activate it, so it's atomic.

Re: Nix solves the package manager ejection problem

#24
post #17
post #12

Off-topic question about Nix. I understand it works by redirecting symlinks from, say, one version of a package's files to another. Isn't there a race-condition here -- like if I invoke a program at the wrong time while it's in the process of changing symlinks, could it pick up the wrong libraries or something? Does Linux OS allow a "changeset" of files to be locked and altered together in a batch, or anything like t…

I don't think "redirecting symlinks" is a totally accurate way of describing how Nix works. Each Nix package, as packaged, has a hard-coded dependency on the specific hashed versions of all its dependencies. For instance, if you're building NPM and its build scripts hash to abcd1234, and it depends on Node.js whose build scripts hash to dcba4321, then /nix/store/abcd1234-npm-1.0/bin/npm has a hard-coded reference to…

The reason that there's no race condition is that you're not "repointing ~/.nix-profile/bin/npm", instead, .nix-profile itself is a symlink, so the entire PATH is changed atomically.

Re: Nix solves the package manager ejection problem

#26

How do NixOS users typically manage software that is not a Nix package, like a source code tarball where you would traditionally run configure && make && make install?

> How do NixOS users typically manage software that is not a Nix package

By writing a Nix package for it (I don't mean for this to sound flippant, tone is a bit hard to convey over text).

For example I have this alpha quality rust binary that I'm developing but I also want a stable version installed at the OS level. I write a Nix package and simply compose it into my overall NixOS configuration alongside the more official Nixpkgs: https://github.com/rraval/nix/blob/master/git-nomad.nix

> like a source code tarball where you would traditionally run configure && make && make install?

Nix has a bunch of defaults that make a conventional package like this straightforward.

Here's a package for a vanilla C binary + library that does the `autoreconf && ./configure && make && make install` dance: https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/secu...

It's almost a little misleading because the actual steps are largely inherited from the defaults, you can read more about `stdenv.mkDerivation` here: https://nixos.org/guides/nix-pills/fundamentals-of-stdenv.ht...

Re: Nix solves the package manager ejection problem

#27

How do NixOS users typically manage software that is not a Nix package, like a source code tarball where you would traditionally run configure && make && make install?

As a NixOS user of 3 years, this rarely happens.

When it does, I either:

* build it via Nix, 10-15 lines, equivalent to packaging it.

* build it in a nix-shell that contains its dependencies

Re: Nix solves the package manager ejection problem

#28
post #19
post #4

To be fair Gentoo has /etc/portage/pqtches so that you can patch software from official packages instead of having to create a new one

Thanks, I didn't know about this. It's been about a decade since I actually used Gentoo and I was writing from the hip. I've published a correction: https://zeroindexed.com/nix-ejection-problem#on-gentoo

Great post! I'm a mildly fanatical Gentoo user myself, but NixOS has tempted me into migrating to function package manager. I've no hesitation to face fiddily systems and work around limitations in the name of freedom and flexibility, so I've choosen GNU Guix. It inherits these same ideas, ostensibly from NixOS itself, but also from the Lisp-driven environment of Emacs with it's advice functions (including sophisticated extensions to the advice system itself, such as el-patch @ https://github.com/raxod502/el-patch)

Re: Nix solves the package manager ejection problem

#29
post #16
post #12

Off-topic question about Nix. I understand it works by redirecting symlinks from, say, one version of a package's files to another. Isn't there a race-condition here -- like if I invoke a program at the wrong time while it's in the process of changing symlinks, could it pick up the wrong libraries or something? Does Linux OS allow a "changeset" of files to be locked and altered together in a batch, or anything like t…

Nix doesn't work by redirecting symlinks, much less between different versions of the same package. So there is no race condition as you describe. Simply, if package A depends on package B then A's files will end up mentioning the absolute path to B directly (say, /nix/store/abcdef-b-1.0/bin/some-bin-file, where "abcdef" is a hash). If package C depends on a different version of package B, then C's files will contain…

Thanks, let me clarify my question with a proper example. Let's say I install A-1.0 and A-1.1. Both versions will depend on say a resource file they expect is at /usr/share/A.res

I was thinking that nix would symlink /bin/A -> /nix/store/abcdef-A-1.0/bin/A, and also /usr/share/A.res -> /nix/store/abcdef-A-1.0/usr/share/A.res

So when I'm upgrading to A-1.1, maybe the /bin/A symlink would update a moment before the /usr/share/A.res symlink, which means invoking A at around the same time as the upgrade could pick up the wrong resource.

Do we just try to make sure that binaries know to look for resources relative to their binary-path? Or do we use chroot/containers? Sorry if this is a dumb question :)

Re: Nix solves the package manager ejection problem

#30

So, how does Guix compare to Nix in 2021 for the average user (who does not want to spend all their time on package management)?

Basic commands in guix are simpler, last I compared them. "guix install", "guix upgrade", etc. These are equivalent to longer guix package commands like "guix package -i" and "guix package -u". I recall nix's package install command being odd, something like "nix-env -ia".

Package names in guix are very consistent, lowercase and hyphen-separated. I recall some nix packages having capital letters in them. It could certainly be confusing.

For declarative user packages, guix has manifests. This is a first class feature. You make a list of packages in a .scm file and apply it, which adds or removes things as needed. With Nix you need to use Home Manager, which isn't part of the main Nix project. A bit of a shame, as this declarative package management is a big selling point, and separating system and user packages lets you have a small system list for fast kernel upgrades and such, while you can keep stuff like icecat in user profile and know that the user package updates may take longer. (especially if there's no substitute and it has to be built)

I think more care is taken to making things simple for the user with guix. What you lose out on is number of things packaged. However, I find guix packages generally have less problems. Nix's mpv package performed worse than guix's with guix being on two generations older hardware (ThinkPad X220T w/ i5 being better than ThinkPad T440p w/ i7). I also ran into strange bugs in some things like pcmanfm. It may be not every package gets much attention and use.

I would say I'm an average user as far as just using my system but not contributing much aside from bug reports.

Note: In all examples I was using each package manager on its home distro, not a foreign distro.

Post reply on HN