mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Merge pull request #14426 from obsidiansystems/json-schema-build-result
JSON Impl and schema for BuildResult
This commit is contained in:
commit
147e183c68
16 changed files with 467 additions and 0 deletions
|
|
@ -44,6 +44,7 @@ mkMesonDerivation (finalAttrs: {
|
||||||
../../src/libstore-tests/data/derived-path
|
../../src/libstore-tests/data/derived-path
|
||||||
../../src/libstore-tests/data/path-info
|
../../src/libstore-tests/data/path-info
|
||||||
../../src/libstore-tests/data/nar-info
|
../../src/libstore-tests/data/nar-info
|
||||||
|
../../src/libstore-tests/data/build-result
|
||||||
# Too many different types of files to filter for now
|
# Too many different types of files to filter for now
|
||||||
../../doc/manual
|
../../doc/manual
|
||||||
./.
|
./.
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@
|
||||||
- [Derivation](protocols/json/derivation.md)
|
- [Derivation](protocols/json/derivation.md)
|
||||||
- [Deriving Path](protocols/json/deriving-path.md)
|
- [Deriving Path](protocols/json/deriving-path.md)
|
||||||
- [Build Trace Entry](protocols/json/build-trace-entry.md)
|
- [Build Trace Entry](protocols/json/build-trace-entry.md)
|
||||||
|
- [Build Result](protocols/json/build-result.md)
|
||||||
- [Serving Tarball Flakes](protocols/tarball-fetcher.md)
|
- [Serving Tarball Flakes](protocols/tarball-fetcher.md)
|
||||||
- [Store Path Specification](protocols/store-path.md)
|
- [Store Path Specification](protocols/store-path.md)
|
||||||
- [Nix Archive (NAR) Format](protocols/nix-archive/index.md)
|
- [Nix Archive (NAR) Format](protocols/nix-archive/index.md)
|
||||||
|
|
|
||||||
21
doc/manual/source/protocols/json/build-result.md
Normal file
21
doc/manual/source/protocols/json/build-result.md
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
{{#include build-result-v1-fixed.md}}
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Successful build
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-result-v1/success.json}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Failed build (output rejected)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-result-v1/output-rejected.json}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Failed build (non-deterministic)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{{#include schema/build-result-v1/not-deterministic.json}}
|
||||||
|
```
|
||||||
|
|
@ -16,6 +16,7 @@ schemas = [
|
||||||
'derivation-v3',
|
'derivation-v3',
|
||||||
'deriving-path-v1',
|
'deriving-path-v1',
|
||||||
'build-trace-entry-v1',
|
'build-trace-entry-v1',
|
||||||
|
'build-result-v1',
|
||||||
]
|
]
|
||||||
|
|
||||||
schema_files = files()
|
schema_files = files()
|
||||||
|
|
|
||||||
1
doc/manual/source/protocols/json/schema/build-result-v1
Symbolic link
1
doc/manual/source/protocols/json/schema/build-result-v1
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../src/libstore-tests/data/build-result
|
||||||
136
doc/manual/source/protocols/json/schema/build-result-v1.yaml
Normal file
136
doc/manual/source/protocols/json/schema/build-result-v1.yaml
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema"
|
||||||
|
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/build-result-v1.json"
|
||||||
|
title: Build Result
|
||||||
|
description: |
|
||||||
|
This schema describes the JSON representation of Nix's `BuildResult` type, which represents the result of building a derivation or substituting store paths.
|
||||||
|
|
||||||
|
Build results can represent either successful builds (with built outputs) or various types of failures.
|
||||||
|
|
||||||
|
oneOf:
|
||||||
|
- "$ref": "#/$defs/success"
|
||||||
|
- "$ref": "#/$defs/failure"
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- success
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
timesBuilt:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: Times built
|
||||||
|
description: |
|
||||||
|
How many times this build was performed.
|
||||||
|
|
||||||
|
startTime:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: Start time
|
||||||
|
description: |
|
||||||
|
The start time of the build (or one of the rounds, if it was repeated), as a Unix timestamp.
|
||||||
|
|
||||||
|
stopTime:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: Stop time
|
||||||
|
description: |
|
||||||
|
The stop time of the build (or one of the rounds, if it was repeated), as a Unix timestamp.
|
||||||
|
|
||||||
|
cpuUser:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: User CPU time
|
||||||
|
description: |
|
||||||
|
User CPU time the build took, in microseconds.
|
||||||
|
|
||||||
|
cpuSystem:
|
||||||
|
type: integer
|
||||||
|
minimum: 0
|
||||||
|
title: System CPU time
|
||||||
|
description: |
|
||||||
|
System CPU time the build took, in microseconds.
|
||||||
|
|
||||||
|
"$defs":
|
||||||
|
success:
|
||||||
|
type: object
|
||||||
|
title: Successful Build Result
|
||||||
|
description: |
|
||||||
|
Represents a successful build with built outputs.
|
||||||
|
required:
|
||||||
|
- success
|
||||||
|
- status
|
||||||
|
- builtOutputs
|
||||||
|
properties:
|
||||||
|
success:
|
||||||
|
const: true
|
||||||
|
title: Success indicator
|
||||||
|
description: |
|
||||||
|
Always true for successful build results.
|
||||||
|
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
title: Success status
|
||||||
|
description: |
|
||||||
|
Status string for successful builds.
|
||||||
|
enum:
|
||||||
|
- "Built"
|
||||||
|
- "Substituted"
|
||||||
|
- "AlreadyValid"
|
||||||
|
- "ResolvesToAlreadyValid"
|
||||||
|
|
||||||
|
builtOutputs:
|
||||||
|
type: object
|
||||||
|
title: Built outputs
|
||||||
|
description: |
|
||||||
|
A mapping from output names to their build trace entries.
|
||||||
|
additionalProperties:
|
||||||
|
"$ref": "build-trace-entry-v1.yaml"
|
||||||
|
|
||||||
|
failure:
|
||||||
|
type: object
|
||||||
|
title: Failed Build Result
|
||||||
|
description: |
|
||||||
|
Represents a failed build with error information.
|
||||||
|
required:
|
||||||
|
- success
|
||||||
|
- status
|
||||||
|
- errorMsg
|
||||||
|
properties:
|
||||||
|
success:
|
||||||
|
const: false
|
||||||
|
title: Success indicator
|
||||||
|
description: |
|
||||||
|
Always false for failed build results.
|
||||||
|
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
title: Failure status
|
||||||
|
description: |
|
||||||
|
Status string for failed builds.
|
||||||
|
enum:
|
||||||
|
- "PermanentFailure"
|
||||||
|
- "InputRejected"
|
||||||
|
- "OutputRejected"
|
||||||
|
- "TransientFailure"
|
||||||
|
- "CachedFailure"
|
||||||
|
- "TimedOut"
|
||||||
|
- "MiscFailure"
|
||||||
|
- "DependencyFailed"
|
||||||
|
- "LogLimitExceeded"
|
||||||
|
- "NotDeterministic"
|
||||||
|
- "NoSubstituters"
|
||||||
|
- "HashMismatch"
|
||||||
|
|
||||||
|
errorMsg:
|
||||||
|
type: string
|
||||||
|
title: Error message
|
||||||
|
description: |
|
||||||
|
Information about the error if the build failed.
|
||||||
|
|
||||||
|
isNonDeterministic:
|
||||||
|
type: boolean
|
||||||
|
title: Non-deterministic flag
|
||||||
|
description: |
|
||||||
|
If timesBuilt > 1, whether some builds did not produce the same result.
|
||||||
|
|
||||||
|
Note that 'isNonDeterministic = false' does not mean the build is deterministic,
|
||||||
|
just that we don't have evidence of non-determinism.
|
||||||
1
src/json-schema-checks/build-result
Symbolic link
1
src/json-schema-checks/build-result
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../src/libstore-tests/data/build-result
|
||||||
|
|
@ -150,6 +150,15 @@ schemas += [
|
||||||
'impure.json',
|
'impure.json',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'stem' : 'build-result',
|
||||||
|
'schema' : schema_dir / 'build-result-v1.yaml',
|
||||||
|
'files' : [
|
||||||
|
'success.json',
|
||||||
|
'output-rejected.json',
|
||||||
|
'not-deterministic.json',
|
||||||
|
],
|
||||||
|
},
|
||||||
# Match exact variant
|
# Match exact variant
|
||||||
{
|
{
|
||||||
'stem' : 'store-object-info',
|
'stem' : 'store-object-info',
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ mkMesonDerivation (finalAttrs: {
|
||||||
../../src/libstore-tests/data/derived-path
|
../../src/libstore-tests/data/derived-path
|
||||||
../../src/libstore-tests/data/path-info
|
../../src/libstore-tests/data/path-info
|
||||||
../../src/libstore-tests/data/nar-info
|
../../src/libstore-tests/data/nar-info
|
||||||
|
../../src/libstore-tests/data/build-result
|
||||||
./.
|
./.
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
108
src/libstore-tests/build-result.cc
Normal file
108
src/libstore-tests/build-result.cc
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "nix/store/build-result.hh"
|
||||||
|
#include "nix/util/tests/json-characterization.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
class BuildResultTest : public virtual CharacterizationTest
|
||||||
|
{
|
||||||
|
std::filesystem::path unitTestData = getUnitTestData() / "build-result";
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::filesystem::path goldenMaster(std::string_view testStem) const override
|
||||||
|
{
|
||||||
|
return unitTestData / testStem;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using nlohmann::json;
|
||||||
|
|
||||||
|
struct BuildResultJsonTest : BuildResultTest,
|
||||||
|
JsonCharacterizationTest<BuildResult>,
|
||||||
|
::testing::WithParamInterface<std::pair<std::string_view, BuildResult>>
|
||||||
|
{};
|
||||||
|
|
||||||
|
TEST_P(BuildResultJsonTest, from_json)
|
||||||
|
{
|
||||||
|
auto & [name, expected] = GetParam();
|
||||||
|
readJsonTest(name, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(BuildResultJsonTest, to_json)
|
||||||
|
{
|
||||||
|
auto & [name, value] = GetParam();
|
||||||
|
writeJsonTest(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
BuildResultJSON,
|
||||||
|
BuildResultJsonTest,
|
||||||
|
::testing::Values(
|
||||||
|
std::pair{
|
||||||
|
"not-deterministic",
|
||||||
|
BuildResult{
|
||||||
|
.inner{BuildResult::Failure{
|
||||||
|
.status = BuildResult::Failure::NotDeterministic,
|
||||||
|
.errorMsg = "no idea why",
|
||||||
|
.isNonDeterministic = false, // Note: This field is separate from the status
|
||||||
|
}},
|
||||||
|
.timesBuilt = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
std::pair{
|
||||||
|
"output-rejected",
|
||||||
|
BuildResult{
|
||||||
|
.inner{BuildResult::Failure{
|
||||||
|
.status = BuildResult::Failure::OutputRejected,
|
||||||
|
.errorMsg = "no idea why",
|
||||||
|
.isNonDeterministic = false,
|
||||||
|
}},
|
||||||
|
.timesBuilt = 3,
|
||||||
|
.startTime = 30,
|
||||||
|
.stopTime = 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
std::pair{
|
||||||
|
"success",
|
||||||
|
BuildResult{
|
||||||
|
.inner{BuildResult::Success{
|
||||||
|
.status = BuildResult::Success::Built,
|
||||||
|
.builtOutputs{
|
||||||
|
{
|
||||||
|
"foo",
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||||
|
},
|
||||||
|
DrvOutput{
|
||||||
|
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||||
|
.outputName = "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bar",
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||||
|
},
|
||||||
|
DrvOutput{
|
||||||
|
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||||
|
.outputName = "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
.timesBuilt = 3,
|
||||||
|
.startTime = 30,
|
||||||
|
.stopTime = 50,
|
||||||
|
.cpuUser = std::chrono::microseconds(500s),
|
||||||
|
.cpuSystem = std::chrono::microseconds(604s),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
} // namespace nix
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"errorMsg": "no idea why",
|
||||||
|
"isNonDeterministic": false,
|
||||||
|
"startTime": 0,
|
||||||
|
"status": "NotDeterministic",
|
||||||
|
"stopTime": 0,
|
||||||
|
"success": false,
|
||||||
|
"timesBuilt": 1
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"errorMsg": "no idea why",
|
||||||
|
"isNonDeterministic": false,
|
||||||
|
"startTime": 30,
|
||||||
|
"status": "OutputRejected",
|
||||||
|
"stopTime": 50,
|
||||||
|
"success": false,
|
||||||
|
"timesBuilt": 3
|
||||||
|
}
|
||||||
23
src/libstore-tests/data/build-result/success.json
Normal file
23
src/libstore-tests/data/build-result/success.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"builtOutputs": {
|
||||||
|
"bar": {
|
||||||
|
"dependentRealisations": {},
|
||||||
|
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!bar",
|
||||||
|
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||||
|
"signatures": []
|
||||||
|
},
|
||||||
|
"foo": {
|
||||||
|
"dependentRealisations": {},
|
||||||
|
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!foo",
|
||||||
|
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||||
|
"signatures": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cpuSystem": 604000000,
|
||||||
|
"cpuUser": 500000000,
|
||||||
|
"startTime": 30,
|
||||||
|
"status": "Built",
|
||||||
|
"stopTime": 50,
|
||||||
|
"success": true,
|
||||||
|
"timesBuilt": 3
|
||||||
|
}
|
||||||
|
|
@ -54,6 +54,7 @@ deps_private += gtest
|
||||||
subdir('nix-meson-build-support/common')
|
subdir('nix-meson-build-support/common')
|
||||||
|
|
||||||
sources = files(
|
sources = files(
|
||||||
|
'build-result.cc',
|
||||||
'common-protocol.cc',
|
'common-protocol.cc',
|
||||||
'content-address.cc',
|
'content-address.cc',
|
||||||
'derivation-advanced-attrs.cc',
|
'derivation-advanced-attrs.cc',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
#include "nix/store/build-result.hh"
|
#include "nix/store/build-result.hh"
|
||||||
|
#include "nix/util/json-utils.hh"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
@ -11,4 +13,144 @@ std::strong_ordering BuildResult::Success::operator<=>(const BuildResult::Succes
|
||||||
bool BuildResult::Failure::operator==(const BuildResult::Failure &) const noexcept = default;
|
bool BuildResult::Failure::operator==(const BuildResult::Failure &) const noexcept = default;
|
||||||
std::strong_ordering BuildResult::Failure::operator<=>(const BuildResult::Failure &) const noexcept = default;
|
std::strong_ordering BuildResult::Failure::operator<=>(const BuildResult::Failure &) const noexcept = default;
|
||||||
|
|
||||||
|
static constexpr std::array<std::pair<BuildResult::Success::Status, std::string_view>, 4> successStatusStrings{{
|
||||||
|
#define ENUM_ENTRY(e) {BuildResult::Success::e, #e}
|
||||||
|
ENUM_ENTRY(Built),
|
||||||
|
ENUM_ENTRY(Substituted),
|
||||||
|
ENUM_ENTRY(AlreadyValid),
|
||||||
|
ENUM_ENTRY(ResolvesToAlreadyValid),
|
||||||
|
#undef ENUM_ENTRY
|
||||||
|
}};
|
||||||
|
|
||||||
|
static std::string_view successStatusToString(BuildResult::Success::Status status)
|
||||||
|
{
|
||||||
|
for (const auto & [enumVal, str] : successStatusStrings) {
|
||||||
|
if (enumVal == status)
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
throw Error("unknown success status: %d", static_cast<int>(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuildResult::Success::Status successStatusFromString(std::string_view str)
|
||||||
|
{
|
||||||
|
for (const auto & [enumVal, enumStr] : successStatusStrings) {
|
||||||
|
if (enumStr == str)
|
||||||
|
return enumVal;
|
||||||
|
}
|
||||||
|
throw Error("unknown built result success status '%s'", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::array<std::pair<BuildResult::Failure::Status, std::string_view>, 12> failureStatusStrings{{
|
||||||
|
#define ENUM_ENTRY(e) {BuildResult::Failure::e, #e}
|
||||||
|
ENUM_ENTRY(PermanentFailure),
|
||||||
|
ENUM_ENTRY(InputRejected),
|
||||||
|
ENUM_ENTRY(OutputRejected),
|
||||||
|
ENUM_ENTRY(TransientFailure),
|
||||||
|
ENUM_ENTRY(CachedFailure),
|
||||||
|
ENUM_ENTRY(TimedOut),
|
||||||
|
ENUM_ENTRY(MiscFailure),
|
||||||
|
ENUM_ENTRY(DependencyFailed),
|
||||||
|
ENUM_ENTRY(LogLimitExceeded),
|
||||||
|
ENUM_ENTRY(NotDeterministic),
|
||||||
|
ENUM_ENTRY(NoSubstituters),
|
||||||
|
ENUM_ENTRY(HashMismatch),
|
||||||
|
#undef ENUM_ENTRY
|
||||||
|
}};
|
||||||
|
|
||||||
|
static std::string_view failureStatusToString(BuildResult::Failure::Status status)
|
||||||
|
{
|
||||||
|
for (const auto & [enumVal, str] : failureStatusStrings) {
|
||||||
|
if (enumVal == status)
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
throw Error("unknown failure status: %d", static_cast<int>(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuildResult::Failure::Status failureStatusFromString(std::string_view str)
|
||||||
|
{
|
||||||
|
for (const auto & [enumVal, enumStr] : failureStatusStrings) {
|
||||||
|
if (enumStr == str)
|
||||||
|
return enumVal;
|
||||||
|
}
|
||||||
|
throw Error("unknown built result failure status '%s'", str);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
||||||
|
namespace nlohmann {
|
||||||
|
|
||||||
|
using namespace nix;
|
||||||
|
|
||||||
|
void adl_serializer<BuildResult>::to_json(json & res, const BuildResult & br)
|
||||||
|
{
|
||||||
|
res = json::object();
|
||||||
|
|
||||||
|
// Common fields
|
||||||
|
res["timesBuilt"] = br.timesBuilt;
|
||||||
|
res["startTime"] = br.startTime;
|
||||||
|
res["stopTime"] = br.stopTime;
|
||||||
|
|
||||||
|
if (br.cpuUser.has_value()) {
|
||||||
|
res["cpuUser"] = br.cpuUser->count();
|
||||||
|
}
|
||||||
|
if (br.cpuSystem.has_value()) {
|
||||||
|
res["cpuSystem"] = br.cpuSystem->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle success or failure variant
|
||||||
|
std::visit(
|
||||||
|
overloaded{
|
||||||
|
[&](const BuildResult::Success & success) {
|
||||||
|
res["success"] = true;
|
||||||
|
res["status"] = successStatusToString(success.status);
|
||||||
|
res["builtOutputs"] = success.builtOutputs;
|
||||||
|
},
|
||||||
|
[&](const BuildResult::Failure & failure) {
|
||||||
|
res["success"] = false;
|
||||||
|
res["status"] = failureStatusToString(failure.status);
|
||||||
|
res["errorMsg"] = failure.errorMsg;
|
||||||
|
res["isNonDeterministic"] = failure.isNonDeterministic;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
br.inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildResult adl_serializer<BuildResult>::from_json(const json & _json)
|
||||||
|
{
|
||||||
|
auto & json = getObject(_json);
|
||||||
|
|
||||||
|
BuildResult br;
|
||||||
|
|
||||||
|
// Common fields
|
||||||
|
br.timesBuilt = getUnsigned(valueAt(json, "timesBuilt"));
|
||||||
|
br.startTime = getUnsigned(valueAt(json, "startTime"));
|
||||||
|
br.stopTime = getUnsigned(valueAt(json, "stopTime"));
|
||||||
|
|
||||||
|
if (auto cpuUser = optionalValueAt(json, "cpuUser")) {
|
||||||
|
br.cpuUser = std::chrono::microseconds(getUnsigned(*cpuUser));
|
||||||
|
}
|
||||||
|
if (auto cpuSystem = optionalValueAt(json, "cpuSystem")) {
|
||||||
|
br.cpuSystem = std::chrono::microseconds(getUnsigned(*cpuSystem));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine success or failure based on success field
|
||||||
|
bool success = getBoolean(valueAt(json, "success"));
|
||||||
|
std::string statusStr = getString(valueAt(json, "status"));
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
BuildResult::Success s;
|
||||||
|
s.status = successStatusFromString(statusStr);
|
||||||
|
s.builtOutputs = valueAt(json, "builtOutputs");
|
||||||
|
br.inner = std::move(s);
|
||||||
|
} else {
|
||||||
|
BuildResult::Failure f;
|
||||||
|
f.status = failureStatusFromString(statusStr);
|
||||||
|
f.errorMsg = getString(valueAt(json, "errorMsg"));
|
||||||
|
f.isNonDeterministic = getBoolean(valueAt(json, "isNonDeterministic"));
|
||||||
|
br.inner = std::move(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return br;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nlohmann
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "nix/store/derived-path.hh"
|
#include "nix/store/derived-path.hh"
|
||||||
#include "nix/store/realisation.hh"
|
#include "nix/store/realisation.hh"
|
||||||
|
#include "nix/util/json-impls.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
@ -175,3 +176,5 @@ struct KeyedBuildResult : BuildResult
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
||||||
|
JSON_IMPL(nix::BuildResult)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue