1
1
Fork 0
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:
Eelco Dolstra 2019-04-29 22:12:13 +02:00
parent b19b221f98
commit abbbad5679
3 changed files with 144 additions and 0 deletions

View file

@ -17,6 +17,7 @@ namespace nix {
class Store; class Store;
class EvalState; class EvalState;
struct Derivation;
enum RepairFlag : bool; enum RepairFlag : bool;
@ -341,6 +342,10 @@ private:
friend struct ExprOpConcatLists; friend struct ExprOpConcatLists;
friend struct ExprSelect; friend struct ExprSelect;
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v); friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v);
public:
std::function<void(const Path & drvPath, const Derivation & drv)> derivationHook;
}; };

View file

@ -757,6 +757,8 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
/* Write the resulting term into the Nix store directory. */ /* Write the resulting term into the Nix store directory. */
Path drvPath = writeDerivation(state.store, drv, drvName, state.repair); Path drvPath = writeDerivation(state.store, drv, drvName, state.repair);
if (state.derivationHook) state.derivationHook(drvPath, drv);
printMsg(lvlChatty, format("instantiated '%1%' -> '%2%'") printMsg(lvlChatty, format("instantiated '%1%' -> '%2%'")
% drvName % drvPath); % drvName % drvPath);

137
src/nix/list-tarballs.cc Normal file
View 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>());