mirror of
https://github.com/NixOS/nix
synced 2025-07-06 21:41:48 +02:00
Merge pull request #9032 from Ma27/structured-attrs-env-vars
structured attrs: improve support / usage of NIX_ATTRS_{SH,JSON}_FILE
This commit is contained in:
commit
3c042f3b0b
10 changed files with 146 additions and 21 deletions
|
@ -8,9 +8,12 @@
|
|||
#include "derivations.hh"
|
||||
#include "progress-bar.hh"
|
||||
#include "run.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace nix;
|
||||
|
||||
|
@ -51,6 +54,7 @@ struct BuildEnvironment
|
|||
|
||||
std::map<std::string, Value> vars;
|
||||
std::map<std::string, std::string> bashFunctions;
|
||||
std::optional<std::pair<std::string, std::string>> structuredAttrs;
|
||||
|
||||
static BuildEnvironment fromJSON(std::string_view in)
|
||||
{
|
||||
|
@ -74,6 +78,10 @@ struct BuildEnvironment
|
|||
res.bashFunctions.insert({name, def});
|
||||
}
|
||||
|
||||
if (json.contains("structuredAttrs")) {
|
||||
res.structuredAttrs = {json["structuredAttrs"][".attrs.json"], json["structuredAttrs"][".attrs.sh"]};
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -102,6 +110,13 @@ struct BuildEnvironment
|
|||
|
||||
res["bashFunctions"] = bashFunctions;
|
||||
|
||||
if (providesStructuredAttrs()) {
|
||||
auto contents = nlohmann::json::object();
|
||||
contents[".attrs.sh"] = getAttrsSH();
|
||||
contents[".attrs.json"] = getAttrsJSON();
|
||||
res["structuredAttrs"] = std::move(contents);
|
||||
}
|
||||
|
||||
auto json = res.dump();
|
||||
|
||||
assert(BuildEnvironment::fromJSON(json) == *this);
|
||||
|
@ -109,6 +124,23 @@ struct BuildEnvironment
|
|||
return json;
|
||||
}
|
||||
|
||||
bool providesStructuredAttrs() const
|
||||
{
|
||||
return structuredAttrs.has_value();
|
||||
}
|
||||
|
||||
std::string getAttrsJSON() const
|
||||
{
|
||||
assert(providesStructuredAttrs());
|
||||
return structuredAttrs->first;
|
||||
}
|
||||
|
||||
std::string getAttrsSH() const
|
||||
{
|
||||
assert(providesStructuredAttrs());
|
||||
return structuredAttrs->second;
|
||||
}
|
||||
|
||||
void toBash(std::ostream & out, const std::set<std::string> & ignoreVars) const
|
||||
{
|
||||
for (auto & [name, value] : vars) {
|
||||
|
@ -291,6 +323,7 @@ struct Common : InstallableCommand, MixProfile
|
|||
std::string makeRcScript(
|
||||
ref<Store> store,
|
||||
const BuildEnvironment & buildEnvironment,
|
||||
const Path & tmpDir,
|
||||
const Path & outputsDir = absPath(".") + "/outputs")
|
||||
{
|
||||
// A list of colon-separated environment variables that should be
|
||||
|
@ -353,9 +386,48 @@ struct Common : InstallableCommand, MixProfile
|
|||
}
|
||||
}
|
||||
|
||||
if (buildEnvironment.providesStructuredAttrs()) {
|
||||
fixupStructuredAttrs(
|
||||
"sh",
|
||||
"NIX_ATTRS_SH_FILE",
|
||||
buildEnvironment.getAttrsSH(),
|
||||
rewrites,
|
||||
buildEnvironment,
|
||||
tmpDir
|
||||
);
|
||||
fixupStructuredAttrs(
|
||||
"json",
|
||||
"NIX_ATTRS_JSON_FILE",
|
||||
buildEnvironment.getAttrsJSON(),
|
||||
rewrites,
|
||||
buildEnvironment,
|
||||
tmpDir
|
||||
);
|
||||
}
|
||||
|
||||
return rewriteStrings(script, rewrites);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the value of NIX_ATTRS_*_FILE (`/build/.attrs.*`) with a tmp file
|
||||
* that's accessible from the interactive shell session.
|
||||
*/
|
||||
void fixupStructuredAttrs(
|
||||
const std::string & ext,
|
||||
const std::string & envVar,
|
||||
const std::string & content,
|
||||
StringMap & rewrites,
|
||||
const BuildEnvironment & buildEnvironment,
|
||||
const Path & tmpDir)
|
||||
{
|
||||
auto targetFilePath = tmpDir + "/.attrs." + ext;
|
||||
writeFile(targetFilePath, content);
|
||||
|
||||
auto fileInBuilderEnv = buildEnvironment.vars.find(envVar);
|
||||
assert(fileInBuilderEnv != buildEnvironment.vars.end());
|
||||
rewrites.insert({BuildEnvironment::getString(fileInBuilderEnv->second), targetFilePath});
|
||||
}
|
||||
|
||||
Strings getDefaultFlakeAttrPaths() override
|
||||
{
|
||||
Strings paths{
|
||||
|
@ -487,7 +559,9 @@ struct CmdDevelop : Common, MixEnvironment
|
|||
|
||||
auto [rcFileFd, rcFilePath] = createTempFile("nix-shell");
|
||||
|
||||
auto script = makeRcScript(store, buildEnvironment);
|
||||
AutoDelete tmpDir(createTempDir("", "nix-develop"), true);
|
||||
|
||||
auto script = makeRcScript(store, buildEnvironment, (Path) tmpDir);
|
||||
|
||||
if (verbosity >= lvlDebug)
|
||||
script += "set -x\n";
|
||||
|
@ -615,10 +689,12 @@ struct CmdPrintDevEnv : Common, MixJSON
|
|||
|
||||
stopProgressBar();
|
||||
|
||||
logger->writeToStdout(
|
||||
json
|
||||
? buildEnvironment.toJSON()
|
||||
: makeRcScript(store, buildEnvironment));
|
||||
if (json) {
|
||||
logger->writeToStdout(buildEnvironment.toJSON());
|
||||
} else {
|
||||
AutoDelete tmpDir(createTempDir("", "nix-dev-env"), true);
|
||||
logger->writeToStdout(makeRcScript(store, buildEnvironment, tmpDir));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
set -e
|
||||
if [ -e .attrs.sh ]; then source .attrs.sh; fi
|
||||
if [ -e "$NIX_ATTRS_SH_FILE" ]; then source "$NIX_ATTRS_SH_FILE"; fi
|
||||
|
||||
export IN_NIX_SHELL=impure
|
||||
export dontAddDisableDepTrack=1
|
||||
|
@ -101,7 +101,21 @@ __dumpEnv() {
|
|||
|
||||
printf "}"
|
||||
done < <(printf "%s\n" "$__vars")
|
||||
printf '\n }\n}'
|
||||
printf '\n }'
|
||||
|
||||
if [ -e "$NIX_ATTRS_SH_FILE" ]; then
|
||||
printf ',\n "structuredAttrs": {\n '
|
||||
__escapeString ".attrs.sh"
|
||||
printf ': '
|
||||
__escapeString "$(<"$NIX_ATTRS_SH_FILE")"
|
||||
printf ',\n '
|
||||
__escapeString ".attrs.json"
|
||||
printf ': '
|
||||
__escapeString "$(<"$NIX_ATTRS_JSON_FILE")"
|
||||
printf '\n }'
|
||||
fi
|
||||
|
||||
printf '\n}'
|
||||
}
|
||||
|
||||
__escapeString() {
|
||||
|
@ -117,7 +131,7 @@ __escapeString() {
|
|||
# In case of `__structuredAttrs = true;` the list of outputs is an associative
|
||||
# array with a format like `outname => /nix/store/hash-drvname-outname`, so `__olist`
|
||||
# must contain the array's keys (hence `${!...[@]}`) in this case.
|
||||
if [ -e .attrs.sh ]; then
|
||||
if [ -e "$NIX_ATTRS_SH_FILE" ]; then
|
||||
__olist="${!outputs[@]}"
|
||||
else
|
||||
__olist=$outputs
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue