-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatic finalAttrs
pattern migration
#293452
Comments
Discussed this in the Architecture Team meeting:
|
This isn't caused nor exacerbated by The packageName.overrideAttrs (oldAttrs: {
version = "0.1.1";
src = oldAttrs.src.overrideAttrs {
outputHash = "...";
};
}) Without packageName.overrideAttrs (oldAttrs: {
version = "0.1.1";
src = fetchFromGitHub {
repo = "...";
owner = "...";
rev = "...";
hash = "...";
};
}) |
The problem is that it looks more correct. Yes, it is scope creep, but it's quite a serious issue that is exacerbated by this, even if slightly.
I think this is the most promising pattern; something like: version = finalAttrs.src.version;
src = fetchFromGitHub {
rev = "v2.1";
# ...
}; |
I doubt most users are aware of the implementation details of everything they override. If they were, surely after the first couple of "FOD moments" they'd know better? Either way this seems more like an opportunity to document/educate. FODs are already discussed in the nix manual, so the nixpkgs manual's section on overriding might direct them there with some ancillary notes.
This forces users to not use their intuition to override Moreover, extracting |
Yes, the idea was that each fetcher sets
I don't think fetchers currently set a
At least the package won't have any code that could make them believe that overriding just |
IMO: this should be done after #234651 |
seems like it has potential to silently break packages that don't have enough unit tests due to subtle differences in semantics. |
How would he ensured that there won't be an unmanageable amount of silent breakages especially in people's overlays? Also how would packages be filtered which would be broken by this change because they previously relied on the rec behavior? Also it would probably be a good idea to first write a tool to verify the correctness of FOD hashes to easily spot breakages in any urls which might change because of wrong usages of pname as part of URLs/paths/binary names in combination with overlays which append suffixes like
This would conflict with our current contributing guide and the -unstable-XXXX-XX-XX suffix. Also short refs are not really recommended for long term use.
Which would probably also need to consider refs/tags prefix and we probably collect more of those over time and could easily make it complicated. |
i think packages should be updated to use finalAttrs as they're touched honestly, even if you made the commits automatically, you would still need to review them manually, and that would probably be about the same amount of work, but because github only allows you to approve a PR and not individual files of a PR, all that review work would probably have to be done by one person (actually several, a change this big should require multiple approvals) there's lots of patterns that are inoccuous with |
I'd agree, if this tool didn't account for the main point of Give it a try on some individual packages :) |
but we also need to look at the less often used misuses, otherwise we could run into a situation where a tiny fraction of the changes, still takes a significant amount of the time to fix things afterwards. I don't have good idea, how we could tell apart packages which are very safe to change and which will likely cause issues. Maybe we would need to analyze the AST and can then categorize the packages based on that and start with the very safe packages and do the complicated ones by hand. I skimmed through the source code and I think it currently only checks pname which is in my opinion not enough and the to do list should get an entry to develop the tool and write good tests for it. Also the following comment from the readme makes me think that this is not rock solid and deeply tested:
This can already be shortened with override nixpkgs/pkgs/applications/finance/odoo/default.nix Lines 14 to 20 in 01048ff
|
Indeed I forgot to mention the measures I took to ensure a robust migration:
That text is outdated, I'll remove it.
I should definitely add some. I've been using nixpkgs itself to test the tool, and I can extract some golden tests from it. |
Maybe I can have the tool output a list of all the used recursive variable names? |
I thought about this, and I agree with @SuperSandro2000 that it isn't the right solution.
|
The problem of the irrelevant FOD hashes can be solved by embedding We could make fetchers support |
I made a PR #294068 to demonstrate this solution. |
just want to let you know this has been tried several times before. |
Are there some PR about these attempts? What obstacles did they encounter? |
here's a few attempts at solving the fixed-output derivation problem |
Thank you!
Those proposal targets Nix itself, while mine works on the fetchers inside Nixpkgs and doesn't affect the behavior of Nix. |
see also NixOS/rfcs#171: Default name of fetchFromGithub FOD to include revision |
@ShamrockLee also note that nix flakes seem to have implemented some kind of workaround for this, as i haven't seen this problem occur there. |
@lolbinarycat I haven't dug deep into the C++ implementation of flake inside Nix, but since At Nix level, they can see the original store derivation ( At Nixpkgs level, all we have is the current specification, nothing else. All we could use to invalidate previous store paths are new store paths. As the |
🤔 So here |
@oxalica |
@oxalica no, # hello_2_10/package.nix
{ stdenv, fetchurl }:
stdenv.mkDerivation (finalAttrs: {
pname = "hello";
version = "2.10";
src = fetchurl {
url = "mirror://gnu/hello/hello-${finalAttrs.version}.tar.gz";
hash = "sha256-MeBmE3qWJnbon2nRtlOC3pWn732RS4y5VvQepy4PUWs=";
};
}) # some_overlay.nix
hello_2_12 = hello_2_10.overrideAttrs (
finalAttrs: prevAttrs: {
version = "2.12";
src = prevAttrs.src.overrideAttrs {
outputHash = "sha256-zwSvhtwIUmjF9EcPuuSbGK+8Iht4CWqrhC2TSna60Ks=";
};
}
); The reason, why you don't have to manually propagate Edit: sniped, lol |
yeah the arguments are opposite in |
I wouldn't say "opposite". Here are the valid "signatures": {
# Old-style signatures
# You can still use them, but they don't cooperate well with multiple overrideAttrs
# rec { } was commonly used with these signatures, but now it's considered an antipattern
_ = mkDerivation { };
_ = overrideAttrs { };
_ = overrideAttrs (prevAttrs: { });
# New-style signatures
# (added in PR 119942)
_ = mkDerivation (finalAttrs: { });
_ = overrideAttrs (finatlAttrs: prevAttrs: { });
}
|
I recently wrote a tool that automatically performs a migration to the
finalAttrs
pattern (#119942), and I believe it is now robust enough to be let loose on nixpkgs.However this is the first large treewide change I'm performing, so I'm not 100% sure how to proceed. Some questions:
cc @drupol who was interested in this
Example run of the tool on pkgs/applications and pkgs/by-name: https://github.com/fgaz/nixpkgs/commits/finalattrs-test-8/
The text was updated successfully, but these errors were encountered: