mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-27 00:06:16 +02:00
Merge remote-tracking branch 'upstream/master' into ca-floating-upstream
This commit is contained in:
commit
3786a801c3
40 changed files with 189 additions and 126 deletions
|
@ -51,6 +51,9 @@ Nix store is also printed.
|
||||||
result to the Nix store. The resulting hash can be used with
|
result to the Nix store. The resulting hash can be used with
|
||||||
functions such as Nixpkgs’s `fetchzip` or `fetchFromGitHub`.
|
functions such as Nixpkgs’s `fetchzip` or `fetchFromGitHub`.
|
||||||
|
|
||||||
|
- `--executable`
|
||||||
|
Set the executable bit on the downloaded file.
|
||||||
|
|
||||||
- `--name` *name*
|
- `--name` *name*
|
||||||
Override the name of the file in the Nix store. By default, this is
|
Override the name of the file in the Nix store. By default, this is
|
||||||
`hash-basename`, where *basename* is the last component of *url*.
|
`hash-basename`, where *basename* is the last component of *url*.
|
||||||
|
|
11
flake.lock
11
flake.lock
|
@ -3,16 +3,15 @@
|
||||||
"lowdown-src": {
|
"lowdown-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1598296217,
|
"lastModified": 1598695561,
|
||||||
"narHash": "sha256-ha7lyNY1d8m+osmDpPc9f/bfZ3ZC1IVIXwfyklSWg8I=",
|
"narHash": "sha256-gyH/5j+h/nWw0W8AcR2WKvNBUsiQ7QuxqSJNXAwV+8E=",
|
||||||
"owner": "edolstra",
|
"owner": "kristapsdz",
|
||||||
"repo": "lowdown",
|
"repo": "lowdown",
|
||||||
"rev": "c7a4e715af1e233080842db82d15b261cb74cb28",
|
"rev": "1705b4a26fbf065d9574dce47a94e8c7c79e052f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "edolstra",
|
"owner": "kristapsdz",
|
||||||
"ref": "no-structs-in-anonymous-unions",
|
|
||||||
"repo": "lowdown",
|
"repo": "lowdown",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
description = "The purely functional package manager";
|
description = "The purely functional package manager";
|
||||||
|
|
||||||
inputs.nixpkgs.url = "nixpkgs/nixos-20.03-small";
|
inputs.nixpkgs.url = "nixpkgs/nixos-20.03-small";
|
||||||
inputs.lowdown-src = { url = "github:edolstra/lowdown/no-structs-in-anonymous-unions"; flake = false; };
|
inputs.lowdown-src = { url = "github:kristapsdz/lowdown"; flake = false; };
|
||||||
|
|
||||||
outputs = { self, nixpkgs, lowdown-src }:
|
outputs = { self, nixpkgs, lowdown-src }:
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
|
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
makeFlags = "profiledir=$(out)/etc/profile.d";
|
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
|
||||||
|
|
||||||
doCheck = true;
|
doCheck = true;
|
||||||
|
|
||||||
|
@ -334,9 +334,6 @@
|
||||||
# syntax-check generated dot files, it still requires some
|
# syntax-check generated dot files, it still requires some
|
||||||
# fonts. So provide those.
|
# fonts. So provide those.
|
||||||
FONTCONFIG_FILE = texFunctions.fontsConf;
|
FONTCONFIG_FILE = texFunctions.fontsConf;
|
||||||
|
|
||||||
# To test building without precompiled headers.
|
|
||||||
makeFlagsArray = [ "PRECOMPILE_HEADERS=0" ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# System tests.
|
# System tests.
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
<dict>
|
<dict>
|
||||||
<key>EnvironmentVariables</key>
|
<key>EnvironmentVariables</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>NIX_SSL_CERT_FILE</key>
|
||||||
|
<string>/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt</string>
|
||||||
<key>OBJC_DISABLE_INITIALIZE_FORK_SAFETY</key>
|
<key>OBJC_DISABLE_INITIALIZE_FORK_SAFETY</key>
|
||||||
<string>YES</string>
|
<string>YES</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
PRECOMPILE_HEADERS ?= 1
|
PRECOMPILE_HEADERS ?= 0
|
||||||
|
|
||||||
print-var-help += \
|
print-var-help += \
|
||||||
echo " PRECOMPILE_HEADERS ($(PRECOMPILE_HEADERS)): Whether to use precompiled headers to speed up the build";
|
echo " PRECOMPILE_HEADERS ($(PRECOMPILE_HEADERS)): Whether to use precompiled headers to speed up the build";
|
||||||
|
|
|
@ -356,6 +356,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
|
||||||
, sEpsilon(symbols.create(""))
|
, sEpsilon(symbols.create(""))
|
||||||
, repair(NoRepair)
|
, repair(NoRepair)
|
||||||
, store(store)
|
, store(store)
|
||||||
|
, regexCache(makeRegexCache())
|
||||||
, baseEnv(allocEnv(128))
|
, baseEnv(allocEnv(128))
|
||||||
, staticBaseEnv(false, 0)
|
, staticBaseEnv(false, 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "symbol-table.hh"
|
#include "symbol-table.hh"
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
|
|
||||||
#include <regex>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -65,6 +64,11 @@ typedef std::list<SearchPathElem> SearchPath;
|
||||||
void initGC();
|
void initGC();
|
||||||
|
|
||||||
|
|
||||||
|
struct RegexCache;
|
||||||
|
|
||||||
|
std::shared_ptr<RegexCache> makeRegexCache();
|
||||||
|
|
||||||
|
|
||||||
class EvalState
|
class EvalState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -120,7 +124,7 @@ private:
|
||||||
std::unordered_map<Path, Path> resolvedPaths;
|
std::unordered_map<Path, Path> resolvedPaths;
|
||||||
|
|
||||||
/* Cache used by prim_match(). */
|
/* Cache used by prim_match(). */
|
||||||
std::unordered_map<std::string, std::regex> regexCache;
|
std::shared_ptr<RegexCache> regexCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "flakeref.hh"
|
#include "flakeref.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "registry.hh"
|
#include "registry.hh"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "lockfile.hh"
|
#include "lockfile.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
|
|
@ -3085,17 +3085,25 @@ static RegisterPrimOp primop_hashString({
|
||||||
.fun = prim_hashString,
|
.fun = prim_hashString,
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Match a regular expression against a string and return either
|
struct RegexCache
|
||||||
‘null’ or a list containing substring matches. */
|
{
|
||||||
|
std::unordered_map<std::string, std::regex> cache;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<RegexCache> makeRegexCache()
|
||||||
|
{
|
||||||
|
return std::make_shared<RegexCache>();
|
||||||
|
}
|
||||||
|
|
||||||
void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
auto re = state.forceStringNoCtx(*args[0], pos);
|
auto re = state.forceStringNoCtx(*args[0], pos);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
auto regex = state.regexCache.find(re);
|
auto regex = state.regexCache->cache.find(re);
|
||||||
if (regex == state.regexCache.end())
|
if (regex == state.regexCache->cache.end())
|
||||||
regex = state.regexCache.emplace(re, std::regex(re, std::regex::extended)).first;
|
regex = state.regexCache->cache.emplace(re, std::regex(re, std::regex::extended)).first;
|
||||||
|
|
||||||
PathSet context;
|
PathSet context;
|
||||||
const std::string str = state.forceString(*args[1], context, pos);
|
const std::string str = state.forceString(*args[1], context, pos);
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "tarfile.hh"
|
#include "tarfile.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,15 @@
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
namespace nix::fetchers {
|
namespace nix::fetchers {
|
||||||
|
|
||||||
// A github or gitlab url
|
// A github or gitlab host
|
||||||
const static std::string urlRegexS = "[a-zA-Z0-9.]*"; // FIXME: check
|
const static std::string hostRegexS = "[a-zA-Z0-9.]*"; // FIXME: check
|
||||||
std::regex urlRegex(urlRegexS, std::regex::ECMAScript);
|
std::regex hostRegex(hostRegexS, std::regex::ECMAScript);
|
||||||
|
|
||||||
struct GitArchiveInputScheme : InputScheme
|
struct GitArchiveInputScheme : InputScheme
|
||||||
{
|
{
|
||||||
|
@ -50,9 +51,9 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
throw BadURL("URL '%s' contains multiple branch/tag names", url.url);
|
throw BadURL("URL '%s' contains multiple branch/tag names", url.url);
|
||||||
ref = value;
|
ref = value;
|
||||||
}
|
}
|
||||||
else if (name == "url") {
|
else if (name == "host") {
|
||||||
if (!std::regex_match(value, urlRegex))
|
if (!std::regex_match(value, hostRegex))
|
||||||
throw BadURL("URL '%s' contains an invalid instance url", url.url);
|
throw BadURL("URL '%s' contains an invalid instance host", url.url);
|
||||||
host_url = value;
|
host_url = value;
|
||||||
}
|
}
|
||||||
// FIXME: barf on unsupported attributes
|
// FIXME: barf on unsupported attributes
|
||||||
|
@ -67,7 +68,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
input.attrs.insert_or_assign("repo", path[1]);
|
input.attrs.insert_or_assign("repo", path[1]);
|
||||||
if (rev) input.attrs.insert_or_assign("rev", rev->gitRev());
|
if (rev) input.attrs.insert_or_assign("rev", rev->gitRev());
|
||||||
if (ref) input.attrs.insert_or_assign("ref", *ref);
|
if (ref) input.attrs.insert_or_assign("ref", *ref);
|
||||||
if (host_url) input.attrs.insert_or_assign("url", *host_url);
|
if (host_url) input.attrs.insert_or_assign("host", *host_url);
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +78,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
if (maybeGetStrAttr(attrs, "type") != type()) return {};
|
if (maybeGetStrAttr(attrs, "type") != type()) return {};
|
||||||
|
|
||||||
for (auto & [name, value] : attrs)
|
for (auto & [name, value] : attrs)
|
||||||
if (name != "type" && name != "owner" && name != "repo" && name != "ref" && name != "rev" && name != "narHash" && name != "lastModified")
|
if (name != "type" && name != "owner" && name != "repo" && name != "ref" && name != "rev" && name != "narHash" && name != "lastModified" && name != "host")
|
||||||
throw Error("unsupported input attribute '%s'", name);
|
throw Error("unsupported input attribute '%s'", name);
|
||||||
|
|
||||||
getStrAttr(attrs, "owner");
|
getStrAttr(attrs, "owner");
|
||||||
|
@ -210,7 +211,7 @@ struct GitHubInputScheme : GitArchiveInputScheme
|
||||||
{
|
{
|
||||||
// FIXME: use regular /archive URLs instead? api.github.com
|
// FIXME: use regular /archive URLs instead? api.github.com
|
||||||
// might have stricter rate limits.
|
// might have stricter rate limits.
|
||||||
auto host_url = maybeGetStrAttr(input.attrs, "url").value_or("github.com");
|
auto host_url = maybeGetStrAttr(input.attrs, "host").value_or("github.com");
|
||||||
auto url = fmt("https://api.%s/repos/%s/%s/tarball/%s", // FIXME: check if this is correct for self hosted instances
|
auto url = fmt("https://api.%s/repos/%s/%s/tarball/%s", // FIXME: check if this is correct for self hosted instances
|
||||||
host_url, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"),
|
host_url, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"),
|
||||||
input.getRev()->to_string(Base16, false));
|
input.getRev()->to_string(Base16, false));
|
||||||
|
@ -236,7 +237,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
|
||||||
|
|
||||||
Hash getRevFromRef(nix::ref<Store> store, const Input & input) const override
|
Hash getRevFromRef(nix::ref<Store> store, const Input & input) const override
|
||||||
{
|
{
|
||||||
auto host_url = maybeGetStrAttr(input.attrs, "url").value_or("gitlab.com");
|
auto host_url = maybeGetStrAttr(input.attrs, "host").value_or("gitlab.com");
|
||||||
auto url = fmt("https://%s/api/v4/projects/%s%%2F%s/repository/commits?ref_name=%s",
|
auto url = fmt("https://%s/api/v4/projects/%s%%2F%s/repository/commits?ref_name=%s",
|
||||||
host_url, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"), *input.getRef());
|
host_url, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"), *input.getRef());
|
||||||
auto json = nlohmann::json::parse(
|
auto json = nlohmann::json::parse(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
namespace nix::fetchers {
|
namespace nix::fetchers {
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "tarfile.hh"
|
#include "tarfile.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "nar-accessor.hh"
|
#include "nar-accessor.hh"
|
||||||
#include "json.hh"
|
#include "json.hh"
|
||||||
#include "thread-pool.hh"
|
#include "thread-pool.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "daemon.hh"
|
#include "daemon.hh"
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
#include "topo-sort.hh"
|
#include "topo-sort.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "s3.hh"
|
#include "s3.hh"
|
||||||
#include "compression.hh"
|
#include "compression.hh"
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#ifdef ENABLE_S3
|
#ifdef ENABLE_S3
|
||||||
#include <aws/core/client/ClientConfiguration.h>
|
#include <aws/core/client/ClientConfiguration.h>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
#include "args.hh"
|
#include "args.hh"
|
||||||
|
#include "abstract-setting-to-json.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
#include "abstractsettingtojson.hh"
|
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "filetransfer.hh"
|
#include "filetransfer.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "nar-info-disk-cache.hh"
|
#include "nar-info-disk-cache.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
#include "ssh.hh"
|
#include "ssh.hh"
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
#include "nar-info.hh"
|
#include "nar-info.hh"
|
||||||
#include "references.hh"
|
#include "references.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "thread-pool.hh"
|
#include "thread-pool.hh"
|
||||||
#include "topo-sort.hh"
|
#include "topo-sort.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
#include "names.hh"
|
#include "names.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
struct Regex
|
||||||
|
{
|
||||||
|
std::regex regex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
DrvName::DrvName()
|
DrvName::DrvName()
|
||||||
{
|
{
|
||||||
name = "";
|
name = "";
|
||||||
|
@ -30,11 +38,18 @@ DrvName::DrvName(std::string_view s) : hits(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DrvName::~DrvName()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
bool DrvName::matches(DrvName & n)
|
bool DrvName::matches(DrvName & n)
|
||||||
{
|
{
|
||||||
if (name != "*") {
|
if (name != "*") {
|
||||||
if (!regex) regex = std::unique_ptr<std::regex>(new std::regex(name, std::regex::extended));
|
if (!regex) {
|
||||||
if (!std::regex_match(n.name, *regex)) return false;
|
regex = std::make_unique<Regex>();
|
||||||
|
regex->regex = std::regex(name, std::regex::extended);
|
||||||
|
}
|
||||||
|
if (!std::regex_match(n.name, regex->regex)) return false;
|
||||||
}
|
}
|
||||||
if (version != "" && version != n.version) return false;
|
if (version != "" && version != n.version) return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -99,7 +114,7 @@ DrvNames drvNamesFromArgs(const Strings & opArgs)
|
||||||
{
|
{
|
||||||
DrvNames result;
|
DrvNames result;
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
result.push_back(DrvName(i));
|
result.emplace_back(i);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
struct Regex;
|
||||||
|
|
||||||
struct DrvName
|
struct DrvName
|
||||||
{
|
{
|
||||||
string fullName;
|
string fullName;
|
||||||
|
@ -16,10 +17,12 @@ struct DrvName
|
||||||
|
|
||||||
DrvName();
|
DrvName();
|
||||||
DrvName(std::string_view s);
|
DrvName(std::string_view s);
|
||||||
|
~DrvName();
|
||||||
|
|
||||||
bool matches(DrvName & n);
|
bool matches(DrvName & n);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<std::regex> regex;
|
std::unique_ptr<Regex> regex;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef list<DrvName> DrvNames;
|
typedef list<DrvName> DrvNames;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "pool.hh"
|
#include "pool.hh"
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
#include "logging.hh"
|
#include "logging.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
#include "json.hh"
|
#include "json.hh"
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
|
#include "callback.hh"
|
||||||
#include <future>
|
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
46
src/libutil/callback.hh
Normal file
46
src/libutil/callback.hh
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
/* A callback is a wrapper around a lambda that accepts a valid of
|
||||||
|
type T or an exception. (We abuse std::future<T> to pass the value or
|
||||||
|
exception.) */
|
||||||
|
template<typename T>
|
||||||
|
class Callback
|
||||||
|
{
|
||||||
|
std::function<void(std::future<T>)> fun;
|
||||||
|
std::atomic_flag done = ATOMIC_FLAG_INIT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Callback(std::function<void(std::future<T>)> fun) : fun(fun) { }
|
||||||
|
|
||||||
|
Callback(Callback && callback) : fun(std::move(callback.fun))
|
||||||
|
{
|
||||||
|
auto prev = callback.done.test_and_set();
|
||||||
|
if (prev) done.test_and_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(T && t) noexcept
|
||||||
|
{
|
||||||
|
auto prev = done.test_and_set();
|
||||||
|
assert(!prev);
|
||||||
|
std::promise<T> promise;
|
||||||
|
promise.set_value(std::move(t));
|
||||||
|
fun(promise.get_future());
|
||||||
|
}
|
||||||
|
|
||||||
|
void rethrow(const std::exception_ptr & exc = std::current_exception()) noexcept
|
||||||
|
{
|
||||||
|
auto prev = done.test_and_set();
|
||||||
|
assert(!prev);
|
||||||
|
std::promise<T> promise;
|
||||||
|
promise.set_exception(exc);
|
||||||
|
fun(promise.get_future());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
#include "args.hh"
|
#include "args.hh"
|
||||||
#include "abstractsettingtojson.hh"
|
#include "abstract-setting-to-json.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "ansicolor.hh"
|
#include "ansicolor.hh"
|
||||||
|
|
||||||
|
|
44
src/libutil/url-parts.hh
Normal file
44
src/libutil/url-parts.hh
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
// URI stuff.
|
||||||
|
const static std::string pctEncoded = "(?:%[0-9a-fA-F][0-9a-fA-F])";
|
||||||
|
const static std::string schemeRegex = "(?:[a-z+.-]+)";
|
||||||
|
const static std::string ipv6AddressRegex = "(?:\\[[0-9a-fA-F:]+\\])";
|
||||||
|
const static std::string unreservedRegex = "(?:[a-zA-Z0-9-._~])";
|
||||||
|
const static std::string subdelimsRegex = "(?:[!$&'\"()*+,;=])";
|
||||||
|
const static std::string hostnameRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + ")*)";
|
||||||
|
const static std::string hostRegex = "(?:" + ipv6AddressRegex + "|" + hostnameRegex + ")";
|
||||||
|
const static std::string userRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|:)*)";
|
||||||
|
const static std::string authorityRegex = "(?:" + userRegex + "@)?" + hostRegex + "(?::[0-9]+)?";
|
||||||
|
const static std::string pcharRegex = "(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|[:@])";
|
||||||
|
const static std::string queryRegex = "(?:" + pcharRegex + "|[/? \"])*";
|
||||||
|
const static std::string segmentRegex = "(?:" + pcharRegex + "+)";
|
||||||
|
const static std::string absPathRegex = "(?:(?:/" + segmentRegex + ")*/?)";
|
||||||
|
const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRegex + ")*/?)";
|
||||||
|
|
||||||
|
// A Git ref (i.e. branch or tag name).
|
||||||
|
const static std::string refRegexS = "[a-zA-Z0-9][a-zA-Z0-9_.-]*"; // FIXME: check
|
||||||
|
extern std::regex refRegex;
|
||||||
|
|
||||||
|
// Instead of defining what a good Git Ref is, we define what a bad Git Ref is
|
||||||
|
// This is because of the definition of a ref in refs.c in https://github.com/git/git
|
||||||
|
// See tests/fetchGitRefs.sh for the full definition
|
||||||
|
const static std::string badGitRefRegexS = "//|^[./]|/\\.|\\.\\.|[[:cntrl:][:space:]:?^~\[]|\\\\|\\*|\\.lock$|\\.lock/|@\\{|[/.]$|^@$|^$";
|
||||||
|
extern std::regex badGitRefRegex;
|
||||||
|
|
||||||
|
// A Git revision (a SHA-1 commit hash).
|
||||||
|
const static std::string revRegexS = "[0-9a-fA-F]{40}";
|
||||||
|
extern std::regex revRegex;
|
||||||
|
|
||||||
|
// A ref or revision, or a ref followed by a revision.
|
||||||
|
const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refRegexS + ")(?:/(" + revRegexS + "))?))";
|
||||||
|
|
||||||
|
const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*";
|
||||||
|
extern std::regex flakeIdRegex;
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
|
#include "url-parts.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
#include "error.hh"
|
#include "error.hh"
|
||||||
|
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
struct ParsedURL
|
struct ParsedURL
|
||||||
|
@ -29,40 +27,4 @@ std::map<std::string, std::string> decodeQuery(const std::string & query);
|
||||||
|
|
||||||
ParsedURL parseURL(const std::string & url);
|
ParsedURL parseURL(const std::string & url);
|
||||||
|
|
||||||
// URI stuff.
|
|
||||||
const static std::string pctEncoded = "(?:%[0-9a-fA-F][0-9a-fA-F])";
|
|
||||||
const static std::string schemeRegex = "(?:[a-z+.-]+)";
|
|
||||||
const static std::string ipv6AddressRegex = "(?:\\[[0-9a-fA-F:]+\\])";
|
|
||||||
const static std::string unreservedRegex = "(?:[a-zA-Z0-9-._~])";
|
|
||||||
const static std::string subdelimsRegex = "(?:[!$&'\"()*+,;=])";
|
|
||||||
const static std::string hostnameRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + ")*)";
|
|
||||||
const static std::string hostRegex = "(?:" + ipv6AddressRegex + "|" + hostnameRegex + ")";
|
|
||||||
const static std::string userRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|:)*)";
|
|
||||||
const static std::string authorityRegex = "(?:" + userRegex + "@)?" + hostRegex + "(?::[0-9]+)?";
|
|
||||||
const static std::string pcharRegex = "(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|[:@])";
|
|
||||||
const static std::string queryRegex = "(?:" + pcharRegex + "|[/? \"])*";
|
|
||||||
const static std::string segmentRegex = "(?:" + pcharRegex + "+)";
|
|
||||||
const static std::string absPathRegex = "(?:(?:/" + segmentRegex + ")*/?)";
|
|
||||||
const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRegex + ")*/?)";
|
|
||||||
|
|
||||||
// A Git ref (i.e. branch or tag name).
|
|
||||||
const static std::string refRegexS = "[a-zA-Z0-9][a-zA-Z0-9_.-]*"; // FIXME: check
|
|
||||||
extern std::regex refRegex;
|
|
||||||
|
|
||||||
// Instead of defining what a good Git Ref is, we define what a bad Git Ref is
|
|
||||||
// This is because of the definition of a ref in refs.c in https://github.com/git/git
|
|
||||||
// See tests/fetchGitRefs.sh for the full definition
|
|
||||||
const static std::string badGitRefRegexS = "//|^[./]|/\\.|\\.\\.|[[:cntrl:][:space:]:?^~\[]|\\\\|\\*|\\.lock$|\\.lock/|@\\{|[/.]$|^@$|^$";
|
|
||||||
extern std::regex badGitRefRegex;
|
|
||||||
|
|
||||||
// A Git revision (a SHA-1 commit hash).
|
|
||||||
const static std::string revRegexS = "[0-9a-fA-F]{40}";
|
|
||||||
extern std::regex revRegex;
|
|
||||||
|
|
||||||
// A ref or revision, or a ref followed by a revision.
|
|
||||||
const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refRegexS + ")(?:/(" + revRegexS + "))?))";
|
|
||||||
|
|
||||||
const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*";
|
|
||||||
extern std::regex flakeIdRegex;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,9 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <future>
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
|
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
|
||||||
#define DT_UNKNOWN 0
|
#define DT_UNKNOWN 0
|
||||||
|
@ -480,43 +476,8 @@ std::optional<typename T::mapped_type> get(const T & map, const typename T::key_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A callback is a wrapper around a lambda that accepts a valid of
|
|
||||||
type T or an exception. (We abuse std::future<T> to pass the value or
|
|
||||||
exception.) */
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Callback
|
class Callback;
|
||||||
{
|
|
||||||
std::function<void(std::future<T>)> fun;
|
|
||||||
std::atomic_flag done = ATOMIC_FLAG_INIT;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Callback(std::function<void(std::future<T>)> fun) : fun(fun) { }
|
|
||||||
|
|
||||||
Callback(Callback && callback) : fun(std::move(callback.fun))
|
|
||||||
{
|
|
||||||
auto prev = callback.done.test_and_set();
|
|
||||||
if (prev) done.test_and_set();
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(T && t) noexcept
|
|
||||||
{
|
|
||||||
auto prev = done.test_and_set();
|
|
||||||
assert(!prev);
|
|
||||||
std::promise<T> promise;
|
|
||||||
promise.set_value(std::move(t));
|
|
||||||
fun(promise.get_future());
|
|
||||||
}
|
|
||||||
|
|
||||||
void rethrow(const std::exception_ptr & exc = std::current_exception()) noexcept
|
|
||||||
{
|
|
||||||
auto prev = done.test_and_set();
|
|
||||||
assert(!prev);
|
|
||||||
std::promise<T> promise;
|
|
||||||
promise.set_exception(exc);
|
|
||||||
fun(promise.get_future());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Start a thread that handles various signals. Also block those signals
|
/* Start a thread that handles various signals. Also block those signals
|
||||||
|
|
|
@ -230,7 +230,7 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
|
||||||
{
|
{
|
||||||
DrvNames selectors = drvNamesFromArgs(args);
|
DrvNames selectors = drvNamesFromArgs(args);
|
||||||
if (selectors.empty())
|
if (selectors.empty())
|
||||||
selectors.push_back(DrvName("*"));
|
selectors.emplace_back("*");
|
||||||
|
|
||||||
DrvInfos elems;
|
DrvInfos elems;
|
||||||
set<unsigned int> done;
|
set<unsigned int> done;
|
||||||
|
|
|
@ -57,6 +57,7 @@ static int _main(int argc, char * * argv)
|
||||||
bool fromExpr = false;
|
bool fromExpr = false;
|
||||||
string attrPath;
|
string attrPath;
|
||||||
bool unpack = false;
|
bool unpack = false;
|
||||||
|
bool executable = false;
|
||||||
string name;
|
string name;
|
||||||
|
|
||||||
struct MyArgs : LegacyArgs, MixEvalArgs
|
struct MyArgs : LegacyArgs, MixEvalArgs
|
||||||
|
@ -81,6 +82,8 @@ static int _main(int argc, char * * argv)
|
||||||
}
|
}
|
||||||
else if (*arg == "--unpack")
|
else if (*arg == "--unpack")
|
||||||
unpack = true;
|
unpack = true;
|
||||||
|
else if (*arg == "--executable")
|
||||||
|
executable = true;
|
||||||
else if (*arg == "--name")
|
else if (*arg == "--name")
|
||||||
name = getArg(*arg, arg, end);
|
name = getArg(*arg, arg, end);
|
||||||
else if (*arg != "" && arg->at(0) == '-')
|
else if (*arg != "" && arg->at(0) == '-')
|
||||||
|
@ -175,7 +178,11 @@ static int _main(int argc, char * * argv)
|
||||||
|
|
||||||
/* Download the file. */
|
/* Download the file. */
|
||||||
{
|
{
|
||||||
AutoCloseFD fd = open(tmpFile.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600);
|
auto mode = 0600;
|
||||||
|
if (executable)
|
||||||
|
mode = 0700;
|
||||||
|
|
||||||
|
AutoCloseFD fd = open(tmpFile.c_str(), O_WRONLY | O_CREAT | O_EXCL, mode);
|
||||||
if (!fd) throw SysError("creating temporary file '%s'", tmpFile);
|
if (!fd) throw SysError("creating temporary file '%s'", tmpFile);
|
||||||
|
|
||||||
FdSink sink(fd.get());
|
FdSink sink(fd.get());
|
||||||
|
@ -201,7 +208,7 @@ static int _main(int argc, char * * argv)
|
||||||
tmpFile = unpacked;
|
tmpFile = unpacked;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto method = unpack ? FileIngestionMethod::Recursive : FileIngestionMethod::Flat;
|
const auto method = unpack || executable ? FileIngestionMethod::Recursive : FileIngestionMethod::Flat;
|
||||||
|
|
||||||
auto info = store->addToStoreSlow(name, tmpFile, method, ht, expectedHash);
|
auto info = store->addToStoreSlow(name, tmpFile, method, ht, expectedHash);
|
||||||
storePath = info.path;
|
storePath = info.path;
|
||||||
|
|
|
@ -98,14 +98,14 @@ struct CmdBundle : InstallableCommand
|
||||||
if (!evalState->isDerivation(*vRes))
|
if (!evalState->isDerivation(*vRes))
|
||||||
throw Error("the bundler '%s' does not produce a derivation", bundler.what());
|
throw Error("the bundler '%s' does not produce a derivation", bundler.what());
|
||||||
|
|
||||||
auto attr1 = vRes->attrs->find(evalState->sDrvPath);
|
auto attr1 = vRes->attrs->get(evalState->sDrvPath);
|
||||||
if (!attr1)
|
if (!attr1)
|
||||||
throw Error("the bundler '%s' does not produce a derivation", bundler.what());
|
throw Error("the bundler '%s' does not produce a derivation", bundler.what());
|
||||||
|
|
||||||
PathSet context2;
|
PathSet context2;
|
||||||
StorePath drvPath = store->parseStorePath(evalState->coerceToPath(*attr1->pos, *attr1->value, context2));
|
StorePath drvPath = store->parseStorePath(evalState->coerceToPath(*attr1->pos, *attr1->value, context2));
|
||||||
|
|
||||||
auto attr2 = vRes->attrs->find(evalState->sOutPath);
|
auto attr2 = vRes->attrs->get(evalState->sOutPath);
|
||||||
if (!attr2)
|
if (!attr2)
|
||||||
throw Error("the bundler '%s' does not produce a derivation", bundler.what());
|
throw Error("the bundler '%s' does not produce a derivation", bundler.what());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue