Merge pull request #391 from nix-community/refactor/use-flake-parts

This commit is contained in:
Yusuf Bera Ertan 2022-11-22 18:25:05 +03:00 committed by GitHub
commit 4e3d3b572e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1233 additions and 1174 deletions

View File

@ -20,7 +20,7 @@
}; };
makeOutputs = pkgs: let makeOutputs = pkgs: let
outputs = (initD2N pkgs).makeOutputs { outputs = (initD2N pkgs).dream2nix-interface.makeOutputs {
source = inp.src; source = inp.src;
settings = [ settings = [
{ {

View File

@ -93,6 +93,24 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1668450977,
"narHash": "sha256-cfLhMhnvXn6x1vPm+Jow3RiFAUSCw/l1utktCw5rVA4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "d591857e9d7dd9ddbfba0ea02b43b927c3c0f1fa",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils-pre-commit": { "flake-utils-pre-commit": {
"locked": { "locked": {
"lastModified": 1644229661, "lastModified": 1644229661,
@ -186,6 +204,24 @@
"type": "indirect" "type": "indirect"
} }
}, },
"nixpkgs-lib": {
"locked": {
"dir": "lib",
"lastModified": 1665349835,
"narHash": "sha256-UK4urM3iN80UXQ7EaOappDzcisYIuEURFRoGQ/yPkug=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "34c5293a71ffdb2fe054eb5288adc1882c1eb0b1",
"type": "github"
},
"original": {
"dir": "lib",
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"poetry2nix": { "poetry2nix": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -232,6 +268,7 @@
"all-cabal-json": "all-cabal-json", "all-cabal-json": "all-cabal-json",
"crane": "crane", "crane": "crane",
"devshell": "devshell", "devshell": "devshell",
"flake-parts": "flake-parts",
"flake-utils-pre-commit": "flake-utils-pre-commit", "flake-utils-pre-commit": "flake-utils-pre-commit",
"ghc-utils": "ghc-utils", "ghc-utils": "ghc-utils",
"gomod2nix": "gomod2nix", "gomod2nix": "gomod2nix",

444
flake.nix
View File

@ -9,6 +9,8 @@
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable"; nixpkgs.url = "nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
### dev dependencies ### dev dependencies
alejandra.url = "github:kamadorueda/alejandra"; alejandra.url = "github:kamadorueda/alejandra";
alejandra.inputs.nixpkgs.follows = "nixpkgs"; alejandra.inputs.nixpkgs.follows = "nixpkgs";
@ -64,6 +66,7 @@
self, self,
alejandra, alejandra,
devshell, devshell,
flake-parts,
gomod2nix, gomod2nix,
mach-nix, mach-nix,
nixpkgs, nixpkgs,
@ -74,19 +77,10 @@
ghc-utils, ghc-utils,
... ...
} @ inp: let } @ inp: let
b = builtins;
l = lib // builtins; l = lib // builtins;
lib = nixpkgs.lib; lib = nixpkgs.lib;
supportedSystems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"];
forSystems = systems: f:
lib.genAttrs systems
(system: f system nixpkgs.legacyPackages.${system});
forAllSystems = forSystems supportedSystems;
# To use dream2nix in non-flake + non-IFD enabled repos, the source code of dream2nix # To use dream2nix in non-flake + non-IFD enabled repos, the source code of dream2nix
# must be installed into these repos (using nix run dream2nix#install). # must be installed into these repos (using nix run dream2nix#install).
# The problem is, all of dream2nix' dependecies need to be installed as well. # The problem is, all of dream2nix' dependecies need to be installed as well.
@ -138,14 +132,6 @@
]; ];
}; };
# create a directory containing the files listed in externalPaths
makeExternalDir = import ./src/utils/external-dir.nix;
externalDirFor = forAllSystems (system: pkgs:
makeExternalDir {
inherit externalPaths externalSources pkgs;
});
# An interface to access files of external projects. # An interface to access files of external projects.
# This implementation accesses the flake inputs directly, # This implementation accesses the flake inputs directly,
# but if dream2nix is used without flakes, it defaults # but if dream2nix is used without flakes, it defaults
@ -164,268 +150,194 @@
overridesDirs = [(toString ./overrides)]; overridesDirs = [(toString ./overrides)];
# system specific dream2nix api
dream2nixFor = forAllSystems (system: pkgs:
import ./src rec {
externalDir = externalDirFor."${system}";
inherit externalPaths externalSources inputs lib pkgs;
config = {inherit overridesDirs;};
});
docsCli = forAllSystems (
system: pkgs:
pkgs.callPackage ./src/utils/view-docs {
dream2nixDocsSrc = "${self}/docs/src";
}
);
# System independent dream2nix api. # System independent dream2nix api.
# Similar to drem2nixFor but will require 'system(s)' or 'pkgs' as an argument.
# Produces flake-like output schema. # Produces flake-like output schema.
d2n-lib = d2n-lib = import ./src/lib.nix {
(import ./src/lib.nix { inherit externalPaths externalSources inputs overridesDirs lib;
inherit externalPaths externalSources inputs overridesDirs lib; nixpkgsSrc = "${nixpkgs}";
nixpkgsSrc = "${nixpkgs}";
})
# system specific dream2nix library
// (forAllSystems (system: pkgs: dream2nixFor."${system}"));
in {
lib = d2n-lib;
# kept for compat
lib2 = d2n-lib;
flakeModuleBeta = {
imports = [./src/modules/flake-parts];
dream2nix.lib = d2n-lib;
}; };
# all apps including cli, install, etc. perSystem = {
apps = forAllSystems ( config,
system: pkgs: pkgs,
dream2nixFor."${system}".framework.flakeApps system,
// { ...
tests-unit.type = "app"; }: let
tests-unit.program = d2n = import ./src {
b.toString inherit externalPaths externalSources inputs lib pkgs;
(dream2nixFor."${system}".callPackageDream ./tests/unit { dream2nixConfig = {inherit overridesDirs;};
inherit self; };
}); docsCli = pkgs.callPackage ./src/utils/view-docs {
dream2nixDocsSrc = "${self}/docs/src";
};
in {
options = {
d2n = l.mkOption {
type = l.types.raw;
};
};
config = {
inherit d2n;
tests-integration.type = "app"; # all apps including cli, install, etc.
tests-integration.program = apps =
b.toString d2n.flakeApps
(dream2nixFor."${system}".callPackageDream ./tests/integration { // {
inherit self; # passes through extra flags to treefmt
}); format.type = "app";
format.program =
tests-integration-d2n-flakes.type = "app"; l.toString
tests-integration-d2n-flakes.program = (pkgs.writeScript "format" ''
b.toString export PATH="${alejandra.defaultPackage.${system}}/bin"
(dream2nixFor."${system}".callPackageDream ./tests/integration-d2n-flakes { ${pkgs.treefmt}/bin/treefmt --clear-cache "$@"
inherit self;
});
tests-examples.type = "app";
tests-examples.program =
b.toString
(dream2nixFor."${system}".callPackageDream ./tests/examples {
inherit self;
});
tests-all.type = "app";
tests-all.program =
l.toString
(dream2nixFor.${system}.framework.utils.writePureShellScript
[
alejandra.defaultPackage.${system}
pkgs.coreutils
pkgs.gitMinimal
pkgs.nix
]
''
echo "check for correct formatting"
WORKDIR=$(realpath ./.)
cd $TMPDIR
cp -r $WORKDIR ./repo
cd ./repo
${self.apps.${system}.format.program} --fail-on-change
cd -
echo "running unit tests"
${self.apps.${system}.tests-unit.program}
echo "running integration tests"
${self.apps.${system}.tests-integration.program}
echo "checking flakes under ./examples"
${self.apps.${system}.tests-examples.program}
echo "running nix flake check"
cd $WORKDIR
nix flake show >/dev/null
nix flake check
''); '');
# passes through extra flags to treefmt docs.type = "app";
format.type = "app"; docs.program = "${docsCli}/bin/d2n-docs";
format.program =
l.toString
(pkgs.writeScript "format" ''
export PATH="${alejandra.defaultPackage.${system}}/bin"
${pkgs.treefmt}/bin/treefmt --clear-cache "$@"
'');
docs.type = "app";
docs.program = "${docsCli.${system}}/bin/d2n-docs";
}
);
# a dev shell for working on dream2nix
# use via 'nix develop . -c $SHELL'
devShells = forAllSystems (system: pkgs: let
makeDevshell = import "${inp.devshell}/modules" pkgs;
mkShell = config:
(makeDevshell {
configuration = {
inherit config;
imports = [];
};
})
.shell;
in rec {
default = dream2nix-shell;
dream2nix-shell = mkShell {
devshell.name = "dream2nix-devshell";
commands =
[
{package = pkgs.nix;}
{
package = pkgs.mdbook;
category = "documentation";
}
{
package = docsCli.${system};
category = "documentation";
help = "CLI for listing and viewing dream2nix documentation";
}
{
package = pkgs.treefmt;
category = "formatting";
}
{
package = alejandra.defaultPackage.${system};
category = "formatting";
}
]
# using linux is highly recommended as cntr is amazing for debugging builds
++ lib.optional pkgs.stdenv.isLinux {
package = pkgs.cntr;
category = "debugging";
}; };
devshell.startup = { # a dev shell for working on dream2nix
preCommitHooks.text = self.checks.${system}.pre-commit-check.shellHook; # use via 'nix develop . -c $SHELL'
dream2nixEnv.text = '' devShells = let
export NIX_PATH=nixpkgs=${nixpkgs} makeDevshell = import "${inp.devshell}/modules" pkgs;
export d2nExternalDir=${externalDirFor."${system}"} mkShell = config:
export dream2nixWithExternals=${dream2nixFor."${system}".dream2nixWithExternals} (makeDevshell {
configuration = {
inherit config;
imports = [];
};
})
.shell;
in rec {
default = dream2nix-shell;
dream2nix-shell = mkShell {
devshell.name = "dream2nix-devshell";
if [ -e ./overrides ]; then commands =
export d2nOverridesDir=$(realpath ./overrides) [
else {package = pkgs.nix;}
export d2nOverridesDir=${./overrides} {
echo -e "\nManually execute 'export d2nOverridesDir={path to your dream2nix overrides dir}'" package = pkgs.mdbook;
fi category = "documentation";
}
{
package = docsCli;
category = "documentation";
help = "CLI for listing and viewing dream2nix documentation";
}
{
package = pkgs.treefmt;
category = "formatting";
}
{
package = alejandra.defaultPackage.${system};
category = "formatting";
}
]
# using linux is highly recommended as cntr is amazing for debugging builds
++ lib.optional pkgs.stdenv.isLinux {
package = pkgs.cntr;
category = "debugging";
};
if [ -e ../dream2nix ]; then devshell.startup = {
export dream2nixWithExternals=$(realpath ./src) preCommitHooks.text = self.checks.${system}.pre-commit-check.shellHook;
else dream2nixEnv.text = ''
export dream2nixWithExternals=${./src} export NIX_PATH=nixpkgs=${nixpkgs}
echo -e "\nManually execute 'export dream2nixWithExternals={path to your dream2nix checkout}'" export d2nExternalDir=${d2n.externalDir}
fi export dream2nixWithExternals=${d2n.dream2nixWithExternals}
'';
if [ -e ./overrides ]; then
export d2nOverridesDir=$(realpath ./overrides)
else
export d2nOverridesDir=${./overrides}
echo -e "\nManually execute 'export d2nOverridesDir={path to your dream2nix overrides dir}'"
fi
if [ -e ../dream2nix ]; then
export dream2nixWithExternals=$(realpath ./src)
else
export dream2nixWithExternals=${./src}
echo -e "\nManually execute 'export dream2nixWithExternals={path to your dream2nix checkout}'"
fi
'';
};
};
};
checks = {
pre-commit-check = pre-commit-hooks.lib.${system}.run {
src = ./.;
hooks = {
treefmt = {
enable = true;
name = "treefmt";
pass_filenames = false;
entry = l.toString (pkgs.writeScript "treefmt" ''
#!${pkgs.bash}/bin/bash
export PATH="$PATH:${alejandra.defaultPackage.${system}}/bin"
${pkgs.treefmt}/bin/treefmt --clear-cache --fail-on-change
'');
};
cleanup = {
enable = true;
name = "cleaned";
entry = l.toString (pkgs.writeScript "cleaned" ''
#!${pkgs.bash}/bin/bash
for badFile in $(find ./examples | grep 'flake.lock\|dream2nix-packages'); do
rm -rf $badFile
git add $badFile || :
done
'');
};
is-cleaned = {
enable = true;
name = "is-cleaned";
entry = l.toString (pkgs.writeScript "is-cleaned" ''
#!${pkgs.bash}/bin/bash
if find ./examples | grep -q 'flake.lock\|dream2nix-packages'; then
echo "./examples should not contain any flake.lock files or dream2nix-packages directories" >&2
exit 1
fi
'');
};
};
};
};
packages = {
docs =
pkgs.runCommand
"dream2nix-docs"
{nativeBuildInputs = [pkgs.mdbook];}
''
mdbook build -d $out ${./.}/docs
'';
}; };
}; };
}); };
checks = forAllSystems (system: pkgs: { flake = {
pre-commit-check = pre-commit-hooks.lib.${system}.run { lib = d2n-lib;
src = ./.; # kept for compat
hooks = { lib2 = d2n-lib;
treefmt = {
enable = true; flakeModuleBeta = {
name = "treefmt"; imports = [./src/modules/flake-parts];
pass_filenames = false; dream2nix.lib = d2n-lib;
entry = l.toString (pkgs.writeScript "treefmt" ''
#!${pkgs.bash}/bin/bash
export PATH="$PATH:${alejandra.defaultPackage.${system}}/bin"
${pkgs.treefmt}/bin/treefmt --clear-cache --fail-on-change
'');
};
cleanup = {
enable = true;
name = "cleaned";
entry = l.toString (pkgs.writeScript "cleaned" ''
#!${pkgs.bash}/bin/bash
for badFile in $(find ./examples | grep 'flake.lock\|dream2nix-packages'); do
rm -rf $badFile
git add $badFile || :
done
'');
};
is-cleaned = {
enable = true;
name = "is-cleaned";
entry = l.toString (pkgs.writeScript "is-cleaned" ''
#!${pkgs.bash}/bin/bash
if find ./examples | grep -q 'flake.lock\|dream2nix-packages'; then
echo "./examples should not contain any flake.lock files or dream2nix-packages directories" >&2
exit 1
fi
'');
};
};
}; };
}); };
in
packages = forAllSystems (system: pkgs: { flake-parts.lib.mkFlake {inherit self;} {
docs = imports = [
pkgs.runCommand ./tests
"dream2nix-docs" ./templates
{nativeBuildInputs = [pkgs.mdbook];} ];
'' systems = [
mdbook build -d $out ${./.}/docs "x86_64-linux"
''; "aarch64-linux"
}); "x86_64-darwin"
"aarch64-darwin"
templates = ];
{ inherit flake perSystem;
default = self.templates.simple; };
simple = {
description = "Simple dream2nix flake";
path = ./templates/simple;
welcomeText = ''
You just created a simple dream2nix package!
start with typing `nix flake show` to discover the projects attributes.
commands:
- `nix develop` <-- enters the devShell
- `nix build .#` <-- builds the default package (`.#default`)
Start hacking and -_- have some fun!
> dont forget to add nix `result` folder to your `.gitignore`
'';
};
}
// (b.mapAttrs (name: value: {
description = "Example: ${name} template";
path = ./examples/${name};
}) (l.filterAttrs (n: v: v == "directory") (b.readDir ./examples)));
};
} }

