mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-09-11 14:35:30 +03:00
feat: use devshell for rust devshells (#302)
This commit is contained in:
parent
0f3b6c5dd1
commit
0503a1272d
16
flake.nix
16
flake.nix
@ -108,6 +108,22 @@
|
|||||||
"pkgs/installCargoArtifactsHook.sh"
|
"pkgs/installCargoArtifactsHook.sh"
|
||||||
"LICENSE"
|
"LICENSE"
|
||||||
];
|
];
|
||||||
|
devshell = [
|
||||||
|
"modules/back-compat.nix"
|
||||||
|
"modules/commands.nix"
|
||||||
|
"modules/default.nix"
|
||||||
|
"modules/devshell.nix"
|
||||||
|
"modules/env.nix"
|
||||||
|
"modules/modules.nix"
|
||||||
|
"modules/modules-docs.nix"
|
||||||
|
"nix/ansi.nix"
|
||||||
|
"nix/mkNakedShell.nix"
|
||||||
|
"nix/source.nix"
|
||||||
|
"nix/strOrPackage.nix"
|
||||||
|
"nix/writeDefaultShellScript.nix"
|
||||||
|
"extra/language/c.nix"
|
||||||
|
"LICENSE"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# create a directory containing the files listed in externalPaths
|
# create a directory containing the files listed in externalPaths
|
||||||
|
@ -121,6 +121,10 @@ in let
|
|||||||
subsystems = callPackageDream ./subsystems {};
|
subsystems = callPackageDream ./subsystems {};
|
||||||
|
|
||||||
externals = {
|
externals = {
|
||||||
|
devshell = {
|
||||||
|
makeShell = import "${externalSources.devshell}/modules" pkgs;
|
||||||
|
imports.c = "${externalSources.devshell}/extra/language/c.nix";
|
||||||
|
};
|
||||||
crane = let
|
crane = let
|
||||||
importLibFile = name: import "${externalSources.crane}/lib/${name}.nix";
|
importLibFile = name: import "${externalSources.crane}/lib/${name}.nix";
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
lib,
|
lib,
|
||||||
dlib,
|
dlib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
callPackageDream,
|
||||||
...
|
...
|
||||||
} @ topArgs: {
|
} @ topArgs: {
|
||||||
subsystemAttrs,
|
subsystemAttrs,
|
||||||
@ -48,9 +49,10 @@
|
|||||||
cargoTestFlags = cargoBuildFlags;
|
cargoTestFlags = cargoBuildFlags;
|
||||||
|
|
||||||
cargoVendorDir = "../nix-vendor";
|
cargoVendorDir = "../nix-vendor";
|
||||||
|
dream2nixVendorDir = vendoring.vendoredDependencies;
|
||||||
|
|
||||||
postUnpack = ''
|
postUnpack = ''
|
||||||
${vendoring.copyVendorDir "./nix-vendor"}
|
${vendoring.copyVendorDir "$dream2nixVendorDir" "./nix-vendor"}
|
||||||
export CARGO_HOME=$(pwd)/.cargo_home
|
export CARGO_HOME=$(pwd)/.cargo_home
|
||||||
'';
|
'';
|
||||||
|
|
||||||
@ -66,16 +68,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
mkShellForPkg = pkg:
|
mkShellForPkg = pkg:
|
||||||
pkg.overrideAttrs (old: {
|
callPackageDream ../devshell.nix {drv = pkg;};
|
||||||
buildInputs =
|
|
||||||
(old.buildInputs or [])
|
|
||||||
++ (
|
|
||||||
with pkg.passthru.rustToolchain; [
|
|
||||||
cargo
|
|
||||||
rustc
|
|
||||||
]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
allPackages =
|
allPackages =
|
||||||
l.mapAttrs
|
l.mapAttrs
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
externals,
|
externals,
|
||||||
|
callPackageDream,
|
||||||
...
|
...
|
||||||
} @ topArgs: {
|
} @ topArgs: {
|
||||||
subsystemAttrs,
|
subsystemAttrs,
|
||||||
@ -83,8 +84,9 @@
|
|||||||
pnameSuffix = depsNameSuffix;
|
pnameSuffix = depsNameSuffix;
|
||||||
# Make sure cargo only checks the package we want
|
# Make sure cargo only checks the package we want
|
||||||
cargoCheckCommand = "cargo check --release --package ${pname}";
|
cargoCheckCommand = "cargo check --release --package ${pname}";
|
||||||
|
dream2nixVendorDir = vendoring.vendoredDependencies;
|
||||||
preUnpack = ''
|
preUnpack = ''
|
||||||
${vendoring.copyVendorDir "$cargoVendorDir"}
|
${vendoring.copyVendorDir "$dream2nixVendorDir" "$cargoVendorDir"}
|
||||||
'';
|
'';
|
||||||
# move the vendored dependencies folder to $out for main derivation to use
|
# move the vendored dependencies folder to $out for main derivation to use
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
@ -103,7 +105,7 @@
|
|||||||
cargoArtifacts = deps;
|
cargoArtifacts = deps;
|
||||||
# link the vendor dir we used earlier to the correct place
|
# link the vendor dir we used earlier to the correct place
|
||||||
preUnpack = ''
|
preUnpack = ''
|
||||||
ln -sf ${deps}/nix-vendor $cargoVendorDir
|
${vendoring.copyVendorDir "$cargoArtifacts/nix-vendor" "$cargoVendorDir"}
|
||||||
'';
|
'';
|
||||||
# write our cargo lock
|
# write our cargo lock
|
||||||
# note: we don't do this in buildDepsOnly since
|
# note: we don't do this in buildDepsOnly since
|
||||||
@ -123,38 +125,11 @@
|
|||||||
# dependencies derivation. this could cause confusion for users.
|
# dependencies derivation. this could cause confusion for users.
|
||||||
mkShellForPkg = pkg: let
|
mkShellForPkg = pkg: let
|
||||||
pkgDeps = pkg.passthru.dependencies;
|
pkgDeps = pkg.passthru.dependencies;
|
||||||
|
depsShell = callPackageDream ../devshell.nix {drv = pkgDeps;};
|
||||||
|
mainShell = callPackageDream ../devshell.nix {drv = pkg;};
|
||||||
|
shell = depsShell.combineWith mainShell;
|
||||||
in
|
in
|
||||||
pkg.overrideAttrs (old: {
|
shell;
|
||||||
# we have to set these to empty because crane uses the phases
|
|
||||||
# to compile & test. buildRustPackage uses hooks instead so that's
|
|
||||||
# why build-rust-package doesn't need to do this.
|
|
||||||
buildPhase = "";
|
|
||||||
checkPhase = "";
|
|
||||||
# we have to have some output, so we just record the build inputs
|
|
||||||
# to a file (like mkShell does). this makes the derivation buildable.
|
|
||||||
# see https://github.com/NixOS/nixpkgs/pull/153194.
|
|
||||||
installPhase = "echo >> $out && export >> $out";
|
|
||||||
|
|
||||||
# set cargo artifacts to empty string so that dependencies
|
|
||||||
# derivation doesn't get built when entering devshell.
|
|
||||||
cargoArtifacts = "";
|
|
||||||
|
|
||||||
# merge build inputs from main drv and dependencies drv.
|
|
||||||
buildInputs = l.unique (
|
|
||||||
(old.buildInputs or [])
|
|
||||||
++ (pkgDeps.buildInputs or [])
|
|
||||||
++ [
|
|
||||||
(
|
|
||||||
pkg.passthru.rustToolchain.cargoHostTarget
|
|
||||||
or pkg.passthru.rustToolchain.cargo
|
|
||||||
)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
nativeBuildInputs = l.unique (
|
|
||||||
(old.nativeBuildInputs or [])
|
|
||||||
++ (pkgDeps.nativeBuildInputs or [])
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
allPackages =
|
allPackages =
|
||||||
l.mapAttrs
|
l.mapAttrs
|
||||||
|
121
src/subsystems/rust/builders/devshell.nix
Normal file
121
src/subsystems/rust/builders/devshell.nix
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
{
|
||||||
|
# args
|
||||||
|
drv,
|
||||||
|
# d2n
|
||||||
|
externals,
|
||||||
|
# nixpkgs
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
libiconv,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
l = lib // builtins;
|
||||||
|
|
||||||
|
# function to merge two devshells
|
||||||
|
mergeShellConfig = base: other: let
|
||||||
|
c = base.config;
|
||||||
|
oc = other.config;
|
||||||
|
i = base.imports;
|
||||||
|
oi = other.imports;
|
||||||
|
hasCConfig = config: (config ? language) && (config.language ? c);
|
||||||
|
in {
|
||||||
|
config =
|
||||||
|
c
|
||||||
|
// oc
|
||||||
|
// {
|
||||||
|
packages = l.unique (c.packages ++ oc.packages);
|
||||||
|
commands = l.unique (c.commands ++ oc.commands);
|
||||||
|
env = l.unique (c.env ++ oc.env);
|
||||||
|
}
|
||||||
|
// l.optionalAttrs (hasCConfig c || hasCConfig oc) {
|
||||||
|
language.c = let
|
||||||
|
cConf = c.language.c;
|
||||||
|
ocConf = oc.language.c;
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
# 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 = [
|
||||||
|
"all"
|
||||||
|
"args"
|
||||||
|
"drvPath"
|
||||||
|
"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];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
mkShell conf
|
@ -98,5 +98,5 @@ in rec {
|
|||||||
# All dependencies in the Cargo.lock file, vendored
|
# All dependencies in the Cargo.lock file, vendored
|
||||||
vendoredDependencies = vendorDependencies allDependencies;
|
vendoredDependencies = vendorDependencies allDependencies;
|
||||||
|
|
||||||
copyVendorDir = path: ''cp -rs --no-preserve=mode,ownership ${vendoredDependencies} ${path}'';
|
copyVendorDir = from: to: ''cp -rs --no-preserve=mode,ownership ${from} ${to}'';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user