Support URLs in $NIX_PATH

This didn't work (despite claims in the manual), because the colon in
"http://" was parsed as a element separator. So handle "://"
specially.
This commit is contained in:
Eelco Dolstra 2015-06-17 16:20:11 +02:00
parent 0d4d92fcf9
commit 65f17cd330
3 changed files with 32 additions and 1 deletions

View file

@ -234,6 +234,18 @@ void initGC()
} }
/* Very hacky way to parse $NIX_PATH, which is colon-separated, but
can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */
static Strings parseNixPath(const string & in)
{
string marker = "\001//";
auto res = tokenizeString<Strings>(replaceStrings(in, "://", marker), ":");
for (auto & s : res)
s = replaceStrings(s, marker, "://");
return res;
}
EvalState::EvalState(const Strings & _searchPath) EvalState::EvalState(const Strings & _searchPath)
: sWith(symbols.create("<with>")) : sWith(symbols.create("<with>"))
, sOutPath(symbols.create("outPath")) , sOutPath(symbols.create("outPath"))
@ -266,7 +278,7 @@ EvalState::EvalState(const Strings & _searchPath)
assert(gcInitialised); assert(gcInitialised);
/* Initialise the Nix expression search path. */ /* Initialise the Nix expression search path. */
Strings paths = tokenizeString<Strings>(getEnv("NIX_PATH", ""), ":"); Strings paths = parseNixPath(getEnv("NIX_PATH", ""));
for (auto & i : _searchPath) addToSearchPath(i, true); for (auto & i : _searchPath) addToSearchPath(i, true);
for (auto & i : paths) addToSearchPath(i); for (auto & i : paths) addToSearchPath(i);
addToSearchPath("nix=" + settings.nixDataDir + "/nix/corepkgs"); addToSearchPath("nix=" + settings.nixDataDir + "/nix/corepkgs");

View file

@ -1095,6 +1095,20 @@ string trim(const string & s, const string & whitespace)
} }
string replaceStrings(const std::string & s,
const std::string & from, const std::string & to)
{
if (from.empty()) return s;
string res = s;
size_t pos = 0;
while ((pos = res.find(from, pos)) != std::string::npos) {
res.replace(pos, from.size(), to);
pos += to.size();
}
return res;
}
string statusToString(int status) string statusToString(int status)
{ {
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {

View file

@ -341,6 +341,11 @@ string chomp(const string & s);
string trim(const string & s, const string & whitespace = " \n\r\t"); string trim(const string & s, const string & whitespace = " \n\r\t");
/* Replace all occurrences of a string inside another string. */
string replaceStrings(const std::string & s,
const std::string & from, const std::string & to);
/* Convert the exit status of a child as returned by wait() into an /* Convert the exit status of a child as returned by wait() into an
error string. */ error string. */
string statusToString(int status); string statusToString(int status);