refactor: use nixpkgs' mkShell for rust devshells, dont create separate shells for each package

This commit is contained in:
Yusuf Bera Ertan 2022-12-21 00:23:52 +03:00
parent 5fef684214
commit b679bb78f5
No known key found for this signature in database
GPG Key ID: 1D8F8FAF2294D6EA
3 changed files with 70 additions and 145 deletions

View File

@ -71,27 +71,23 @@
args = buildArgs;
});
mkShellForPkg = pkg:
pkgs.callPackage ../devshell.nix {
inherit externals;
drv = pkg;
};
allPackages =
l.mapAttrs
(name: version: {"${version}" = buildPackage name version;})
args.packages;
allDevshells =
l.mapAttrs
(name: version: mkShellForPkg allPackages.${name}.${version})
allPackagesList =
l.mapAttrsToList
(name: version: allPackages.${name}.${version})
args.packages;
shell = pkgs.callPackage ../devshell.nix {
name = "devshell";
drvs = allPackagesList;
};
in {
packages = allPackages;
devShells =
allDevshells
// {
default = allDevshells.${defaultPackageName};
};
devShells = {
default = shell;
};
};
}

View File

@ -131,35 +131,28 @@
in
build;
mkShellForPkg = pkg: let
pkgDeps = pkg.passthru.dependencies;
depsShell = pkgs.callPackage ../devshell.nix {
inherit externals;
drv = pkgDeps;
};
mainShell = pkgs.callPackage ../devshell.nix {
inherit externals;
drv = pkg;
};
shell = depsShell.combineWith mainShell;
in
shell;
allPackages =
l.mapAttrs
(name: version: {"${version}" = buildPackage name version;})
args.packages;
allDevshells =
l.mapAttrs
(name: version: mkShellForPkg allPackages.${name}.${version})
args.packages;
allPackagesList = l.flatten (
l.mapAttrsToList
(
name: version: let
pkg = allPackages.${name}.${version};
in [pkg.passthru.dependencies pkg]
)
args.packages
);
shell = pkgs.callPackage ../devshell.nix {
name = "devshell";
drvs = allPackagesList;
};
in {
packages = allPackages;
devShells =
allDevshells
// {
default = allDevshells.${defaultPackageName};
};
devShells = {
default = shell;
};
};
}

View File

@ -1,129 +1,65 @@
{
# args
drv,
# d2n
externals,
drvs,
name,
# nixpkgs
lib,
stdenv,
libiconv,
mkShell,
...
}: let
l = lib // builtins;
# function to merge two devshells
mergeShellConfig = base: other: let
c = base.config;
oc = other.config;
i = base.imports or [];
oi = other.imports or [];
hasCConfig = config: (config ? language) && (config.language ? c);
in {
config =
c
// oc
// {
packages = l.unique ((c.packages or []) ++ (oc.packages or []));
commands = l.unique ((c.commands or []) ++ (oc.commands or []));
env = l.unique ((c.env or []) ++ (oc.env or []));
devshell =
(c.devshell or {})
// (oc.devshell or {})
// {
startup = (c.devshell.startup or {}) // (oc.devshell.startup or {});
};
}
// l.optionalAttrs (hasCConfig c || hasCConfig oc) {
language.c = let
cConf = c.language.c or {};
ocConf = oc.language.c or {};
in {
compiler = ocConf.compiler or cConf.compiler;
libraries =
l.unique ((cConf.libraries or []) ++ (ocConf.libraries or []));
includes =
l.unique ((cConf.includes or []) ++ (ocConf.includes or []));
};
};
imports = l.unique (i ++ oi);
};
# creates a shell from a config
mkShell = config: let
shell = (externals.devshell.makeShell {configuration = config;}).shell;
in
shell
// {
passthru.config = config;
combineWith = other:
mkShell (mergeShellConfig config other.passthru.config);
addConfig = otherConfig:
mkShell (mergeShellConfig config {config = otherConfig;});
};
# convenience utils for converting a nix attribute to a shell env
# TODO: we could probably replace this with something from nixpkgs?
toStr = v:
if l.isBool v
then l.boolToString v
else l.toString v;
toShellEnv = v:
if l.isList v
then "( ${l.concatStringsSep " " (l.map (v: ''"${toStr v}"'') v)} )"
else l.toString v;
# illegal env names to be removed and not be added to the devshell
illegalEnvNames = [
"name"
"pname"
"version"
"all"
"args"
"drvPath"
"drvAttrs"
"outPath"
"stdenv"
"cargoArtifacts"
"dream2nixVendorDir"
"cargoVendorDir"
];
isIllegalEnv = name: l.any (oname: name == oname) illegalEnvNames;
inputs = (drv.buildInputs or []) ++ (drv.nativeBuildInputs or []);
rustToolchain = drv.passthru.rustToolchain;
# the config we will use
conf = {
config =
{
packages = inputs;
commands = [
{
package = rustToolchain.cargoHostTarget or rustToolchain.cargo;
name = "cargo";
category = "rust";
help = "Rust build tool";
}
];
env =
# filter out attrsets, functions and illegal environment vars
l.filter
(env: (env != null) && (! isIllegalEnv env.name))
(
l.mapAttrsToList
(
n: v:
if ! (l.isAttrs v || l.isFunction v)
then {
name = n;
value = toShellEnv v;
}
else null
)
drv
);
}
# only add c stuff *if* the stdenv has a c compiler
# if the user wants to use stdenvNoCC this allows them to do it easily
// l.optionalAttrs (drv.stdenv ? cc) {
language.c = {
compiler = drv.stdenv.cc;
libraries = inputs ++ (lib.optional stdenv.isDarwin libiconv);
includes = inputs;
};
};
imports = [externals.devshell.imports.c];
};
isIllegalEnv = name: l.elem name illegalEnvNames;
getEnvs = drv:
# filter out attrsets, functions and illegal environment vars
l.filterAttrs
(name: env: (env != null) && (! isIllegalEnv name))
(
l.mapAttrs
(
n: v:
if ! (l.isAttrs v || l.isFunction v)
then v
else null
)
drv
);
combineEnvs = envs:
l.foldl'
(
all: env:
all
// env
// {
packages = (all.packages or []) ++ (env.packages or []);
buildInputs = (all.buildInputs or []) ++ (env.buildInputs or []);
nativeBuildInputs = (all.nativeBuildInputs or []) ++ (env.nativeBuildInputs or []);
propagatedBuildInputs = (all.propagatedBuildInputs or []) ++ (env.propagatedBuildInputs or []);
propagatedNativeBuildInputs = (all.propagatedNativeBuildInputs or []) ++ (env.propagatedNativeBuildInputs or []);
}
)
{}
envs;
shellEnv =
(combineEnvs (l.map getEnvs drvs))
// {
inherit name;
};
in
mkShell conf
(mkShell.override {stdenv = (l.head drvs).stdenv;}) shellEnv