From ccf72b853738cba2de2c4b22cfc1668792201bb3 Mon Sep 17 00:00:00 2001 From: Symphorien Gibol Date: Sat, 8 Sep 2018 14:14:56 +0200 Subject: fetchcargo: normalise cargo config to ensure determinism --- pkgs/build-support/rust/cargo-vendor-normalise.py | 32 +++++++++++++++++++++++ pkgs/build-support/rust/default.nix | 8 +++--- pkgs/build-support/rust/fetchcargo.nix | 13 +++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100755 pkgs/build-support/rust/cargo-vendor-normalise.py (limited to 'pkgs') diff --git a/pkgs/build-support/rust/cargo-vendor-normalise.py b/pkgs/build-support/rust/cargo-vendor-normalise.py new file mode 100755 index 00000000000..19463696856 --- /dev/null +++ b/pkgs/build-support/rust/cargo-vendor-normalise.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +import toml +import sys + +def escape(s): + return '"'+s.replace('"', r'\"').replace("\n", r"\n").replace("\\", "\\\\")+'"' + +data = toml.load(sys.stdin) + +assert list(data.keys()) == [ "source" ] + +# this value is non deterministic +data["source"]["vendored-sources"]["directory"] = "@vendor@" + +result = "" +inner = data["source"] +for source in sorted(inner.keys()): + result += '[source.{}]\n'.format(escape(source)) + if source == "vendored-sources": + result += '"directory" = "@vendor@"\n' + else: + for key in sorted(inner[source].keys()): + result += '{} = {}\n'.format(escape(key), escape(inner[source][key])) + result += "\n" + +real = toml.loads(result) +assert real == data, "output = {} while input = {}".format(real, data) + +print(result) + + diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index a2dc5df4d92..864e42c4761 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -1,7 +1,7 @@ -{ stdenv, cacert, git, rust, cargo-vendor }: +{ stdenv, cacert, git, rust, cargo-vendor, python3 }: let fetchcargo = import ./fetchcargo.nix { - inherit stdenv cacert git rust cargo-vendor; + inherit stdenv cacert git rust cargo-vendor python3; }; in { name, cargoSha256 ? "unset" @@ -69,8 +69,8 @@ in stdenv.mkDerivation (args // { mkdir .cargo '' + (if useRealVendorConfig then '' - sed "s|directory = \".*\"|directory = \"$(pwd)/$cargoDepsCopy\"|g" \ - "$(pwd)/$cargoDepsCopy/.cargo/config" > .cargo/config + substitute "$(pwd)/$cargoDepsCopy/.cargo/config" .cargo/config \ + --subst-var-by vendor "$(pwd)/$cargoDepsCopy" '' else '' cat >.cargo/config <<-EOF [source.crates-io] diff --git a/pkgs/build-support/rust/fetchcargo.nix b/pkgs/build-support/rust/fetchcargo.nix index 2d8a36a30ac..f04988a7dc1 100644 --- a/pkgs/build-support/rust/fetchcargo.nix +++ b/pkgs/build-support/rust/fetchcargo.nix @@ -1,5 +1,14 @@ -{ stdenv, cacert, git, rust, cargo-vendor }: +{ stdenv, cacert, git, rust, cargo-vendor, python3 }: { name ? "cargo-deps", src, srcs, patches, sourceRoot, sha256, cargoUpdateHook ? "", writeVendorConfig ? false }: +let cargo-vendor-normalise = stdenv.mkDerivation { + name = "cargo-vendor-normalise"; + src = ./cargo-vendor-normalise.py; + unpackPhase = ":"; + installPhase = "install -D $src $out/bin/cargo-vendor-normalise"; + buildInputs = [ (python3.withPackages(ps: [ ps.toml ])) ]; + preferLocalBuild = true; +}; +in stdenv.mkDerivation { name = "${name}-vendor"; nativeBuildInputs = [ cacert cargo-vendor git rust.cargo ]; @@ -27,7 +36,7 @@ stdenv.mkDerivation { cargo vendor $out > config '' + stdenv.lib.optionalString writeVendorConfig '' mkdir $out/.cargo - sed "s|directory = \".*\"|directory = \"./vendor\"|g" config > $out/.cargo/config + < config ${cargo-vendor-normalise}/bin/cargo-vendor-normalise > $out/.cargo/config ''; outputHashAlgo = "sha256"; -- cgit 1.4.1