2020-03-30 17:04:18 +03:00
|
|
|
#include "primops.hh"
|
|
|
|
#include "eval-inline.hh"
|
|
|
|
#include "store-api.hh"
|
|
|
|
#include "fetchers.hh"
|
2020-04-08 15:12:22 +03:00
|
|
|
#include "filetransfer.hh"
|
2020-04-07 15:29:45 +03:00
|
|
|
#include "registry.hh"
|
2020-03-30 17:04:18 +03:00
|
|
|
|
|
|
|
#include <ctime>
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
void emitTreeAttrs(
|
|
|
|
EvalState & state,
|
|
|
|
const fetchers::Tree & tree,
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
const fetchers::Input & input,
|
2020-07-28 23:46:39 +03:00
|
|
|
Value & v,
|
|
|
|
bool emptyRevFallback)
|
2020-03-30 17:04:18 +03:00
|
|
|
{
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
assert(input.isImmutable());
|
|
|
|
|
2020-03-30 17:04:18 +03:00
|
|
|
state.mkAttrs(v, 8);
|
|
|
|
|
|
|
|
auto storePath = state.store->printStorePath(tree.storePath);
|
|
|
|
|
|
|
|
mkString(*state.allocAttr(v, state.sOutPath), storePath, PathSet({storePath}));
|
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
// FIXME: support arbitrary input attributes.
|
|
|
|
|
|
|
|
auto narHash = input.getNarHash();
|
|
|
|
assert(narHash);
|
2020-03-30 17:04:18 +03:00
|
|
|
mkString(*state.allocAttr(v, state.symbols.create("narHash")),
|
2020-06-17 11:26:52 +03:00
|
|
|
narHash->to_string(SRI, true));
|
2020-03-30 17:04:18 +03:00
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
if (auto rev = input.getRev()) {
|
|
|
|
mkString(*state.allocAttr(v, state.symbols.create("rev")), rev->gitRev());
|
|
|
|
mkString(*state.allocAttr(v, state.symbols.create("shortRev")), rev->gitShortRev());
|
2020-07-28 23:46:39 +03:00
|
|
|
} else if (emptyRevFallback) {
|
|
|
|
// Backwards compat for `builtins.fetchGit`: dirty repos return an empty sha1 as rev
|
|
|
|
auto emptyHash = Hash(htSHA1);
|
|
|
|
mkString(*state.allocAttr(v, state.symbols.create("rev")), emptyHash.gitRev());
|
|
|
|
mkString(*state.allocAttr(v, state.symbols.create("shortRev")), emptyHash.gitRev());
|
2020-03-30 17:04:18 +03:00
|
|
|
}
|
|
|
|
|
2020-04-29 23:39:58 +03:00
|
|
|
if (input.getType() == "git")
|
|
|
|
mkBool(*state.allocAttr(v, state.symbols.create("submodules")), maybeGetBoolAttr(input.attrs, "submodules").value_or(false));
|
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
if (auto revCount = input.getRevCount())
|
|
|
|
mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *revCount);
|
2020-07-28 23:46:39 +03:00
|
|
|
else if (emptyRevFallback)
|
|
|
|
mkInt(*state.allocAttr(v, state.symbols.create("revCount")), 0);
|
2020-03-30 17:04:18 +03:00
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
if (auto lastModified = input.getLastModified()) {
|
|
|
|
mkInt(*state.allocAttr(v, state.symbols.create("lastModified")), *lastModified);
|
2020-04-02 19:39:41 +03:00
|
|
|
mkString(*state.allocAttr(v, state.symbols.create("lastModifiedDate")),
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
fmt("%s", std::put_time(std::gmtime(&*lastModified), "%Y%m%d%H%M%S")));
|
2020-04-02 19:39:41 +03:00
|
|
|
}
|
2020-03-30 17:04:18 +03:00
|
|
|
|
|
|
|
v.attrs->sort();
|
|
|
|
}
|
|
|
|
|
2020-04-29 23:39:58 +03:00
|
|
|
std::string fixURI(std::string uri, EvalState &state)
|
2020-03-30 17:04:18 +03:00
|
|
|
{
|
2020-04-29 23:39:58 +03:00
|
|
|
state.checkURI(uri);
|
|
|
|
return uri.find("://") != std::string::npos ? uri : "file://" + uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
void addURI(EvalState &state, fetchers::Attrs &attrs, Symbol name, std::string v)
|
|
|
|
{
|
|
|
|
string n(name);
|
|
|
|
attrs.emplace(name, n == "url" ? fixURI(v, state) : v);
|
|
|
|
}
|
2020-03-30 17:04:18 +03:00
|
|
|
|
2020-04-29 23:39:58 +03:00
|
|
|
static void fetchTree(
|
|
|
|
EvalState &state,
|
|
|
|
const Pos &pos,
|
|
|
|
Value **args,
|
|
|
|
Value &v,
|
2020-07-28 23:46:39 +03:00
|
|
|
const std::optional<std::string> type,
|
|
|
|
bool emptyRevFallback = false
|
2020-04-29 23:39:58 +03:00
|
|
|
) {
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
fetchers::Input input;
|
2020-03-30 17:04:18 +03:00
|
|
|
PathSet context;
|
|
|
|
|
|
|
|
state.forceValue(*args[0]);
|
|
|
|
|
|
|
|
if (args[0]->type == tAttrs) {
|
|
|
|
state.forceAttrs(*args[0], pos);
|
|
|
|
|
|
|
|
fetchers::Attrs attrs;
|
|
|
|
|
|
|
|
for (auto & attr : *args[0]->attrs) {
|
|
|
|
state.forceValue(*attr.value);
|
2020-04-29 23:39:58 +03:00
|
|
|
if (attr.value->type == tPath || attr.value->type == tString)
|
|
|
|
addURI(
|
|
|
|
state,
|
|
|
|
attrs,
|
|
|
|
attr.name,
|
|
|
|
state.coerceToString(*attr.pos, *attr.value, context, false, false)
|
|
|
|
);
|
|
|
|
else if (attr.value->type == tString)
|
|
|
|
addURI(state, attrs, attr.name, attr.value->string.s);
|
2020-03-30 17:04:18 +03:00
|
|
|
else if (attr.value->type == tBool)
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
attrs.emplace(attr.name, fetchers::Explicit<bool>{attr.value->boolean});
|
2020-04-02 17:51:56 +03:00
|
|
|
else if (attr.value->type == tInt)
|
|
|
|
attrs.emplace(attr.name, attr.value->integer);
|
2020-03-30 17:04:18 +03:00
|
|
|
else
|
2020-04-02 17:51:56 +03:00
|
|
|
throw TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected",
|
2020-03-30 17:04:18 +03:00
|
|
|
attr.name, showType(*attr.value));
|
|
|
|
}
|
|
|
|
|
2020-04-29 23:39:58 +03:00
|
|
|
if (type)
|
|
|
|
attrs.emplace("type", type.value());
|
|
|
|
|
2020-03-30 17:04:18 +03:00
|
|
|
if (!attrs.count("type"))
|
2020-06-15 15:06:58 +03:00
|
|
|
throw Error({
|
|
|
|
.hint = hintfmt("attribute 'type' is missing in call to 'fetchTree'"),
|
2020-06-24 00:30:13 +03:00
|
|
|
.errPos = pos
|
2020-06-15 15:06:58 +03:00
|
|
|
});
|
2020-03-30 17:04:18 +03:00
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
input = fetchers::Input::fromAttrs(std::move(attrs));
|
2020-04-29 23:39:58 +03:00
|
|
|
} else {
|
|
|
|
auto url = fixURI(state.coerceToString(pos, *args[0], context, false, false), state);
|
|
|
|
|
|
|
|
if (type == "git") {
|
|
|
|
fetchers::Attrs attrs;
|
|
|
|
attrs.emplace("type", "git");
|
|
|
|
attrs.emplace("url", url);
|
|
|
|
input = fetchers::Input::fromAttrs(std::move(attrs));
|
|
|
|
} else {
|
|
|
|
input = fetchers::Input::fromURL(url);
|
|
|
|
}
|
|
|
|
}
|
2020-02-12 00:53:46 +02:00
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
if (!evalSettings.pureEval && !input.isDirect())
|
2020-02-20 23:14:44 +02:00
|
|
|
input = lookupInRegistries(state.store, input).first;
|
2020-03-30 17:04:18 +03:00
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
if (evalSettings.pureEval && !input.isImmutable())
|
2020-04-02 20:03:32 +03:00
|
|
|
throw Error("in pure evaluation mode, 'fetchTree' requires an immutable input, at %s", pos);
|
2020-03-30 17:04:18 +03:00
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
auto [tree, input2] = input.fetch(state.store);
|
2020-03-30 17:04:18 +03:00
|
|
|
|
|
|
|
if (state.allowedPaths)
|
|
|
|
state.allowedPaths->insert(tree.actualPath);
|
|
|
|
|
2020-07-28 23:46:39 +03:00
|
|
|
emitTreeAttrs(state, tree, input2, v, emptyRevFallback);
|
2020-03-30 17:04:18 +03:00
|
|
|
}
|
|
|
|
|
2020-04-29 23:39:58 +03:00
|
|
|
static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
|
|
|
{
|
|
|
|
settings.requireExperimentalFeature("flakes");
|
|
|
|
fetchTree(state, pos, args, v, std::nullopt);
|
|
|
|
}
|
|
|
|
|
2020-03-30 17:04:18 +03:00
|
|
|
static RegisterPrimOp r("fetchTree", 1, prim_fetchTree);
|
|
|
|
|
|
|
|
static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
|
|
|
|
const string & who, bool unpack, std::string name)
|
|
|
|
{
|
|
|
|
std::optional<std::string> url;
|
|
|
|
std::optional<Hash> expectedHash;
|
|
|
|
|
|
|
|
state.forceValue(*args[0]);
|
|
|
|
|
|
|
|
if (args[0]->type == tAttrs) {
|
|
|
|
|
|
|
|
state.forceAttrs(*args[0], pos);
|
|
|
|
|
|
|
|
for (auto & attr : *args[0]->attrs) {
|
|
|
|
string n(attr.name);
|
|
|
|
if (n == "url")
|
|
|
|
url = state.forceStringNoCtx(*attr.value, *attr.pos);
|
|
|
|
else if (n == "sha256")
|
2020-06-12 18:09:42 +03:00
|
|
|
expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
|
2020-03-30 17:04:18 +03:00
|
|
|
else if (n == "name")
|
|
|
|
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
|
|
|
else
|
2020-06-15 15:06:58 +03:00
|
|
|
throw EvalError({
|
|
|
|
.hint = hintfmt("unsupported argument '%s' to '%s'", attr.name, who),
|
2020-06-24 00:30:13 +03:00
|
|
|
.errPos = *attr.pos
|
2020-06-15 15:06:58 +03:00
|
|
|
});
|
2020-05-12 19:52:26 +03:00
|
|
|
}
|
2020-03-30 17:04:18 +03:00
|
|
|
|
|
|
|
if (!url)
|
2020-06-15 15:06:58 +03:00
|
|
|
throw EvalError({
|
|
|
|
.hint = hintfmt("'url' argument required"),
|
2020-06-24 00:30:13 +03:00
|
|
|
.errPos = pos
|
2020-06-15 15:06:58 +03:00
|
|
|
});
|
2020-03-30 17:04:18 +03:00
|
|
|
} else
|
|
|
|
url = state.forceStringNoCtx(*args[0], pos);
|
|
|
|
|
|
|
|
url = resolveUri(*url);
|
|
|
|
|
|
|
|
state.checkURI(*url);
|
|
|
|
|
|
|
|
if (name == "")
|
|
|
|
name = baseNameOf(*url);
|
|
|
|
|
|
|
|
if (evalSettings.pureEval && !expectedHash)
|
|
|
|
throw Error("in pure evaluation mode, '%s' requires a 'sha256' argument", who);
|
|
|
|
|
|
|
|
auto storePath =
|
|
|
|
unpack
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
|
|
|
? fetchers::downloadTarball(state.store, *url, name, (bool) expectedHash).first.storePath
|
2020-03-30 17:04:18 +03:00
|
|
|
: fetchers::downloadFile(state.store, *url, name, (bool) expectedHash).storePath;
|
|
|
|
|
|
|
|
auto path = state.store->toRealPath(storePath);
|
|
|
|
|
|
|
|
if (expectedHash) {
|
|
|
|
auto hash = unpack
|
|
|
|
? state.store->queryPathInfo(storePath)->narHash
|
|
|
|
: hashFile(htSHA256, path);
|
|
|
|
if (hash != *expectedHash)
|
|
|
|
throw Error((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n wanted: %s\n got: %s",
|
2020-06-19 21:41:33 +03:00
|
|
|
*url, expectedHash->to_string(Base32, true), hash->to_string(Base32, true));
|
2020-03-30 17:04:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (state.allowedPaths)
|
|
|
|
state.allowedPaths->insert(path);
|
|
|
|
|
|
|
|
mkString(v, path, PathSet({path}));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prim_fetchurl(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
|
|
|
{
|
|
|
|
fetch(state, pos, args, v, "fetchurl", false, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void prim_fetchTarball(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
|
|
|
{
|
|
|
|
fetch(state, pos, args, v, "fetchTarball", true, "source");
|
|
|
|
}
|
|
|
|
|
2020-04-29 23:39:58 +03:00
|
|
|
static void prim_fetchGit(EvalState &state, const Pos &pos, Value **args, Value &v)
|
|
|
|
{
|
2020-07-28 23:46:39 +03:00
|
|
|
fetchTree(state, pos, args, v, "git", true);
|
2020-04-29 23:39:58 +03:00
|
|
|
}
|
|
|
|
|
2020-03-30 17:04:18 +03:00
|
|
|
static RegisterPrimOp r2("__fetchurl", 1, prim_fetchurl);
|
|
|
|
static RegisterPrimOp r3("fetchTarball", 1, prim_fetchTarball);
|
2020-04-29 23:39:58 +03:00
|
|
|
static RegisterPrimOp r4("fetchGit", 1, prim_fetchGit);
|
2020-03-30 17:04:18 +03:00
|
|
|
|
|
|
|
}
|