Skip to content
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

pkgs: introduce package-list.nix and trivialPackages stage #50643

Closed
wants to merge 2 commits into from

Conversation

oxij
Copy link
Member

@oxij oxij commented Nov 18, 2018

The idea here is to move as much of all-packages.nix to package-list.nix as humanly possible.

Pros:

  • It improves metrics because import package-list.nix gets cached between stages. Meanwhile, doing the same with import all-packages.nix produces a negative impact because all-packages.nix is complicated and caching it adds pressure on GC. Meanwhile, package-list.nix is just a list of paths, which is cheap.

  • It allows for easy experimentation with alternatives to callPackage as package-list.nix is, by definition, a set of trivial packages. (This was the initial motivation for this change.)

  • It's homogeneous with NixOS' module-list.nix.

  • Eventually package-list.nix can be completely autogenerated.

Cons:

  • Migration to package-list.nix does introduce some code churn.

This also adds maintainers/scripts/all-packages-to-package-list.sh script that does the (very conservative, currently) conversion automagically.

Take you time merging and testing this, conflicts are easy to fix: just rebase dropping the last commit and rerun the script.

Yes, this is a massive noop change. :)

/cc @matthewbauer @Ericson2314 @vcunat @edolstra

@oxij
Copy link
Member Author

oxij commented Nov 18, 2018

As a side note, to convert all of all-packages.nix to this format the policy on the naming of package arguments needs to be reconsidered. With this you usually won't want to have { python = python3; } and similar.

The idea here is to move as much of `all-packages.nix` to
`package-list.nix` as humanly possible.

Pros:

- It improves metrics because `import package-list.nix` gets cached
  between stages. Meanwhile, doing the same with `import
  all-packages.nix` produces a negative impact because
  `all-packages.nix` is complicated and caching it adds pressure on
  GC. Meanwhile, `package-list.nix` is just a list of paths, which is
  cheap.

- It allows for easy experimentation with alternatives to
  `callPackage` as `package-list.nix` is, by definition, a set of
  trivial packages. (This was the initial motivation for this change.)

- It's homogeneous with NixOS' `module-list.nix`.

- Eventually `package-list.nix` can be completely autogenerated.

Cons:

- Migration to `package-list.nix` does introduce some code churn.

This also adds `maintainers/scripts/all-packages-to-package-list.sh` script that
does the (very conservative, currently) conversion automagically.
Hint: if this conflicts with your change you can revert this commit,
rebase your change on top, run the script yourself, commit the result,
squash. It's magic.
@oxij
Copy link
Member Author

oxij commented Nov 22, 2018

Ping. I see thumbs down, but can I have an explanation why? I see no reason not to proceed in this way except for the churn. And the churn won't be too much of an issue if we migrate in tiny installments (i.e. if we agree to merge the infra from the first commit and start adding new packages there).

Concerning package arguments, I think the better policy to doing what the current policy does is switching to using the following method:

Now:

in package:
  { stdenv, package }: ...

in all-packages:
  xxx = callPackage ... { package = package_version; };

After:

in package:
  { stdenv, package_version, package ? package_version }: ...

in all-packages:
  xxx = callPackage ... { };

@oxij
Copy link
Member Author

oxij commented Nov 22, 2018

I'm not even against making an RFC for this change, but I want to hear out some thoughts first.

Disclaimer: Yes, I want this because it greatly simplifies the proper implementation of #12877, but even if you don't want use-flags functionality in Nixpkgs I see no reason not to implement this particular change.

@7c6f434c
Copy link
Member

Re: re-importing: not sure if it would be better than mapping callPackage over the list in all-packages.nix — I guess some packages will still be in all-packages.nix till the next Nix language redesign, so it would be too fragile to be used.

Future plans of modularising Nixpkgs seems to be an argument in favour of doing version selection in-package. Treewide version pinning changes might become more complicated, though.

Unlike all-packages.nix, the list of trivial packages is almost sure to end up in a sorted state. all-packages.nix is quasi-sorted in an order that I fail to fully understand and that is also sometimes unintentionally violated and that is also sometimes intentionally violated. Not sure if we consider the current intentional violations of sorting order valuable.

@oxij
Copy link
Member Author

oxij commented Nov 22, 2018

Re: re-importing ...

Please elaborate, I don't understand what you are trying to convey in that paragraph. "mapping callPackage over the list in all-packages.nix" what list? all-packages.nix is not a list.

