Skip to content

Commit

Permalink
Merge pull request NixOS#4998 from edolstra/nix-print-dev-env-json
Browse files Browse the repository at this point in the history
nix print-dev-env: Add --json flag
  • Loading branch information
edolstra authored Jul 9, 2021
2 parents 223e056 + 86fb01c commit 9cf991f
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 10 deletions.
59 changes: 52 additions & 7 deletions src/nix/develop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand All @@ -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"];
Expand All @@ -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) {
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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};
}
};

Expand Down Expand Up @@ -462,7 +504,7 @@ struct CmdDevelop : Common, MixEnvironment
}
};

struct CmdPrintDevEnv : Common
struct CmdPrintDevEnv : Common, MixJSON
{
std::string description() override
{
Expand All @@ -484,7 +526,10 @@ struct CmdPrintDevEnv : Common

stopProgressBar();

std::cout << makeRcScript(store, buildEnvironment);
logger->writeToStdout(
json
? buildEnvironment.toJSON()
: makeRcScript(store, buildEnvironment));
}
};

Expand Down
1 change: 1 addition & 0 deletions src/nix/get-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 || \
Expand Down
37 changes: 34 additions & 3 deletions src/nix/print-dev-env.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

)""
2 changes: 2 additions & 0 deletions tests/nix-shell.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]]
Expand Down

0 comments on commit 9cf991f

Please sign in to comment.