Don't hide repeated values while generating manifest.nix

Fixes #6243.
This commit is contained in:
Eelco Dolstra 2022-03-22 13:18:11 +01:00
parent 732296ddc0
commit a0259a21a4
4 changed files with 32 additions and 18 deletions

View file

@ -96,20 +96,20 @@ RootValue allocRootValue(Value * v)
} }
void printValue(std::ostream & str, std::set<const void *> & seen, const Value & v) void Value::print(std::ostream & str, std::set<const void *> * seen) const
{ {
checkInterrupt(); checkInterrupt();
switch (v.internalType) { switch (internalType) {
case tInt: case tInt:
str << v.integer; str << integer;
break; break;
case tBool: case tBool:
str << (v.boolean ? "true" : "false"); str << (boolean ? "true" : "false");
break; break;
case tString: case tString:
str << "\""; str << "\"";
for (const char * i = v.string.s; *i; i++) for (const char * i = string.s; *i; i++)
if (*i == '\"' || *i == '\\') str << "\\" << *i; if (*i == '\"' || *i == '\\') str << "\\" << *i;
else if (*i == '\n') str << "\\n"; else if (*i == '\n') str << "\\n";
else if (*i == '\r') str << "\\r"; else if (*i == '\r') str << "\\r";
@ -119,19 +119,19 @@ void printValue(std::ostream & str, std::set<const void *> & seen, const Value &
str << "\""; str << "\"";
break; break;
case tPath: case tPath:
str << v.path; // !!! escaping? str << path; // !!! escaping?
break; break;
case tNull: case tNull:
str << "null"; str << "null";
break; break;
case tAttrs: { case tAttrs: {
if (!v.attrs->empty() && !seen.insert(v.attrs).second) if (seen && !attrs->empty() && !seen->insert(attrs).second)
str << "«repeated»"; str << "«repeated»";
else { else {
str << "{ "; str << "{ ";
for (auto & i : v.attrs->lexicographicOrder()) { for (auto & i : attrs->lexicographicOrder()) {
str << i->name << " = "; str << i->name << " = ";
printValue(str, seen, *i->value); i->value->print(str, seen);
str << "; "; str << "; ";
} }
str << "}"; str << "}";
@ -141,12 +141,12 @@ void printValue(std::ostream & str, std::set<const void *> & seen, const Value &
case tList1: case tList1:
case tList2: case tList2:
case tListN: case tListN:
if (v.listSize() && !seen.insert(v.listElems()).second) if (seen && listSize() && !seen->insert(listElems()).second)
str << "«repeated»"; str << "«repeated»";
else { else {
str << "[ "; str << "[ ";
for (auto v2 : v.listItems()) { for (auto v2 : listItems()) {
printValue(str, seen, *v2); v2->print(str, seen);
str << " "; str << " ";
} }
str << "]"; str << "]";
@ -166,10 +166,10 @@ void printValue(std::ostream & str, std::set<const void *> & seen, const Value &
str << "<PRIMOP-APP>"; str << "<PRIMOP-APP>";
break; break;
case tExternal: case tExternal:
str << *v.external; str << *external;
break; break;
case tFloat: case tFloat:
str << v.fpoint; str << fpoint;
break; break;
default: default:
abort(); abort();
@ -177,10 +177,16 @@ void printValue(std::ostream & str, std::set<const void *> & seen, const Value &
} }
std::ostream & operator << (std::ostream & str, const Value & v) void Value::print(std::ostream & str, bool showRepeated) const
{ {
std::set<const void *> seen; std::set<const void *> seen;
printValue(str, seen, v); print(str, showRepeated ? nullptr : &seen);
}
std::ostream & operator << (std::ostream & str, const Value & v)
{
v.print(str, false);
return str; return str;
} }

View file

@ -119,10 +119,13 @@ private:
InternalType internalType; InternalType internalType;
friend std::string showType(const Value & v); friend std::string showType(const Value & v);
friend void printValue(std::ostream & str, std::set<const void *> & seen, const Value & v);
void print(std::ostream & str, std::set<const void *> * seen) const;
public: public:
void print(std::ostream & str, bool showRepeated = false) const;
// Functions needed to distinguish the type // Functions needed to distinguish the type
// These should be removed eventually, by putting the functionality that's // These should be removed eventually, by putting the functionality that's
// needed by callers into methods of this type // needed by callers into methods of this type

View file

@ -105,8 +105,10 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
/* Also write a copy of the list of user environment elements to /* Also write a copy of the list of user environment elements to
the store; we need it for future modifications of the the store; we need it for future modifications of the
environment. */ environment. */
std::ostringstream str;
manifest.print(str, true);
auto manifestFile = state.store->addTextToStore("env-manifest.nix", auto manifestFile = state.store->addTextToStore("env-manifest.nix",
fmt("%s", manifest), references); str.str(), references);
/* Get the environment builder expression. */ /* Get the environment builder expression. */
Value envBuilder; Value envBuilder;

View file

@ -8,6 +8,8 @@ assert foo == "foo";
let let
platforms = let x = "foobar"; in [ x x ];
makeDrv = name: progName: (mkDerivation { makeDrv = name: progName: (mkDerivation {
name = assert progName != "fail"; name; name = assert progName != "fail"; name;
inherit progName system; inherit progName system;
@ -15,6 +17,7 @@ let
} // { } // {
meta = { meta = {
description = "A silly test package with some \${escaped anti-quotation} in it"; description = "A silly test package with some \${escaped anti-quotation} in it";
inherit platforms;
}; };
}); });