Always build from dream-lock.json if exists

- add an invalidationHash to dream-lock.json
- always evaluate dream-lock.json if exists
- warn user if dream-lock.json doesn't exist
This commit is contained in:
DavHau 2022-02-22 18:23:49 +07:00
parent ba967fcbe0
commit d8300cb909
6 changed files with 93 additions and 15 deletions

View File

@ -63,6 +63,7 @@ class AddCommand(Command):
),
option("force", None, "override existing files", flag=True),
option("no-default-nix", None, "create default.nix", flag=True),
option("invalidation-hash", None, "invalidation hash to attach", flag=False),
]
def handle(self):
@ -383,6 +384,7 @@ class AddCommand(Command):
) + [
f"--arg {n}={v}" for n, v in specified_extra_args.items()
])
lock['_generic']['invalidationHash'] = self.option('invalidation-hash')
def calc_outputs(self, main_package_dir_name, packages_root):
if self.option('target'):
@ -504,7 +506,7 @@ class AddCommand(Command):
# assume defaults for unspecified extra args
specified_extra_args.update(
{n: (True if v['type'] == 'flag' else v['default']) \
{n: (False if v['type'] == 'flag' else v['default']) \
for n, v in translator['extraArgs'].items() \
if n not in specified_extra_args}
)

View File

@ -15,9 +15,9 @@
# default to empty dream2nix config
config ?
# if called via CLI, load cnfig via env
if builtins ? getEnv && builtins.getEnv "d2nConfigFile" != "" then
builtins.toPath (builtins.getEnv "d2nConfigFile")
# if called via CLI, load config via env
if builtins ? getEnv && builtins.getEnv "dream2nixConfig" != "" then
builtins.toPath (builtins.getEnv "dream2nixConfig")
# load from default directory
else
{},

View File

@ -110,6 +110,7 @@ let
riseAndShineFunc =
{
pname,
pkgs ? null,
source,
systems ? [],
@ -121,12 +122,12 @@ let
config = args.config or ((import ./utils/config.nix).loadConfig {});
argsForward = b.removeAttrs args [ "config" "pkgs" "systems" ];
argsForward = b.removeAttrs args [ "config" "pname" "pkgs" "systems" ];
allPkgs = makeNixpkgs pkgs systems;
dream2nixFor =
lib.mapAttrs (dream2nixForSystem {}) allPkgs;
lib.mapAttrs (dream2nixForSystem config) allPkgs;
allBuilderOutputs =
lib.mapAttrs
@ -139,18 +140,65 @@ let
translatorName = args.translator or null;
};
result = translator:
dream2nix.riseAndShine (argsForward // {
invalidationHash = dream2nix.utils.calcInvalidationHash {
inherit source translatorArgs;
translator = translatorFound.name;
};
dreamLockJsonPath = with config;
"${projectRoot}/${packagesDir}/${pname}/dream-lock.json";
dreamLock = dream2nix.utils.readDreamLock {
dreamLock = dreamLockJsonPath;
};
dreamLockExistsAndValid =
b.pathExists dreamLockJsonPath
&& dreamLock.lock._generic.invalidationHash or "" == invalidationHash;
result = translator: args:
dream2nix.riseAndShine (argsForward // args // {
# TODO: this triggers the translator finding routine a second time
translator = translatorFound.name;
});
in
if b.elem translatorFound.type [ "pure" "ifd" ] then
result translatorFound
else
if dreamLockExistsAndValid then
# we need to override the source here as it is coming from
# a flake input
let
defaultPackage = dreamLock.lock._generic.defaultPackage;
defaultPackageVersion =
dreamLock.lock._generic.packages."${defaultPackage}";
in
result translatorFound {
source = dreamLockJsonPath;
sourceOverrides = oldSources: {
"${defaultPackage}"."${defaultPackageVersion}" =
args.source;
};
}
else if b.elem translatorFound.type [ "pure" "ifd" ] then
# warn the user about potentially slow on-the-fly evaluation
b.trace ''
Some information is missing to build this project reproducibly.
Please execute nix run .#resolve to resolve impurities.
${"\n"}
The dream-lock.json for input '${pname}' doesn't exist or is outdated.
...Falling back to on-the-fly evaluation (possibly slow).
To speed up future evalutations run once:
nix run .#resolve
''
result translatorFound {}
else
# print error because impure translation is required first.
# continue the evaluation anyways, as otherwise we won't have
# the `resolve` app
b.trace ''
${"\n"}
ERROR:
Some information is missing to build this project reproducibly.
Please execute nix run .#resolve to resolve all impurities.
''
{})
@ -178,11 +226,20 @@ let
resolve.program =
let
utils = (dream2nixFor."${system}".utils);
# TODO: Too many calls to findOneTranslator.
# -> make findOneTranslator system independent
translatorFound =
dream2nixFor."${system}".translators.findOneTranslator {
inherit source;
translatorName = args.translator or null;
};
in
b.toString
(utils.makePackageLockScript {
inherit source translator translatorArgs;
inherit source translatorArgs;
packagesDir = config.packagesDir;
translator = translatorFound.name;
});
});
};

View File

@ -154,6 +154,7 @@
"type": "object",
"properties": {
"defaultPackage": { "type": ["string", "null"] },
"invalidationHash": { "type": ["string", "null"] },
"packages": { "type": "object" },
"sourcesAggregatedHash": { "type": ["string", "null"] },
"subsystem": { "type": "string" },

View File

@ -23,7 +23,8 @@ let
defaults = {
overridesDirs = [];
packagesDir = null;
repoName = "this repo";
projectRoot = throw "projectRoot not specified in dream2nix config";
repoName = null;
};
in
defaults // config;

View File

@ -198,6 +198,19 @@ rec {
recursiveUpdateUntilDepth = depth: lhs: rhs:
lib.recursiveUpdateUntil (path: l: r: (b.length path) > depth) lhs rhs;
# calculate an invalidation hash for given source translation inputs
calcInvalidationHash =
{
source,
translator,
translatorArgs,
}:
b.hashString "sha256" ''
${source}
${translator}
${b.toString
(lib.mapAttrsToList (k: v: "${k}=${v}") translatorArgs)}
'';
# a script that produces and dumps the dream-lock json for a given source
makePackageLockScript =
@ -210,10 +223,14 @@ rec {
writePureShellScript
[]
''
cd $WORKDIR
${apps.cli.program} add ${source} \
--force \
--no-default-nix \
--translator ${translator} \
--invalidation-hash ${calcInvalidationHash {
inherit source translator translatorArgs;
}} \
--packages-root $WORKDIR/${packagesDir} \
${lib.concatStringsSep " \\\n"
(lib.mapAttrsToList