mirror of
https://github.com/nix-community/naersk
synced 2024-11-15 00:17:10 +00:00
Merge pull request #4 from nmattia/nm-wip-3
Avoid IFD as much as possible
This commit is contained in:
commit
5834403f4f
6 changed files with 209 additions and 80 deletions
54
build.nix
54
build.nix
|
@ -17,8 +17,8 @@ src:
|
||||||
, buildInputs ? []
|
, buildInputs ? []
|
||||||
, nativeBuildInputs ? []
|
, nativeBuildInputs ? []
|
||||||
, builtDependencies ? []
|
, builtDependencies ? []
|
||||||
, cargolockPath ? null
|
, cargolock ? null
|
||||||
, cargotomlPath ? null
|
, cargotoml ? null
|
||||||
, release ? true
|
, release ? true
|
||||||
, stdenv
|
, stdenv
|
||||||
, lib
|
, lib
|
||||||
|
@ -37,23 +37,34 @@ src:
|
||||||
with
|
with
|
||||||
{ builtinz =
|
{ builtinz =
|
||||||
builtins //
|
builtins //
|
||||||
import ./builtins.nix
|
import ./builtins
|
||||||
{ inherit lib writeText remarshal runCommand ; };
|
{ inherit lib writeText remarshal runCommand ; };
|
||||||
};
|
};
|
||||||
|
|
||||||
with rec
|
with rec
|
||||||
{
|
{
|
||||||
drv = stdenv.mkDerivation
|
drv = stdenv.mkDerivation (
|
||||||
{ inherit
|
{ inherit
|
||||||
src
|
src
|
||||||
doCheck
|
doCheck
|
||||||
nativeBuildInputs
|
nativeBuildInputs
|
||||||
cargolockPath
|
|
||||||
cargotomlPath
|
|
||||||
cratePaths
|
cratePaths
|
||||||
name
|
name
|
||||||
version;
|
version;
|
||||||
|
|
||||||
|
cargoconfig = builtinz.toTOML
|
||||||
|
{ source =
|
||||||
|
{ crates-io = { replace-with = "nix-sources"; } ;
|
||||||
|
nix-sources =
|
||||||
|
{ directory = symlinkJoin
|
||||||
|
{ name = "crates-io";
|
||||||
|
paths = map (v: unpackCrate v.name v.version v.sha256)
|
||||||
|
crateDependencies;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
outputs = [ "out" ] ++ lib.optional doDoc "doc";
|
outputs = [ "out" ] ++ lib.optional doDoc "doc";
|
||||||
preInstallPhases = lib.optional doDoc [ "docPhase" ];
|
preInstallPhases = lib.optional doDoc [ "docPhase" ];
|
||||||
|
|
||||||
|
@ -88,24 +99,24 @@ with rec
|
||||||
''
|
''
|
||||||
runHook preConfigure
|
runHook preConfigure
|
||||||
|
|
||||||
if [ -n "$cargolockPath" ]
|
if [ -n "$cargolock" ]
|
||||||
then
|
then
|
||||||
echo "Setting Cargo.lock"
|
echo "Setting Cargo.lock"
|
||||||
if [ -f "Cargo.lock" ]
|
if [ -f "Cargo.lock" ]
|
||||||
then
|
then
|
||||||
echo "WARNING: replacing existing Cargo.lock"
|
echo "WARNING: replacing existing Cargo.lock"
|
||||||
fi
|
fi
|
||||||
cp --no-preserve mode "$cargolockPath" Cargo.lock
|
echo "$cargolock" > Cargo.lock
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$cargotomlPath" ]
|
if [ -n "$cargotoml" ]
|
||||||
then
|
then
|
||||||
echo "Setting Cargo.toml"
|
echo "Setting Cargo.toml"
|
||||||
if [ -f "Cargo.toml" ]
|
if [ -f "Cargo.toml" ]
|
||||||
then
|
then
|
||||||
echo "WARNING: replacing existing Cargo.toml"
|
echo "WARNING: replacing existing Cargo.toml"
|
||||||
fi
|
fi
|
||||||
cp "$cargotomlPath" Cargo.toml
|
echo "$cargotoml" > Cargo.toml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p target
|
mkdir -p target
|
||||||
|
@ -127,7 +138,7 @@ with rec
|
||||||
export CARGO_HOME=''${CARGO_HOME:-$PWD/.cargo-home}
|
export CARGO_HOME=''${CARGO_HOME:-$PWD/.cargo-home}
|
||||||
mkdir -p $CARGO_HOME
|
mkdir -p $CARGO_HOME
|
||||||
|
|
||||||
cp --no-preserve mode ${cargoconfig} $CARGO_HOME/config
|
echo "$cargoconfig" > $CARGO_HOME/config
|
||||||
|
|
||||||
# TODO: figure out why "1" works whereas "0" doesn't
|
# TODO: figure out why "1" works whereas "0" doesn't
|
||||||
find . -type f -exec touch --date=@1 {} +
|
find . -type f -exec touch --date=@1 {} +
|
||||||
|
@ -209,7 +220,13 @@ with rec
|
||||||
|
|
||||||
runHook postInstall
|
runHook postInstall
|
||||||
'';
|
'';
|
||||||
};
|
} //
|
||||||
|
lib.optionalAttrs (! isNull cargolock )
|
||||||
|
{ cargolock = builtinz.toTOML cargolock; } //
|
||||||
|
lib.optionalAttrs (! isNull cargotoml )
|
||||||
|
{ cargotoml = builtinz.toTOML cargotoml; }
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
# XXX: the actual crate format is not documented but in practice is a
|
# XXX: the actual crate format is not documented but in practice is a
|
||||||
# gzipped tar; we simply unpack it and introduce a ".cargo-checksum.json"
|
# gzipped tar; we simply unpack it and introduce a ".cargo-checksum.json"
|
||||||
|
@ -227,18 +244,5 @@ with rec
|
||||||
tar -xvzf ${crate} -C $out
|
tar -xvzf ${crate} -C $out
|
||||||
echo '{"package":"${sha256}","files":{}}' > $out/${name}-${version}/.cargo-checksum.json
|
echo '{"package":"${sha256}","files":{}}' > $out/${name}-${version}/.cargo-checksum.json
|
||||||
'';
|
'';
|
||||||
|
|
||||||
cargoconfig = builtinz.writeTOML
|
|
||||||
{ source =
|
|
||||||
{ crates-io = { replace-with = "nix-sources"; } ;
|
|
||||||
nix-sources =
|
|
||||||
{ directory = symlinkJoin
|
|
||||||
{ name = "crates-io";
|
|
||||||
paths = map (v: unpackCrate v.name v.version v.sha256)
|
|
||||||
crateDependencies;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
if isNull override then drv else drv.overrideAttrs override
|
if isNull override then drv else drv.overrideAttrs override
|
||||||
|
|
|
@ -1,36 +1,33 @@
|
||||||
# some extra "builtins"
|
# some extra "builtins"
|
||||||
{ lib, writeText, runCommand, remarshal }:
|
{ lib
|
||||||
|
, writeText
|
||||||
|
, runCommand
|
||||||
|
, remarshal
|
||||||
|
}:
|
||||||
|
|
||||||
|
rec
|
||||||
{
|
{
|
||||||
# Nix < 2.3 cannot parse all TOML files
|
toTOML = import ./to-toml.nix { inherit lib; };
|
||||||
# https://github.com/NixOS/nix/issues/2901
|
writeTOML = attrs: writeText "write-toml" (toTOML attrs);
|
||||||
# can then be replaced with:
|
|
||||||
# readTOML = f: builtins.fromTOML (builtins.readFile f);
|
|
||||||
readTOML = f: builtins.fromJSON (builtins.readFile (runCommand "read-toml"
|
|
||||||
{ buildInputs = [ remarshal ];
|
|
||||||
allowSubstitutes = false;
|
|
||||||
preferLocalBuild = true;
|
|
||||||
}
|
|
||||||
''
|
|
||||||
remarshal \
|
|
||||||
-if toml \
|
|
||||||
-i ${f} \
|
|
||||||
-of json \
|
|
||||||
-o $out
|
|
||||||
''));
|
|
||||||
|
|
||||||
writeTOML = attrs: runCommand "write-toml"
|
readTOML = usePure: f:
|
||||||
{ buildInputs = [ remarshal ];
|
if usePure then
|
||||||
allowSubstitutes = false;
|
builtins.fromTOML (builtins.readFile f)
|
||||||
preferLocalBuild = true;
|
else
|
||||||
}
|
builtins.fromJSON (builtins.readFile (
|
||||||
''
|
runCommand "from-toml"
|
||||||
remarshal \
|
{ buildInputs = [ remarshal ];
|
||||||
-if json \
|
allowSubstitutes = false;
|
||||||
-i ${writeText "toml-json" (builtins.toJSON attrs)} \
|
preferLocalBuild = true;
|
||||||
-of toml \
|
}
|
||||||
-o $out
|
''
|
||||||
'';
|
echo "$from_toml_in" > in.toml
|
||||||
|
remarshal \
|
||||||
|
-if toml \
|
||||||
|
-i ${f} \
|
||||||
|
-of json \
|
||||||
|
-o $out
|
||||||
|
''));
|
||||||
|
|
||||||
writeJSON = name: attrs: writeText name
|
writeJSON = name: attrs: writeText name
|
||||||
(builtins.toJSON attrs);
|
(builtins.toJSON attrs);
|
130
builtins/to-toml.nix
Normal file
130
builtins/to-toml.nix
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
{ lib }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
length
|
||||||
|
elemAt
|
||||||
|
concatMap
|
||||||
|
all
|
||||||
|
concatLists
|
||||||
|
concatStringsSep
|
||||||
|
concatMapStringsSep
|
||||||
|
mapAttrsToList
|
||||||
|
;
|
||||||
|
inherit (builtins)
|
||||||
|
abort
|
||||||
|
match
|
||||||
|
toJSON
|
||||||
|
typeOf
|
||||||
|
;
|
||||||
|
|
||||||
|
quoteKey = k:
|
||||||
|
if match "[a-zA-Z]+" k == []
|
||||||
|
then k
|
||||||
|
else quoteString k;
|
||||||
|
|
||||||
|
quoteString = builtins.toJSON;
|
||||||
|
|
||||||
|
outputValInner = v:
|
||||||
|
let ty = tomlTy v; in
|
||||||
|
if ty == "set" then
|
||||||
|
let
|
||||||
|
vals = mapAttrsToList
|
||||||
|
(k': v': "${quoteKey k'} = ${outputValInner v'}") v;
|
||||||
|
valsStr = concatStringsSep ", " vals;
|
||||||
|
in
|
||||||
|
"{ ${valsStr} }" else
|
||||||
|
outputVal v;
|
||||||
|
|
||||||
|
outputVal = v:
|
||||||
|
let ty = tomlTy v; in
|
||||||
|
if ty == "bool" then
|
||||||
|
builtins.toJSON v
|
||||||
|
else
|
||||||
|
if ty == "string" then
|
||||||
|
quoteString v
|
||||||
|
else
|
||||||
|
if ty == "list" || ty == "list_of_attrs" then
|
||||||
|
let
|
||||||
|
vals = map quoteString v;
|
||||||
|
valsStr = concatStringsSep ", " vals;
|
||||||
|
in
|
||||||
|
"[ ${valsStr} ]" else
|
||||||
|
if ty == "set" then
|
||||||
|
abort "unsupported set for not-inner value"
|
||||||
|
else abort "Not implemented: type ${ty}"
|
||||||
|
;
|
||||||
|
|
||||||
|
outputKeyValInner = k: v:
|
||||||
|
let ty = tomlTy v; in
|
||||||
|
if ty == "set" then
|
||||||
|
let
|
||||||
|
vals = mapAttrsToList
|
||||||
|
(k': v': "${quoteKey k'} = ${outputValInner v'}") v;
|
||||||
|
valsStr = concatStringsSep ", " vals;
|
||||||
|
in
|
||||||
|
[ "${quoteKey k} = { ${valsStr} }" ] else
|
||||||
|
outputKeyVal k v;
|
||||||
|
|
||||||
|
# Returns a list of strings; one string per line
|
||||||
|
outputKeyVal = k: v:
|
||||||
|
let ty = tomlTy v; in
|
||||||
|
if ty == "bool" then
|
||||||
|
[ "${quoteKey k} = ${outputValInner v}" ]
|
||||||
|
else
|
||||||
|
if ty == "string" then
|
||||||
|
[ "${quoteKey k} = ${quoteString v}" ]
|
||||||
|
else
|
||||||
|
if ty == "list_of_attrs" then
|
||||||
|
concatMap (inner:
|
||||||
|
[ "[[${k}]]" ] ++
|
||||||
|
(concatLists (mapAttrsToList outputKeyValInner inner))) v
|
||||||
|
else
|
||||||
|
if ty == "list" then
|
||||||
|
let
|
||||||
|
vals = map quoteString v;
|
||||||
|
valsStr = concatStringsSep ", " vals;
|
||||||
|
in
|
||||||
|
[ "${quoteKey k} = [ ${valsStr} ]" ] else
|
||||||
|
if ty == "set" then
|
||||||
|
[ "[${k}]" ] ++
|
||||||
|
(concatLists (mapAttrsToList outputKeyValInner v))
|
||||||
|
else abort "Not implemented: type ${ty} for key ${k}"
|
||||||
|
;
|
||||||
|
|
||||||
|
tomlTy = x:
|
||||||
|
if typeOf x == "string" then "string" else
|
||||||
|
if typeOf x == "bool" then "bool" else
|
||||||
|
if typeOf x == "int" then "int" else
|
||||||
|
if typeOf x == "float" then "float" else
|
||||||
|
if typeOf x == "set" then
|
||||||
|
if lib.isDerivation x then "string" else "set" else
|
||||||
|
if typeOf x == "list" then
|
||||||
|
if length x == 0 then "list"
|
||||||
|
else
|
||||||
|
let ty = typeOf (elemAt x 0); in
|
||||||
|
#assert (all (v: typeOf v == ty) x);
|
||||||
|
if ty == "set" then "list_of_attrs" else "list"
|
||||||
|
else abort "Not implemented: toml type for ${typeOf x}";
|
||||||
|
|
||||||
|
toTOML = attrs:
|
||||||
|
assert (typeOf attrs == "set");
|
||||||
|
let
|
||||||
|
byTy = lib.foldl
|
||||||
|
(acc: x:
|
||||||
|
let ty = tomlTy x.v; in
|
||||||
|
acc // { "${ty}" = (acc.${ty} or []) ++ [ x ]; }
|
||||||
|
)
|
||||||
|
{} (mapAttrsToList (k: v: { inherit k v ; }) attrs);
|
||||||
|
in
|
||||||
|
concatMapStringsSep "\n"
|
||||||
|
(kv: concatStringsSep "\n" (outputKeyVal kv.k kv.v))
|
||||||
|
( (byTy.string or []) ++
|
||||||
|
(byTy.int or []) ++
|
||||||
|
(byTy.float or []) ++
|
||||||
|
(byTy.list or []) ++
|
||||||
|
(byTy.list_of_attrs or []) ++
|
||||||
|
(byTy.set or [])
|
||||||
|
)
|
||||||
|
;
|
||||||
|
in
|
||||||
|
toTOML
|
35
default.nix
35
default.nix
|
@ -36,7 +36,7 @@ with
|
||||||
with
|
with
|
||||||
{ builtinz =
|
{ builtinz =
|
||||||
builtins //
|
builtins //
|
||||||
import ./builtins.nix
|
import ./builtins
|
||||||
{ inherit lib writeText remarshal runCommand ; };
|
{ inherit lib writeText remarshal runCommand ; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,18 +44,17 @@ with
|
||||||
with rec
|
with rec
|
||||||
{
|
{
|
||||||
commonAttrs = src: attrs: rec
|
commonAttrs = src: attrs: rec
|
||||||
{ cargolockPath = attrs.cargolockPath or null;
|
{ usePureFromTOML = attrs.usePureFromTOML or true;
|
||||||
cargotomlPath = attrs.cargotomlPath or null;
|
cargolock = attrs.cargolock or null;
|
||||||
cargolock =
|
cargotoml = attrs.cargotoml or null;
|
||||||
if isNull cargolockPath then
|
cargolock' =
|
||||||
builtinz.readTOML "${src}/Cargo.lock"
|
if isNull cargolock then
|
||||||
else
|
builtinz.readTOML usePureFromTOML "${src}/Cargo.lock"
|
||||||
builtinz.readTOML cargolockPath;
|
else cargolock;
|
||||||
rootCargotoml =
|
rootCargotoml =
|
||||||
if isNull cargotomlPath then
|
if isNull cargotoml then
|
||||||
builtinz.readTOML "${src}/Cargo.toml"
|
builtinz.readTOML usePureFromTOML "${src}/Cargo.toml"
|
||||||
else
|
else cargotoml;
|
||||||
builtinz.readTOML cargotomlPath;
|
|
||||||
|
|
||||||
# All the Cargo.tomls, including the top-level one
|
# All the Cargo.tomls, including the top-level one
|
||||||
cargotomls =
|
cargotomls =
|
||||||
|
@ -68,7 +67,7 @@ with rec
|
||||||
lib.elem cargotoml.package.name attrs.targets
|
lib.elem cargotoml.package.name attrs.targets
|
||||||
else true
|
else true
|
||||||
) ( map
|
) ( map
|
||||||
(member: (builtinz.readTOML "${src}/${member}/Cargo.toml"))
|
(member: (builtinz.readTOML usePureFromTOML "${src}/${member}/Cargo.toml"))
|
||||||
members );
|
members );
|
||||||
|
|
||||||
# The list of paths to Cargo.tomls. If this is a workspace, the paths
|
# The list of paths to Cargo.tomls. If this is a workspace, the paths
|
||||||
|
@ -80,7 +79,7 @@ with rec
|
||||||
|
|
||||||
if isNull workspaceMembers then "."
|
if isNull workspaceMembers then "."
|
||||||
else lib.concatStringsSep "\n" workspaceMembers;
|
else lib.concatStringsSep "\n" workspaceMembers;
|
||||||
crateDependencies = libb.mkVersions cargolock;
|
crateDependencies = libb.mkVersions cargolock';
|
||||||
targetInstructions =
|
targetInstructions =
|
||||||
if builtins.hasAttr "targets" attrs then
|
if builtins.hasAttr "targets" attrs then
|
||||||
lib.concatMapStringsSep " " (target: "-p ${target}") attrs.targets
|
lib.concatMapStringsSep " " (target: "-p ${target}") attrs.targets
|
||||||
|
@ -102,7 +101,7 @@ with rec
|
||||||
version = (lib.head cargotomls).package.version;
|
version = (lib.head cargotomls).package.version;
|
||||||
inherit cratePaths crateDependencies cargoBuild;
|
inherit cratePaths crateDependencies cargoBuild;
|
||||||
} //
|
} //
|
||||||
(removeAttrs attrs [ "targets"])
|
(removeAttrs attrs [ "targets" "usePureFromTOML" ])
|
||||||
);
|
);
|
||||||
|
|
||||||
buildPackageIncremental = src: attrs:
|
buildPackageIncremental = src: attrs:
|
||||||
|
@ -163,12 +162,10 @@ with rec
|
||||||
{ cargoBuild = "source ${buildDepsScript}";
|
{ cargoBuild = "source ${buildDepsScript}";
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
copyBuildArtifacts = true;
|
copyBuildArtifacts = true;
|
||||||
cargolockPath = builtinz.writeTOML cargolock;
|
cargolock = cargolock';
|
||||||
cargotomlPath = builtinz.writeTOML
|
cargotoml =
|
||||||
(
|
|
||||||
{ package = { name = "dummy"; version = "0.0.0"; }; } //
|
{ package = { name = "dummy"; version = "0.0.0"; }; } //
|
||||||
{ dependencies = directDependencies; }
|
{ dependencies = directDependencies; }
|
||||||
)
|
|
||||||
;
|
;
|
||||||
name =
|
name =
|
||||||
if lib.length cargotomls == 0 then
|
if lib.length cargotomls == 0 then
|
||||||
|
|
2
lib.nix
2
lib.nix
|
@ -2,7 +2,7 @@
|
||||||
with
|
with
|
||||||
{ builtinz =
|
{ builtinz =
|
||||||
builtins //
|
builtins //
|
||||||
import ./builtins.nix
|
import ./builtins
|
||||||
{ inherit lib writeText remarshal runCommand ; };
|
{ inherit lib writeText remarshal runCommand ; };
|
||||||
};
|
};
|
||||||
rec
|
rec
|
||||||
|
|
13
test.nix
13
test.nix
|
@ -15,7 +15,7 @@ with rec
|
||||||
};
|
};
|
||||||
|
|
||||||
with
|
with
|
||||||
{ builtinz = builtins // pkgs.callPackage ./builtins.nix {}; };
|
{ builtinz = builtins // pkgs.callPackage ./builtins {}; };
|
||||||
|
|
||||||
rec
|
rec
|
||||||
{ rustfmt = naersk.buildPackage sources.rustfmt {};
|
{ rustfmt = naersk.buildPackage sources.rustfmt {};
|
||||||
|
@ -23,7 +23,7 @@ rec
|
||||||
{ buildInputs = [ rustfmt ]; }
|
{ buildInputs = [ rustfmt ]; }
|
||||||
"rustfmt --help && cargo-fmt --help && touch $out";
|
"rustfmt --help && cargo-fmt --help && touch $out";
|
||||||
|
|
||||||
ripgrep = naersk.buildPackage sources.ripgrep {};
|
ripgrep = naersk.buildPackage sources.ripgrep { usePureFromTOML = false; };
|
||||||
# XXX: executables are missing
|
# XXX: executables are missing
|
||||||
#ripgrep_test = pkgs.runCommand "ripgrep-test"
|
#ripgrep_test = pkgs.runCommand "ripgrep-test"
|
||||||
#{ buildInputs = [ ripgrep ]; }
|
#{ buildInputs = [ ripgrep ]; }
|
||||||
|
@ -98,7 +98,8 @@ rec
|
||||||
cargo =
|
cargo =
|
||||||
with rec
|
with rec
|
||||||
{ cargoSrc = sources.cargo;
|
{ cargoSrc = sources.cargo;
|
||||||
cargoCargoToml = builtinz.readTOML "${cargoSrc}/Cargo.toml";
|
# cannot use the pure readTOML
|
||||||
|
cargoCargoToml = builtinz.readTOML false "${cargoSrc}/Cargo.toml";
|
||||||
|
|
||||||
# XXX: this works around some hack that breaks the build. For more info
|
# XXX: this works around some hack that breaks the build. For more info
|
||||||
# on the hack, see
|
# on the hack, see
|
||||||
|
@ -109,11 +110,11 @@ rec
|
||||||
cargoCargoToml.dependencies;
|
cargoCargoToml.dependencies;
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoCargoLock = "${sources.rust}/Cargo.lock";
|
cargoCargoLock = builtinz.readTOML true "${sources.rust}/Cargo.lock";
|
||||||
};
|
};
|
||||||
naersk.buildPackage cargoSrc
|
naersk.buildPackage cargoSrc
|
||||||
{ cargolockPath = cargoCargoLock;
|
{ cargolock = cargoCargoLock;
|
||||||
cargotomlPath = builtinz.writeTOML cargoCargoToml';
|
cargotoml = cargoCargoToml';
|
||||||
|
|
||||||
# Tests fail, although cargo seems to operate normally
|
# Tests fail, although cargo seems to operate normally
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
|
|
Loading…
Reference in a new issue