View File

@ -14,7 +14,7 @@ utils.writePureShellScript
nixpkgs = <nixpkgs>; nixpkgs = <nixpkgs>;
l = (import \"\''${nixpkgs}/lib\") // builtins; l = (import \"\''${nixpkgs}/lib\") // builtins;
dream2nix = import ${dream2nixWithExternals} { dream2nix = import ${dream2nixWithExternals} {
config = ''${dream2nixConfig:-"${dream2nixConfigFile}"}; dream2nixConfig = ''${dream2nixConfig:-"${dream2nixConfigFile}"};
}; };
in ''${@:$#} in ''${@:$#}
" "

View File

@ -30,7 +30,7 @@ utils.writePureShellScriptBin
resultBin="$TMPDIR/result" resultBin="$TMPDIR/result"
${apps.callNixWithD2N} build -L --keep-failed --show-trace --out-link $resultBin \ ${apps.callNixWithD2N} build -L --keep-failed --show-trace --out-link $resultBin \
"dream2nix.framework.indexers.$name.indexBin" "dream2nix.indexers.$name.indexBin"
$resultBin $inputFile $resultBin $inputFile
'' ''

View File

@ -60,7 +60,7 @@ in
if [ ! -e "$bin" ]; then if [ ! -e "$bin" ]; then
echo "building executable for translator $translator" echo "building executable for translator $translator"
${apps.callNixWithD2N} build -o "$bin" " ${apps.callNixWithD2N} build -o "$bin" "
dream2nix.framework.translators.$translator.finalTranslateBin dream2nix.translators.$translator.finalTranslateBin
" "
fi fi
done done

View File

@ -45,7 +45,7 @@ utils.writePureShellScriptBin
translateBin="$TRANSLATOR_DIR/$translator" translateBin="$TRANSLATOR_DIR/$translator"
else else
translateBin=$(${apps.callNixWithD2N} build --print-out-paths --no-link " translateBin=$(${apps.callNixWithD2N} build --print-out-paths --no-link "
dream2nix.framework.translators.$translator.finalTranslateBin dream2nix.translators.$translator.finalTranslateBin
") ")
fi fi

View File

@ -1,11 +0,0 @@
{pkgs, ...}:
pkgs.writers.writeBash
"translateSourceShortcut"
''
set -e
sourceShortcut=''${1:?"error: you must pass a source shortcut"}
# translate shortcut to source info
${pkgs.callNixWithD2N} eval --json \
"dream2nix.fetchers.translateShortcut {shortcut=\"$sourceShortcut\";}"
''

View File

@ -19,7 +19,7 @@ pkgs.writers.writeBash
pkgs = import ${pkgs.path} {inherit system;}; pkgs = import ${pkgs.path} {inherit system;};
d2n = import ${dream2nixWithExternals} { d2n = import ${dream2nixWithExternals} {
inherit pkgs; inherit pkgs;
config = ''${dream2nixConfig:-"{}"}; dream2nixConfig = ''${dream2nixConfig:-"{}"};
}; };
src = d2n.fetchers.fetchSource { src = d2n.fetchers.fetchSource {
source = b.fromJSON (b.readFile \"''${flakeSrcInfoPath:?"error: set source info path"}\"); source = b.fromJSON (b.readFile \"''${flakeSrcInfoPath:?"error: set source info path"}\");

View File

@ -1,747 +1 @@
# This is the system specific api for dream2nix. import ./modules/framework.nix
# It requires passing one specific pkgs.
# If the intention is to generate output for several systems,
# use ./lib.nix instead.
{
pkgs ? import <nixpkgs> {},
lib ? pkgs.lib,
nix ? pkgs.nix,
# already validated config.
# this is mainly used by src/lib.nix since it loads the config beforehand.
loadedConfig ? null,
# default to empty dream2nix config. This is assumed to be not loaded.
config ?
if builtins ? getEnv && builtins.getEnv "dream2nixConfig" != ""
# if called via CLI, load config via env
then builtins.toPath (builtins.getEnv "dream2nixConfig")
# load from default directory
else {},
/*
Inputs that are not required for building, and therefore not need to be
copied alongside a dream2nix installation.
*/
inputs ?
(import ../flake-compat.nix {
src = ../.;
inherit (pkgs) system;
})
.inputs,
# dependencies of dream2nix builders
externalSources ?
lib.genAttrs
(lib.attrNames (builtins.readDir externalDir))
(inputName: "${/. + externalDir}/${inputName}"),
# will be defined if called via flake
externalPaths ? null,
# required for non-flake mode
externalDir ?
# if flake is used, construct external dir from flake inputs
if externalPaths != null
then
(import ./utils/external-dir.nix {
inherit externalPaths externalSources pkgs;
})
# if called via CLI, load externals via env
else if builtins ? getEnv && builtins.getEnv "d2nExternalDir" != ""
then /. + (builtins.getEnv "d2nExternalDir")
# load from default directory
else ./external,
} @ args: let
argsConfig = config;
in let
b = builtins;
l = lib // builtins;
config =
if loadedConfig != null
then loadedConfig
else
import ./modules/config.nix {
inherit lib;
rawConfig = argsConfig;
};
configFile = pkgs.writeText "dream2nix-config.json" (b.toJSON config);
framework = import ./modules/framework.nix {
inherit
inputs
lib
pkgs
externals
externalSources
dream2nixWithExternals
;
dream2nixConfigFile = configFile;
dream2nixConfig = config;
dream2nixInterface = {
inherit
makeOutputsForDreamLock
;
};
};
inherit (framework) dlib;
/*
The nixos module system seems to break pkgs.callPackage.
Therefore we always need to pass all of pkgs with callPackageDream.
callPackageDream should also be deprecated once all functionality is moved to
the module system.
*/
callPackageDreamArgs =
pkgs
// {
inherit callPackageDream;
inherit config;
inherit configFile;
inherit externals;
inherit externalSources;
inherit inputs;
inherit framework;
inherit dream2nixWithExternals;
inherit nix;
};
# like pkgs.callPackage, but includes all the dream2nix modules
callPackageDream = f: fargs:
(
if l.isFunction f
then f
else import f
) (callPackageDreamArgs // fargs);
inherit (framework) utils;
# updater modules to find newest package versions
updaters = callPackageDream ./updaters {};
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";
makeHook = attrs: name:
pkgs.makeSetupHook
({inherit name;} // attrs)
"${externalSources.crane}/pkgs/${name}.sh";
genHooks = names: attrs: lib.genAttrs names (makeHook attrs);
in
{
cargoHostTarget,
cargoBuildBuild,
}: rec {
otherHooks =
genHooks [
"cargoHelperFunctions"
"configureCargoCommonVarsHook"
"configureCargoVendoredDepsHook"
]
{};
installHooks =
genHooks [
"inheritCargoArtifactsHook"
"installCargoArtifactsHook"
]
{
substitutions = {
zstd = "${pkgs.pkgsBuildBuild.zstd}/bin/zstd";
};
};
installLogHook = genHooks ["installFromCargoBuildLogHook"] {
substitutions = {
cargo = "${cargoBuildBuild}/bin/cargo";
jq = "${pkgs.pkgsBuildBuild.jq}/bin/jq";
};
};
# These aren't used by dream2nix
crateNameFromCargoToml = null;
vendorCargoDeps = null;
writeTOML = importLibFile "writeTOML" {
inherit (pkgs) runCommand pkgsBuildBuild;
};
cleanCargoToml = importLibFile "cleanCargoToml" {};
findCargoFiles = importLibFile "findCargoFiles" {
inherit (pkgs) lib;
};
mkDummySrc = importLibFile "mkDummySrc" {
inherit (pkgs) writeText runCommandLocal lib;
inherit writeTOML cleanCargoToml findCargoFiles;
};
mkCargoDerivation = importLibFile "mkCargoDerivation" {
cargo = cargoHostTarget;
inherit (pkgs) stdenv lib;
inherit
(installHooks)
inheritCargoArtifactsHook
installCargoArtifactsHook
;
inherit
(otherHooks)
configureCargoCommonVarsHook
configureCargoVendoredDepsHook
;
cargoHelperFunctionsHook = otherHooks.cargoHelperFunctions;
};
buildDepsOnly = importLibFile "buildDepsOnly" {
inherit
mkCargoDerivation
crateNameFromCargoToml
vendorCargoDeps
mkDummySrc
;
};
cargoBuild = importLibFile "cargoBuild" {
inherit
mkCargoDerivation
buildDepsOnly
crateNameFromCargoToml
vendorCargoDeps
;
};
buildPackage = importLibFile "buildPackage" {
inherit (pkgs) removeReferencesTo lib;
inherit (installLogHook) installFromCargoBuildLogHook;
inherit cargoBuild;
};
};
};
dreamOverrides = let
overridesDirs =
config.overridesDirs
++ (lib.optionals (b ? getEnv && b.getEnv "d2nOverridesDir" != "") [
(b.getEnv "d2nOverridesDir")
]);
in
utils.loadOverridesDirs overridesDirs pkgs;
# the location of the dream2nix framework for self references (update scripts, etc.)
dream2nixWithExternals =
if b.pathExists (./. + "/external")
then ./.
else
pkgs.runCommandLocal "dream2nix-full-src" {} ''
cp -r ${./.} $out
chmod +w $out
mkdir $out/external
cp -r ${externalDir}/* $out/external/
'';
# automatically find a suitable builder for a given dream lock
findBuilder = dreamLock: let
subsystem = dreamLock._generic.subsystem;
in
if ! framework.buildersBySubsystem ? ${subsystem}
then throw "Could not find any builder for subsystem '${subsystem}'"
else framework.buildersBySubsystem.${subsystem}.default;
# detect if granular or combined fetching must be used
findFetcher = dreamLock:
if null != dreamLock._generic.sourcesAggregatedHash or null
then framework.functions.combinedFetcher
else framework.functions.defaultFetcher;
# fetch only sources and do not build
fetchSources = {
dreamLock,
sourceRoot ? null,
fetcher ? null,
extract ? false,
sourceOverrides ? oldSources: {},
} @ args: let
# if dream lock is a file, read and parse it
dreamLock' = (utils.dream-lock.readDreamLock {inherit dreamLock;}).lock;
fetcher =
if args.fetcher or null == null
then findFetcher dreamLock'
else args.fetcher;
fetched = fetcher rec {
inherit sourceOverrides sourceRoot;
defaultPackage = dreamLock._generic.defaultPackage;
defaultPackageVersion = dreamLock._generic.packages."${defaultPackage}";
sources = dreamLock'.sources;
sourcesAggregatedHash = dreamLock'._generic.sourcesAggregatedHash;
};
fetchedSources = fetched.fetchedSources;
in
fetched
// {
fetchedSources =
if extract
then
lib.mapAttrs
(key: source: utils.extractSource {inherit source;})
fetchedSources
else fetchedSources;
};
# build a dream lock via a specific builder
callBuilder = {
builder,
builderArgs,
fetchedSources,
sourceRoot,
dreamLock,
inject,
sourceOverrides,
packageOverrides,
allOutputs,
} @ args: let
# inject dependencies
dreamLock = utils.dream-lock.injectDependencies args.dreamLock inject;
dreamLockInterface = (utils.dream-lock.readDreamLock {inherit dreamLock;}).interface;
produceDerivation = name: pkg:
utils.applyOverridesToPackage {
inherit pkg;
outputs = allOutputs;
pname = name;
conditionalOverrides = packageOverrides;
};
outputs = builder.build (builderArgs
// {
inherit
produceDerivation
dreamLock
sourceRoot
;
inherit
(dreamLockInterface)
subsystemAttrs
getSourceSpec
getRoot
getDependencies
getCyclicDependencies
defaultPackageName
defaultPackageVersion
packages
packageVersions
;
getSource = utils.dream-lock.getSource fetchedSources;
});
# Makes the packages tree compatible with flakes schema.
# For each package the attr `{pname}` will link to the latest release.
# Other package versions will be inside: `{pname}.versions`
# Adds a `default` package by using `defaultPackageName` and `defaultPackageVersion`.
formattedOutputs =
outputs
// {
packages = let
allPackages = outputs.packages or {};
latestPackages =
lib.mapAttrs'
(pname: releases: let
latest =
releases."${dlib.latestVersion (b.attrNames releases)}";
in (lib.nameValuePair
"${pname}"
(latest
// {
versions = releases;
})))
allPackages;
defaultPackage =
allPackages
."${dreamLockInterface.defaultPackageName}"
."${dreamLockInterface.defaultPackageVersion}";
in
latestPackages // {default = defaultPackage;};
};
in
formattedOutputs;
riseAndShine = throw ''
`riseAndShine` is deprecated. See usage in readme.md.
'';
makeOutputsForDreamLock = {
dreamLock,
sourceRoot ? null,
fetcher ? null,
builder ? null,
builderArgs ? {},
inject ? {},
sourceOverrides ? oldSources: {},
packageOverrides ? {},
} @ args: let
# parse dreamLock
dreamLockLoaded = utils.dream-lock.readDreamLock {inherit (args) dreamLock;};
dreamLock = dreamLockLoaded.lock;
dreamLockInterface = dreamLockLoaded.interface;
builder' =
if builder == null
then findBuilder dreamLock
else if l.isString builder
then framework.buildersBySubsystem.${dreamLock._generic.subsystem}.${builder}
else builder;
fetcher' =
if fetcher == null
then findFetcher dreamLock
else fetcher;
fetchedSources =
(fetchSources {
inherit dreamLock sourceOverrides sourceRoot;
fetcher = fetcher';
})
.fetchedSources;
builderOutputs = callBuilder {
inherit
dreamLock
fetchedSources
allOutputs
sourceOverrides
sourceRoot
;
builder = builder';
inherit builderArgs;
packageOverrides =
lib.recursiveUpdate
(dreamOverrides."${dreamLock._generic.subsystem}" or {})
(args.packageOverrides or {});
inject = args.inject or {};
};
allOutputs = builderOutputs;
in
allOutputs;
translateProjects = {
discoveredProjects ?
framework.functions.discoverers.discoverProjects
{inherit settings tree;},
projects ? {},
source ? throw "Pass either `source` or `tree` to translateProjects",
tree ? dlib.prepareSourceTree {inherit source;},
pname,
settings ? [],
} @ args: let
getTranslator = translatorName:
framework.translators.${translatorName};
isImpure = project: translatorName:
(getTranslator translatorName).type == "impure";
getInvalidationHash = project:
dlib.calcInvalidationHash {
inherit project source;
# TODO: add translatorArgs
translatorArgs = {};
translator = project.translator;
inherit config;
};
isResolved = project: let
dreamLockExists =
l.pathExists "${toString config.projectRoot}/${project.dreamLockPath}";
dreamLockValid =
project.dreamLock._generic.invalidationHash
or ""
== project.invalidationHash;
in
dreamLockExists && dreamLockValid;
getProjectKey = project: "${project.name}_|_${project.subsystem}_|_${project.relPath}";
# list of projects extended with some information requried for processing
projectsList =
l.map
(project: (let
self =
project
// rec {
dreamLock =
(utils.dream-lock.readDreamLock {
dreamLock = "${toString config.projectRoot}/${project.dreamLockPath}";
})
.lock;
impure = isImpure project translator;
invalidationHash = getInvalidationHash project;
key = getProjectKey project;
resolved = isResolved self;
translator = project.translator or (l.head project.translators);
};
in
self))
discoveredProjects;
# projects without existing valid dream-lock.json
projectsPureUnresolved =
l.filter
(project: ! project.resolved && ! project.impure)
projectsList;
# already resolved projects
projectsResolved =
l.filter
(project: project.resolved)
projectsList;
# list of pure projects extended with 'dreamLock' attribute
projectsResolvedOnTheFly =
l.forEach projectsPureUnresolved
(proj: let
translator = getTranslator proj.translator;
dreamLock'' = translator.finalTranslate {
inherit source tree discoveredProjects;
project = proj;
};
/*
simpleTranslate2 exposes result via `.result` in order to allow for
unit testing via `.inputs`.
*/
dreamLock' = dreamLock''.result or dreamLock'';
dreamLock =
dreamLock'
// {
_generic =
dreamLock'._generic
// {
invalidationHash = proj.invalidationHash;
};
};
in
proj
// {
inherit dreamLock;
});
resolvedProjects = projectsResolved ++ projectsResolvedOnTheFly;
in
resolvedProjects;
# transform a list of resolved projects to buildable outputs
realizeProjects = {
inject ? {},
translatedProjects ? translateProjects {inherit pname settings source;},
# alternative way of calling (for debugging)
pname ? null,
source ? null,
packageOverrides ? {},
sourceOverrides ? oldSources: {},
settings ? [],
}: let
dreamLocks = l.forEach translatedProjects (proj: proj.dreamLock);
defaultSourceOverride = dreamLock:
if source == null
then {}
else let
defaultPackage = dreamLock._generic.defaultPackage;
defaultPackageVersion =
dreamLock._generic.packages."${defaultPackage}";
in {
"${defaultPackage}"."${defaultPackageVersion}" = "${source}/${dreamLock._generic.location}";
};
# extends each package with a `.resolve` attribute
# and applies sourceOverrides
outputsForProject = proj: let
outputs = makeOutputsForDreamLock {
inherit inject packageOverrides;
sourceRoot = source;
builder = proj.builder or null;
dreamLock = proj.dreamLock;
sourceOverrides = oldSources:
dlib.recursiveUpdateUntilDepth
1
(defaultSourceOverride proj.dreamLock)
(sourceOverrides oldSources);
};
in
outputs
// {
packages =
l.mapAttrs
(pname: pkg:
pkg.overrideAttrs (old: {
passthru =
old.passthru
or {}
// {
resolve = utils.makeTranslateScript {
inherit source;
invalidationHash = proj.invalidationHash;
project = proj;
};
};
}))
(outputs.packages or {});
};
projectOutputs = l.map outputsForProject translatedProjects;
in
dlib.mergeFlakes projectOutputs;
generateImpureResolveScript = {
source,
impureProjects,
}: let
impureResolveScriptsList =
l.listToAttrs
(
l.map
(
project:
l.nameValuePair
"Name: ${project.name}; Subsystem: ${project.subsystem or "?"}; relPath: ${project.relPath}"
(utils.makeTranslateScript {inherit project source;})
)
impureProjects
);
resolveImpureScript =
utils.writePureShellScriptBin
"resolve"
[]
''
${l.concatStringsSep "\n"
(l.mapAttrsToList
(title: script: ''
echo "Resolving:: ${title}"
${script}/bin/resolve
'')
impureResolveScriptsList)}
'';
in
resolveImpureScript;
makeOutputs = {
source ? throw "pass a 'source' to 'makeOutputs'",
discoveredProjects ?
framework.functions.discoverers.discoverProjects {
inherit settings source;
},
pname ? null,
projects ? {},
settings ? [],
packageOverrides ? {},
sourceOverrides ? old: {},
inject ? {},
}: let
# if projects are defined manually, ignore discoveredProjects
finalProjects =
if projects != {}
then let
projectsList = l.attrValues projects;
in
# skip discovery and just add required attributes to project list
l.forEach projectsList
(proj:
proj
// {
relPath = proj.relPath or "";
translator = proj.translator or (l.head proj.translators);
dreamLockPath =
framework.functions.discoverers.getDreamLockPath
proj
(l.head projectsList);
})
else discoveredProjects;
impureProjects =
l.filter
(proj:
framework.translators."${proj.translator}".type
== "impure")
finalProjects;
resolveImpureScript = generateImpureResolveScript {
inherit impureProjects source;
};
translatedProjects = translateProjects {
discoveredProjects = finalProjects;
inherit
pname
settings
source
;
};
realizedProjects = realizeProjects {
inherit
inject
packageOverrides
sourceOverrides
translatedProjects
source
;
};
impureFakeDerivations =
l.listToAttrs
(l.map
(proj:
l.nameValuePair
proj.name
rec {
type = "derivation";
name = proj.name;
resolve = utils.makeTranslateScript {
project = proj;
inherit source;
};
drvPath = throw ''
The ${proj.subsystem} package ${proj.name} contains unresolved impurities.
Resolve by running the .resolve attribute of this derivation
or by resolving all impure projects by running the `resolveImpure` package
'';
})
impureProjects);
in
realizedProjects
// {
packages =
l.warnIf
(realizeProjects.packages.resolveImpure or null != null)
''
a builder outputted a package named 'resolveImpure'
this will be overridden by dream2nix!
''
impureFakeDerivations
// (realizedProjects.packages or {})
// {resolveImpure = resolveImpureScript;};
};
in {
inherit
callPackageDream
dream2nixWithExternals
framework
fetchSources
realizeProjects
translateProjects
riseAndShine
updaters
makeOutputsForDreamLock
makeOutputs
;
}