Treewide version pinning changes might become more complicated, though.

I don't see why, you can pin in all-packages.nix as before and then just grep around. If anything, it doesn't change much in that regard as many packages depend on particular versions already, so you have to grep anyway when you want to pin something.

quasi-sorted in an order that I fail to fully understand and that is also sometimes unintentionally violated and that is also sometimes intentionally violated

Oh, yes, that bugs me too.

@7c6f434c
Copy link
Member

re: re-importing:

I expect that all-packages.nix will stay in some form even if the current PR is adopted, so a full simplification won't happen.

I am not sure that the extra caching will be noticeable — I would expect that looking up any attribute name in the resulting attrset should end up with the same outcome as evaluation of the current all-packages.nix; the mapAttrs will need to be evaluated enough to have the list of names.

Re: pinning: replacing a single argument name in a package is a simpler operation that doing something about two related ones.

@edolstra
Copy link
Member

This was tried before (ece61b7) but was reverted. In short, it's confusing if some packages are in all-packages.nix and some aren't. And if you need to override an argument, you now need to modify two files. Saving a few lines didn't really justify this.

@oxij
Copy link
Member Author

oxij commented Nov 22, 2018 via email

@oxij
Copy link
Member Author

oxij commented Nov 22, 2018 via email

@7c6f434c
Copy link
Member

7c6f434c commented Nov 22, 2018 via email

@oxij
Copy link
Member Author

oxij commented Nov 22, 2018 via email

@oxij oxij mentioned this pull request Jan 18, 2019
1 task
@danbst
Copy link
Contributor

danbst commented Jan 24, 2019

I've made a test which showed:

  • proposed approach runs a bit faster than original
  • I don't observe "metrics improved"

Also, I've added a third option, indexed all-package.nix. It is like

self: super: {
  inherit (import ./all-packages.nix self super)
    package1
    package2
    package3
  ;
}

and measures how better would things be if "callPackage" string is offloaded until real need.

So, the result for 40000 packages:

  • original runtime is 0.168197s, oxij's list is 0.144745s, index version is 0.08515s
  • original has 96 bytes per package, oxij's list has 416, index has 96
  • original has 1,7M on disk, oxij's has 927K, index has 498K

The test script:

#!/usr/bin/env bash

NUM_PACKAGES="${1:-100}"

mkdir -p packages

echo 'self: super: with self; {' > all-packages.nix
echo 'self: super: { inherit (import ./all-packages.nix self super)' > all-packages-index.nix
echo 'self: super:
let nameValuePair = n: v: { name = n; value = v; };
in builtins.listToAttrs
    (map (path: nameValuePair (baseNameOf (toString path)) path) [' > packages-list.nix
for p in $(seq 1 $NUM_PACKAGES); do
  echo "package$p = callPackage ./packages/$p;" >> all-packages.nix
  echo "package$p" >> all-packages-index.nix
  echo "./packages/package$p" >> packages-list.nix
done
echo '}' >> all-packages.nix
echo ';}' >> all-packages-index.nix
echo '])' >> packages-list.nix

# twice to reduce caching interfernece
for file in all-packages.nix all-packages.nix \
            all-packages-index.nix all-packages-index.nix \
            packages-list.nix packages-list.nix; do
  NIX_SHOW_STATS=1 NIX_COUNT_CALLS=1 \
    nix-instantiate --eval -E "builtins.attrNames (import ./$file {} {})" \
    2> result.$file 1>/dev/null
done

@oxij
Copy link
Member Author

oxij commented Jan 25, 2019 via email

@danbst
Copy link
Contributor

danbst commented Jan 25, 2019

No changes for nix-env -qa metrics? On either variant?

no, in my simple test. I hope it tests the pure extract of your idea.

@mmahut
Copy link
Member

mmahut commented Aug 18, 2019

Are there any updates on this pull request, please?

@stale
Copy link

stale bot commented Jun 1, 2020

Thank you for your contributions.
This has been automatically marked as stale because it has had no activity for 180 days.
If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.
Here are suggestions that might help resolve this more quickly:

  1. Search for maintainers and people that previously touched the
    related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse. 3. Ask on the #nixos channel on
    irc.freenode.net.

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 1, 2020
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Oct 3, 2020
@stale
Copy link

stale bot commented Jun 5, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 5, 2021
@Artturin
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: merge conflict 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 10.rebuild-darwin: 0 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants