aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nix/develop.cc59
-rw-r--r--src/nix/get-env.sh1
-rw-r--r--src/nix/print-dev-env.md37
-rw-r--r--tests/nix-shell.sh2
4 files changed, 89 insertions, 10 deletions
diff --git a/src/nix/develop.cc b/src/nix/develop.cc
index 9b2945ba3..ca04f297d 100644
--- a/src/nix/develop.cc
+++ b/src/nix/develop.cc
@@ -31,6 +31,11 @@ struct BuildEnvironment
{
bool exported;
std::string value;
+
+ bool operator == (const String & other) const
+ {
+ return exported == other.exported && value == other.value;
+ }
};
using Array = std::vector<std::string>;
@@ -42,15 +47,13 @@ struct BuildEnvironment
std::map<std::string, Value> vars;
std::map<std::string, std::string> bashFunctions;
- static BuildEnvironment fromJSON(const Path & path)
+ static BuildEnvironment fromJSON(std::string_view in)
{
BuildEnvironment res;
std::set<std::string> exported;
- debug("reading environment file '%s'", path);
-
- auto json = nlohmann::json::parse(readFile(path));
+ auto json = nlohmann::json::parse(in);
for (auto & [name, info] : json["variables"].items()) {
std::string type = info["type"];
@@ -69,6 +72,38 @@ struct BuildEnvironment
return res;
}
+ std::string toJSON() const
+ {
+ auto res = nlohmann::json::object();
+
+ auto vars2 = nlohmann::json::object();
+ for (auto & [name, value] : vars) {
+ auto info = nlohmann::json::object();
+ if (auto str = std::get_if<String>(&value)) {
+ info["type"] = str->exported ? "exported" : "var";
+ info["value"] = str->value;
+ }
+ else if (auto arr = std::get_if<Array>(&value)) {
+ info["type"] = "array";
+ info["value"] = *arr;
+ }
+ else if (auto arr = std::get_if<Associative>(&value)) {
+ info["type"] = "associative";
+ info["value"] = *arr;
+ }
+ vars2[name] = std::move(info);
+ }
+ res["variables"] = std::move(vars2);
+
+ res["bashFunctions"] = bashFunctions;
+
+ auto json = res.dump();
+
+ assert(BuildEnvironment::fromJSON(json) == *this);
+
+ return json;
+ }
+
void toBash(std::ostream & out, const std::set<std::string> & ignoreVars) const
{
for (auto & [name, value] : vars) {
@@ -116,6 +151,11 @@ struct BuildEnvironment
else
throw Error("bash variable is not a string or array");
}
+
+ bool operator == (const BuildEnvironment & other) const
+ {
+ return vars == other.vars && bashFunctions == other.bashFunctions;
+ }
};
const static std::string getEnvSh =
@@ -309,7 +349,9 @@ struct Common : InstallableCommand, MixProfile
updateProfile(shellOutPath);
- return {BuildEnvironment::fromJSON(strPath), strPath};
+ debug("reading environment file '%s'", strPath);
+
+ return {BuildEnvironment::fromJSON(readFile(strPath)), strPath};
}
};
@@ -462,7 +504,7 @@ struct CmdDevelop : Common, MixEnvironment
}
};
-struct CmdPrintDevEnv : Common
+struct CmdPrintDevEnv : Common, MixJSON
{
std::string description() override
{
@@ -484,7 +526,10 @@ struct CmdPrintDevEnv : Common
stopProgressBar();
- std::cout << makeRcScript(store, buildEnvironment);
+ logger->writeToStdout(
+ json
+ ? buildEnvironment.toJSON()
+ : makeRcScript(store, buildEnvironment));
}
};
diff --git a/src/nix/get-env.sh b/src/nix/get-env.sh
index 20937b956..2df3e543f 100644
--- a/src/nix/get-env.sh
+++ b/src/nix/get-env.sh
@@ -49,6 +49,7 @@ __dumpEnv() {
$__var_name = FUNCNAME || \
$__var_name = HISTCMD || \
$__var_name = HOSTNAME || \
+ $__var_name = GROUPS || \
$__var_name = PIPESTATUS || \
$__var_name = PWD || \
$__var_name = RANDOM || \
diff --git a/src/nix/print-dev-env.md b/src/nix/print-dev-env.md
index b80252acf..2aad491de 100644
--- a/src/nix/print-dev-env.md
+++ b/src/nix/print-dev-env.md
@@ -8,12 +8,43 @@ R""(
# . <(nix print-dev-env nixpkgs#hello)
```
+* Get the build environment in JSON format:
+
+ ```console
+ # nix print-dev-env nixpkgs#hello --json
+ ```
+
+ The output will look like this:
+
+ ```json
+ {
+ "bashFunctions": {
+ "buildPhase": " \n runHook preBuild;\n...",
+ ...
+ },
+ "variables": {
+ "src": {
+ "type": "exported",
+ "value": "/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz"
+ },
+ "postUnpackHooks": {
+ "type": "array",
+ "value": ["_updateSourceDateEpochFromSourceRoot"]
+ },
+ ...
+ }
+ }
+ ```
+
# Description
-This command prints a shell script that can be sourced by `b`ash and
-that sets the environment variables and shell functions defined by the
-build process of *installable*. This allows you to get a similar build
+This command prints a shell script that can be sourced by `bash` and
+that sets the variables and shell functions defined by the build
+process of *installable*. This allows you to get a similar build
environment in your current shell rather than in a subshell (as with
`nix develop`).
+With `--json`, the output is a JSON serialisation of the variables and
+functions defined by the build process.
+
)""
diff --git a/tests/nix-shell.sh b/tests/nix-shell.sh
index ec43db349..f60102f9c 100644
--- a/tests/nix-shell.sh
+++ b/tests/nix-shell.sh
@@ -96,6 +96,8 @@ echo foo | nix develop -f shell.nix shellDrv -c cat | grep -q foo
nix_develop -f shell.nix shellDrv -c echo foo |& grep -q foo
# Test 'nix print-dev-env'.
+[[ $(nix print-dev-env -f shell.nix shellDrv --json | jq -r .variables.arr1.value[2]) = '3 4' ]]
+
source <(nix print-dev-env -f shell.nix shellDrv)
[[ -n $stdenv ]]
[[ ${arr1[2]} = "3 4" ]]