View File

@ -12,10 +12,9 @@
l = lib // builtins; l = lib // builtins;
initDream2nix = config: pkgs: initDream2nix = config: pkgs:
import ./default.nix import ./modules/framework.nix {
{ inherit lib inputs pkgs externalPaths externalSources;
loadedConfig = config; dream2nixConfig = config;
inherit inputs pkgs externalPaths externalSources;
}; };
loadConfig = config'': let loadConfig = config'': let
@ -89,13 +88,9 @@
config = loadConfig (args.config or {}); config = loadConfig (args.config or {});
framework = import ./modules/framework.nix { framework = import ./modules/framework.nix {
inherit lib externalSources inputs; inherit lib externalPaths externalSources inputs;
dream2nixConfig = config; dream2nixConfig = config;
dream2nixConfigFile = l.toFile "dream2nix-config.json" (l.toJSON config);
pkgs = throw "pkgs is not available before nixpkgs is imported"; pkgs = throw "pkgs is not available before nixpkgs is imported";
externals = throw "externals is not available before nixpkgs is imported";
dream2nixWithExternals = throw "not available before nixpkgs is imported";
dream2nixInterface = throw "not available before nixpkgs is imported";
}; };
systems = systems =
@ -140,7 +135,7 @@
l.mapAttrs l.mapAttrs
(system: pkgs: let (system: pkgs: let
dream2nix = dream2nixFor."${system}"; dream2nix = dream2nixFor."${system}";
allOutputs = dream2nix.makeOutputs { allOutputs = dream2nix.dream2nix-interface.makeOutputs {
discoveredProjects = finalProjects; discoveredProjects = finalProjects;
inherit inherit
source source
@ -193,7 +188,7 @@
l.mapAttrs l.mapAttrs
(system: pkgs: let (system: pkgs: let
dream2nix = dream2nixFor."${system}"; dream2nix = dream2nixFor."${system}";
allOutputs = dream2nix.framework.utils.makeOutputsForIndexes { allOutputs = dream2nix.utils.makeOutputsForIndexes {
inherit inherit
source source
indexes indexes

View File

@ -0,0 +1,6 @@
{
imports = [
./implementation.nix
./interface.nix
];
}

View File

@ -0,0 +1,523 @@
{config, ...}: let
l = config.lib // builtins;
b = builtins;
inherit (config) dream2nixConfig pkgs utils dlib lib;
dreamOverrides = let
overridesDirs =
config.dream2nixConfig.overridesDirs
++ (lib.optionals (b ? getEnv && b.getEnv "d2nOverridesDir" != "") [
(b.getEnv "d2nOverridesDir")
]);
in
utils.loadOverridesDirs overridesDirs pkgs;
# automatically find a suitable builder for a given dream lock
findBuilder = dreamLock: let
subsystem = dreamLock._generic.subsystem;
in
if ! config.buildersBySubsystem ? ${subsystem}
then throw "Could not find any builder for subsystem '${subsystem}'"
else config.buildersBySubsystem.${subsystem}.default;
# detect if granular or combined fetching must be used
findFetcher = dreamLock:
if null != dreamLock._generic.sourcesAggregatedHash or null
then config.functions.combinedFetcher
else config.functions.defaultFetcher;
# fetch only sources and do not build
fetchSources = {
dreamLock,
sourceRoot ? null,
fetcher ? null,
extract ? false,
sourceOverrides ? oldSources: {},
} @ args: let
# if dream lock is a file, read and parse it
dreamLock' = (utils.dream-lock.readDreamLock {inherit dreamLock;}).lock;
fetcher =
if args.fetcher or null == null
then findFetcher dreamLock'
else args.fetcher;
fetched = fetcher rec {
inherit sourceOverrides sourceRoot;
defaultPackage = dreamLock._generic.defaultPackage;
defaultPackageVersion = dreamLock._generic.packages."${defaultPackage}";
sources = dreamLock'.sources;
sourcesAggregatedHash = dreamLock'._generic.sourcesAggregatedHash;
};
fetchedSources = fetched.fetchedSources;
in
fetched
// {
fetchedSources =
if extract
then
lib.mapAttrs
(key: source: utils.extractSource {inherit source;})
fetchedSources
else fetchedSources;
};
# build a dream lock via a specific builder
callBuilder = {
builder,
builderArgs,
fetchedSources,
sourceRoot,
dreamLock,
inject,
sourceOverrides,
packageOverrides,
allOutputs,
} @ args: let
# inject dependencies
dreamLock = utils.dream-lock.injectDependencies args.dreamLock inject;
dreamLockInterface = (utils.dream-lock.readDreamLock {inherit dreamLock;}).interface;
produceDerivation = name: pkg:
utils.applyOverridesToPackage {
inherit pkg;
outputs = allOutputs;
pname = name;
conditionalOverrides = packageOverrides;
};
outputs = builder.build (builderArgs
// {
inherit
produceDerivation
dreamLock
sourceRoot
;
inherit
(dreamLockInterface)
subsystemAttrs
getSourceSpec
getRoot
getDependencies
getCyclicDependencies
defaultPackageName
defaultPackageVersion
packages
packageVersions
;
getSource = utils.dream-lock.getSource fetchedSources;
});
# Makes the packages tree compatible with flakes schema.
# For each package the attr `{pname}` will link to the latest release.
# Other package versions will be inside: `{pname}.versions`
# Adds a `default` package by using `defaultPackageName` and `defaultPackageVersion`.
formattedOutputs =
outputs
// {
packages = let
allPackages = outputs.packages or {};
latestPackages =
lib.mapAttrs'
(pname: releases: let
latest =
releases."${dlib.latestVersion (b.attrNames releases)}";
in (lib.nameValuePair
"${pname}"
(latest
// {
versions = releases;
})))
allPackages;
defaultPackage =
allPackages
."${dreamLockInterface.defaultPackageName}"
."${dreamLockInterface.defaultPackageVersion}";
in
latestPackages // {default = defaultPackage;};
};
in
formattedOutputs;
riseAndShine = throw ''
`riseAndShine` is deprecated. See usage in readme.md.
'';
makeOutputsForDreamLock = {
dreamLock,
sourceRoot ? null,
fetcher ? null,
builder ? null,
builderArgs ? {},
inject ? {},
sourceOverrides ? oldSources: {},
packageOverrides ? {},
} @ args: let
# parse dreamLock
dreamLockLoaded = utils.dream-lock.readDreamLock {inherit (args) dreamLock;};
dreamLock = dreamLockLoaded.lock;
dreamLockInterface = dreamLockLoaded.interface;
builder' =
if builder == null
then findBuilder dreamLock
else if l.isString builder
then config.buildersBySubsystem.${dreamLock._generic.subsystem}.${builder}
else builder;
fetcher' =
if fetcher == null
then findFetcher dreamLock
else fetcher;
fetchedSources =
(fetchSources {
inherit dreamLock sourceOverrides sourceRoot;
fetcher = fetcher';
})
.fetchedSources;
builderOutputs = callBuilder {
inherit
dreamLock
fetchedSources
allOutputs
sourceOverrides
sourceRoot
;
builder = builder';
inherit builderArgs;
packageOverrides =
lib.recursiveUpdate
(dreamOverrides."${dreamLock._generic.subsystem}" or {})
(args.packageOverrides or {});
inject = args.inject or {};
};
allOutputs = builderOutputs;
in
allOutputs;
translateProjects = {
discoveredProjects ?
config.functions.discoverers.discoverProjects
{inherit settings tree;},
projects ? {},
source ? throw "Pass either `source` or `tree` to translateProjects",
tree ? dlib.prepareSourceTree {inherit source;},
pname,
settings ? [],
} @ args: let
getTranslator = translatorName:
config.translators.${translatorName};
isImpure = project: translatorName:
(getTranslator translatorName).type == "impure";
getInvalidationHash = project:
dlib.calcInvalidationHash {
inherit project source;
# TODO: add translatorArgs
translatorArgs = {};
translator = project.translator;
config = dream2nixConfig;
};
isResolved = project: let
dreamLockExists =
l.pathExists "${toString dream2nixConfig.projectRoot}/${project.dreamLockPath}";
dreamLockValid =
project.dreamLock._generic.invalidationHash
or ""
== project.invalidationHash;
in
dreamLockExists && dreamLockValid;
getProjectKey = project: "${project.name}_|_${project.subsystem}_|_${project.relPath}";
# list of projects extended with some information requried for processing
projectsList =
l.map
(project: (let
self =
project
// rec {
dreamLock =
(utils.dream-lock.readDreamLock {
dreamLock = "${toString dream2nixConfig.projectRoot}/${project.dreamLockPath}";
})
.lock;
impure = isImpure project translator;
invalidationHash = getInvalidationHash project;
key = getProjectKey project;
resolved = isResolved self;
translator = project.translator or (l.head project.translators);
};
in
self))
discoveredProjects;
# projects without existing valid dream-lock.json
projectsPureUnresolved =
l.filter
(project: ! project.resolved && ! project.impure)
projectsList;
# already resolved projects
projectsResolved =
l.filter
(project: project.resolved)
projectsList;
# list of pure projects extended with 'dreamLock' attribute
projectsResolvedOnTheFly =
l.forEach projectsPureUnresolved
(proj: let
translator = getTranslator proj.translator;
dreamLock'' = translator.finalTranslate {
inherit source tree discoveredProjects;
project = proj;
};
/*
simpleTranslate2 exposes result via `.result` in order to allow for
unit testing via `.inputs`.
*/
dreamLock' = dreamLock''.result or dreamLock'';
dreamLock =
dreamLock'
// {
_generic =
dreamLock'._generic
// {
invalidationHash = proj.invalidationHash;
};
};
in
proj
// {
inherit dreamLock;
});
resolvedProjects = projectsResolved ++ projectsResolvedOnTheFly;
in
resolvedProjects;
# transform a list of resolved projects to buildable outputs
realizeProjects = {
inject ? {},
translatedProjects ? translateProjects {inherit pname settings source;},
# alternative way of calling (for debugging)
pname ? null,
source ? null,
packageOverrides ? {},
sourceOverrides ? oldSources: {},
settings ? [],
}: let
dreamLocks = l.forEach translatedProjects (proj: proj.dreamLock);
defaultSourceOverride = dreamLock:
if source == null
then {}
else let
defaultPackage = dreamLock._generic.defaultPackage;
defaultPackageVersion =
dreamLock._generic.packages."${defaultPackage}";
in {
"${defaultPackage}"."${defaultPackageVersion}" = "${source}/${dreamLock._generic.location}";
};
# extends each package with a `.resolve` attribute
# and applies sourceOverrides
outputsForProject = proj: let
outputs = makeOutputsForDreamLock {
inherit inject packageOverrides;
sourceRoot = source;
builder = proj.builder or null;
dreamLock = proj.dreamLock;
sourceOverrides = oldSources:
dlib.recursiveUpdateUntilDepth
1
(defaultSourceOverride proj.dreamLock)
(sourceOverrides oldSources);
};
in
outputs
// {
packages =
l.mapAttrs
(pname: pkg:
pkg.overrideAttrs (old: {
passthru =
old.passthru
or {}
// {
resolve = utils.makeTranslateScript {
inherit source;
invalidationHash = proj.invalidationHash;
project = proj;
};
};
}))
(outputs.packages or {});
};
projectOutputs = l.map outputsForProject translatedProjects;
in
dlib.mergeFlakes projectOutputs;
generateImpureResolveScript = {
source,
impureProjects,
}: let
impureResolveScriptsList =
l.listToAttrs
(
l.map
(
project:
l.nameValuePair
"Name: ${project.name}; Subsystem: ${project.subsystem or "?"}; relPath: ${project.relPath}"
(utils.makeTranslateScript {inherit project source;})
)
impureProjects
);
resolveImpureScript =
utils.writePureShellScriptBin
"resolve"
[]
''
${l.concatStringsSep "\n"
(l.mapAttrsToList
(title: script: ''
echo "Resolving:: ${title}"
${script}/bin/resolve
'')
impureResolveScriptsList)}
'';
in
resolveImpureScript;
makeOutputs = {
source ? throw "pass a 'source' to 'makeOutputs'",
discoveredProjects ?
config.functions.discoverers.discoverProjects {
inherit settings source;
},
pname ? null,
projects ? {},
settings ? [],
packageOverrides ? {},
sourceOverrides ? old: {},
inject ? {},
}: let
# if projects are defined manually, ignore discoveredProjects
finalProjects =
if projects != {}
then let
projectsList = l.attrValues projects;
in
# skip discovery and just add required attributes to project list
l.forEach projectsList
(proj:
proj
// {
relPath = proj.relPath or "";
translator = proj.translator or (l.head proj.translators);
dreamLockPath =
config.functions.discoverers.getDreamLockPath
proj
(l.head projectsList);
})
else discoveredProjects;
impureProjects =
l.filter
(proj:
config.translators."${proj.translator}".type
== "impure")
finalProjects;
resolveImpureScript = generateImpureResolveScript {
inherit impureProjects source;
};
translatedProjects = translateProjects {
discoveredProjects = finalProjects;
inherit
pname
settings
source
;
};
realizedProjects = realizeProjects {
inherit
inject
packageOverrides
sourceOverrides
translatedProjects
source
;
};
impureFakeDerivations =
l.listToAttrs
(l.map
(proj:
l.nameValuePair
proj.name
{
type = "derivation";
name = proj.name;
resolve = utils.makeTranslateScript {
project = proj;
inherit source;
};
drvPath = throw ''
The ${proj.subsystem} package ${proj.name} contains unresolved impurities.
Resolve by running the .resolve attribute of this derivation
or by resolving all impure projects by running the `resolveImpure` package
'';
})
impureProjects);
in
realizedProjects
// {
packages =
l.warnIf
(realizeProjects.packages.resolveImpure or null != null)
''
a builder outputted a package named 'resolveImpure'
this will be overridden by dream2nix!
''
impureFakeDerivations
// (realizedProjects.packages or {})
// {resolveImpure = resolveImpureScript;};
};
in {
config.dream2nix-interface = {
inherit
fetchSources
realizeProjects
translateProjects
riseAndShine
makeOutputsForDreamLock
makeOutputs
;
};
}

