Skip to content

Commit

Permalink
Split utility functions out from default.nix
Browse files Browse the repository at this point in the history
nix-thunk has two consumers: those who want to build the tool as such,
and those who want to use its nix functions to manipulate thunks. The
utility nix functions have been split out into `lib.nix`.
  • Loading branch information
madeline-os committed Aug 22, 2022
1 parent abe673d commit fe75967
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 47 deletions.
55 changes: 8 additions & 47 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@

with pkgs.haskell.lib;

let inherit (pkgs) lib; in rec {
rec {
inherit (import ./dep/gitignore.nix { inherit (pkgs) lib; }) gitignoreSource;
lib = pkgs.callPackage ./lib.nix {
inherit gitignoreSource;
inherit (pkgs) fetchgitPrivate;
};
inherit (lib) thunkSource mapSubdirectories;

# The version of nixpkgs that we use for fetching packing thunks (by
# themselves). Not to be used for building packages.
packedThunkNixpkgs = builtins.fetchTarball {
Expand Down Expand Up @@ -105,52 +112,6 @@ let inherit (pkgs) lib; in rec {

command = generateOptparseApplicativeCompletion "nix-thunk" (justStaticExecutables haskellPackages.nix-thunk);

inherit (import ./dep/gitignore.nix { inherit lib; }) gitignoreSource;

# Retrieve source that is controlled by the hack-* scripts; it may be either a stub or a checked-out git repo
thunkSource = p:
let
contents = builtins.readDir p;

contentsMatch = { required, optional }:
(let all = required // optional; in all // contents == all)
&& builtins.intersectAttrs required contents == required;

# Newer obelisk thunks include the feature of hackGet with a thunk.nix file in the thunk.
isObeliskThunkWithThunkNix =
let
packed = jsonFileName: {
required = { ${jsonFileName} = "regular"; "default.nix" = "regular"; "thunk.nix" = "regular"; };
optional = { ".attr-cache" = "directory"; };
};
in builtins.any (n: contentsMatch (packed n)) [ "git.json" "github.json" ];

filterArgs = x: removeAttrs x [ "branch" ];
hasValidThunk = name: if builtins.pathExists (p + ("/" + name))
then
contentsMatch {
required = { ${name} = "regular"; };
optional = { "default.nix" = "regular"; ".attr-cache" = "directory"; };
}
|| throw "Thunk at ${toString p} has files in addition to ${name} and optionally default.nix and .attr-cache. Remove either ${name} or those other files to continue (check for leftover .git too)."
else false;
in
if isObeliskThunkWithThunkNix then import (p + "/thunk.nix")
else if hasValidThunk "git.json" then (
let gitArgs = filterArgs (builtins.fromJSON (builtins.readFile (p + "/git.json")));
in if builtins.elem "@" (lib.stringToCharacters gitArgs.url)
then pkgs.fetchgitPrivate gitArgs
else pkgs.fetchgit gitArgs
)
else if hasValidThunk "github.json" then
pkgs.fetchFromGitHub (filterArgs (builtins.fromJSON (builtins.readFile (p + "/github.json"))))
else {
name = baseNameOf p;
outPath = gitignoreSource p;
};

#TODO: This really shouldn't include *all* symlinks, just ones that point at directories
mapSubdirectories = f: dir: lib.mapAttrs (name: _: f (dir + "/${name}")) (lib.filterAttrs (_: type: type == "directory" || type == "symlink") (builtins.readDir dir));

##############################################################################
# Deprecated functions
Expand Down
47 changes: 47 additions & 0 deletions lib.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{ lib, fetchgit, fetchgitPrivate, gitignoreSource, fetchFromGitHub }:
rec {
# Retrieve source that is controlled by the hack-* scripts; it may be either a stub or a checked-out git repo
thunkSource = p:
let
contents = builtins.readDir p;

contentsMatch = { required, optional }:
(let all = required // optional; in all // contents == all)
&& builtins.intersectAttrs required contents == required;

# Newer obelisk thunks include the feature of hackGet with a thunk.nix file in the thunk.
isObeliskThunkWithThunkNix =
let
packed = jsonFileName: {
required = { ${jsonFileName} = "regular"; "default.nix" = "regular"; "thunk.nix" = "regular"; };
optional = { ".attr-cache" = "directory"; };
};
in builtins.any (n: contentsMatch (packed n)) [ "git.json" "github.json" ];

filterArgs = x: removeAttrs x [ "branch" ];
hasValidThunk = name: if builtins.pathExists (p + ("/" + name))
then
contentsMatch {
required = { ${name} = "regular"; };
optional = { "default.nix" = "regular"; ".attr-cache" = "directory"; };
}
|| throw "Thunk at ${toString p} has files in addition to ${name} and optionally default.nix and .attr-cache. Remove either ${name} or those other files to continue (check for leftover .git too)."
else false;
in
if isObeliskThunkWithThunkNix then import (p + "/thunk.nix")
else if hasValidThunk "git.json" then (
let gitArgs = filterArgs (builtins.fromJSON (builtins.readFile (p + "/git.json")));
in if builtins.elem "@" (lib.stringToCharacters gitArgs.url)
then fetchgitPrivate gitArgs
else fetchgit gitArgs
)
else if hasValidThunk "github.json" then
fetchFromGitHub (filterArgs (builtins.fromJSON (builtins.readFile (p + "/github.json"))))
else {
name = baseNameOf p;
outPath = gitignoreSource p;
};

#TODO: This really shouldn't include *all* symlinks, just ones that point at directories
mapSubdirectories = f: dir: lib.mapAttrs (name: _: f (dir + "/${name}")) (lib.filterAttrs (_: type: type == "directory" || type == "symlink") (builtins.readDir dir));
}

0 comments on commit fe75967

Please sign in to comment.