1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-29 06:21:14 +02:00

Factor out abstract syntax for Store URIs

Need to decouple parsing from actually opening a store for Machine
configs.

Co-authored-by: Théophane Hufschmitt <7226587+thufschmitt@users.noreply.github.com>
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
John Ericson 2024-01-23 14:23:03 -05:00
parent 1d6c2316a9
commit c036d75f9e
4 changed files with 236 additions and 132 deletions

View file

@ -0,0 +1,92 @@
#include <regex>
#include "error.hh"
#include "url.hh"
#include "store-reference.hh"
#include "file-system.hh"
namespace nix {
static bool isNonUriPath(const std::string & spec)
{
return
// is not a URL
spec.find("://") == std::string::npos
// Has at least one path separator, and so isn't a single word that
// might be special like "auto"
&& spec.find("/") != std::string::npos;
}
StoreReference StoreReference::parse(const std::string & uri, const StoreReference::Params & extraParams)
{
auto params = extraParams;
try {
auto parsedUri = parseURL(uri);
params.insert(parsedUri.query.begin(), parsedUri.query.end());
auto baseURI = parsedUri.authority.value_or("") + parsedUri.path;
return {
.variant =
Specified{
.scheme = std::move(parsedUri.scheme),
.authority = std::move(baseURI),
},
.params = std::move(params),
};
} catch (BadURL &) {
auto [baseURI, uriParams] = splitUriAndParams(uri);
params.insert(uriParams.begin(), uriParams.end());
if (baseURI == "" || baseURI == "auto") {
return {
.variant = Auto{},
.params = std::move(params),
};
} else if (baseURI == "daemon") {
return {
.variant =
Specified{
.scheme = "unix",
.authority = "",
},
.params = std::move(params),
};
} else if (baseURI == "local") {
return {
.variant =
Specified{
.scheme = "local",
.authority = "",
},
.params = std::move(params),
};
} else if (isNonUriPath(baseURI)) {
return {
.variant =
Specified{
.scheme = "local",
.authority = absPath(baseURI),
},
.params = std::move(params),
};
}
}
throw UsageError("Cannot parse Nix store '%s'", uri);
}
/* Split URI into protocol+hierarchy part and its parameter set. */
std::pair<std::string, StoreReference::Params> splitUriAndParams(const std::string & uri_)
{
auto uri(uri_);
StoreReference::Params params;
auto q = uri.find('?');
if (q != std::string::npos) {
params = decodeQuery(uri.substr(q + 1));
uri = uri_.substr(0, q);
}
return {uri, params};
}
}