View File

@ -0,0 +1,10 @@
{config, ...}: let
l = config.lib // builtins;
t = l.types;
in {
options = {
dream2nix-interface = l.mkOption {
type = t.lazyAttrsOf t.raw;
};
};
}

6
src/modules/externals/default.nix vendored Normal file
View File

@ -0,0 +1,6 @@
{
imports = [
./implementation.nix
./interface.nix
];
}

103
src/modules/externals/implementation.nix vendored Normal file
View File

@ -0,0 +1,103 @@
{config, ...}: let
l = config.lib // builtins;
inherit (config) pkgs externalSources;
in {
config = {
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";
makeHook = attrs: name:
pkgs.makeSetupHook
({inherit name;} // attrs)
"${externalSources.crane}/pkgs/${name}.sh";
genHooks = names: attrs: l.genAttrs names (makeHook attrs);
in
{
cargoHostTarget,
cargoBuildBuild,
}: rec {
otherHooks =
genHooks [
"cargoHelperFunctions"
"configureCargoCommonVarsHook"
"configureCargoVendoredDepsHook"
]
{};
installHooks =
genHooks [
"inheritCargoArtifactsHook"
"installCargoArtifactsHook"
]
{
substitutions = {
zstd = "${pkgs.pkgsBuildBuild.zstd}/bin/zstd";
};
};
installLogHook = genHooks ["installFromCargoBuildLogHook"] {
substitutions = {
cargo = "${cargoBuildBuild}/bin/cargo";
jq = "${pkgs.pkgsBuildBuild.jq}/bin/jq";
};
};
# These aren't used by dream2nix
crateNameFromCargoToml = null;
vendorCargoDeps = null;
writeTOML = importLibFile "writeTOML" {
inherit (pkgs) runCommand pkgsBuildBuild;
};
cleanCargoToml = importLibFile "cleanCargoToml" {};
findCargoFiles = importLibFile "findCargoFiles" {
inherit (pkgs) lib;
};
mkDummySrc = importLibFile "mkDummySrc" {
inherit (pkgs) writeText runCommandLocal lib;
inherit writeTOML cleanCargoToml findCargoFiles;
};
mkCargoDerivation = importLibFile "mkCargoDerivation" {
cargo = cargoHostTarget;
inherit (pkgs) stdenv lib;
inherit
(installHooks)
inheritCargoArtifactsHook
installCargoArtifactsHook
;
inherit
(otherHooks)
configureCargoCommonVarsHook
configureCargoVendoredDepsHook
;
cargoHelperFunctionsHook = otherHooks.cargoHelperFunctions;
};
buildDepsOnly = importLibFile "buildDepsOnly" {
inherit
mkCargoDerivation
crateNameFromCargoToml
vendorCargoDeps
mkDummySrc
;
};
cargoBuild = importLibFile "cargoBuild" {
inherit
mkCargoDerivation
buildDepsOnly
crateNameFromCargoToml
vendorCargoDeps
;
};
buildPackage = importLibFile "buildPackage" {
inherit (pkgs) removeReferencesTo lib;
inherit (installLogHook) installFromCargoBuildLogHook;
inherit cargoBuild;
};
};
};
};
}

