mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-25 15:26:17 +02:00
nix build --json: Include build statistics
Example: # nix build -L --extra-experimental-features cgroups --impure --expr 'with import <nixpkgs> {}; runCommand "foo" {} "dd if=/dev/urandom bs=1M count=1024 | md5sum; mkdir $out"' --json [ { "cpuSystem": 1.911431, "cpuUser": 1.214249, "drvPath": "/nix/store/xzdqz67xba18hljhycp0hwfigzrs2z69-foo.drv", "outputs": { "out": "/nix/store/rh9mc9l2gkpq8kn2sgzndr6ll7ffjh6l-foo" }, "startTime": 1669024076, "stopTime": 1669024079 } ]
This commit is contained in:
parent
f538ee4342
commit
300753d594
7 changed files with 77 additions and 46 deletions
|
@ -840,20 +840,20 @@ std::shared_ptr<Installable> SourceExprCommand::parseInstallable(
|
|||
return installables.front();
|
||||
}
|
||||
|
||||
BuiltPaths Installable::build(
|
||||
std::vector<BuiltPathWithResult> Installable::build(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables,
|
||||
BuildMode bMode)
|
||||
{
|
||||
BuiltPaths res;
|
||||
for (auto & [_, builtPath] : build2(evalStore, store, mode, installables, bMode))
|
||||
res.push_back(builtPath);
|
||||
std::vector<BuiltPathWithResult> res;
|
||||
for (auto & [_, builtPathWithResult] : build2(evalStore, store, mode, installables, bMode))
|
||||
res.push_back(builtPathWithResult);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> Installable::build2(
|
||||
std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> Installable::build2(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
|
@ -873,7 +873,7 @@ std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> Installable::bui
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> res;
|
||||
std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> res;
|
||||
|
||||
switch (mode) {
|
||||
|
||||
|
@ -914,10 +914,10 @@ std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> Installable::bui
|
|||
output, *drvOutput->second);
|
||||
}
|
||||
}
|
||||
res.push_back({installable, BuiltPath::Built { bfd.drvPath, outputs }});
|
||||
res.push_back({installable, {.path = BuiltPath::Built { bfd.drvPath, outputs }}});
|
||||
},
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
res.push_back({installable, BuiltPath::Opaque { bo.path }});
|
||||
res.push_back({installable, {.path = BuiltPath::Opaque { bo.path }}});
|
||||
},
|
||||
}, path.raw());
|
||||
}
|
||||
|
@ -939,10 +939,10 @@ std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> Installable::bui
|
|||
std::map<std::string, StorePath> outputs;
|
||||
for (auto & path : buildResult.builtOutputs)
|
||||
outputs.emplace(path.first.outputName, path.second.outPath);
|
||||
res.push_back({installable, BuiltPath::Built { bfd.drvPath, outputs }});
|
||||
res.push_back({installable, {.path = BuiltPath::Built { bfd.drvPath, outputs }, .result = buildResult}});
|
||||
},
|
||||
[&](const DerivedPath::Opaque & bo) {
|
||||
res.push_back({installable, BuiltPath::Opaque { bo.path }});
|
||||
res.push_back({installable, {.path = BuiltPath::Opaque { bo.path }, .result = buildResult}});
|
||||
},
|
||||
}, buildResult.path.raw());
|
||||
}
|
||||
|
@ -965,9 +965,12 @@ BuiltPaths Installable::toBuiltPaths(
|
|||
OperateOn operateOn,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables)
|
||||
{
|
||||
if (operateOn == OperateOn::Output)
|
||||
return Installable::build(evalStore, store, mode, installables);
|
||||
else {
|
||||
if (operateOn == OperateOn::Output) {
|
||||
BuiltPaths res;
|
||||
for (auto & p : Installable::build(evalStore, store, mode, installables))
|
||||
res.push_back(p.path);
|
||||
return res;
|
||||
} else {
|
||||
if (mode == Realise::Nothing)
|
||||
settings.readOnlyMode = true;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "eval.hh"
|
||||
#include "store-api.hh"
|
||||
#include "flake/flake.hh"
|
||||
#include "build-result.hh"
|
||||
|
||||
#include <optional>
|
||||
|
||||
|
@ -51,6 +52,12 @@ enum class OperateOn {
|
|||
Derivation
|
||||
};
|
||||
|
||||
struct BuiltPathWithResult
|
||||
{
|
||||
BuiltPath path;
|
||||
std::optional<BuildResult> result;
|
||||
};
|
||||
|
||||
struct Installable
|
||||
{
|
||||
virtual ~Installable() { }
|
||||
|
@ -91,14 +98,14 @@ struct Installable
|
|||
return FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}});
|
||||
}
|
||||
|
||||
static BuiltPaths build(
|
||||
static std::vector<BuiltPathWithResult> build(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
const std::vector<std::shared_ptr<Installable>> & installables,
|
||||
BuildMode bMode = bmNormal);
|
||||
|
||||
static std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> build2(
|
||||
static std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> build2(
|
||||
ref<Store> evalStore,
|
||||
ref<Store> store,
|
||||
Realise mode,
|
||||
|
|
|
@ -53,28 +53,13 @@ StorePathSet BuiltPath::outPaths() const
|
|||
);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
nlohmann::json stuffToJSON(const std::vector<T> & ts, ref<Store> store) {
|
||||
auto res = nlohmann::json::array();
|
||||
for (const T & t : ts) {
|
||||
std::visit([&res, store](const auto & t) {
|
||||
res.push_back(t.toJSON(store));
|
||||
}, t.raw());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
nlohmann::json builtPathsToJSON(const BuiltPaths & buildables, ref<Store> store)
|
||||
{ return stuffToJSON<BuiltPath>(buildables, store); }
|
||||
nlohmann::json derivedPathsToJSON(const DerivedPaths & paths, ref<Store> store)
|
||||
{ return stuffToJSON<DerivedPath>(paths, store); }
|
||||
|
||||
|
||||
std::string DerivedPath::Opaque::to_string(const Store & store) const {
|
||||
std::string DerivedPath::Opaque::to_string(const Store & store) const
|
||||
{
|
||||
return store.printStorePath(path);
|
||||
}
|
||||
|
||||
std::string DerivedPath::Built::to_string(const Store & store) const {
|
||||
std::string DerivedPath::Built::to_string(const Store & store) const
|
||||
{
|
||||
return store.printStorePath(drvPath)
|
||||
+ "!"
|
||||
+ (outputs.empty() ? std::string { "*" } : concatStringsSep(",", outputs));
|
||||
|
|
|
@ -125,7 +125,4 @@ struct BuiltPath : _BuiltPathRaw {
|
|||
typedef std::vector<DerivedPath> DerivedPaths;
|
||||
typedef std::vector<BuiltPath> BuiltPaths;
|
||||
|
||||
nlohmann::json builtPathsToJSON(const BuiltPaths & buildables, ref<Store> store);
|
||||
nlohmann::json derivedPathsToJSON(const DerivedPaths & , ref<Store> store);
|
||||
|
||||
}
|
||||
|
|
|
@ -37,11 +37,13 @@ struct InstallableDerivedPath : Installable
|
|||
* Return the rewrites that are needed to resolve a string whose context is
|
||||
* included in `dependencies`.
|
||||
*/
|
||||
StringPairs resolveRewrites(Store & store, const BuiltPaths dependencies)
|
||||
StringPairs resolveRewrites(
|
||||
Store & store,
|
||||
const std::vector<BuiltPathWithResult> & dependencies)
|
||||
{
|
||||
StringPairs res;
|
||||
for (auto & dep : dependencies)
|
||||
if (auto drvDep = std::get_if<BuiltPathBuilt>(&dep))
|
||||
if (auto drvDep = std::get_if<BuiltPathBuilt>(&dep.path))
|
||||
for (auto & [ outputName, outputPath ] : drvDep->outputs)
|
||||
res.emplace(
|
||||
downstreamPlaceholder(store, drvDep->drvPath, outputName),
|
||||
|
@ -53,7 +55,10 @@ StringPairs resolveRewrites(Store & store, const BuiltPaths dependencies)
|
|||
/**
|
||||
* Resolve the given string assuming the given context.
|
||||
*/
|
||||
std::string resolveString(Store & store, const std::string & toResolve, const BuiltPaths dependencies)
|
||||
std::string resolveString(
|
||||
Store & store,
|
||||
const std::string & toResolve,
|
||||
const std::vector<BuiltPathWithResult> & dependencies)
|
||||
{
|
||||
auto rewrites = resolveRewrites(store, dependencies);
|
||||
return rewriteStrings(toResolve, rewrites);
|
||||
|
|
|
@ -10,6 +10,37 @@
|
|||
|
||||
using namespace nix;
|
||||
|
||||
nlohmann::json derivedPathsToJSON(const DerivedPaths & paths, ref<Store> store)
|
||||
{
|
||||
auto res = nlohmann::json::array();
|
||||
for (auto & t : paths) {
|
||||
std::visit([&res, store](const auto & t) {
|
||||
res.push_back(t.toJSON(store));
|
||||
}, t.raw());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
nlohmann::json builtPathsWithResultToJSON(const std::vector<BuiltPathWithResult> & buildables, ref<Store> store)
|
||||
{
|
||||
auto res = nlohmann::json::array();
|
||||
for (auto & b : buildables) {
|
||||
std::visit([&](const auto & t) {
|
||||
auto j = t.toJSON(store);
|
||||
if (b.result) {
|
||||
j["startTime"] = b.result->startTime;
|
||||
j["stopTime"] = b.result->stopTime;
|
||||
if (b.result->cpuUser)
|
||||
j["cpuUser"] = ((double) b.result->cpuUser->count()) / 1000000;
|
||||
if (b.result->cpuSystem)
|
||||
j["cpuSystem"] = ((double) b.result->cpuSystem->count()) / 1000000;
|
||||
}
|
||||
res.push_back(j);
|
||||
}, b.path.raw());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
|
||||
{
|
||||
Path outLink = "result";
|
||||
|
@ -78,7 +109,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
|
|||
Realise::Outputs,
|
||||
installables, buildMode);
|
||||
|
||||
if (json) logger->cout("%s", builtPathsToJSON(buildables, store).dump());
|
||||
if (json) logger->cout("%s", builtPathsWithResultToJSON(buildables, store).dump());
|
||||
|
||||
if (outLink != "")
|
||||
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
|
||||
|
@ -98,7 +129,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
|
|||
store2->addPermRoot(output.second, absPath(symlink));
|
||||
}
|
||||
},
|
||||
}, buildable.raw());
|
||||
}, buildable.path.raw());
|
||||
}
|
||||
|
||||
if (printOutputPaths) {
|
||||
|
@ -113,11 +144,14 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
|
|||
std::cout << store->printStorePath(output.second) << std::endl;
|
||||
}
|
||||
},
|
||||
}, buildable.raw());
|
||||
}, buildable.path.raw());
|
||||
}
|
||||
}
|
||||
|
||||
updateProfile(buildables);
|
||||
BuiltPaths buildables2;
|
||||
for (auto & b : buildables)
|
||||
buildables2.push_back(b.path);
|
||||
updateProfile(buildables2);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -253,11 +253,11 @@ struct ProfileManifest
|
|||
|
||||
static std::map<Installable *, BuiltPaths>
|
||||
builtPathsPerInstallable(
|
||||
const std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> & builtPaths)
|
||||
const std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> & builtPaths)
|
||||
{
|
||||
std::map<Installable *, BuiltPaths> res;
|
||||
for (auto & [installable, builtPath] : builtPaths)
|
||||
res[installable.get()].push_back(builtPath);
|
||||
res[installable.get()].push_back(builtPath.path);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue