Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/libcmd/installable-flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,10 @@ FlakeRef InstallableFlake::nixpkgsFlakeRef() const

std::shared_ptr<const Provenance> InstallableFlake::makeProvenance(std::string_view attrPath) const
{
if (!evalSettings.pureEval)
return nullptr;
auto provenance = getLockedFlake()->flake.provenance;
if (!provenance)
return nullptr;
return std::make_shared<const FlakeProvenance>(provenance, std::string(attrPath));
return std::make_shared<const FlakeProvenance>(provenance, std::string(attrPath), evalSettings.pureEval);
}

} // namespace nix
6 changes: 2 additions & 4 deletions src/libfetchers/fetchers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,7 @@ std::pair<ref<SourceAccessor>, Input> Input::getAccessorUnchecked(const Settings
{{"hash", store.queryPathInfo(*storePath)->narHash.to_string(HashFormat::SRI, true)}});
}

if (isLocked(settings))
accessor->provenance = std::make_shared<TreeProvenance>(*this);
accessor->provenance = std::make_shared<TreeProvenance>(*this);

// FIXME: ideally we would use the `showPath()` of the
// "real" accessor for this fetcher type.
Expand All @@ -365,8 +364,7 @@ std::pair<ref<SourceAccessor>, Input> Input::getAccessorUnchecked(const Settings
else
accessor->fingerprint = result.getFingerprint(store);

if (result.isLocked(settings))
accessor->provenance = std::make_shared<TreeProvenance>(result);
accessor->provenance = std::make_shared<TreeProvenance>(result);

return {accessor, std::move(result)};
} catch (Error & e) {
Expand Down
6 changes: 4 additions & 2 deletions src/libflake/include/nix/flake/provenance.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ struct FlakeProvenance : Provenance
{
std::shared_ptr<const Provenance> next;
std::string flakeOutput;
bool pure = true;

FlakeProvenance(std::shared_ptr<const Provenance> next, std::string flakeOutput)
FlakeProvenance(std::shared_ptr<const Provenance> next, std::string flakeOutput, bool pure)
: next(std::move(next))
, flakeOutput(std::move(flakeOutput)) {};
, flakeOutput(std::move(flakeOutput))
, pure(pure) {};

nlohmann::json to_json() const override;
};
Expand Down
7 changes: 5 additions & 2 deletions src/libflake/provenance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@ nlohmann::json FlakeProvenance::to_json() const
{"type", "flake"},
{"next", next ? next->to_json() : nlohmann::json(nullptr)},
{"flakeOutput", flakeOutput},
};
{"pure", pure}};
}

Provenance::Register registerFlakeProvenance("flake", [](nlohmann::json json) {
auto & obj = getObject(json);
std::shared_ptr<const Provenance> next;
if (auto p = optionalValueAt(obj, "next"); p && !p->is_null())
next = Provenance::from_json(*p);
return make_ref<FlakeProvenance>(next, getString(valueAt(obj, "flakeOutput")));
bool pure = true;
if (auto p = optionalValueAt(obj, "pure"))
pure = getBoolean(*p);
return make_ref<FlakeProvenance>(next, getString(valueAt(obj, "flakeOutput")), pure);
});

} // namespace nix
9 changes: 7 additions & 2 deletions src/nix/provenance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ struct CmdProvenanceShow : StorePathsCommand
fetchers::Input::fromAttrs(fetchSettings, fetchers::jsonToAttrs(*tree->attrs)),
Path(flakePath.parent().value_or(CanonPath::root).rel()));
logger->cout(
"← instantiated from flake output " ANSI_BOLD "%s#%s" ANSI_NORMAL,
"← %sinstantiated from %sflake output " ANSI_BOLD "%s#%s" ANSI_NORMAL,
flake->pure ? "" : ANSI_RED "impurely" ANSI_NORMAL " ",
flakeRef.input.isLocked(fetchSettings) ? "" : ANSI_RED "unlocked" ANSI_NORMAL " ",
flakeRef.to_string(),
flake->flakeOutput);
break;
Expand All @@ -89,7 +91,10 @@ struct CmdProvenanceShow : StorePathsCommand
}
} else if (auto tree = std::dynamic_pointer_cast<const TreeProvenance>(provenance)) {
auto input = fetchers::Input::fromAttrs(fetchSettings, fetchers::jsonToAttrs(*tree->attrs));
logger->cout("← from tree " ANSI_BOLD "%s" ANSI_NORMAL, input.to_string());
logger->cout(
"← from %stree " ANSI_BOLD "%s" ANSI_NORMAL,
input.isLocked(fetchSettings) ? "" : ANSI_RED "unlocked" ANSI_NORMAL " ",
input.to_string());
break;
} else if (auto subpath = std::dynamic_pointer_cast<const SubpathProvenance>(provenance)) {
logger->cout("← from file " ANSI_BOLD "%s" ANSI_NORMAL, subpath->subpath.abs());
Expand Down
50 changes: 47 additions & 3 deletions tests/functional/flakes/provenance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ builder=$(nix eval --raw "$flake1Dir#packages.$system.default._builder")
"subpath": "/flake.nix",
"type": "subpath"
},
"pure": true,
"type": "flake"
},
"type": "derivation"
Expand Down Expand Up @@ -98,6 +99,13 @@ EOF
EOF
) ]]

[[ "$(nix provenance show "$builder")" = $(cat <<EOF
$builder
← from file /simple.builder.sh
← from tree git+file://$flake1Dir?ref=refs/heads/master&rev=$rev
EOF
) ]]

# Check that substituting from a binary cache adds "copied" provenance.
binaryCache="$TEST_ROOT/binary-cache"
nix copy --to "file://$binaryCache" "$outPath"
Expand Down Expand Up @@ -149,6 +157,7 @@ nix copy --from "file://$binaryCache" "$outPath" --no-check-sigs
"subpath": "/flake.nix",
"type": "subpath"
},
"pure": true,
"type": "flake"
},
"type": "derivation"
Expand Down Expand Up @@ -194,7 +203,26 @@ nix build --impure --print-out-paths --no-link "$flake1Dir#packages.$system.defa
}
]
},
"next": null,
"next": {
"flakeOutput": "packages.$system.default",
"next": {
"next": {
"attrs": {
"lastModified": $lastModified,
"ref": "refs/heads/master",
"rev": "$rev",
"revCount": 1,
"type": "git",
"url": "file://$flake1Dir"
},
"type": "tree"
},
"subpath": "/flake.nix",
"type": "subpath"
},
"pure": false,
"type": "flake"
},
"type": "derivation"
}
EOF
Expand All @@ -204,5 +232,21 @@ clearStore
echo foo > "$flake1Dir/somefile"
git -C "$flake1Dir" add somefile
nix build --impure --print-out-paths --no-link "$flake1Dir#packages.$system.default"
builder=$(nix eval --raw "$flake1Dir#packages.$system.default._builder")
[[ $(nix path-info --json --json-format 1 "$builder" | jq ".\"$builder\".provenance") = null ]]
[[ $(nix path-info --json --json-format 1 "$builder" | jq ".\"$builder\".provenance") != null ]]

[[ "$(nix provenance show "$outPath")" = $(cat <<EOF
$outPath
← built from derivation $drvPath (output out) on test-host for $system
← with derivation metadata
Licenses:
- lgpl21
← impurely instantiated from unlocked flake output git+file://$flake1Dir#packages.$system.default
EOF
) ]]

[[ "$(nix provenance show "$builder")" = $(cat <<EOF
$builder
← from file /simple.builder.sh
← from unlocked tree git+file://$flake1Dir
EOF
) ]]