Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions dev/_bootstrap-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,32 @@ let
'';
};

test-nixlock-update = pkgs.writeShellApplication {
name = "test-nixlock-update";
runtimeInputs = [
(empty.flake-file.apps.write-nixlock pkgs)
];
text = ''
write-nixlock lock
grep empty ${outdir}/nixlock.lock.nix
write-nixlock update
grep empty ${outdir}/nixlock.lock.nix
'';
};

test-nixlock-update-one = pkgs.writeShellApplication {
name = "test-nixlock-update-one";
runtimeInputs = [
(empty.flake-file.apps.write-nixlock pkgs)
];
text = ''
write-nixlock lock
write-nixlock update empty
grep empty ${outdir}/nixlock.lock.nix
if write-nixlock update nonexistent 2>/dev/null; then exit 1; fi
'';
};

test-nixlock = pkgs.writeShellApplication {
name = "test-nixlock";
runtimeInputs = [
Expand Down Expand Up @@ -268,6 +294,8 @@ pkgs.mkShell {
test-npins-follows
test-npins-transitive
test-nixlock
test-nixlock-update
test-nixlock-update-one
test-nixlock-schemes
test-write-lock-flake
test-write-lock-npins
Expand Down
134 changes: 103 additions & 31 deletions modules/nixlock/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,92 @@ let
inherit (config) flake-file;
inherit (import ../lib.nix lib) inputsExpr;

inputs = inputsExpr flake-file.inputs;
inputs = flake-file.nixlock.preProcess (inputsExpr flake-file.inputs);

nixlock-source = fetchTarball {
url = flake-file.nixlock.url;
sha256 = flake-file.nixlock.sha256;
};

nlLibs = (import "${nixlock-source}/${flake-file.nixlock.version}").libs;
nl = import "${nixlock-source}/${flake-file.nixlock.version}" flake-file.nixlock.customTypes;
inherit (nl.nllib)
lockFileStart
lockFileEnd
lockFileMerge
getFetcher
withInputs
;
types = nl.types;

inherit (import ./parse.nix lib) toNixlockInput;

inputsFile = lib.filterAttrs (_: v: v != null) (lib.mapAttrs toNixlockInput inputs);

lockListFor =
upType: lockFile:
lib.filterAttrs (
name: value:
!(lockFile ? ${name})
|| value != lockFile.${name}.meta or { }
|| (if upType == "update" then !(value.isFreeze or false) else false)
) inputsFile;
lockFilePath = "${flake-file.intoPath}/${flake-file.nixlock.lockFileName}";
existingLock =
if lib.hasPrefix "/" lockFilePath && builtins.pathExists lockFilePath then
import lockFilePath
else
{ };

shellFor =
upType: lockFile: lockFileName:
let
entries = lockListFor upType lockFile;
in
nlLibs.toLockShell {
inherit lockFile lockFileName;
inputsFile = entries;
cmds = lib.concatStringsSep "\n" (
lib.mapAttrsToList (n: v: nlLibs.types.${v.type}.fresh n v) entries
);
};
sources = existingLock: withInputs fetchedInputs existingLock;

cmdFor =
name: v:
if existingLock ? ${name} then
lockFileMerge {
inherit name;
meta = v;
lock = existingLock.${name}.lock;
}
else
types.${v.type}.update name v;

scriptWith = cmds: lockFileName: ''
${lockFileStart}
${lib.concatStringsSep "\n" cmds}
${lockFileEnd}
echo $LOCKFILE | nixfmt > '${lockFileName}'
'';

lockScript =
lockFileName:
scriptWith (lib.mapAttrsToList (n: v: types.${v.type}.update n v) inputsFile) lockFileName;

updateScript =
lockFileName:
scriptWith (lib.mapAttrsToList (
n: v: if v.isFreeze or false then cmdFor n v else types.${v.type}.update n v
) inputsFile) lockFileName;

updateOneScript =
target: lockFileName:
scriptWith (lib.mapAttrsToList (
n: v: if n == target then types.${v.type}.update n v else cmdFor n v
) inputsFile) lockFileName;

perInputCases =
lockFileName:
lib.concatStringsSep "\n" (
lib.mapAttrsToList (name: _: ''
${name}) ${updateOneScript name lockFileName} ;;
'') inputsFile
);

fetchedInputs = lib.mapAttrs (
_name: entry:
getFetcher {
rootPath = flake-file.intoPath;
inherit (entry) meta lock;
type = "stable";
}
) existingLock;

write-nixlock =
pkgs:
let
rootPath = flake-file.intoPath;
lockFileName = flake-file.nixlock.lockFileName;
lockScript = shellFor "lock" { } lockFileName;
updateScript = shellFor "update" { } lockFileName;
in
pkgs.writeShellApplication {
name = "write-nixlock";
Expand All @@ -69,35 +113,63 @@ let
text = ''
cd ${rootPath}
case "''${1:-lock}" in
lock) ${lockScript} ;;
update) ${updateScript} ;;
*) echo "usage: write-nixlock [lock|update]" >&2; exit 1 ;;
lock)
${lockScript lockFileName}
;;
update)
case "''${2:-}" in
"")
${updateScript lockFileName}
;;
${perInputCases lockFileName}
*) echo "unknown input: ''${2}" >&2; exit 1 ;;
esac
;;
*) echo "usage: write-nixlock [lock|update [<input>]]" >&2; exit 1 ;;
esac
'';
};
in
{
config.flake-file.apps = { inherit write-nixlock; };
config = {
flake-file.apps = { inherit write-nixlock; };
};
options.flake-file.nixlock = {
url = lib.mkOption {
type = lib.types.str;
description = "nixlock archive url";
default = "https://codeberg.org/FrdrCkII/nixlock/archive/dad9155634ce5d5183429daaeef2bbf6de9afcbf.tar.gz";
default = "https://codeberg.org/FrdrCkII/nixlock/archive/fc10414fc2a2db7ad5daeeaa9e92e0e139102f9f.tar.gz";
};
sha256 = lib.mkOption {
type = lib.types.str;
description = "nixlock archive sha256";
default = "sha256:0bycgfdar1xcxgbp75r7bpmfvm2qh8206q2h2vsx5qn8fr39x0li";
default = "sha256:0zqxki955iizglm5qs7gp914p7vsv7wjdabx053nk9maba7zpdja";
};
version = lib.mkOption {
type = lib.types.str;
description = "nixlock version to load";
default = "v3";
default = "v3.1";
};
lockFileName = lib.mkOption {
type = lib.types.str;
description = "nixlock lockfile name";
default = "nixlock.lock.nix";
};
sources = lib.mkOption {
type = lib.types.functionTo lib.types.unspecified;
readOnly = true;
description = "Fetched inputs from the nixlock lockfile via withInputs, ready to use as flake inputs.";
default = sources;
};
customTypes = lib.mkOption {
type = lib.types.raw;
description = "nixlock custom input types";
default = { };
};
preProcess = lib.mkOption {
type = lib.types.functionTo lib.types.raw;
description = "Pre-process flake-file inputs before giving to nixlock";
default = lib.id;
};
};
}
8 changes: 4 additions & 4 deletions modules/nixlock/parse.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ let
lib.splitString "&" (lib.last (lib.splitString "?" urlWithParams))
);
in
if pairs != [ ] then lib.removePrefix "ref=" (builtins.head pairs) else "HEAD";
if pairs != [ ] then lib.removePrefix "ref=" (builtins.head pairs) else null;

baseUrl = urlWithParams: builtins.head (lib.splitString "?" urlWithParams);

Expand All @@ -18,7 +18,7 @@ let
parts = lib.splitString "/" path;
owner = builtins.elemAt parts 0;
repo = builtins.elemAt parts 1;
ref = if builtins.length parts > 2 then builtins.elemAt parts 2 else "HEAD";
ref = if builtins.length parts > 2 then builtins.elemAt parts 2 else null;
in
{
type = "gitArchive";
Expand Down Expand Up @@ -51,13 +51,13 @@ let
{
type = "gitArchive";
url = "${mgithost}/${input.owner}/${input.repo}";
ref = input.ref or "HEAD";
ref = input.ref or null;
}
else if input.type == "git" then
{
type = "git";
url = input.url;
ref = input.ref or "HEAD";
ref = input.ref or null;
}
else if
lib.elem input.type [
Expand Down
Loading