Use mocked builders to get default pkg name faster

Since evaluating pkgs is expensive, this speeds up evaluation of flakes
with `packages.default` by attempting to get the name using a pkgs set
containing only mocked builders that just return the name.
This commit is contained in:
Archit Gupta 2024-01-11 23:21:49 -08:00
parent 4b9d78f35f
commit 99d8fc8a85
2 changed files with 53 additions and 2 deletions

View File

@ -5,8 +5,8 @@
{ config, lib, inputs, flakelight, genSystems, ... }:
let
inherit (builtins) parseDrvName tryEval;
inherit (lib) filterAttrs findFirst mapAttrs mapAttrs' mkIf mkMerge
mkOption nameValuePair optionalAttrs;
inherit (lib) filterAttrs findFirst mapAttrs mapAttrs' mkIf mkMerge mkOption
nameValuePair optionalAttrs;
inherit (lib.types) lazyAttrsOf nullOr str uniq;
inherit (flakelight) supportedSystem;
inherit (flakelight.types) overlay packageDef;
@ -49,12 +49,14 @@ in
getName = pkg: pkg.pname or (parseDrvName pkg.name).name;
inherit (prev.stdenv.hostPlatform) system;
baseNixpkgs = inputs.nixpkgs.legacyPackages.${system};
mockPkgs = import ../misc/nameMockedPkgs.nix prev;
defaultPkgName = findFirst (x: (tryEval x).success)
(throw ("Could not determine the name of the default package; " +
"please set the `pname` flakelight option to the intended name."))
[
(assert config.pname != null; config.pname)
(getName (mockPkgs.callPackage config.packages.default { }))
(getName (baseNixpkgs.callPackage config.packages.default { }))
(getName (import inputs.nixpkgs {
inherit (prev.stdenv.hostPlatform) system;

49
misc/nameMockedPkgs.nix Normal file
View File

@ -0,0 +1,49 @@
# flakelight -- Framework for simplifying flake setup
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
# SPDX-License-Identifier: MIT
# This is a fake pkgs set to enable efficiently extracting a derivation's name
real:
let
inherit (real) lib;
callPackageWith = autoArgs: fn: args:
let
f = if lib.isFunction fn then fn else import fn;
fargs = lib.functionArgs f;
mock = lib.mapAttrs (_: _: { }) (lib.filterAttrs (_: v: !v) fargs);
in
f (mock // builtins.intersectAttrs fargs autoArgs // args);
in
lib.fix (self: {
pkgs = self;
lib = lib // { inherit callPackageWith; };
callPackage = callPackageWith self;
stdenv = real.stdenv // {
mkDerivation = args:
if lib.isFunction args then lib.fix args else args;
};
runCommandWith = { name, ... }: _: { inherit name; };
runCommand = name: _: _: { inherit name; };
runCommandLocal = name: _: _: { inherit name; };
runCommandCC = name: _: _: { inherit name; };
writeTextFile = { name, ... }: { inherit name; };
writeText = name: _: { inherit name; };
writeTextDir = path: _: { name = builtins.baseNameOf path; };
writeScript = name: _: { inherit name; };
writeScriptBin = name: _: { inherit name; };
writeShellScript = name: _: { inherit name; };
writeShellScriptBin = name: _: { inherit name; };
writeShellApplication = { name, ... }: { inherit name; };
writeCBin = pname: _: { inherit pname; };
concatTextFile = { name, ... }: { inherit name; };
concatText = name: _: { inherit name; };
concatScript = name: _: { inherit name; };
symlinkJoin = { name, ... }: { inherit name; };
linkFarm = name: _: { inherit name; };
linkFarmFromDrvs = name: _: { inherit name; };
})