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

lib.packagesFromDirectoryRecursive: init #270537

Merged
merged 1 commit into from
Dec 19, 2023

Conversation

9999years
Copy link
Contributor

@9999years 9999years commented Nov 28, 2023

Description of changes

Adds a packagesFromDirectoryRecursive helper, which combines builtins.readDir and callPackage to transform a directory of .nix package files into a matching nested attribute set of derivations.

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/)
  • 23.11 Release Notes (or backporting 23.05 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.

Priorities

Add a 👍 reaction to pull requests you find important.

@9999years 9999years requested a review from infinisil as a code owner November 28, 2023 01:24
@github-actions github-actions bot added 8.has: documentation This PR adds or changes documentation 6.topic: lib The Nixpkgs function library labels Nov 28, 2023
Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

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

Can you split out the documentation updates into a separate PR?

Regarding packagesFromDirectory, I'd rather make this be unified with pkgs/by-name than a separate convention. The 2-letter prefix of pkgs/by-name should definitely be optional, and the ability to use files or directories only could also be optional.

@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 labels Nov 28, 2023
@9999years
Copy link
Contributor Author

Split the documentation updates into #270696.

@9999years 9999years force-pushed the packagesFromDirectory branch from c8d2a86 to 1331025 Compare November 28, 2023 17:11
@9999years
Copy link
Contributor Author

9999years commented Nov 28, 2023

I'd rather make this be unified with pkgs/by-name than a separate convention.

That makes sense, but I'd rather not lose the recursive behavior here (subdirectories are also mapped to nested package attributes). I'll see if I can prototype a version with optional two-letter shards and optional directory recursion.

Where should I put tests for this?

@9999years 9999years marked this pull request as draft November 28, 2023 18:18
@9999years 9999years force-pushed the packagesFromDirectory branch 3 times, most recently from d6fd380 to 4620198 Compare November 28, 2023 20:06
@9999years 9999years force-pushed the packagesFromDirectory branch from 4620198 to 308243e Compare November 28, 2023 20:36
@9999years
Copy link
Contributor Author

OK, I've unified lib.packagesFromDirectory with the pkgs/by-name overlay. The pkgs/by-name tree is already set up in the same manner packagesFromDirectory expects, so I didn't need to make as many changes as anticipated (there's no extra directories without a package.nix for packagesFromDirectory to recurse into).

I've also reimplemented packagesFromDirectory in terms of a new helper, lib.packageFilesFromDirectory, which just returns a set of package paths and skips invoking callPackage. This also lets us hoist the directory traversal portion of the pkgs/by-name out of the overlay function itself, to save evaluation time if the overlay is applied multiple times.

@9999years 9999years requested a review from infinisil November 28, 2023 20:42
@9999years 9999years marked this pull request as ready for review November 28, 2023 20:43
@ofborg ofborg bot added the 8.has: package (new) This PR adds a new package label Nov 29, 2023
@9999years 9999years force-pushed the packagesFromDirectory branch from 308243e to 3d3ad0b Compare November 29, 2023 18:42
@infinisil
Copy link
Member

Thinking about it again, this does sound distinct enough that maybe it shouldn't be shared with pkgs/by-name. Especially since the latter comes with its own CI checking tool (pkgs/tests/nixpkgs-check-by-name) and an RFC.

I'm afraid I don't have a lot of capacity to review this right now though, I hope others can help out with this.

@9999years
Copy link
Contributor Author

But this is totally compatible with pkgs/by-name and the pkgs/tests/nixpkgs-check-by-name tool?

@infinisil
Copy link
Member

The function seems to support a superset of pkgs/by-name functionality. Using files instead of directories is only supported by function, not pkgs/by-name. Same for the recursive sets. Notably the additional checking of pkgs/by-name is only implemented in CI. So people could e.g. create pkgs/by-name/foo/foo.nix locally, and it works just fine locally, but then CI complains. Comparatively before this PR it just didn't work.

Furthermore, as soon as you have a package set there's the requirement of being able to override it. If you use lib.makeScope this gets handled somewhat decently at least for one level, but it's going to get messy for multiple levels. This really needs a lot of thought, and I don't have the capacity for this right now.

Copy link
Contributor

@Gabriella439 Gabriella439 left a comment

Choose a reason for hiding this comment

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

I'm filling in to review since @infinisil indicated that he doesn't have time to give this a full review.

I think this is still okay to merge with just one small change. In particular, I'm not too concerned that the pkgs/by-name function might (hypothetically) in the future have different requirements than lib.packagesFromDirectory. If we ever get to that point it won't be hard to split the two implementations, but as far as I'm concerned the fact that this can be reused to powerpkgs/by-name functionality in its present state is a feature.

Comment on lines 320 to 323
# `pkgs.callPackage`
callPackage:
# The directory to read package files from
directory:
Copy link
Contributor

Choose a reason for hiding this comment

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

The main thing I'll suggest is to make this take an attribute set instead of position arguments:

{ callPackage, directory }:

… that way if we need to add new optional arguments (with sensible defaults) we don't have to break backwards-compatibility. This would also be consistent with how pkgs.haskell.lib.packagesFromDirectory works (it also takes an attribute set)

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, and also, have the attribute set ignore extra arguments (for forward compatibility), also the same as pkgs.haskell.lib.packagesFromDirectory:

{ callPackage, directory, ... }:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

@nbraud nbraud Nov 28, 2024

Choose a reason for hiding this comment

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

@Gabriella439, could you clarify the forward-compatibility aspect? As-is, packagesFromDirectoryRecursive will silently ignore any unknown parameter, which seems to me more likely to cause subtle bugs than make things work on older nixpkgs version: presumably, new (optional) parameters would only be introduced (and specified) if they change the function's behaviour.

Having (older versions of) packagesFromDirectoryRecursive silently revert to the default behaviour, is then non-compatible (the behaviour is different) but the incompatibility is silent rather than an explicit error.

Sorry for coming rather late to the party: I only learnt of packagesFromDirectory yesterday, and it's great! Thank you and @9999years ❤️

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd be fine removing the .... I'm not too attached to it.

Copy link
Contributor

@nbraud nbraud Dec 1, 2024

Choose a reason for hiding this comment

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

I was more trying to ask if I was missing some part of the reasoning behind accepting ... 😅

If I accidentally convinced you that dropping ... would be preferable, should I do it as part of #359984 ?
It compounds the issue, by giving a usecase for putting extra parameters (used by recurseIntoDirectory rather than packagesFromDirectoryRecursive itself)

Copy link
Member

Choose a reason for hiding this comment

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

+1 for dropping ...!

@9999years 9999years force-pushed the packagesFromDirectory branch from 3d3ad0b to a3ed91f Compare December 5, 2023 01:01
@9999years 9999years force-pushed the packagesFromDirectory branch from cb59ca6 to e8332f1 Compare December 5, 2023 17:35
@github-actions github-actions bot removed the 8.has: documentation This PR adds or changes documentation label Dec 5, 2023
@9999years 9999years force-pushed the packagesFromDirectory branch from e8332f1 to d3b65c4 Compare December 5, 2023 17:53
Copy link
Contributor

@tomberek tomberek left a comment

Choose a reason for hiding this comment

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

I'm not sure this callPackage will do the right thing with packages that depend on each other. I can imagine using this via an identity function or an import and then using a standard callPackage.

That being said, this is a good addition into our standard library, often needed.

@9999years
Copy link
Contributor Author

9999years commented Dec 6, 2023

@tomberek Yeah, the documentation I was asked to remove made this clearer, but lib.packagesFromDirectory is most helpful in combination with lib.makeScope.

@RaitoBezarius
Copy link
Member

I'm not a maintainer of lib per se but this seems to be a very useful addition and there's many out of tree code that reinvents the same thing all the time, it would be tidy if we could just reuse nixpkgs for that directly.

lib/filesystem.nix Outdated Show resolved Hide resolved
lib/filesystem.nix Outdated Show resolved Hide resolved
lib/filesystem.nix Show resolved Hide resolved
lib/filesystem.nix Outdated Show resolved Hide resolved
lib/filesystem.nix Outdated Show resolved Hide resolved
pkgs/development/haskell-modules/lib/compose.nix Outdated Show resolved Hide resolved
lib/filesystem.nix Outdated Show resolved Hide resolved
lib/tests/packages-from-directory/default.nix Outdated Show resolved Hide resolved
lib/tests/packages-from-directory/default.nix Outdated Show resolved Hide resolved
lib/tests/packages-from-directory/default.nix Outdated Show resolved Hide resolved
@9999years 9999years force-pushed the packagesFromDirectory branch from 074108c to 7093beb Compare December 11, 2023 23:44
@9999years 9999years requested a review from infinisil December 11, 2023 23:45
@9999years 9999years changed the title lib.packagesFromDirectory: init lib.packagesFromDirectoryRecursive: init Dec 12, 2023
@9999years 9999years force-pushed the packagesFromDirectory branch from 7093beb to 8eb9280 Compare December 14, 2023 21:34
Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

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

Just minor comments, looking pretty good now!

lib/filesystem.nix Outdated Show resolved Hide resolved
lib/filesystem.nix Outdated Show resolved Hide resolved
lib/filesystem.nix Show resolved Hide resolved
lib/tests/misc.nix Show resolved Hide resolved
@9999years 9999years force-pushed the packagesFromDirectory branch 2 times, most recently from 2918dab to b7c61e8 Compare December 19, 2023 17:33
@9999years 9999years force-pushed the packagesFromDirectory branch from b7c61e8 to 090b929 Compare December 19, 2023 17:48
@9999years 9999years requested a review from infinisil December 19, 2023 17:48
@infinisil
Copy link
Member

Not gonna bother waiting for CI, it's too slow.. I tested it locally, all good 👍

@infinisil infinisil merged commit cf47b9a into NixOS:master Dec 19, 2023
5 of 6 checks passed
@9999years 9999years deleted the packagesFromDirectory branch December 19, 2023 21:04
@philiptaron
Copy link
Contributor

I really love this function. Thanks for adding it @9999years. 🙇🏻

nbraud added a commit to nbraud/nixpkgs that referenced this pull request Dec 3, 2024
nbraud added a commit to nbraud/nixpkgs that referenced this pull request Dec 28, 2024
nbraud added a commit to nbraud/nixpkgs that referenced this pull request Dec 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: lib The Nixpkgs function library 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: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants