|
|
||
|---|---|---|
| systems | init | |
| default.nix | init | |
| lock.nix | init | |
| README.md | init | |
Reflake: A flake-compatible alternative implemented in common nix code
So, all my attempts to get rid of flakes eventually led me to implement my own version of flakes in stable Nix.
Still relies on the experimental fetchTree feature, which is part of flakes but can be enabled independently.
Features
- Flat dependency management inspired by unflake
- Input locking from nixlock and fetchTree features
- Inspired by flake-file, the
nix flakecommand implemented throughnix-shell - Pure evaluation support implemented using Nix's lazy evaluation features
How to use
All functions are packaged in default.nix. Copy it, then find the config part in this file.
config =
let
# Name of the lock file
# The name of the lock file(lockName) and its content(lockFile) are two different things. The content should be a nix attribute set.
# If you want, you can simply modify the `lockShell` function to use toml/json or any type you like in the lock file.
lockName = "lock.nix";
lockFile = import ./${lockName};
# Place inputs similar to flakes here;
# they can be written directly here, or placed in another file and then `import ./inputs.nix`.
# You can use complete nix here, such as functions.
# However, these should be able to be evaluated as simple nix attribute sets, just like flakes inputs.
# This is a strange example from my configuration file, using mirror infrastructure located in China to speed up my network.
inputsFile =
let
# git = url: args: (args // { type = "git"; } // { inherit url; });
# file = url: args: (args // { type = "file"; } // { inherit url; });
tarball = url: args: (args // { type = "tarball"; } // { inherit url; });
nixpkgs =
url: tarball ("https://mirror.nju.edu.cn/nix-channels/releases/" + url + "/nixexprs.tar.xz") { };
archive = url: args: (args // { type = "gitArchive"; } // { inherit url; });
github = url: args: archive ("https://v6.gh-proxy.org/https://github.com/" + url) args;
codeberg = url: args: archive ("https://codeberg.org/" + url) args;
path = path: args: (args // { type = "path"; } // { inherit path; });
in
{
nixpkgs = nixpkgs "nixos-25.11@nixos-25.11.941.c97c47f2bac4";
falake = codeberg "FrdrCkII/falake" { ref = "main"; };
flake-aspects = github "vic/flake-aspects" { ref = "main"; };
impermanence = github "nix-community/impermanence" { ref = "master"; };
disko = github "nix-community/disko" { ref = "master"; };
smfhhhh = github "feel-co/smfh" { ref = "master"; };
hjem = github "feel-co/hjem" {
ref = "main";
# Similar to 'follows' in flake inputs
follows = {
smfh = "smfhhhh";
};
};
systems = path "systems" { };
};
mkLockShell = args: lockLib.lockShell ({ inherit inputsFile lockName lockFile; } // args);
in
{
lock = mkLockShell { };
update = mkLockShell { update = true; };
# Sometimes nix doesn't immediately update cached inputs, and in this case, you need to use
# nix-shell -A update --option tarball-ttl 0
inputsLock = lockLib.lockInputs {
# The root directory of the entire git repository.
# You must specify it manually.
root = ./.;
inherit lockFile;
# Inputs alias.
# In this example, you will get an input called `nixpkgs-stable`, which is copied from `nixpkgs`.
# Basically it's the global version of `follows`.
inputsAlias = {
nixpkgs-stable = "nixpkgs";
};
};
};
Then create an empty lock file
# Just like this
{ }
Finally, run nix-shell -A lock to lock it!
And run nix-shell -A update to update the inputs.
Sometimes nix doesn't immediately update cached inputs, and in this case, you need to use
nix-shell -A update --option tarball-ttl 0
Now you can use this method to get input:
let
inputs = (import ./default.nix).inputsLock;
in
{ ... }
# Or do you want to use `self`? Try the `mkOutputs` function from unflake.
(import ./default.nix).mkOutputs (
inputs:
{ ... }
)
Input types
Currently, only five types are supported in default.nix, but adding new types should be very easy since all types are defined in the Nix code.
General Options
home-manager = {
# Required, input type
type = "git";
# Optional, usually handled automatically, default is yes
flake = false;
};
type = "git";
Lock a git repository
home-manager = {
type = "git";
# Required
url = "https://github.com/nix-community/home-manager";
# Optional
ref = "master";
# Optional, but usually not specified
rev = "1234567890";
# Optional, but usually not specified
narHash = "1234567890";
# Optional, default is false
submodules = true;
# Optional, default is true
shallow = true;
};
type = "gitArchive";
A variant of 'git' that uses tarballs for downloads. It works similarly to 'GitHub', but is more flexible.
home-manager = {
type = "gitArchive";
... # Same as git
# Optional, default is "$url/archive/$rev.tar.gz"
# $url and $rev will be replaced with the values of url and rev.
archiveUrl = "https://mirror.of.github/archive/$rev.tar.gz";
};
type = "tarball";
Tarball
home-manager = {
type = "tarball";
# Required
url = "...";
};
type = "file";
File
home-manager = {
type = "file";
# Required
url = "...";
};
type = "path";
File
system = {
type = "path";
# Required, a string type relative path starting from the project root directory
path = "system";
};