10
src/modules/externals/interface.nix vendored Normal file
View File

@ -0,0 +1,10 @@
{config, ...}: let
l = config.lib // builtins;
t = l.types;
in {
options = {
externals = l.mkOption {
type = t.lazyAttrsOf t.raw;
};
};
}

View File

@ -27,7 +27,7 @@ in {
outputs = outputs =
l.mapAttrs l.mapAttrs
(_: args: instance.makeOutputs args) (_: args: instance.dream2nix-interface.makeOutputs args)
config.dream2nix.inputs; config.dream2nix.inputs;
getAttrFromOutputs = attrName: getAttrFromOutputs = attrName:

View File

@ -1,6 +1,6 @@
{ {
lib, lib ? (args.pkgs or (import <nixpkgs> {})).lib,
dream2nixConfig, dream2nixConfig ? {},
... ...
} @ args: let } @ args: let
topLevel = import ./top-level.nix args; topLevel = import ./top-level.nix args;

View File

@ -41,18 +41,18 @@
--show-trace --impure --raw --expr " --show-trace --impure --raw --expr "
let let
dream2nix = import ${dream2nixWithExternals} { dream2nix = import ${dream2nixWithExternals} {
config = ${dream2nixConfigFile}; dream2nixConfig = ${dream2nixConfigFile};
}; };
translatorArgs = translatorArgs =
(builtins.fromJSON (builtins.fromJSON
(builtins.unsafeDiscardStringContext (builtins.readFile '''$1'''))); (builtins.unsafeDiscardStringContext (builtins.readFile '''$1''')));
dreamLock' = dreamLock' =
dream2nix.framework.translatorsBySubsystem.${subsystem}.${name}.finalTranslate dream2nix.translatorsBySubsystem.${subsystem}.${name}.finalTranslate
translatorArgs; translatorArgs;
# simpleTranslate2 puts dream-lock in result # simpleTranslate2 puts dream-lock in result
dreamLock = dreamLock'.result or dreamLock'; dreamLock = dreamLock'.result or dreamLock';
in in
dream2nix.framework.utils.dream-lock.toJSON dream2nix.utils.dream-lock.toJSON
# don't use nix to detect cycles, this will be more efficient in python # don't use nix to detect cycles, this will be more efficient in python
(dreamLock // { (dreamLock // {
_generic = builtins.removeAttrs dreamLock._generic [ \"cyclicDependencies\" ]; _generic = builtins.removeAttrs dreamLock._generic [ \"cyclicDependencies\" ];

View File

@ -0,0 +1,6 @@
{
imports = [
./implementation.nix
./interface.nix
];
}

View File

@ -1,21 +1,8 @@
{ {config, ...}: let
curl, inherit (config) utils fetchers updaters;
gnugrep,
jq,
lib,
python3,
writeText,
# dream2nix inputs
callPackageDream,
framework,
...
}: let
inherit (framework) utils fetchers;
lockUtils = utils.dream-lock; lockUtils = utils.dream-lock;
updaters = callPackageDream ./updaters.nix {};
getUpdaterName = {dreamLock}: let getUpdaterName = {dreamLock}: let
lock = (utils.dream-lock.readDreamLock {inherit dreamLock;}).lock; lock = (utils.dream-lock.readDreamLock {inherit dreamLock;}).lock;
source = lockUtils.getMainPackageSource lock; source = lockUtils.getMainPackageSource lock;
@ -34,5 +21,7 @@
in in
updater' source; updater' source;
in { in {
inherit getUpdaterName makeUpdateScript updaters; config.functions.updaters = {
inherit getUpdaterName makeUpdateScript;
};
} }

View File

@ -0,0 +1,14 @@
{config, ...}: let
inherit (config.dlib) mkFunction;
l = config.lib // builtins;
t = l.types;
in {
options.functions.updaters = {
getUpdaterName = mkFunction {
type = t.either t.str t.null;
};
makeUpdateScript = mkFunction {
type = t.path;
};
};
}

View File

@ -1,15 +1,43 @@
{ {
externals, inputs ?
externalSources, (import ../../flake-compat.nix {
inputs, src = ../../.;
lib, inherit (pkgs) system;
pkgs, })
dream2nixConfig, .inputs,
dream2nixConfigFile, lib ? pkgs.lib,
dream2nixWithExternals, pkgs ? import <nixpkgs> {},
dream2nixInterface, dream2nixConfig ?
if builtins ? getEnv && builtins.getEnv "dream2nixConfig" != ""
# if called via CLI, load config via env
then builtins.toPath (builtins.getEnv "dream2nixConfig")
# load from default directory
else {},
externalPaths ? null,
externalSources ? null,
} @ args: let } @ args: let
b = builtins;
t = lib.types; t = lib.types;
externalDir =
if externalPaths != null
then
(import ../utils/external-dir.nix {
inherit externalPaths externalSources pkgs;
})
# if called via CLI, load externals via env
else if b ? getEnv && b.getEnv "d2nExternalDir" != ""
then ../. + (b.getEnv "d2nExternalDir")
# load from default directory
else ../external;
externalSources =
args.externalSources
or (
lib.genAttrs
(lib.attrNames (builtins.readDir externalDir))
(inputName: "${../. + externalDir}/${inputName}")
);
in { in {
imports = [ imports = [
./functions.discoverers ./functions.discoverers
@ -17,6 +45,7 @@ in {
./functions.default-fetcher ./functions.default-fetcher
./functions.combined-fetcher ./functions.combined-fetcher
./functions.translators ./functions.translators
./functions.updaters
./apps ./apps
./builders ./builders
./discoverers ./discoverers
@ -34,41 +63,65 @@ in {
./dlib.parsing ./dlib.parsing
./dlib.construct ./dlib.construct
./dlib.simpleTranslate2 ./dlib.simpleTranslate2
./updaters
./externals
./dream2nix-interface
]; ];
options = { options = {
lib = lib.mkOption { lib = lib.mkOption {
type = t.raw; type = t.raw;
}; };
externals = lib.mkOption {
type = t.lazyAttrsOf t.raw;
};
externalSources = lib.mkOption {
type = t.lazyAttrsOf t.path;
};
inputs = lib.mkOption { inputs = lib.mkOption {
type = t.lazyAttrsOf t.attrs; type = t.lazyAttrsOf t.attrs;
}; };
pkgs = lib.mkOption { pkgs = lib.mkOption {
type = t.raw; type = t.raw;
}; };
externalDir = lib.mkOption {
type = t.path;
};
externalPaths = lib.mkOption {
type = t.listOf t.str;
};
externalSources = lib.mkOption {
type = t.lazyAttrsOf t.path;
};
dream2nixWithExternals = lib.mkOption {
type = t.path;
};
dream2nixConfig = lib.mkOption { dream2nixConfig = lib.mkOption {
type = t.submoduleWith { type = t.submoduleWith {
modules = [./config]; modules = [./config];
}; };
}; };
dream2nixWithExternals = lib.mkOption {
type = t.path;
};
dream2nixConfigFile = lib.mkOption { dream2nixConfigFile = lib.mkOption {
type = t.path; type = t.path;
}; };
dream2nixInterface = lib.mkOption {
type = t.raw;
};
}; };
config = config = {
args inherit
// { dream2nixConfig
lib = args.lib // builtins; pkgs
}; inputs
externalPaths
externalSources
externalDir
;
lib = lib // builtins;
dream2nixConfigFile = b.toFile "dream2nix-config.json" (b.toJSON dream2nixConfig);
# the location of the dream2nix framework for self references (update scripts, etc.)
dream2nixWithExternals =
if b.pathExists (../. + "/external")
then ../.
else
pkgs.runCommandLocal "dream2nix-full-src" {} ''
cp -r ${../.} $out
chmod +w $out
mkdir $out/external
cp -r ${externalDir}/* $out/external/
'';
};
} }

View File

@ -0,0 +1,6 @@
{
imports = [
./implementation.nix
./interface.nix
];
}

View File

@ -0,0 +1,17 @@
{config, ...}: let
l = config.lib // builtins;
updatersDir = ../../updaters;
updaterNames = l.attrNames (
l.filterAttrs
(_: type: type == "directory")
(l.readDir updatersDir)
);
updaterModules =
l.genAttrs
updaterNames
(name: import "${updatersDir}/${name}" config);
in {
config = {
updaters = updaterModules;
};
}

View File

@ -0,0 +1,10 @@
{config, ...}: let
l = config.lib // builtins;
t = l.types;
in {
options = {
updaters = l.mkOption {
type = t.lazyAttrsOf (t.functionTo t.path);
};
};
}

View File

@ -31,7 +31,7 @@
); );
dreamLocks = findDreamLocks tree; dreamLocks = findDreamLocks tree;
makePackagesForDreamLock = dreamLock: makePackagesForDreamLock = dreamLock:
(config.dream2nixInterface.makeOutputsForDreamLock { (config.dream2nix-interface.makeOutputsForDreamLock {
inherit inherit
dreamLock dreamLock
inject inject

View File

@ -21,7 +21,7 @@ def aggregate_hashes(lock, outputDreamLock, dream2nix_src, dream2nix_config):
# compute FOD hash of aggregated sources # compute FOD hash of aggregated sources
proc = nix( proc = nix(
"build", "--impure", "-L", "--show-trace", "--expr", "build", "--impure", "-L", "--show-trace", "--expr",
f"(import {dream2nix_src} {{ config = {dream2nix_config}; }}).fetchSources {{ dreamLock = {outputDreamLock}; }}" f"(import {dream2nix_src} {{ dream2nixConfig = {dream2nix_config}; }}).dream2nix-interface.fetchSources {{ dreamLock = {outputDreamLock}; }}"
) )
print(proc.stderr.decode()) print(proc.stderr.decode())
# read the output hash from the failed build log # read the output hash from the failed build log

View File

@ -25,7 +25,7 @@ def callNixFunction(function_path, **kwargs):
d2n = (import {dream2nix_src} {{}}); d2n = (import {dream2nix_src} {{}});
in in
builtins.toJSON ( builtins.toJSON (
(d2n.framework.dlib.callViaEnv d2n.{function_path}) (d2n.dlib.callViaEnv d2n.{function_path})
) )
''', ''',
env=env env=env
@ -63,11 +63,11 @@ def eval(attr_path, wrapper_code=None, **kwargs):
d2n = (import {dream2nix_src} {{}}); d2n = (import {dream2nix_src} {{}});
result' = result' =
if "{is_function_call}" == "True" if "{is_function_call}" == "True"
then d2n.framework.dlib.callViaEnv d2n.{attr_path} then d2n.dlib.callViaEnv d2n.{attr_path}
else d2n.{attr_path}; else d2n.{attr_path};
result = (d2n.callPackageDream result = (d2n.pkgs.callPackage
{wrapper_code_file.name} {wrapper_code_file.name}
{{ result = result'; }}); (d2n // {{ result = result'; }}));
in in
b.toJSON ( b.toJSON (
# remove override attributes added by callPackage # remove override attributes added by callPackage
@ -101,7 +101,7 @@ def buildNixFunction(function_path, **kwargs):
let let
d2n = (import {dream2nix_src} {{}}); d2n = (import {dream2nix_src} {{}});
in in
(d2n.framework.dlib.callViaEnv d2n.{function_path}) (d2n.dlib.callViaEnv d2n.{function_path})
''', ''',
env=env env=env
) )

View File

@ -4,7 +4,7 @@
}: cwd: let }: cwd: let
b = builtins; b = builtins;
dream2nix = import dream2nixWithExternals { dream2nix = import dream2nixWithExternals {
config = b.path {path = dream2nixConfig;}; dream2nixConfig = b.path {path = dream2nixConfig;};
}; };
parsed = b.fromTOML (builtins.readFile "${cwd}/gomod2nix.toml"); parsed = b.fromTOML (builtins.readFile "${cwd}/gomod2nix.toml");
pkgs = import <nixpkgs> {}; pkgs = import <nixpkgs> {};
@ -14,7 +14,7 @@
(goName: depAttrs: depAttrs // {inherit goName;}) (goName: depAttrs: depAttrs // {inherit goName;})
parsed; parsed;
translated = translated =
dream2nix.framework.utils.simpleTranslate dream2nix.utils.simpleTranslate
({ ({
getDepByNameVer, getDepByNameVer,
dependenciesByOriginalID, dependenciesByOriginalID,
@ -68,4 +68,4 @@
}; };
}); });
in in
dream2nix.framework.utils.dream-lock.toJSON translated dream2nix.utils.dream-lock.toJSON translated

View File

@ -0,0 +1,12 @@
{
pkgs,
utils,
...
}: {
owner,
repo,
...
}:
utils.writePureShellScript (with pkgs; [curl jq]) ''
curl -s "https://api.github.com/repos/${owner}/${repo}/releases?per_page=1" | jq -r '.[0].tag_name'
''

View File

@ -0,0 +1,9 @@
{
pkgs,
utils,
...
}: {pname, ...}:
# api docs: https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#get
utils.writePureShellScript (with pkgs; [curl jq]) ''
curl -s https://registry.npmjs.com/${pname} | jq -r '."dist-tags".latest'
''

View File

@ -0,0 +1,8 @@
{
pkgs,
utils,
...
}: {pname, ...}:
utils.writePureShellScript (with pkgs; [curl jq]) ''
curl -s https://pypi.org/pypi/${pname}/json | jq -r '.info.version'
''

View File

@ -1,50 +0,0 @@
{
curl,
gnugrep,
jq,
lib,
python3,
writeText,
# dream2nix inputs
utils,
...
}: {
githubNewestReleaseTag = {
owner,
repo,
...
}:
utils.writePureShellScript [curl jq] ''
curl -s "https://api.github.com/repos/${owner}/${repo}/releases?per_page=1" | jq -r '.[0].tag_name'
'';
pypiNewestReleaseVersion = {pname, ...}:
utils.writePureShellScript [curl jq] ''
curl -s https://pypi.org/pypi/${pname}/json | jq -r '.info.version'
'';
npmNewestReleaseVersion = {pname, ...}:
# api docs: https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#get
utils.writePureShellScript [curl jq] ''
curl -s https://registry.npmjs.com/${pname} | jq -r '."dist-tags".latest'
'';
urlRegexPython =
# Don't forget to use double quoted strings
# or double escape ('\\' instead of '\').
# Expects named group 'rev' to be defined.
# Example regex:
# ''[Pp]ython-(?P<ver>[\d\.]+)\.tgz''
{
url,
regex,
...
}: let
reFile = writeText "regex" regex;
in
utils.writePureShellScript [curl gnugrep python3] ''
curl -s ${url} \
| python3 -c \
'import re, sys; print(re.search(open("${reFile}").read(), sys.stdin.read()).group("ver"), end="")'
'';
}

View File

@ -0,0 +1,22 @@
{
pkgs,
utils,
...
}:
# Don't forget to use double quoted strings
# or double escape ('\\' instead of '\').
# Expects named group 'rev' to be defined.
# Example regex:
# ''[Pp]ython-(?P<ver>[\d\.]+)\.tgz''
{
url,
regex,
...
}: let
reFile = pkgs.writeText "regex" regex;
in
utils.writePureShellScript (with pkgs; [curl gnugrep python3]) ''
curl -s ${url} \
| python3 -c \
'import re, sys; print(re.search(open("${reFile}").read(), sys.stdin.read()).group("ver"), end="")'
''

42
templates/default.nix Normal file
View File

@ -0,0 +1,42 @@
{
lib,
self,
...
}: let
l = lib // builtins;
in {
flake = {
templates =
{
default = self.templates.simple;
simple = {
description = "Simple dream2nix flake";
path = ./templates/simple;
welcomeText = ''
You just created a simple dream2nix package!
start with typing `nix flake show` to discover the projects attributes.
commands:
- `nix develop` <-- enters the devShell
- `nix build .#` <-- builds the default package (`.#default`)
Start hacking and -_- have some fun!
> dont forget to add nix `result` folder to your `.gitignore`
'';
};
}
// (
l.genAttrs
(self.lib.dlib.listDirs ../examples)
(name: {
description = "Example: ${name} template";
path = ../examples/${name};
})
);
};
}

76
tests/default.nix Normal file
View File

@ -0,0 +1,76 @@
{
inputs,
self,
...
}: {
perSystem = {
config,
pkgs,
system,
...
}: let
b = builtins;
callTests = f:
pkgs.callPackage f {
inherit self;
framework = config.d2n;
};
in {
apps = {
tests-unit.type = "app";
tests-unit.program =
b.toString
(callTests ./unit);
tests-integration.type = "app";
tests-integration.program =
b.toString
(callTests ./integration);
tests-integration-d2n-flakes.type = "app";
tests-integration-d2n-flakes.program =
b.toString
(callTests ./integration-d2n-flakes);
tests-examples.type = "app";
tests-examples.program =
b.toString
(callTests ./examples);
tests-all.type = "app";
tests-all.program =
b.toString
(config.d2n.utils.writePureShellScript
[
inputs.alejandra.defaultPackage.${system}
pkgs.coreutils
pkgs.gitMinimal
pkgs.nix
]
''
echo "check for correct formatting"
WORKDIR=$(realpath ./.)
cd $TMPDIR
cp -r $WORKDIR ./repo
cd ./repo
${config.apps.format.program} --fail-on-change
cd -
echo "running unit tests"
${config.apps.tests-unit.program}
echo "running integration tests"
${config.apps.tests-integration.program}
echo "checking flakes under ./examples"
${config.apps.tests-examples.program}
echo "running nix flake check"
cd $WORKDIR
nix flake show >/dev/null
nix flake check
'');
};
};
}

View File

@ -11,7 +11,6 @@
nix, nix,
pkgs, pkgs,
framework, framework,
dream2nixWithExternals,
... ...
}: let }: let
l = lib // builtins; l = lib // builtins;

View File

@ -7,7 +7,6 @@
git, git,
parallel, parallel,
nix, nix,
dream2nixWithExternals,
framework, framework,
... ...
}: let }: let

View File

@ -9,15 +9,18 @@
nix, nix,
pkgs, pkgs,
framework, framework,
dream2nixWithExternals,
callPackageDream,
... ...
}: let }: let
l = lib // builtins; l = lib // builtins;
testDirs = l.attrNames (l.readDir ./tests); testDirs = l.attrNames (l.readDir ./tests);
testScripts = testScripts =
map map
(dir: callPackageDream (./tests + "/${dir}") {inherit self;}) (
dir:
pkgs.callPackage
(./tests + "/${dir}")
{inherit self framework;}
)
testDirs; testDirs;
testScriptsFile = pkgs.writeText "scripts-list" (l.concatStringsSep "\n" testScripts); testScriptsFile = pkgs.writeText "scripts-list" (l.concatStringsSep "\n" testScripts);
execTest = execTest =

View File

@ -5,7 +5,6 @@
nix, nix,
git, git,
python3, python3,
dream2nixWithExternals,
framework, framework,
... ...
}: let }: let

View File

@ -26,7 +26,7 @@ exampleDreamLock = dict(
def test_dream_lock_inject(): def test_dream_lock_inject():
result = nix_ffi.callNixFunction( result = nix_ffi.callNixFunction(
'framework.utils.dream-lock.injectDependencies', 'utils.dream-lock.injectDependencies',
dreamLock=exampleDreamLock, dreamLock=exampleDreamLock,
inject=dict( inject=dict(
example={ example={
@ -43,7 +43,7 @@ def test_dream_lock_inject():
def test_dream_lock_replace_root_sources(): def test_dream_lock_replace_root_sources():
result = nix_ffi.callNixFunction( result = nix_ffi.callNixFunction(
'framework.utils.dream-lock.replaceRootSources', 'utils.dream-lock.replaceRootSources',
dreamLock=exampleDreamLock, dreamLock=exampleDreamLock,
newSourceRoot=dict( newSourceRoot=dict(
type = "http", type = "http",

View File

@ -5,7 +5,7 @@ import pytest
def get_projects_to_test(): def get_projects_to_test():
tests = nix_ffi.eval( tests = nix_ffi.eval(
'framework.translators', 'translators',
wrapper_code = ''' wrapper_code = '''
{result, ...}: let {result, ...}: let
lib = (import <nixpkgs> {}).lib; lib = (import <nixpkgs> {}).lib;
@ -65,7 +65,7 @@ def check_format_sourceSpec(sourceSpec):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_packageName(p): def test_packageName(p):
defaultPackage = nix_ffi.eval( defaultPackage = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
@ -81,7 +81,7 @@ def test_packageName(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_exportedPackages(p): def test_exportedPackages(p):
exportedPackages = nix_ffi.eval( exportedPackages = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
@ -97,7 +97,7 @@ def test_exportedPackages(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_extraObjects(p): def test_extraObjects(p):
extraObjects = nix_ffi.eval( extraObjects = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
@ -121,7 +121,7 @@ def test_extraObjects(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_location(p): def test_location(p):
location = nix_ffi.eval( location = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
@ -136,7 +136,7 @@ def test_location(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_serializedRawObjects(p): def test_serializedRawObjects(p):
serializedRawObjects = nix_ffi.eval( serializedRawObjects = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
@ -159,7 +159,7 @@ def test_serializedRawObjects(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_subsystemName(p): def test_subsystemName(p):
subsystemName = nix_ffi.eval( subsystemName = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
@ -175,7 +175,7 @@ def test_subsystemName(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_subsystemAttrs(p): def test_subsystemAttrs(p):
subsystemAttrs = nix_ffi.eval( subsystemAttrs = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
@ -191,7 +191,7 @@ def test_subsystemAttrs(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_translatorName(p): def test_translatorName(p):
translatorName = nix_ffi.eval( translatorName = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
@ -207,18 +207,18 @@ def test_translatorName(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_extractors(p): def test_extractors(p):
finalObjects = nix_ffi.eval( finalObjects = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
), ),
wrapper_code = ''' wrapper_code = '''
{result, framework, ...}: {result, dlib, ...}:
let let
l = builtins; l = builtins;
inputs = result.inputs; inputs = result.inputs;
rawObjects = inputs.serializedRawObjects; rawObjects = inputs.serializedRawObjects;
s = framework.dlib.simpleTranslate2; s = dlib.simpleTranslate2;
finalObjects = s.mkFinalObjects rawObjects inputs.extractors; finalObjects = s.mkFinalObjects rawObjects inputs.extractors;
allDependencies = s.makeDependencies finalObjects; allDependencies = s.makeDependencies finalObjects;
@ -241,18 +241,18 @@ def test_extractors(p):
@pytest.mark.parametrize("p", projects) @pytest.mark.parametrize("p", projects)
def test_keys(p): def test_keys(p):
objectsByKey = nix_ffi.eval( objectsByKey = nix_ffi.eval(
f"framework.translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate", f"translatorsBySubsystem.{p['subsystem']}.{p['translator']}.finalTranslate",
params=dict( params=dict(
project=p['project'], project=p['project'],
source=p['source'], source=p['source'],
), ),
wrapper_code = ''' wrapper_code = '''
{result, framework, ...}: {result, dlib, ...}:
let let
l = builtins; l = builtins;
inputs = result.inputs; inputs = result.inputs;
rawObjects = inputs.serializedRawObjects; rawObjects = inputs.serializedRawObjects;
s = framework.dlib.simpleTranslate2; s = dlib.simpleTranslate2;
finalObjects = s.mkFinalObjects rawObjects inputs.extractors; finalObjects = s.mkFinalObjects rawObjects inputs.extractors;
allDependencies = s.makeDependencies finalObjects; allDependencies = s.makeDependencies finalObjects;

View File

@ -68,7 +68,7 @@ import nix_ffi
]) ])
def test_translateShortcut(shortcut, expected): def test_translateShortcut(shortcut, expected):
result = nix_ffi.callNixFunction( result = nix_ffi.callNixFunction(
'framework.functions.fetchers.translateShortcut', 'functions.fetchers.translateShortcut',
shortcut=shortcut, shortcut=shortcut,
computeHash=False, computeHash=False,
) )

View File

@ -5,5 +5,5 @@ import nix_ffi
('3', [ '2', '3', '1' ]), ('3', [ '2', '3', '1' ]),
]) ])
def test_latestVersion(expected, versions): def test_latestVersion(expected, versions):
result = nix_ffi.callNixFunction('framework.dlib.latestVersion', versions=versions) result = nix_ffi.callNixFunction('dlib.latestVersion', versions=versions)
assert result == expected assert result == expected