You can nix build
a check
nix build .#checks.x86_64-linux.nix-format
but it would be more convenient, if like nix build
with packages
, it could handle the arch for you.
You can nix build
a check
nix build .#checks.x86_64-linux.nix-format
but it would be more convenient, if like nix build
with packages
, it could handle the arch for you.
Thanks, that helps indeed, though it would be nice to have it in the interface of nix flake check
.
YIL (the Y stands for “yesterday”), that one can indeed pin entries in the registry declaratively!
nix.registry.<name>.flake
to whatever one wants to pin for that registry entry: pin nixpkgs in flake registry · NobbZ/nixos-config@bda3cef · GitHub
I use flakes to build my system, home-manager and now some dev-env.
I agree with all the comments on global registry:
Indeed I use the nix.registry.<name>.flake
option to pin nixpkgs so that all references for my system and users is using the same version.
Basically my organization is:
overlay
to help combining all the packagesnixosModules.*
for my custom services and to generalize my configsnixosConfigurations.*
to handle my system configurationshomeModules.*
to generalize my home configs (following the nixos* pattern)homeConfigurations.*
to handle home-manager configsPart of my packages a flake-mgr
script to:
This handles my system and user persistent configurations.
For my dev-env, I write another flake depending on the first to see my overlay and pin all upstream flakes. I simply defines a devShell.
BTW: My flakes are currently not in a git repository, and it still works.
Pro Tip: when defining a dev-env, dont put your flake.nix file at the root … otherwise all the folder and subfolders will be pushed to the nix-store and caching will be very bad. I use:
Direnv config using ./nix/flake.nix as a source
Used to pin deps, and provide CI context
Git clone of a backend app
Specific env for this app
Git clone of a frontend app
Specific env for this app
I can’t reproduce…
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/unstable";
outputs = { self, nixpkgs }:
let
pkgs = nixpkgs.packages.x86_64-linux;
in
{
devShell.x86_64-linux = pkgs.mkShell {
buildInputs = [ pkgs.go_1_14 pkgs.nixpkgs-fmt pkgs.lefthook pkgs.docker-compose pkgs.entr ];
};
};
}
This is my .flake.nix
at the company project:
nix develop
warning: unknown setting 'extra-sandbox-paths'
error: --- Error ---------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
source tree referenced by 'git+file:///home/nobbz/path/to/repo?ref=branch-name&rev=0e69a288c41b89dec8566b6d109f6c7a9e3fabaf' does not contain a '/flake.nix' file
If though I git add
the flake.nix
, it will ask for the flake.lock
.
So maybe you can use flakes for things that aren’t in git
yet, but I’m working with things that are already in git, and I’d prefer to have the dev shell defined through flakes, to not have to switch between niv and flake or even manually updating SHAs in the fetchGitHub
or similar call depending on the flake…
Ah yes, if it is inside a git repo, it is forcing the non dirty behavior
Would you mind sharing the implementation of that runTests
function? I’m struggling to find documentation for how to perform a check like cargo fmt -- --check
or cargo clippy
. It seems like the check has to be a derivation but I don’t know how to make a derivation that runs a shell command and then how/if flakes would respect the error code of the command.
I don’t actually have a runTest
function, that was just part of the simplification for the post, but you can take a look at the testing derivations:
I’d like to address some points regarding the registry from your original post, because I have some workarounds for these problems. First of all I show the configuration for Nix:
# inputs are the flake inputs
{
nix = {
package = pkgs.nixFlakes;
registry = { # (1)
self.flake = inputs.self; # (2)
nixpkgs = {
from = {
id = "nixpkgs";
type = "indirect";
};
to = {
owner = "NixOS";
repo = "nixpkgs";
rev = inputs.nixpkgs.rev; # (3)
type = "github";
};
};
};
# (4)
extraOptions = ''
experimental-features = nix-command flakes ca-references
flake-registry = /etc/nix/registry.json
'';
};
}
Using nix.registry
you can set entries in the local registry which is stored in /etc/nix/registry.json
.
First I register the system configuration itself as a flake in the registry under the name self
. This prevents me from accidentally using it as a flake input elsewhere because the name self
is reserved. At the same time I can export legacyPackages
with all my local overlays from the self
flake and get instant Nix shells.
I could do the same for nixpkgs, i.e. nix.registry.nixpkgs.flake = inputs.nixpkgs;
, however, that would write the local store path to the registry and when I then nix flake update
in one of my other flakes it will write the store path into the lock file and others will not be able to build the flake anymore. Instead I just write the registry entry by hand but pin the rev
to the revision of the nixpkgs that the system was built from.
The global flakes registry can be configured in nix.conf
and defaults to https://github.com/NixOS/flake-registry/raw/master/flake-registry.json. It accepts a URI or a local path. Unfortuantely, you can’t leave the field empty (flake-registry =
) and settings it to /dev/null
also doesn’t work because a special JSON format is expected. To this end I just use the local registry located at /etc/nix/registry.json
again. Now all entries in my registry are duplicate but at least the global registry is gone.
After I originally posted my way to pin, I also read deeper into the documentation of nix.registry.*
though I really didn’t understand the from
and to
attributes. Therefore I left everything as I have it.
Though I can not really understand your #3, as I never run nix flake update
on other people projects and in my own projects I never rely on flake:nixpkgs
but instead github:nixos/nixpkgs/<branch>
to avoid any registry mismatches from the get-go.
I’m pretty sure I’ve said it several times, though missed it in this thread it seems. The registry is a nice thing when used on the terminal for quick accessing some often used repos. but in actual flake.nix
I really wish flake:*
URLs as well as implicit usage in the arguments to outputs
function would be forbidden…
You can build your flake from a path rather than VCS if you are explicit about it:
nix run path:$PWD
Hello World
# flake isn't in VCS -> fail
nix run git+file:$PWD
error: --- Error ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
source tree referenced by 'git+file:/tmp/test?ref=master&rev=407a304d0991580a37cea8d53adefb65b447387b' does not contain a '/flake.nix' file
What I wanted to express is that I’d like to have a flake.nix
which is not version controlled within a git repository to define its corresponding dev-env. Currently I have to use nix-shell
for my work related projects, though I’d prefer to have unified nix devel
regardless if its work or private project.
Agree with NobbZ. nix develop
should relax the rules a little. Why should a flake.nix have to be in version control? At the moment I can’t have my flake.nix in .gitignore but must stage and commit it and only then is it happy. This feels like a workflow speedbump to any project that isn’t happy having flake.nix committed into version control… and try to remember not to push the committed flake.nix. Maybe I’m missing something but as a workflow it seems sub-optimal?
If I don’t want to add the flake.nix inside my git repo I just call this way:
nix develop path:$PWD
If flake.nix is in other folder I call this way:
nix develop path:/my/flake/folder
That way Nix will copy the entire tree into the Nix store: Copy local flakes to the store lazily · Issue #3121 · NixOS/nix · GitHub
I’d suggest to use Git pre-commit
and post-commit
hooks to unstage and restage the flake.{nix,lock}
files.
I did notice that it only needs to be staged and not committed (maybe this is a bug?). Still seems a pretty funny requirement to me. If it’s not actually needed to be committed then where are we going with this? Seems like a song and dance over nothing.
I wasn’t aware that I can unstage/stage during the execution of those hooks. That mighht indeed be a viable solution for me.
Even though I had to hook that into our lefthook
workflow without touching the YAML file or damaging the hookfiles created by lefthook…
The reason it needs to be staged is that flake evaluation will only look at files that are tracked by Git. Note that it’s the content of the file in the worktree that counts, not the staging area. In particular, you can git add -N
the flake.nix
file and it’ll be just fine, at least until the next commit.
While I’m at it, my solution when working with a project that does not provide a devshell is usually to put my custom devshell higher in the file hierarchy and to store the project repository under it. It works well with direnv
which I use and also allows to share devshells between related projects and generally decouple devshells from projects. (Admittedly that might not be the original vision for devshells)
Very helpful, thanks!
The from
attr in nix.registry
definitions can be left out for indirect
entries, so you can simply write:
registry = {
self.flake = inputs.self;
nixpkgs.to = {
owner = "NixOS";
repo = "nixpkgs";
rev = inputs.nixpkgs.rev;
type = "github";
};
};
I use this:
registry = lib.mkForce({
pkgs.flake = selfFlake;
} // lib.mapAttrs (names: flakes: { flake = flakes; }) inputs);
where selfFlake
is the self
of outputs
in flake-parts.
Then I defined legacyPackages = (getSystem system).allModuleArgs.final;
so pkgs
will be the same variable I’m using in system flake.