Open nmattia opened 4 years ago
Love it, more opinionation is always good in this kind of tooling.
Some personal feelings:
niv
in the top-level project directory is not much of a cost to me, since it's a tool I use comparatively infrequently. The level of annoyance is comparable to "oh, I ran grep
in a subdir so it won't get everything, better move up". Plus, it adds behavioural complexity (next points).sources.json
files which aren't objects? So it'll break if the user turns it into an object later?sources.nix
have to be by sources.json
? sources.nix
niv status
seems goodniv init
niv init
does anything other than initialize a project. I would prefer something like niv regenerate
which regenerates sources.nix
.I think a bunch of these issues center around the fact that niv
has no configuration and so relies a lot on the (implicit) locations of its files. So here's a sketch of an alternate design:
.niv.yaml
(or whatever format). This allows stating:
sources.json
, otherwise it's $(dirname $NIV_CONFIG_FILE)/nix/sources.json
.sources.nix
, including "don't expect one" (i.e. I inlined it), perhaps with an explicit version stated, otherwise it's $(dirname $NIV_CONFIG_FILE)/nix/sources.nix
.sources.nix
too.niv.yaml
by upwards traversal: it's a single, unambiguously named file, so not too bad..niv.yaml
.To me, the original proposal sounds very reasonable, but I do have some theoretical concerns. I realize that these might not be actual flaws in the design, but I'd still like to see them addressed.
builtins.fetchurl
The fetchurl
built-in still seems to be forbidden in restricted evaluation mode. This is not really an issue for me, but I think it would be a good idea to mention if/how this potentially could cause problems for other users. I am not very familiar with Nix Flakes yet, but investigating how builtins.fetchurl
interacts with those might also be of interest
Generating a default.nix
in the root directory
I suspect many projects using Nix already have a default.nix
file in their root directory. If this is the case, I think Niv should emit a small guide on how to manually edit a default.nix
to use Niv sources.
Niv binary and sources.nix
getting out of sync
If I understand this correctly, Niv updates the sources.nix
file/import based on the Git hash of some branch in the upstream Niv repository. This means the behavior of Niv essentially relies on two update streams, which might be confusing for the user. Maybe it would be a good idea to, at build time, include a hash of the current sources.nix
file in the Niv binary and check whether this hash matches before updating the file/import.
When does the sources.nix
file/import get updated?
From your original proposal, it seems unclear to me when the sources.nix
file/import is updated. Will niv init
continue to serve as the facility to update sources.nix
? In that case I agree with @michaelpj in preferring another command that only updates sources.nix
.
Unlike @michaelpj, I do not think Niv would work better with a configuration file. The original proposal is very opinionated, but should already be flexible enough to support most workflows.
Thanks for giving the community an opportunity to respond to your plans!
I just want to chime in and say that @michaelpj concerns about discovery
seems quite fair to me.
I am probably missing the point but I don't see why niv
makes it so complex. Why not doing what every other tools would do; go and search a default place. For users with special requirements, make it possible to specify another default.
In any case, I would challenge any added complexity, would go with sane defaults and have good documentation for users that want to follow more advanced avenues.
I am actually using niv in some global overlays without any default.nix. I only do sources = import ./nix/sources.nix;
so the whole business with niv init (--light|--heavy)
goes a bit off the top of my head.
This would be nice, because sometimes I put files in nonstandard directories, and passing -s source.json
to niv still fails, because 1) it's doesn't seem to be the right thing anyway 2) it can't find sources.nix even though it's right next to it.
Got a lot of feedback over the past few months, and a lot more experience with niv. This in an outline of the sources handling changes that will happen soon; it's aimed at making basic nix projects even simpler, while giving people more flexibility re. the location of niv's files. Speak now or forever hold your peace!
discovery
sources.json: niv will go up in the directories (til filesystem boundary) until if finds either a
sources.json
or anix/sources.json
. When it does, it will try to parse it (should be an object and all values should be objects). If it doesn't parse, keep searching.sources.nix: same as above, but with
sources.nix
ornix/sources.nix
, and will hash it for a known sources.nix hash (orniv: no_update
)inlined sources.nix: niv will go up in the directories (til filesystem boundary) and for every file with a
.nix
extension in.
and./nix/
and will scan them (up to n characters) for the upload URL of sources.nix (i.e.https://raw.githubusercontent.com/nmattia/niv/<version>/nix/sources.nix
) and the sha256 of a knownsources.nix
.Generally the discovery should be done lazily (not performed if not needed), should be short-circuited with global flags (like
--sources-file
does already) and should not take more than n milliseconds.niv status
This is a new command that displays:
sources.json
sources.nix
, or the path of the nix file where it's inlined (i.e. fetchurl with remote source)sources.nix
niv init templates
niv init
tries to discoversources.json
andsources.nix
. If it finds them (NOTE: both or either?) it considers niv was already initiated and only updatessources.nix
(if necessary). If it does not find them, then it initializes directory.There will be two templates to start with,
light
andheavy
(not sure yet on the name).light
is the default.light:
heavy:
nix/default.nix
similar todefault.nix
inlight
, except that it returnspkgs
(notpkgs.hello
) and that it imports a localsources.nix
that's written innix/sources.nix
. Might add a flag (--remote-sources
) to disable this.the
sources.json
go tonix/sources.json
(instead of./sources.json
) and includeniv
as well (instead of justnixpkgs
).