From b2ca3da052e2251c469e7d33904b3392b2d58593 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sat, 29 Jul 2023 18:37:48 +0300 Subject: [PATCH] feat(rust): port crane builder --- modules/drv-parts/rust-crane/build.nix | 93 +++++++ modules/drv-parts/rust-crane/crane.nix | 104 ++++++++ modules/drv-parts/rust-crane/default.nix | 169 +++++++++++++ modules/drv-parts/rust-crane/devshell.nix | 81 +++++++ modules/drv-parts/rust-crane/interface.nix | 29 +++ .../rust-crane/patch-workspace-deps.jq | 48 ++++ modules/drv-parts/rust-crane/utils.nix | 228 ++++++++++++++++++ modules/drv-parts/rust-crane/vendor.nix | 145 +++++++++++ modules/drvs/ripgrep/default.nix | 3 +- .../default.nix | 4 +- 10 files changed, 900 insertions(+), 4 deletions(-) create mode 100644 modules/drv-parts/rust-crane/build.nix create mode 100644 modules/drv-parts/rust-crane/crane.nix create mode 100644 modules/drv-parts/rust-crane/default.nix create mode 100644 modules/drv-parts/rust-crane/devshell.nix create mode 100644 modules/drv-parts/rust-crane/interface.nix create mode 100644 modules/drv-parts/rust-crane/patch-workspace-deps.jq create mode 100644 modules/drv-parts/rust-crane/utils.nix create mode 100644 modules/drv-parts/rust-crane/vendor.nix diff --git a/modules/drv-parts/rust-crane/build.nix b/modules/drv-parts/rust-crane/build.nix new file mode 100644 index 00000000..a184c690 --- /dev/null +++ b/modules/drv-parts/rust-crane/build.nix @@ -0,0 +1,93 @@ +{ + lib, + crane, + utils, + vendoring, + # lock data + subsystemAttrs, + packages, + ... +}: let + l = lib // builtins; + + buildPackage = pname: version: let + replacePaths = + utils.replaceRelativePathsWithAbsolute + subsystemAttrs.relPathReplacements.${pname}.${version}; + writeGitVendorEntries = vendoring.writeGitVendorEntries "nix-sources"; + + # common args we use for both buildDepsOnly and buildPackage + common = { + inherit pname version; + + src = utils.getRootSource pname version; + cargoVendorDir = "$TMPDIR/nix-vendor"; + installCargoArtifactsMode = "use-zstd"; + + postUnpack = '' + export CARGO_HOME=$(pwd)/.cargo_home + export cargoVendorDir="$TMPDIR/nix-vendor" + ''; + preConfigure = '' + ${writeGitVendorEntries} + ${replacePaths} + ''; + + cargoTestProfile = "release"; + cargoBuildProfile = "release"; + + # Make sure cargo only builds & tests the package we want + cargoBuildCommand = "cargo build \${cargoBuildFlags:-} --profile \${cargoBuildProfile} --package ${pname}"; + cargoTestCommand = "cargo test \${cargoTestFlags:-} --profile \${cargoTestProfile} --package ${pname}"; + }; + + # The deps-only derivation will use this as a prefix to the `pname` + depsNameSuffix = "-deps"; + depsArgs = + common + // { + # we pass cargoLock path to buildDepsOnly + # so that crane's mkDummySrc adds it to the dummy source + inherit (utils) cargoLock; + pnameSuffix = depsNameSuffix; + # Make sure cargo only checks the package we want + cargoCheckCommand = "cargo check \${cargoBuildFlags:-} --profile \${cargoBuildProfile} --package ${pname}"; + dream2nixVendorDir = vendoring.vendoredDependencies; + preUnpack = '' + ${vendoring.copyVendorDir "$dream2nixVendorDir" common.cargoVendorDir} + ''; + # move the vendored dependencies folder to $out for main derivation to use + postInstall = '' + mv $TMPDIR/nix-vendor $out/nix-vendor + ''; + }; + deps = crane.buildDepsOnly depsArgs; + + buildArgs = + common + // { + meta = utils.getMeta pname version; + cargoArtifacts = deps; + # link the vendor dir we used earlier to the correct place + preUnpack = '' + ${vendoring.copyVendorDir "$cargoArtifacts/nix-vendor" common.cargoVendorDir} + ''; + # write our cargo lock + # note: we don't do this in buildDepsOnly since + # that uses a cargoLock argument instead + preConfigure = '' + ${common.preConfigure} + ${utils.writeCargoLock} + ''; + passthru = {dependencies = deps;}; + }; + build = crane.buildPackage buildArgs; + in + build; + + allPackages = + l.mapAttrs + (name: version: {"${version}" = buildPackage name version;}) + packages; +in + allPackages diff --git a/modules/drv-parts/rust-crane/crane.nix b/modules/drv-parts/rust-crane/crane.nix new file mode 100644 index 00000000..1838bf94 --- /dev/null +++ b/modules/drv-parts/rust-crane/crane.nix @@ -0,0 +1,104 @@ +{ + lib, + craneSource, + # nixpkgs + cargo, + makeSetupHook, + runCommand, + runCommandLocal, + writeText, + stdenv, + zstd, + jq, + remarshal, +}: let + importLibFile = name: import "${craneSource}/lib/${name}.nix"; + + makeHook = attrs: name: + makeSetupHook + ({inherit name;} // attrs) + "${craneSource}/lib/setupHooks/${name}.sh"; + genHooks = names: attrs: lib.genAttrs names (makeHook attrs); + + crane = rec { + otherHooks = + genHooks [ + "cargoHelperFunctionsHook" + "configureCargoCommonVarsHook" + "configureCargoVendoredDepsHook" + "removeReferencesToVendoredSourcesHook" + ] + {}; + installHooks = + genHooks [ + "inheritCargoArtifactsHook" + "installCargoArtifactsHook" + ] + { + substitutions = { + zstd = "${zstd}/bin/zstd"; + }; + }; + installLogHook = genHooks ["installFromCargoBuildLogHook"] { + substitutions = { + cargo = "${cargo}/bin/cargo"; + jq = "${jq}/bin/jq"; + }; + }; + + # These aren't used by dream2nix + crateNameFromCargoToml = null; + vendorCargoDeps = null; + + writeTOML = importLibFile "writeTOML" { + inherit runCommand; + pkgsBuildBuild = {inherit remarshal;}; + }; + cleanCargoToml = importLibFile "cleanCargoToml" {}; + findCargoFiles = importLibFile "findCargoFiles" { + inherit lib; + }; + mkDummySrc = importLibFile "mkDummySrc" { + inherit writeText runCommandLocal lib; + inherit writeTOML cleanCargoToml findCargoFiles; + }; + + mkCargoDerivation = importLibFile "mkCargoDerivation" { + inherit stdenv zstd cargo; + inherit + (installHooks) + inheritCargoArtifactsHook + installCargoArtifactsHook + ; + inherit + (otherHooks) + configureCargoCommonVarsHook + configureCargoVendoredDepsHook + cargoHelperFunctionsHook + ; + inherit crateNameFromCargoToml vendorCargoDeps; + }; + buildDepsOnly = importLibFile "buildDepsOnly" { + inherit lib; + inherit + mkCargoDerivation + crateNameFromCargoToml + vendorCargoDeps + mkDummySrc + ; + }; + buildPackage = importLibFile "buildPackage" { + inherit lib jq; + inherit (installLogHook) installFromCargoBuildLogHook; + inherit + buildDepsOnly + crateNameFromCargoToml + vendorCargoDeps + mkCargoDerivation + ; + inherit (otherHooks) removeReferencesToVendoredSourcesHook; + }; + }; +in { + inherit (crane) buildPackage buildDepsOnly; +} diff --git a/modules/drv-parts/rust-crane/default.nix b/modules/drv-parts/rust-crane/default.nix new file mode 100644 index 00000000..f7997409 --- /dev/null +++ b/modules/drv-parts/rust-crane/default.nix @@ -0,0 +1,169 @@ +{ + config, + lib, + extendModules, + ... +}: let + l = lib // builtins; + + cfg = config.rust-crane; + + dreamLock = config.rust-cargo-lock.dreamLock; + + fetchDreamLockSources = + import ../../../lib/internal/fetchDreamLockSources.nix + {inherit lib;}; + getDreamLockSource = import ../../../lib/internal/getDreamLockSource.nix {inherit lib;}; + readDreamLock = import ../../../lib/internal/readDreamLock.nix {inherit lib;}; + hashPath = import ../../../lib/internal/hashPath.nix { + inherit lib; + inherit (config.deps) runCommandLocal nix; + }; + hashFile = import ../../../lib/internal/hashFile.nix { + inherit lib; + inherit (config.deps) runCommandLocal nix; + }; + + # fetchers + fetchers = { + git = import ../../../lib/internal/fetchers/git { + inherit hashPath; + inherit (config.deps) fetchgit; + }; + crates-io = import ../../../lib/internal/fetchers/crates-io { + inherit hashFile; + inherit (config.deps) fetchurl runCommandLocal; + }; + path = import ../../../lib/internal/fetchers/path { + inherit hashPath; + }; + }; + + dreamLockLoaded = readDreamLock {inherit dreamLock;}; + dreamLockInterface = dreamLockLoaded.interface; + + inherit (dreamLockInterface) defaultPackageName defaultPackageVersion; + + fetchedSources' = fetchDreamLockSources { + inherit defaultPackageName defaultPackageVersion; + inherit (dreamLockLoaded.lock) sources; + inherit fetchers; + }; + + fetchedSources = + fetchedSources' + // { + ${defaultPackageName}.${defaultPackageVersion} = config.mkDerivation.src; + }; + + getSource = getDreamLockSource fetchedSources; + + toTOML = import ../../../lib/internal/toTOML.nix {inherit lib;}; + + utils = import ./utils.nix { + inherit dreamLock getSource lib toTOML; + inherit + (dreamLockInterface) + getSourceSpec + getRoot + subsystemAttrs + packages + ; + inherit + (config.deps) + writeText + ; + sourceRoot = config.mkDerivation.src; + }; + + vendoring = import ./vendor.nix { + inherit dreamLock getSource lib; + inherit + (dreamLockInterface) + getSourceSpec + subsystemAttrs + ; + inherit + (config.deps) + cargo + jq + moreutils + python3Packages + runCommandLocal + writePython3 + ; + }; + + allPackages = import ./build.nix { + inherit lib utils vendoring; + inherit (dreamLockInterface) subsystemAttrs packages; + inherit (config.deps) crane; + }; + + selectedPackage = allPackages.${config.name}.${config.version}; +in { + public = lib.mkForce { + type = "derivation"; + inherit config extendModules; + inherit (config) name version; + inherit + (selectedPackage) + drvPath + outPath + outputs + outputName + meta + passthru + ; + }; + + deps = {nixpkgs, ...}: + (l.mapAttrs (_: l.mkDefault) { + cargo = nixpkgs.cargo; + craneSource = config.deps.fetchFromGitHub { + owner = "ipetkov"; + repo = "crane"; + rev = "v0.12.2"; + sha256 = "sha256-looLH5MdY4erLiJw0XwQohGdr0fJL9y6TJY3898RA2U="; + }; + crane = import ./crane.nix { + inherit lib; + inherit + (config.deps) + craneSource + stdenv + cargo + jq + zstd + remarshal + makeSetupHook + writeText + runCommand + runCommandLocal + ; + }; + }) + # maybe it would be better to put these under `options.rust-crane.deps` instead of this `deps` + # since it conflicts with a lot of stuff? + // (l.mapAttrs (_: l.mkOverride 999) { + inherit + (nixpkgs) + stdenv + fetchurl + jq + zstd + remarshal + moreutils + python3Packages + makeSetupHook + runCommandLocal + runCommand + writeText + fetchFromGitHub + ; + inherit + (nixpkgs.writers) + writePython3 + ; + }); +} diff --git a/modules/drv-parts/rust-crane/devshell.nix b/modules/drv-parts/rust-crane/devshell.nix new file mode 100644 index 00000000..e1e890c9 --- /dev/null +++ b/modules/drv-parts/rust-crane/devshell.nix @@ -0,0 +1,81 @@ +{ + # args + drvs, + name, + # nixpkgs + lib, + libiconv, + mkShell, + ... +}: let + l = lib // builtins; + + # illegal env names to be removed and not be added to the devshell + illegalEnvNames = + [ + "src" + "name" + "pname" + "version" + "args" + "stdenv" + "builder" + "outputs" + "phases" + # cargo artifact and vendoring derivations + # we don't need these in the devshell + "cargoArtifacts" + "dream2nixVendorDir" + "cargoVendorDir" + ] + ++ ( + l.map + (phase: "${phase}Phase") + ["configure" "build" "check" "install" "fixup" "unpack"] + ) + ++ l.flatten ( + l.map + (phase: ["pre${phase}" "post${phase}"]) + ["Configure" "Build" "Check" "Install" "Fixup" "Unpack"] + ); + 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.drvAttrs + ); + combineEnvs = envs: + l.foldl' + ( + all: env: let + mergeInputs = name: (all.${name} or []) ++ (env.${name} or []); + in + all + // env + // { + buildInputs = mergeInputs "buildInputs"; + nativeBuildInputs = mergeInputs "nativeBuildInputs"; + propagatedBuildInputs = mergeInputs "propagatedBuildInputs"; + propagatedNativeBuildInputs = mergeInputs "propagatedNativeBuildInputs"; + } + ) + {} + envs; + _shellEnv = combineEnvs (l.map getEnvs drvs); + shellEnv = + _shellEnv + // { + inherit name; + passthru.env = _shellEnv; + }; +in + (mkShell.override {stdenv = (l.head drvs).stdenv;}) shellEnv diff --git a/modules/drv-parts/rust-crane/interface.nix b/modules/drv-parts/rust-crane/interface.nix new file mode 100644 index 00000000..e0cbbc22 --- /dev/null +++ b/modules/drv-parts/rust-crane/interface.nix @@ -0,0 +1,29 @@ +{ + config, + lib, + ... +}: let + l = lib // builtins; + t = l.types; +in { + options.deps = { + cargo = l.mkOption { + type = t.package; + description = "The Cargo package to use"; + }; + craneSource = l.mkOption { + type = t.path; + }; + crane = { + buildPackage = l.mkOption { + type = t.functionTo t.package; + }; + buildDepsOnly = l.mkOption { + type = t.functionTo t.package; + }; + }; + }; + + options.rust-crane = { + }; +} diff --git a/modules/drv-parts/rust-crane/patch-workspace-deps.jq b/modules/drv-parts/rust-crane/patch-workspace-deps.jq new file mode 100644 index 00000000..0eb57d74 --- /dev/null +++ b/modules/drv-parts/rust-crane/patch-workspace-deps.jq @@ -0,0 +1,48 @@ +def normalizeWorkspaceDep: + if ($workspaceDependencies."\(.key)" | type) == "object" + then [.value, $workspaceDependencies."\(.key)"] | add + else [.value, {"version":$workspaceDependencies."\(.key)"}] | add + end + # remove workspace option from the dependency + | del(.workspace) +; + +# normalizes workspace inherited dependencies for one list +def mapWorkspaceDepsFor(name): + if has(name) + then + ."\(name)" = ( + ."\(name)" + | to_entries + | map( + if (.value | type) == "object" and .value.workspace == true + then .value = (. | normalizeWorkspaceDep) + else . + end + ) + | from_entries + ) + else . + end +; + +# shorthand for normalizing all the dependencies list +def mapWorkspaceDeps: + mapWorkspaceDepsFor("dependencies") + | mapWorkspaceDepsFor("dev-dependencies") + | mapWorkspaceDepsFor("build-dependencies") +; + +# normalize workspace inherited deps +mapWorkspaceDeps +| if has("target") + then + # normalize workspace inherited deps in target specific deps + .target = ( + .target + | to_entries + | map(.value = (.value | mapWorkspaceDeps)) + | from_entries + ) + else . + end diff --git a/modules/drv-parts/rust-crane/utils.nix b/modules/drv-parts/rust-crane/utils.nix new file mode 100644 index 00000000..6c777b97 --- /dev/null +++ b/modules/drv-parts/rust-crane/utils.nix @@ -0,0 +1,228 @@ +{ + dreamLock, + getSourceSpec, + getSource, + getRoot, + sourceRoot, + subsystemAttrs, + packages, + lib, + toTOML, + writeText, + ... +}: let + l = lib // builtins; + isInPackages = name: version: (packages.${name} or null) == version; + # a make overridable for rust derivations specifically + makeOverridable = f: origArgs: let + result = f origArgs; + + # Creates a functor with the same arguments as f + copyArgs = g: l.setFunctionArgs g (l.functionArgs f); + # Changes the original arguments with (potentially a function that returns) a set of new attributes + overrideWith = newArgs: + origArgs + // ( + if l.isFunction newArgs + then newArgs origArgs + else newArgs + ); + + # Re-call the function but with different arguments + overrideArgs = copyArgs (newArgs: makeOverridable f (overrideWith newArgs)); + # Change the result of the function call by applying g to it + overrideResult = g: makeOverridable (copyArgs (args: g (f args))) origArgs; + in + result.derivation + // { + override = args: + overrideArgs { + args = + origArgs.args + // ( + if l.isFunction args + then args origArgs.args + else args + ); + }; + overrideRustToolchain = f: overrideArgs {toolchain = f origArgs.toolchain;}; + overrideAttrs = fdrv: overrideResult (x: {derivation = x.derivation.overrideAttrs fdrv;}); + }; +in rec { + getMeta = pname: version: let + meta = subsystemAttrs.meta.${pname}.${version}; + in + meta + // { + license = l.map (name: l.licenses.${name}) meta.license; + }; + + # Gets the root source for a package + getRootSource = pname: version: let + root = getRoot pname version; + in + getSource root.pname root.version; + + # Generates a script that replaces relative path dependency paths with absolute + # ones, if the path dependency isn't in the source dream2nix provides + replaceRelativePathsWithAbsolute = replacements: let + replace = + l.concatStringsSep + " \\\n" + ( + l.mapAttrsToList + ( + # TODO: this is not great, because it forces us to include the entire + # sourceRoot here, which could possibly cause more rebuilds than necessary + # when source is changed (although this mostly depends on how the project + # repository is structured). doing this properly is pretty complex, but + # it should still be done later. + from: relPath: ''--replace "\"${from}\"" "\"${sourceRoot}/${relPath}\""'' + ) + replacements + ); + in '' + substituteInPlace ./Cargo.toml \ + ${replace} + ''; + + mkBuildWithToolchain = mkBuildFunc: let + buildWithToolchain = args: + makeOverridable + (args: { + derivation = + (mkBuildFunc args.toolchain) + ( + args.args + // { + passthru = + (args.args.passthru or {}) + // {rustToolchain = args.toolchain;}; + } + ); + }) + args; + in + buildWithToolchain; + + # Backup original Cargo.lock if it exists and write our own one + writeCargoLock = '' + mv -f Cargo.lock Cargo.lock.orig || echo "no Cargo.lock" + cat ${cargoLock} > Cargo.lock + ''; + + # The Cargo.lock for this dreamLock. + cargoLock = let + mkPkgEntry = { + name, + version, + ... + } @ args: let + # constructs source string for dependency + makeSource = sourceSpec: let + source = + if sourceSpec.type == "crates-io" + then "registry+https://github.com/rust-lang/crates.io-index" + else if sourceSpec.type == "git" + then let + gitSpec = + l.findFirst + (src: src.url == sourceSpec.url && src.sha == sourceSpec.rev) + (throw "no git source: ${sourceSpec.url}#${sourceSpec.rev}") + (subsystemAttrs.gitSources or {}); + refPart = + l.optionalString + (gitSpec ? type) + "?${gitSpec.type}=${gitSpec.value}"; + in "git+${sourceSpec.url}${refPart}#${sourceSpec.rev}" + else null; + in + source; + # constructs source string for dependency entry + makeDepSource = sourceSpec: + if sourceSpec.type == "crates-io" + then makeSource sourceSpec + else if sourceSpec.type == "git" + then l.concatStringsSep "#" (l.init (l.splitString "#" (makeSource sourceSpec))) + else null; + # removes source type information from the version + normalizeVersion = version: srcType: l.removeSuffix ("$" + srcType) version; + + sourceSpec = getSourceSpec name version; + + normalizedVersion = normalizeVersion version sourceSpec.type; + + source = let + src = makeSource sourceSpec; + in + if src == null + then throw "source type '${sourceSpec.type}' not supported" + else src; + dependencies = + l.map + ( + dep: let + depSourceSpec = getSourceSpec dep.name dep.version; + depSource = makeDepSource depSourceSpec; + + normalizedDepVersion = normalizeVersion dep.version depSourceSpec.type; + + hasMultipleVersions = + l.length (l.attrValues dreamLock.sources.${dep.name}) > 1; + hasDuplicateVersions = dep.version != normalizedDepVersion; + + # only put version if there are different versions of the dep + versionString = + l.optionalString hasMultipleVersions " ${normalizedDepVersion}"; + # only put source if there are duplicate versions of the dep + # cargo vendor does not support this anyway and so builds will fail + # until https://github.com/rust-lang/cargo/issues/10310 is resolved. + srcString = + l.optionalString hasDuplicateVersions " (${depSource})"; + in "${dep.name}${versionString}${srcString}" + ) + args.dependencies; + + isMainPackage = isInPackages name version; + in + { + name = sourceSpec.pname or name; + version = sourceSpec.version or normalizedVersion; + } + # put dependencies like how cargo expects them + // ( + l.optionalAttrs + (l.length dependencies > 0) + {inherit dependencies;} + ) + // ( + l.optionalAttrs + (sourceSpec.type != "path" && !isMainPackage) + {inherit source;} + ) + // ( + l.optionalAttrs + (sourceSpec.type == "crates-io" && !isMainPackage) + {checksum = sourceSpec.hash;} + ); + package = l.flatten ( + l.mapAttrsToList + ( + name: versions: + l.mapAttrsToList + ( + version: dependencies: + mkPkgEntry {inherit name version dependencies;} + ) + versions + ) + dreamLock.dependencies + ); + lockTOML = toTOML { + # the lockfile we generate is of version 3 + version = 3; + inherit package; + }; + in + writeText "Cargo.lock" lockTOML; +} diff --git a/modules/drv-parts/rust-crane/vendor.nix b/modules/drv-parts/rust-crane/vendor.nix new file mode 100644 index 00000000..caf12e66 --- /dev/null +++ b/modules/drv-parts/rust-crane/vendor.nix @@ -0,0 +1,145 @@ +{ + lib, + getSource, + getSourceSpec, + subsystemAttrs, + dreamLock, + moreutils, + writePython3, + python3Packages, + runCommandLocal, + ... +} @ args: let + l = lib // builtins; + + allDependencies = + l.flatten + ( + l.mapAttrsToList + ( + name: versions: + l.map (version: {inherit name version;}) (l.attrNames versions) + ) + dreamLock.dependencies + ); +in rec { + # Generates a shell script that writes git vendor entries to .cargo/config. + # `replaceWith` is the name of the vendored source(s) to use. + writeGitVendorEntries = replaceWith: let + makeEntry = source: '' + [source."${source.url}${l.optionalString (source ? type) "?${source.type}=${source.value}"}"] + replace-with = "${replaceWith}" + git = "${source.url}" + ${l.optionalString (source ? type) "${source.type} = \"${source.value}\""} + ''; + entries = l.map makeEntry subsystemAttrs.gitSources; + in '' + echo "Writing git vendor entries to $CARGO_HOME/config.toml" + mkdir -p $CARGO_HOME && touch $CARGO_HOME/config.toml + cat >> $CARGO_HOME/config.toml <&2 echo "Cannot find path for crate '${pkg.name}-${pkg.version}' in the tree in: $tree" + exit 1 + fi + else + # we need to patch dependencies with `workspace = true` (workspace inheritance) + workspaceDependencies="$(cat "$tree/Cargo.toml" | ${tomlToJson} | ${jq} -cr '.workspace.dependencies')" + if [[ "$workspaceDependencies" != "null" ]]; then + tree="$(pwd)/${pkg.name}-${pkg.version}" + cp -prd --no-preserve=mode,ownership "$(dirname $crateCargoTOML)" "$tree" + crateCargoTOML="$tree/Cargo.toml" + cat "$crateCargoTOML" \ + | ${tomlToJson} \ + | ${jq} -cr --argjson workspaceDependencies "$workspaceDependencies" \ + --from-file ${./patch-workspace-deps.jq} \ + | ${jsonToToml} \ + | ${sponge} "$crateCargoTOML" + fi + fi + echo Found crate ${pkg.name} at $crateCargoTOML + tree="$(dirname $crateCargoTOML)" + ''; + makeScript = source: let + isGit = source.spec.type == "git"; + isPath = source.spec.type == "path"; + in + l.optionalString (!isPath) '' + tree="${source.path}" + ${l.optionalString isGit (findCrateSource source)} + echo Vendoring crate ${source.name} + if [ -d $out/${source.name} ]; then + echo Crate is already vendored + echo Crates with duplicate versions cannot be vendored as Cargo does not support this behaviour + exit 1 + else + cp -prd "$tree" $out/${source.name} + chmod u+w $out/${source.name} + ${l.optionalString isGit "printf '{\"files\":{},\"package\":null}' > $out/${source.name}/.cargo-checksum.json"} + fi + ''; + in + runCommandLocal "vendor" {} '' + mkdir -p $out + + ${ + l.concatMapStringsSep "\n" + makeScript + sources + } + ''; + + # All dependencies in the Cargo.lock file, vendored + vendoredDependencies = vendorDependencies allDependencies; + + copyVendorDir = from: to: ''cp -rs --no-preserve=mode,ownership ${from} ${to}''; +} diff --git a/modules/drvs/ripgrep/default.nix b/modules/drvs/ripgrep/default.nix index fd0dc0f8..21706856 100644 --- a/modules/drvs/ripgrep/default.nix +++ b/modules/drvs/ripgrep/default.nix @@ -7,12 +7,11 @@ in { imports = [ ../../drv-parts/rust-cargo-lock - ../../drv-parts/buildRustPackage + ../../drv-parts/rust-crane ]; deps = {nixpkgs, ...}: { inherit (nixpkgs) fetchFromGitHub; - inherit (nixpkgs) stdenv; }; name = l.mkForce "ripgrep"; diff --git a/modules/drvs/rust-workspace-version-inheritance/default.nix b/modules/drvs/rust-workspace-version-inheritance/default.nix index 025f6953..8ad2ae5f 100644 --- a/modules/drvs/rust-workspace-version-inheritance/default.nix +++ b/modules/drvs/rust-workspace-version-inheritance/default.nix @@ -8,7 +8,7 @@ in { imports = [ dream2nix.modules.drv-parts.rust-cargo-lock - dream2nix.modules.drv-parts.buildRustPackage + dream2nix.modules.drv-parts.rust-crane ]; mkDerivation = { @@ -23,5 +23,5 @@ in { }; name = "app"; - version = "1.0.0"; + version = "0.1.0"; }