Advice needed: nitpicking over finalAttrs?

I am a first-time contributor to nixpkgs:

This is simply a single-version binary that is downloaded and installed.

Thanks to my reviewer’s educational comments, I’ve learned a lot and, hopefully, made my submission much better over review iterations.

The only issue left standing seems to be that I preferred a streamlined let binding to define a version string, which is later inherited inside mkDerivation and used in the URL I fetch.

My reviewer seems to be insisting on finalAttrs to make the URL refer to ${finalAttrs.version} instead, making the definition recursive.

I did some research and explained my thought process here, but I still cannot wrap my mind around whether I really need finalAttrs there.

What might I be still missing? Thanks!

1 Like

Hey. It looks like yzhou216 has said this on your PR.

finalAttrs is the idiomatic way of recursively referring to attributes in Nixpkgs.

To expand on that, this pattern is preferred here for 2 reasons.

  1. If someone wants to override your package, they cannot access the values defined in your let binding. This means they have to override all the options you define that use the value from the let binding again, which can be tedious and error prone.

  2. The finalAttrs pattern allows easy override, and fixes the errors in 1. It is actually not recursive, it’s an extra input that is passed the package. This is the preferred way to do self references.

You said you have done research, but it looks to me like you have outsourced the research to a chatbot. Here is the finalAttrs documentation if anything is unclear.

14 Likes

As already said, finalAttrs is the recommendation and besides the technical arguments, in a project as large as nixpkgs conventions help others to grasp the structure of your derivation.

The structure of your derivation at first glance seems very unconventional. Did you take inspiration from some other derivation?

@nadir I pretty much worked it out as a result of my learning process, review iterations, and mpm-specific caveats discovered along the way.

I did see an example of a JSON file with platform-specific hashes stored alongside a published package. That’s how supportedPlatforms set was introduced, for example.

What does seem unconventional from your perspective (apart from finalAttrs, which I’ve just brought back)?

1 Like

Thanks @not-jack! Your elaboration on the topic, along with that bit of documentation, finally brought enough clarity to the mental model I had in mind.

While I understood the role of finalAttrs in successful .overrideAttrs, I could not see a justified reason to override the version rather than bumping it in the file and submitting an update to nixpkgs. However, eventually, I thought I should facilitate the overriding ability regardless.

I’ve now updated my PR and also worked around buildFHSEnv, which does not support overrideAttrs (am I right?).

UPD: I already override the outputs of buildFHSEnv to pass a version check hook there, so my web search probably was misleading…

Bonus question

Alternatively, could I have extra input arguments to package.nix set to default values, so mkDerivation’s inputs depended on them, making the necessary things overridable with .override? Just wondering though.

Someone hacking on their own private version of the project, with or without intention of eventually upstreaming their changes.

4 Likes

It can be nice if you need a specific version of the package, for instance one less recent then the one on your nixpkgs pin. In this case it would also not make sense to upstream your changes :wink:

1 Like

@not-jack, isn’t it more appropriate to pull an earlier version of a package from an earlier release of nixpkgs? I saw such a statement somewhere.

Definitely not. Pulling an entire nixpkgs instance for one package is generally incorrect.

4 Likes

It’s also possible that a specific version has never been packaged :slight_smile:.

4 Likes