mirror of
https://github.com/NixOS/nix.git
synced 2025-11-15 15:02:42 +01:00
Add 'nix list-tarballs' command
E.g. $ nix list-tarballs nixpkgs.hello http://tarballs.nixos.org/stdenv-linux/x86_64/4907fc9e8d0d82b28b3c56e3a478a2882f1d700f/bootstrap-tools.tar.xz ... mirror://gnu/hello/hello-2.10.tar.gz $ nix list-tarballs --json -f '<nixpkgs/maintainers/scripts/all-tarballs.nix>' (BTW the latter returns about 6000 files more than find-tarballs.nix.)
This commit is contained in:
parent
b19b221f98
commit
abbbad5679
3 changed files with 144 additions and 0 deletions
|
|
@ -17,6 +17,7 @@ namespace nix {
|
|||
|
||||
class Store;
|
||||
class EvalState;
|
||||
struct Derivation;
|
||||
enum RepairFlag : bool;
|
||||
|
||||
|
||||
|
|
@ -341,6 +342,10 @@ private:
|
|||
friend struct ExprOpConcatLists;
|
||||
friend struct ExprSelect;
|
||||
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
||||
|
||||
public:
|
||||
|
||||
std::function<void(const Path & drvPath, const Derivation & drv)> derivationHook;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -757,6 +757,8 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
|||
/* Write the resulting term into the Nix store directory. */
|
||||
Path drvPath = writeDerivation(state.store, drv, drvName, state.repair);
|
||||
|
||||
if (state.derivationHook) state.derivationHook(drvPath, drv);
|
||||
|
||||
printMsg(lvlChatty, format("instantiated '%1%' -> '%2%'")
|
||||
% drvName % drvPath);
|
||||
|
||||
|
|
|
|||
137
src/nix/list-tarballs.cc
Normal file
137
src/nix/list-tarballs.cc
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
#include "command.hh"
|
||||
#include "eval.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "derivations.hh"
|
||||
#include "common-args.hh"
|
||||
#include "json.hh"
|
||||
|
||||
using namespace nix;
|
||||
|
||||
struct CmdListTarballs : MixJSON, InstallablesCommand
|
||||
{
|
||||
std::string name() override
|
||||
{
|
||||
return "list-tarballs";
|
||||
}
|
||||
|
||||
std::string description() override
|
||||
{
|
||||
return "list the 'fetchurl' calls made by the dependency graph of a package";
|
||||
}
|
||||
|
||||
Examples examples() override
|
||||
{
|
||||
return {
|
||||
Example{
|
||||
"To get the tarballs required to build GNU Hello and its dependencies:",
|
||||
"nix list-tarballs nixpkgs.hello"
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
struct File
|
||||
{
|
||||
std::string type;
|
||||
bool recursive;
|
||||
Hash hash;
|
||||
std::string url;
|
||||
Path storePath;
|
||||
};
|
||||
|
||||
void doIt(ref<Store> store, std::function<void(const File &)> callback)
|
||||
{
|
||||
settings.readOnlyMode = true;
|
||||
|
||||
auto state = getEvalState();
|
||||
auto autoArgs = getAutoArgs(*state);
|
||||
|
||||
PathSet done;
|
||||
|
||||
state->derivationHook =
|
||||
[&](const Path & drvPath, const Derivation & drv) {
|
||||
if (drv.outputs.size() != 1) return;
|
||||
|
||||
auto & output = *drv.outputs.begin();
|
||||
|
||||
if (output.second.hashAlgo.empty() || output.second.hash.empty()) return;
|
||||
|
||||
if (!done.insert(output.second.path).second) return;
|
||||
|
||||
auto [recursive, hash] = output.second.parseHashInfo();
|
||||
|
||||
if (recursive) return; // FIXME
|
||||
|
||||
std::optional<std::string> url;
|
||||
|
||||
auto i = drv.env.find("url");
|
||||
if (i != drv.env.end())
|
||||
url = i->second;
|
||||
else {
|
||||
i = drv.env.find("urls");
|
||||
if (i == drv.env.end()) return;
|
||||
auto urls = tokenizeString<std::vector<std::string>>(i->second, " ");
|
||||
if (urls.empty()) return;
|
||||
url = urls[0];
|
||||
}
|
||||
|
||||
File file;
|
||||
file.type = drv.builder == "builtin:fetchurl" ? "fetchurl" : "unknown";
|
||||
file.recursive = recursive;
|
||||
file.hash = hash;
|
||||
file.url = *url;
|
||||
file.storePath = output.second.path;
|
||||
|
||||
callback(file);
|
||||
};
|
||||
|
||||
std::function<void(Value * v)> findDerivations;
|
||||
|
||||
findDerivations =
|
||||
[&](Value * v) {
|
||||
state->forceValue(*v);
|
||||
if (v->type == tAttrs) {
|
||||
if (state->isDerivation(*v)) {
|
||||
auto aDrvPath = v->attrs->get(state->sDrvPath);
|
||||
if (!aDrvPath) return;
|
||||
try {
|
||||
state->forceValue(*(*aDrvPath)->value, *(*aDrvPath)->pos);
|
||||
} catch (EvalError & e) {
|
||||
}
|
||||
} else {
|
||||
for (auto & attr : *v->attrs)
|
||||
findDerivations(attr.value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (auto & installable : installables) {
|
||||
auto v = state->allocValue();
|
||||
state->autoCallFunction(autoArgs, installable->toValue(*state), v);
|
||||
findDerivations(v);
|
||||
}
|
||||
}
|
||||
|
||||
void run(ref<Store> store) override
|
||||
{
|
||||
if (json) {
|
||||
JSONList json(std::cout);
|
||||
doIt(store,
|
||||
[&](const File & file) {
|
||||
auto obj = json.object();
|
||||
obj.attr("type", file.type);
|
||||
if (file.recursive)
|
||||
obj.attr("recursive", true);
|
||||
obj.attr("hash", file.hash.to_string(SRI));
|
||||
obj.attr("url", file.url);
|
||||
obj.attr("storePath", file.storePath);
|
||||
});
|
||||
} else {
|
||||
doIt(store,
|
||||
[&](const File & file) {
|
||||
std::cout << file.url << "\n";
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static RegisterCommand r1(make_ref<CmdListTarballs>());
|
||||
Loading…
Add table
Add a link
Reference in a new issue