From 262dabbaf23654a001da7ab24640cb812ca381cc Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Thu, 28 Mar 2019 23:52:37 +0100 Subject: [PATCH 1/2] Refactor `overlay.nix` Simplify `overlay.nix` a bit by removing unnecessary filtering on attribute values. --- overlay.nix | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/overlay.nix b/overlay.nix index bda4332..122729d 100644 --- a/overlay.nix +++ b/overlay.nix @@ -1,23 +1,18 @@ -# You can use this file as a nixpkgs overlay. -# It's useful in the case where you don't want to add the whole NUR namespace -# to your configuration. +# You can use this file as a nixpkgs overlay. This is useful in the +# case where you don't want to add the whole NUR namespace to your +# configuration. self: super: let - filterSet = - (f: g: s: builtins.listToAttrs - (map - (n: { name = n; value = builtins.getAttr n s; }) - (builtins.filter - (n: f n && g (builtins.getAttr n s)) - (builtins.attrNames s) - ) - ) - ); - isReserved = n: builtins.elem n ["lib" "overlays" "modules"]; -in filterSet - (n: !(isReserved n)) # filter out non-packages - (p: true) # all packages are ok - (import ./default.nix { pkgs = super; }) + isReserved = n: n == "lib" || n == "overlays" || n == "modules"; + nameValuePair = n: v: { name = n; value = v; }; + nurAttrs = import ./default.nix { pkgs = super; }; + +in + + builtins.listToAttrs + (map (n: nameValuePair n nurAttrs.${n}) + (builtins.filter (n: !isReserved n) + (builtins.attrNames nurAttrs))) From 87ddc10b67503c54286d0a9618ca05f6b49d1495 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Sun, 31 Mar 2019 21:13:48 +0200 Subject: [PATCH 2/2] Replace `buildable.nix` by `ci.nix` The `ci.nix` file contains a number of improvements over `buildable.nix`. For example, it - honors `recurseForDerivations` to also build packages inside attributes, - builds all package outputs, and - separates buildable and cacheable outputs such that packages having `preferLocalBuild` are not cached. --- .travis.yml | 4 ++-- buildable.nix | 28 -------------------------- ci.nix | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 30 deletions(-) delete mode 100644 buildable.nix create mode 100644 ci.nix diff --git a/.travis.yml b/.travis.yml index e1d6117..8065717 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,13 +22,13 @@ install: - travis_retry nix-channel --update script: - - outs=$(nix-build buildable.nix) && echo Produced $outs + - nix-build ci.nix -A buildOutputs - nix eval -f default.nix 'lib' - nix eval -f default.nix 'modules' - nix eval -f default.nix 'overlays' after_success: - - if [ -n "${CACHIX_CACHE}" ]; then cachix push "${CACHIX_CACHE}" $outs; fi + - if [ -n "${CACHIX_CACHE}" ]; then nix-build ci.nix -A cacheOutputs | cachix push "${CACHIX_CACHE}"; fi - if [ "false" = "${TRAVIS_PULL_REQUEST}" -a "master" = "${TRAVIS_BRANCH}" ]; then curl -XPOST "https://nur-update.herokuapp.com/update?repo=${NUR_REPO}"; fi diff --git a/buildable.nix b/buildable.nix deleted file mode 100644 index 2b61b1f..0000000 --- a/buildable.nix +++ /dev/null @@ -1,28 +0,0 @@ -# This file filters out all the unbuildable packages from your package set. -# It's what gets built by CI, so if you correctly mark broken/unfree packages -# as such your CI will not try to build them and the buildable packages will -# be added to the cache. -{ pkgs ? import {} }: - -let - filterSet = - (f: g: s: builtins.listToAttrs - (map - (n: { name = n; value = builtins.getAttr n s; }) - (builtins.filter - (n: f n && g (builtins.getAttr n s)) - (builtins.attrNames s) - ) - ) - ); - isReserved = n: builtins.elem n ["lib" "overlays" "modules"]; - isBroken = p: p.meta.broken or false; - isFree = p: p.meta.license.free or true; -in filterSet - (n: !(isReserved n)) # filter out non-packages - (p: (builtins.isAttrs p) - && !(isBroken p) - && isFree p - ) - (import ./default.nix { inherit pkgs; }) - diff --git a/ci.nix b/ci.nix new file mode 100644 index 0000000..1377d43 --- /dev/null +++ b/ci.nix @@ -0,0 +1,56 @@ +# This file provides all the buildable and cacheable packages and +# package outputs in you package set. These are what gets built by CI, +# so if you correctly mark packages as +# +# - broken (using `meta.broken`), +# - unfree (using `meta.license.free`), and +# - locally built (using `preferLocalBuild`) +# +# then your CI will be able to build and cache only those packages for +# which this is possible. + +{ pkgs ? import {} }: + +with builtins; + +let + + isReserved = n: n == "lib" || n == "overlays" || n == "modules"; + isDerivation = p: isAttrs p && p ? type && p.type == "derivation"; + isBuildable = p: !(p.meta.broken or false) && p.meta.license.free or false; + isCacheable = p: !(p.preferLocalBuild or false); + shouldRecurseForDerivations = p: isAttrs p && p.recurseForDerivations or false; + + nameValuePair = n: v: { name = n; value = v; }; + + concatMap = builtins.concatMap or (f: xs: concatLists (map f xs)); + + flattenPkgs = s: + let + f = p: + if shouldRecurseForDerivations p then flattenPkgs p + else if isDerivation p then [p] + else []; + in + concatMap f (attrValues s); + + outputsOf = p: map (o: p.${o}) p.outputs; + + nurAttrs = import ./default.nix { inherit pkgs; }; + + nurPkgs = + flattenPkgs + (listToAttrs + (map (n: nameValuePair n nurAttrs.${n}) + (filter (n: !isReserved n) + (attrNames nurAttrs)))); + +in + +rec { + buildPkgs = filter isBuildable nurPkgs; + cachePkgs = filter isCacheable buildPkgs; + + buildOutputs = concatMap outputsOf buildPkgs; + cacheOutputs = concatMap outputsOf cachePkgs; +}