repl: allow :p to print derivation attrs.
Change-Id: I6a6a6964a58c3340acca9272c616c079c5218d6e
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
---
|
||||
synopsis: Derivations can now be printed in detail in `nix repl`
|
||||
cls: [3842]
|
||||
category: Improvements
|
||||
credits: [Lunaphied]
|
||||
---
|
||||
|
||||
Traditionally derivations printed in the REPL would only print a formatted object
|
||||
representing the path of the derivation file it refers to. This makes inspecting
|
||||
the enhanced derivation attribute sets encountered from `mkDerivation` or similar
|
||||
wrappers more difficult. Even the `:p`/`:print` command would not elaborate attribute sets
|
||||
tagged as a derivation.
|
||||
|
||||
With this change you can now use `:p`/`:print` to directly inspect a derivation
|
||||
by providing one as the top-level object. Derivation attribute sets will only be
|
||||
printed two levels deep and internal derivation attrsets will remain in unexpanded
|
||||
path form as before. `drvAttrs` will also be elided as these attributes are already
|
||||
present in the top-level attribute set of the derivation. These heuristics provide
|
||||
a balance between readability and functionality. When the `:p`/`:print` is omitted,
|
||||
a bare derivation is printed in the path format as before.
|
||||
+7
-3
@@ -209,12 +209,14 @@ struct NixRepl
|
||||
|
||||
void printValue(std::ostream & str,
|
||||
Value & v,
|
||||
unsigned int maxDepth = std::numeric_limits<unsigned int>::max())
|
||||
unsigned int maxDepth = std::numeric_limits<unsigned int>::max(),
|
||||
bool replDerivation = false)
|
||||
{
|
||||
::nix::printValue(state, str, v, PrintOptions {
|
||||
.ansiColors = true,
|
||||
.force = true,
|
||||
.derivationPaths = true,
|
||||
.derivationPaths = !replDerivation,
|
||||
.replDerivation = replDerivation,
|
||||
.maxDepth = maxDepth,
|
||||
.prettyIndent = 2,
|
||||
.errors = ErrorPrintBehavior::ThrowTopLevel,
|
||||
@@ -793,8 +795,10 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
||||
evalString(arg, v);
|
||||
if (v.type() == nString) {
|
||||
std::cout << v.str();
|
||||
} else if (v.type() == nAttrs && state.isDerivation(v)) {
|
||||
printValue(std::cout, v, 2, true);
|
||||
} else {
|
||||
printValue(std::cout, v);
|
||||
printValue(std::cout, v, std::numeric_limits<unsigned int>::max());
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,12 @@ struct PrintOptions
|
||||
*/
|
||||
bool derivationPaths = false;
|
||||
|
||||
/**
|
||||
* If true, we are interactively printing a full derivation and should
|
||||
* switch back to printing paths as desired normally after the first entry.
|
||||
*/
|
||||
bool replDerivation = false;
|
||||
|
||||
/**
|
||||
* If true, track which values have been printed and skip them on
|
||||
* subsequent encounters. Useful for self-referential values.
|
||||
|
||||
+21
-2
@@ -286,6 +286,11 @@ private:
|
||||
} else if (seen && !v.attrs()->empty() && !seen->insert(v.attrs()).second) {
|
||||
printRepeated();
|
||||
} else if (depth < options.maxDepth || v.attrs()->empty()) {
|
||||
bool isPrintingReplDerivation = depth == 0 && options.replDerivation && state.isDerivation(v);
|
||||
if (isPrintingReplDerivation) {
|
||||
// Switch back to eliding paths if it was initially off.
|
||||
options.derivationPaths = true;
|
||||
}
|
||||
increaseIndent();
|
||||
output << "{";
|
||||
|
||||
@@ -304,7 +309,7 @@ private:
|
||||
for (auto & i : sorted) {
|
||||
printSpace(prettyPrint);
|
||||
|
||||
if (attrsPrinted >= options.maxAttrs) {
|
||||
if (attrsPrinted >= options.maxAttrs ) {
|
||||
printElided(sorted.size() - printedHere, "attribute", "attributes");
|
||||
break;
|
||||
}
|
||||
@@ -324,6 +329,21 @@ private:
|
||||
}
|
||||
|
||||
output << " = ";
|
||||
|
||||
// Elide repeated drvAttrs attribute.
|
||||
if (isPrintingReplDerivation && i.first == "drvAttrs") {
|
||||
state.forceValue(i.second->value, noPos);
|
||||
if (i.second->value.type() == ValueType::nAttrs) {
|
||||
printElided(i.second->value.attrs()->size(), "attribute", "attributes");
|
||||
} else {
|
||||
print(i.second->value, depth + 1);
|
||||
}
|
||||
output << ";";
|
||||
attrsPrinted++;
|
||||
printedHere++;
|
||||
continue;
|
||||
}
|
||||
|
||||
print(i.second->value, depth + 1);
|
||||
output << ";";
|
||||
attrsPrinted++;
|
||||
@@ -582,7 +602,6 @@ public:
|
||||
seen.reset();
|
||||
}
|
||||
|
||||
ValuesSeen seen;
|
||||
print(v, 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -100,3 +100,15 @@ Printing an environment with :env after adding a variable to the scope
|
||||
|
||||
Env level 1
|
||||
abort baseNameOf break builtins derivation derivationStrict dirOf false fetchGit fetchMercurial fetchTarball fetchTree fromTOML import isNull map null placeholder removeAttrs scopedImport throw toString true
|
||||
|
||||
Printing a derivation or something
|
||||
|
||||
nix-repl> fakeDrv = let drvAttrs = { builder = "meow"; system = "meower"; name = "mrowmrow"; }; in { inherit (drvAttrs) builder system name; inherit drvAttrs; type = "derivation"; }
|
||||
nix-repl> :p fakeDrv
|
||||
{
|
||||
builder = "meow";
|
||||
drvAttrs = «3 attributes elided»;
|
||||
name = "mrowmrow";
|
||||
system = "meower";
|
||||
type = "derivation";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user