Skip to content

Comments

lib.fileset.fromSource: init#261732

Merged
roberth merged 3 commits intoNixOS:masterfrom
tweag:fileset.fromSource
Nov 10, 2023
Merged

lib.fileset.fromSource: init#261732
roberth merged 3 commits intoNixOS:masterfrom
tweag:fileset.fromSource

Conversation

@infinisil
Copy link
Member

@infinisil infinisil commented Oct 17, 2023

Description of changes

Another split off from #222981, motivated by @alyssais's comment here. This introduces one new function:

  • lib.fileset.fromSource: Create a file set from a filtered local source as produced by the lib.sources functions.
    lib.fileset.toSource {
      root = ./.;
      fileset = lib.fileset.intersection
        (lib.fileset.fromSource (lib.sources.cleanSource ./.))
        (lib.fileset.unions [
          ./Makefile
          ./src
        ]);
    }

This is mainly useful for migration from lib.sources-based filtering. In the future we should have a convenience function in lib.fileset that could take over.

This work is sponsored by Antithesis

Things done

  • Tests
  • Clean code
  • Documentation

@github-actions github-actions bot added the 6.topic: lib The Nixpkgs function library label Oct 17, 2023
This was referenced Oct 17, 2023
@infinisil infinisil requested a review from alyssais October 17, 2023 22:50
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. labels Oct 18, 2023
@infinisil infinisil changed the title lib.fileset.fromSource: init lib.fileset.fromSource: init Nov 1, 2023
@infinisil
Copy link
Member Author

I'm wondering if this will still be necessary with #264891 🤔

@alyssais
Copy link
Member

alyssais commented Nov 2, 2023

Definitely is IMO. Not everything is or should be a git repository.

@alyssais
Copy link
Member

alyssais commented Nov 5, 2023

Another reason I can't switch from sources to filesets yet:

I want to be able to do, essentially: src = fileset.difference ./. ./generated.o, where generated.o is some generated file that may or may not exist in my development tree, but that shouldn't be input to the derivation. This is not currently possible, because filesets require all files to exist. So there needs to be a way to filter a fileset that doesn't require the files in the negative set to exist.

@infinisil infinisil mentioned this pull request Nov 7, 2023
3 tasks
@infinisil
Copy link
Member Author

It is possible to do this already with

difference ./.
  (unions
    (lib.optional (builtins.pathExists ./generated.o) ./generated.o)
  )

But I think a convenient shorthand for this would be appropriate, I also had that in #222981, so I just created #265964 which adds a lib.fileset.optional!

Copy link
Contributor

@fricklerhandwerk fricklerhandwerk left a comment

Choose a reason for hiding this comment

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

That's a really valuable addition to the library, as you said because it would ease migration a lot. We may want to note that in the docstring, along the lines of

use this to gradually migrate builds relying on lib.sources to lib.fileset

but that's no reason to block this PR.

PS: Not sure why it's still in draft mode, looks ready to me.

Copy link
Contributor

Choose a reason for hiding this comment

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

What's a source-like value? What's a source?

Copy link
Member

Choose a reason for hiding this comment

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

"Very" good question unfortunately. Basically a path value or the "source attrset" returned by the lib.sources functions. Can we write introductions for sublibraries yet? It'd be great to have a sensible place to document the unique types of each sublibrary.

Copy link
Member Author

Choose a reason for hiding this comment

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

Can we write introductions for sublibraries yet?

Almost

Copy link
Contributor

Choose a reason for hiding this comment

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

The example in the PR description is also relevant, because it shows a bit of integration.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added some more practical examples now

Copy link
Member

@roberth roberth left a comment

Choose a reason for hiding this comment

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

Remember to test that directories for which the predicate is false are not read. This is part of the (implicit) contract.
Other than that, I think the tests will "write themselves" if that makes sense.

Copy link
Member

Choose a reason for hiding this comment

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

This doesn't seem to actually take SourceLike (although I didn't define that in words in lib.sources, you could perhaps tell from the code or behavior).

That type was meant to cover all source-coercible types, similar to how you allow both paths and filesets as arguments to fileset functions. In fact, it seems to be pretty much exactly that.

So what I meant to say is lib.sources users will probably expect to be able to use any source here, whether that's an _isLibCleanSourceWith, or a path value. Rejecting path values makes libraries (e.g. lang2nix) that use this fragile.

Not simplifying fromSource ./. to ./. is harmless, while { src, ... }: f (fromSource src) would be a bug waiting to happen.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done now!

@infinisil
Copy link
Member Author

PS: Not sure why it's still in draft mode, looks ready to me.

See the checklist in the PR description 🙂. Generally I recommend not taking close looks at the code of draft PRs. If I request you for a review it's because I'd like feedback to the approach only. I'll mark PRs as ready to review when I think their implementation is ready to review.

The review comments you both left are very helpful though, will incorporate!

@infinisil infinisil force-pushed the fileset.fromSource branch 3 times, most recently from 4133f7a to 3dfaf15 Compare November 8, 2023 04:32
@infinisil
Copy link
Member Author

Other than that, I think the tests will "write themselves" if that makes sense.

It didn't make sense to me, but I wrote tests anyways and pushed them now :)

Still need to clean up the code and docs a bit, including addressing the review comments. I'll mark it as ready when everything is addressed.

@infinisil infinisil marked this pull request as ready for review November 8, 2023 20:24
Copy link
Member

@roberth roberth left a comment

Choose a reason for hiding this comment

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

One question; otherwise lgtm.

Comment on lines +157 to +160
throw ''
lib.fileset.toSource: `root` is a `lib.sources`-based value, but it should be a path instead.
To use a `lib.sources`-based value, convert it to a file set using `lib.fileset.fromSource` and pass it as `fileset`.
Note that this only works for sources created from paths.''
Copy link
Member

Choose a reason for hiding this comment

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

Any reason not to just call it for them?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not 100% convinced it's a good idea, just minor ideas like

  • The operation this function does is somewhat expensive, so it being explicit makes people aware of that. This is different from the implicit path coercion, which is very cheap
  • Do we want to deprecate this at some point? Probably not
  • Source filters can be impure by changing behavior based on the project directory, does this impurity leak into file sets? Probably not a problem
  • Is it a problem to have a lack of symmetry regarding toSource/fromSource? Probably not, these aren't symmetric, fromSource discard's the root and toSource has to add it
  • Would it be a problem to have cases like toSource { root = ./.; fileset = toSource { root = ./.; fileset = toSource { ...? Probably also no

Furthermore this being an error for now means that we could still do this later.

@roberth roberth merged commit cfd83c9 into NixOS:master Nov 10, 2023
@infinisil infinisil deleted the fileset.fromSource branch November 10, 2023 19:33
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 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants