Skip to content
Closed
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
4 changes: 2 additions & 2 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ let
# linux kernel configuration
kernel = callLibs ./kernel.nix;

inherit (self.flakes) callLocklessFlake;
inherit (self.flakes) callLocklessFlake eachSystem mkApp mkApp';
inherit (builtins) add addErrorContext attrNames concatLists
deepSeq elem elemAt filter genericClosure genList getAttr
hasAttr head isAttrs isBool isInt isList isString length
Expand All @@ -74,7 +74,7 @@ let
info showWarnings nixpkgsVersion version isInOldestRelease
mod compare splitByAndCompare
functionArgs setFunctionArgs isFunction toFunction
toHexString toBaseDigits;
toHexString toBaseDigits exec;
inherit (self.fixedPoints) fix fix' converge extends composeExtensions
composeManyExtensions makeExtensible makeExtensibleWithCustomName;
inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath
Expand Down
82 changes: 81 additions & 1 deletion lib/flakes.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{ lib }:

rec {
let
inherit (lib) isDerivation exec;
inherit (builtins) isAttrs mapAttrs attrNames foldl';
in rec {

/* imports a flake.nix without acknowledging its lock file, useful for
referencing subflakes from a parent flake. The second argument allows
Expand All @@ -19,4 +22,81 @@ rec {
in
self;

/*
Builds a map from <attr>=value to <attr>.<system>=value for each system,
except for the `hydraJobs` attribute, where it maps the inner attributes,
from hydraJobs.<attr>=value to hydraJobs.<attr>.<system>=value.
*/
eachSystem = systems: f:
let

/*
Used to match Hydra's convention of how to define jobs. Basically transforms

hydraJobs = {
hello = <derivation>;
haskellPackages.aeson = <derivation>;
}

to

hydraJobs = {
hello.x86_64-linux = <derivation>;
haskellPackages.aeson.x86_64-linux = <derivation>;
}

if the given flake does `eachSystem [ "x86_64-linux" ] { ... }`.
*/
pushDownSystem = system: merged:
mapAttrs
(name: value:
if ! (isAttrs value) then value
else if isDerivation value then (merged.${name} or {}) // { ${system} = value; }
else pushDownSystem system (merged.${name} or {}) value);

# Merge together the outputs for all systems.
op = attrs: system:
let
ret = f system;
op = attrs: key:
let
appendSystem = key: system: ret:
if key == "hydraJobs"
then (pushDownSystem system (attrs.hydraJobs or {}) ret.hydraJobs)
else { ${system} = ret.${key}; };
in attrs //
{
${key} = (attrs.${key} or { }) // (appendSystem key system ret);
}
;
in
foldl' op attrs (attrNames ret);
in
foldl' op { } systems
;

/*
Returns the structure used by `nix app`

Example:
mkApp neovim
=> { type = "app"; program = "/nix/store/.../bin/nvim"; }
*/
mkApp = drv: {
type = "app";
program = exec drv;
};

/*
Returns the structure used by `nix app`

Example:
mkApp libnotify "notify-send"
=> { type = "app"; program = "/nix/store/.../bin/notify-send"; }
*/
mkApp' = drv: binName: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be easier to combine those and fall back to the first argument of the second is not defined?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's possible to do it that way? The best I can think of in terms of merging is to swap arguments and check if the first argument is a derivation or a string, if its a string - return a function that accepts derivation

Copy link
Contributor Author

@gytis-ivaskevicius gytis-ivaskevicius May 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, another thought occurred - one argument that accepts either attribute set (same as flake-utils) or derivation. This would be a pretty clean implementation.

Anyways, let's wait and see what supreme codeowners has to say about all this, not sure what are your thoughts on the matter but I think its time for reviewers to give in and merge this or something similar

type = "app";
program = "${drv}/bin/${binName}";
};

}
17 changes: 17 additions & 0 deletions lib/trivial.nix
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,23 @@ rec {
# Argument to check for null before passing it to `f`
a: if a == null then a else f a;


/*
Convert derivation to path of main executable

Type: exec :: Derivation -> Path

Example:
exec pkgs.bash
=> /nix/store/...-bash-x-x-x/bin/bash
exec pkgs.libnotify
=> /nix/store/...-libnotify-x-x-x/bin/notify-send
exec (pkgs.writeShellScriptBin "abc.sh" "")
=> /nix/store/...-abc.sh/bin/abc.sh
*/
exec = pkg: "${pkg}/bin/${pkg.meta.mainProgram or pkg.pname or pkg.name}";


# Pull in some builtins not included elsewhere.
inherit (builtins)
pathExists readFile isBool
Expand Down