mirror of
https://github.com/nix-community/dream2nix.git
synced 2024-11-23 09:04:37 +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"
|
||||
"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
|
||||
|
@ -121,6 +121,10 @@ in let
|
||||
subsystems = callPackageDream ./subsystems {};
|
||||
|
||||
externals = {
|
||||
devshell = {
|
||||
makeShell = import "${externalSources.devshell}/modules" pkgs;
|
||||
imports.c = "${externalSources.devshell}/extra/language/c.nix";
|
||||
};
|
||||
crane = let
|
||||
importLibFile = name: import "${externalSources.crane}/lib/${name}.nix";
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
lib,
|
||||
dlib,
|
||||
pkgs,
|
||||
callPackageDream,
|
||||
...
|
||||
} @ topArgs: {
|
||||
subsystemAttrs,
|
||||
@ -48,9 +49,10 @@
|
||||
cargoTestFlags = cargoBuildFlags;
|
||||
|
||||
cargoVendorDir = "../nix-vendor";
|
||||
dream2nixVendorDir = vendoring.vendoredDependencies;
|
||||
|
||||
postUnpack = ''
|
||||
${vendoring.copyVendorDir "./nix-vendor"}
|
||||
${vendoring.copyVendorDir "$dream2nixVendorDir" "./nix-vendor"}
|
||||
export CARGO_HOME=$(pwd)/.cargo_home
|
||||
'';
|
||||
|
||||
@ -66,16 +68,7 @@
|
||||
});
|
||||
|
||||
mkShellForPkg = pkg:
|
||||
pkg.overrideAttrs (old: {
|
||||
buildInputs =
|
||||
(old.buildInputs or [])
|
||||
++ (
|
||||
with pkg.passthru.rustToolchain; [
|
||||
cargo
|
||||
rustc
|
||||
]
|
||||
);
|
||||
});
|
||||
callPackageDream ../devshell.nix {drv = pkg;};
|
||||
|
||||
allPackages =
|
||||
l.mapAttrs
|
||||
|
@ -4,6 +4,7 @@
|
||||
lib,
|
||||
pkgs,
|
||||
externals,
|
||||
callPackageDream,
|
||||
...
|
||||
} @ topArgs: {
|
||||
subsystemAttrs,
|
||||
@ -83,8 +84,9 @@
|
||||
pnameSuffix = depsNameSuffix;
|
||||
# Make sure cargo only checks the package we want
|
||||
cargoCheckCommand = "cargo check --release --package ${pname}";
|
||||
dream2nixVendorDir = vendoring.vendoredDependencies;
|
||||
preUnpack = ''
|
||||
${vendoring.copyVendorDir "$cargoVendorDir"}
|
||||
${vendoring.copyVendorDir "$dream2nixVendorDir" "$cargoVendorDir"}
|
||||
'';
|
||||
# move the vendored dependencies folder to $out for main derivation to use
|
||||
postInstall = ''
|
||||
@ -103,7 +105,7 @@
|
||||
cargoArtifacts = deps;
|
||||
# link the vendor dir we used earlier to the correct place
|
||||
preUnpack = ''
|
||||
ln -sf ${deps}/nix-vendor $cargoVendorDir
|
||||
${vendoring.copyVendorDir "$cargoArtifacts/nix-vendor" "$cargoVendorDir"}
|
||||
'';
|
||||
# write our cargo lock
|
||||
# note: we don't do this in buildDepsOnly since
|
||||
@ -123,38 +125,11 @@
|
||||
# dependencies derivation. this could cause confusion for users.
|
||||
mkShellForPkg = pkg: let
|
||||
pkgDeps = pkg.passthru.dependencies;
|
||||
depsShell = callPackageDream ../devshell.nix {drv = pkgDeps;};
|
||||
mainShell = callPackageDream ../devshell.nix {drv = pkg;};
|
||||
shell = depsShell.combineWith mainShell;
|
||||
in
|
||||
pkg.overrideAttrs (old: {
|
||||
# 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 [])
|
||||
);
|
||||
});
|
||||
shell;
|
||||
|
||||
allPackages =
|
||||
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
|
||||
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