-
Notifications
You must be signed in to change notification settings - Fork 77
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
Make sources.nix
configurable
#134
Comments
I don't see this as a big deal. People do this all the time when importing On the other hand, I have no idea what this magic My vote goes for boring functions and arguments :)
I don't think this should be a global toggle. My experience is that you want to use the builtin fetchers quite deliberately for specific dependencies, if at all. So it works much better as just "another fetcher" and would be a pain if anything as a global toggle.
I like the idea of just letting people define their own fetchers. My first thought is composability: what happens when e.g. I want to share a special fetcher with people in my company? Then I need to fetch that source and import it before I can use it. This is a very similar problem to the problem I have with nixpkgs. I wonder whether there would be some utility in having some "bootstrap" sources that get fetched first and are available to the main fetchers? |
I had an idea. What if we allowed the user to provide overlays that could (mutually) define sources and fetchers? Bear with me, there's a few pieces. Suppose I define the following
Let's say that this gives rise to the following
Now,
Now, I can finally provide an overlay
Now, if we evaluate the overlays I haven't tried this, but I think it would work. Downsides that I can see:
If people are interested I could try whipping up a prototype. |
I made a POC in #137, which IMO works quite nicely. |
Thanks so much @michaelpj ! I had a quick look but that wasn’t enough to fully wrap my head around the idea, I’ll give more feedback tomorrow! |
It might not make much sense 😅 I can also push my examples, tbh that's probably a good idea. |
Not following closely but I have a few observations I want to share: Most of the time, I only want to use the builtin fetcher to bootstrap nixpkgs. The rest can be using build fetchers since they are faster to use (in my experience). The only other reason to use a builtin fetcher would be if it requires some access credentials that are available in my user environment. I want to avoid evaluating nixpkgs twice because it's slow and takes a lot of memory. I usually want to be able to initialize nixpkgs with my own custom config and overlays. So I want a way to get the nixpkgs version from niv, initialize it, and then pass it back to niv to use with the build fetchers. One possible implementation of this could be to pass the nixpkgs initializers to niv and let niv to the bootstrapping internally: let pkgs = import ./nix/sources.nix (sources: {
config = {};
overlays = [ sources.home-manager ];
});
in pkgs Or externally: let
sourcesBuiltins = import ./nix/sources.nix {};
pkgs = import sourcesBuiltins.nixpkgs {
config = {};
overlays = [
(_: super: { sources = import ./nix/sources.nix { pkgs = super; }; })
sourcesBuiltins.home-manager
];
};
in
pkgs Something like that. |
Ok, had some time to dig more into it. I like it! I'd like to retain the interface of #134 (comment) though, so we could pass the overlays as let sources = (import ./nix/sources.nix).__configure { overlays = [ ... ]; }; in ... or maybe even have two: let
sources = import ./nix/sources.nix;
sourcesSimple = sources.__configure { useBuiltinFetchers = true; };
sourcesMoreCustomizable = sources.__overlays [ overlay1 overlay2 ];
in ... since the former can be implemented in terms of the latter. That way we can use overlays when necessary (though is it really necessary?), we don't break backwards compatibility and finally we can still use the simple import. |
I prefer the explicit argument passing to the magic attribute, but I'd live. If we're going to have one, let's just have one. I think a simple interface and an advanced interface are fine, but multiple advanced interfaces is too much.
Apart from the use-cases i gave, I'm pretty sure the overlays approach is powerful enough to let people do whatever they want. So that avoids us coming back to this issue when someone has some weird new thing they want to do. Having some shortcut options for common things also seems fine, although I'm not sure what we'd have. I still think the global builtin fetcher toggle is questionable. However, we can add those on top of the overlays easily enough if some patterns become very common! |
You could define This is a good thing, because it means you can design the new sources.nix interface from scratch, as long as it's a function! You can even have a backward compatible deprecation of the attrset interface this way. |
ok, I really like this overlay + functor solution. Gonna take a stab. |
Maybe this could be combined with the efforts currently going on in #132? I think it would be quite good UX to have let
callSources = import
(builtins.fetchUrl "https://github.com/nmattia/niv/blob/MY_VERSION/nix/api.nix");
in
callSources ./sources.json {
someConfigureArgs = "someValue";
overlays = self: super: {
foo-fetcher = ...;
};
}
|
Did you decide not to go with the overlay solution in the end? |
@michaelpj that's still the idea! Given that the overlay approach is pretty powerful and low-level, I didn't want to make it the only option. It'll look something like this: let sources = import ./nix/sources.nix { sourcesFile = ...; overlay = ... ; } ; in ... |
Until now I've refused to add configuration to
sources.nix
because I really like:and because in most cases it shouldn't have to be configurable. Having to pass in an empty attrset
{}
in most cases is really not nice. However after discussions with @zimbatm and @NinjaTrappeur I've realized we could have e.g. this:Here most users will never have to care about the configuration, but if you need to tweak how packages are fetched, you can feel free to go for it. I have a POC here: https://github.com/nmattia/niv/blob/b69df92ce13f3b9f9d5344b24ecde6ae945c41d6/nix/sources.nix
I'm thinking about having the following configuration fields:
useBuiltinFetchers
: specifies whetherbuiltins.fetchurl
et a. should be used, defaulting totrue
. Hydra users can set it tofalse
. Would solve Fallback on builtin fetchers whenever possible #46 @nlewo and we could get rid ofbuiltin-tarball
@michaelpj . This also solves some opaque infinite recursion errors due to the heuristics we use for figuring out<nixpkgs>
.sourcesJson
: the path to thesources.json
which would (partially) solve Different folder forniv init
#102fetchers
: a functionname: spec: fetcher: ...
which fetches thespec
(the attrset coming fromsources.json
), or just returnsfetcher spec
if no special fetcher is needed. This would solve Fetch via git:// does not work #130 @tfc and fetchGit and submodules #58 @roberth (at least for the case without submodules).Thoughts?
The text was updated successfully, but these errors were encountered: