Personally, I do use npins instead of flakes. However, many people use flakes and for public repositories, I would also like to include a ready-to-use flake.nix file that exposes the content of my package.nix.
Is there a nice way to set up a repository that works both with npins and flakes, without having the complexity of maintaining two lock files?
Here is how I structure my own projects:
# package.nix: Classic nixpkgs style package
{ lib, stdenv, ... }:
stdenv.mkDerivation {
pname = "...";
version = "...";
src = lib.cleanSource ./.;
# rest of derivation
}
# default.nix
let
sources = import ./npins;
pkgsDefault = import sources.nixpkgs { };
in
{ pkgs ? pkgsDefault }:
pkgs.callPackage ./package.nix { }
# shell.nix
let
sources = import ./npins;
pkgsDefault = import sources.nixpkgs { };
in
{ pkgs ? pkgsDefault }:
pkgs.mkShell {
packages = [
# packages dev environment
];
}
Depending on the complexity of the project, I can have multiple smaller package.nix files and the default.nix can do some more plumbing.
If I want to allow ingesting the repository as a flake, I can just hook up the individual parts in a small flake.nix like so:
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
};
outputs =
inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
];
perSystem = { pkgs, ... }: {
packages.default = import ./default.nix { inherit pkgs; };
devShells.default = import ./shell.nix { inherit pkgs; };
};
};
}
The only problem is that I now have to maintain two lock file mechanisms (npins and flake.lock). Is there any way to simplify this further?
One idea I had is that I could have a justfile command that somehow creates a flake.lock file from the npins lock. I noticed that there are nix flake lock and nix flake update commands, but I am unsure if they could help me here.