137 lines
4.7 KiB
Nix
137 lines
4.7 KiB
Nix
{ pkgs }:
|
|
|
|
let inherit (pkgs) bash coreutils findutils nix wget;
|
|
inherit (pkgs) callPackage fetchurl runCommand stdenv substituteAll writeText;
|
|
in
|
|
|
|
/* autonix is a collection of tools to automate packaging large collections
|
|
* of software, particularly KDE. It consists of three components:
|
|
* 1. a script (manifest) to download and hash the packages
|
|
* 2. a dependency scanner (autonix-deps) written in Haskell that examines
|
|
* the package sources and tries to guess their dependencies
|
|
* 3. a library of Nix routines (generateCollection) to generate Nix
|
|
* expressions from the output of the previous steps.
|
|
*/
|
|
|
|
let inherit (stdenv) lib; in
|
|
|
|
let
|
|
|
|
resolveDeps = scope: deps:
|
|
let resolve = dep:
|
|
let res = scope."${dep}" or [];
|
|
in if lib.isList res then res else [res];
|
|
in lib.concatMap resolve deps;
|
|
|
|
in rec {
|
|
|
|
/* Download the packages into the Nix store, compute their hashes,
|
|
* and generate a package manifest in ./manifest.nix.
|
|
*/
|
|
manifest =
|
|
let
|
|
script =
|
|
substituteAll
|
|
{
|
|
src = ./manifest.sh;
|
|
inherit bash coreutils findutils nix wget;
|
|
};
|
|
in
|
|
runCommand "autonix-manifest" {}
|
|
''
|
|
cp ${script} $out
|
|
chmod +x $out
|
|
'';
|
|
|
|
mkPackage = callPackage: defaultOverride: name: pkg: let drv =
|
|
{ mkDerivation, fetchurl, scope }:
|
|
|
|
mkDerivation (defaultOverride {
|
|
inherit (pkg) name;
|
|
|
|
src = fetchurl pkg.src;
|
|
|
|
buildInputs = resolveDeps scope pkg.buildInputs;
|
|
nativeBuildInputs = resolveDeps scope pkg.nativeBuildInputs;
|
|
propagatedBuildInputs = resolveDeps scope pkg.propagatedBuildInputs;
|
|
propagatedNativeBuildInputs =
|
|
resolveDeps scope pkg.propagatedNativeBuildInputs;
|
|
propagatedUserEnvPkgs = resolveDeps scope pkg.propagatedUserEnvPkgs;
|
|
|
|
enableParallelBuilding = true;
|
|
});
|
|
in callPackage drv {};
|
|
|
|
renameDeps = renames: lib.mapAttrs (name: pkg:
|
|
let breakCycles = lib.filter (dep: dep != name);
|
|
rename = dep: renames."${dep}" or dep;
|
|
in pkg // {
|
|
buildInputs = breakCycles (map rename pkg.buildInputs);
|
|
nativeBuildInputs = breakCycles (map rename pkg.nativeBuildInputs);
|
|
propagatedBuildInputs = breakCycles (map rename pkg.propagatedBuildInputs);
|
|
propagatedNativeBuildInputs =
|
|
breakCycles (map rename pkg.propagatedNativeBuildInputs);
|
|
propagatedUserEnvPkgs = breakCycles (map rename pkg.propagatedUserEnvPkgs);
|
|
});
|
|
|
|
propagateDeps = propagated: lib.mapAttrs (name: pkg:
|
|
let isPropagated = dep: lib.elem dep propagated;
|
|
isNotPropagated = dep: !(isPropagated dep);
|
|
in pkg // {
|
|
buildInputs = lib.filter isNotPropagated pkg.buildInputs;
|
|
nativeBuildInputs = lib.filter isNotPropagated pkg.nativeBuildInputs;
|
|
propagatedBuildInputs =
|
|
pkg.propagatedBuildInputs
|
|
++ lib.filter isPropagated pkg.buildInputs;
|
|
propagatedNativeBuildInputs =
|
|
pkg.propagatedNativeBuildInputs
|
|
++ lib.filter isPropagated pkg.nativeBuildInputs;
|
|
});
|
|
|
|
nativeDeps = native: lib.mapAttrs (name: pkg:
|
|
let isNative = dep: lib.elem dep native;
|
|
isNotNative = dep: !(isNative dep);
|
|
in pkg // {
|
|
buildInputs = lib.filter isNotNative pkg.buildInputs;
|
|
nativeBuildInputs =
|
|
pkg.nativeBuildInputs
|
|
++ lib.filter isNative pkg.buildInputs;
|
|
propagatedBuildInputs = lib.filter isNotNative pkg.propagatedBuildInputs;
|
|
propagatedNativeBuildInputs =
|
|
pkg.propagatedNativeBuildInputs
|
|
++ lib.filter isNative pkg.propagatedBuildInputs;
|
|
});
|
|
|
|
userEnvDeps = user: lib.mapAttrs (name: pkg:
|
|
let allDeps = with pkg; lib.concatLists [
|
|
buildInputs
|
|
nativeBuildInputs
|
|
propagatedBuildInputs
|
|
propagatedNativeBuildInputs
|
|
];
|
|
in assert (lib.isList allDeps); pkg // {
|
|
propagatedUserEnvPkgs = lib.filter (dep: lib.elem dep user) allDeps;
|
|
});
|
|
|
|
overrideDerivation = pkg: f: pkg.override (super: super // {
|
|
mkDerivation = drv: super.mkDerivation (drv // f drv);
|
|
});
|
|
|
|
extendDerivation = pkg: attrs:
|
|
let mergeAttrBy = lib.mergeAttrBy // {
|
|
propagatedNativeBuildInputs = a: b: a ++ b;
|
|
NIX_CFLAGS_COMPILE = a: b: "${a} ${b}";
|
|
cmakeFlags = a: b: a ++ b;
|
|
};
|
|
mergeAttrsByFunc = sets:
|
|
let merged = lib.foldl lib.mergeAttrByFunc { inherit mergeAttrBy; } sets;
|
|
in builtins.removeAttrs merged ["mergeAttrBy"];
|
|
in overrideDerivation pkg (drv: mergeAttrsByFunc [ drv attrs ]);
|
|
|
|
overrideScope = pkg: fnOrSet: pkg.override (super: super // {
|
|
scope = if builtins.isFunction fnOrSet
|
|
then super.scope // fnOrSet super.scope
|
|
else super.scope // fnOrSet;
|
|
});
|
|
}
|