rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 heartwooddae14f8b18582e650c17c12dd5a003e88cf1e307
{
"request": "trigger",
"version": 1,
"event_type": "patch",
"repository": {
"id": "rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5",
"name": "heartwood",
"description": "Radicle Heartwood Protocol & Stack",
"private": false,
"default_branch": "master",
"delegates": [
"did:key:z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT",
"did:key:z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW",
"did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"did:key:z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz",
"did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz"
]
},
"action": "Created",
"patch": {
"id": "af2103d6c857571a51a76590d3cb7e1712cecc73",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"title": "Add a function to programmatically modify the configuration",
"state": {
"status": "merged",
"conflicts": []
},
"before": "54551b117435a006acddefbf3850b02d6ee84ffa",
"after": "dae14f8b18582e650c17c12dd5a003e88cf1e307",
"commits": [
"dae14f8b18582e650c17c12dd5a003e88cf1e307",
"0eb91d824c49201fc86751dbf9002e3949f12ab0",
"89137954b96b921c8760cb989cad4f11d94e2bdf"
],
"target": "6cfed884bf37cba1e0d8e97fa8b0e94df4a04b1f",
"labels": [],
"assignees": [],
"revisions": [
{
"id": "af2103d6c857571a51a76590d3cb7e1712cecc73",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "Use new function to add commands for modifying configuration values.\n\nNote that the changes will affect the configuration file, but not the\nrunning instances. For changes to be reflected in the running instances\nthe node would need to be restarted.",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "c872328206cd3a689303eb8a3ddaf933d7ce1034",
"timestamp": 1720957036
},
{
"id": "0cf08119da7545b68e9cd70b7c8594e2e045c6e6",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "Add a function to programmatically modify the configuration\n\nNote that the changes will affect the configuration file, but not the\nrunning instances. For changes to be reflected in the running instances\nthe node would need to be restarted.\nAdd commands for modifying configuration values.",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "e79eae5cbcf9cfc6d89b9283ead5fe527e99c862",
"timestamp": 1720976731
},
{
"id": "056c638e7037a82d3b3d1dcd1fd52a92bd17a1f2",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "Add programmatic config changes\n\nEnsure the config changes don't overwrite existing additional values.",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "62b5b1d1844d604a3c0bb4f90c6f6e255e9098f4",
"timestamp": 1721140116
},
{
"id": "e463769dcb37106070269ae15a6141ea15689cfd",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "Add a function to programmatically modify the configuration\n\nNote that the changes will affect the configuration file, but not the\nrunning instances. For changes to be reflected in the running instances\nthe node would need to be restarted.",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "11bc0cda33a677bd46ce62090bde90750ebb43ff",
"timestamp": 1721153183
},
{
"id": "2b3d51dad9d6073f8c53dca4eeab694d17cbdd12",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "edf156a45bbc0602128f35644c1cce7d08d7fad4",
"timestamp": 1721153994
},
{
"id": "2aa69d827da8be686fda708003c1de9d4377858d",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "bf50a8b2f000e0cdcf87c0bca6646b9271c37140",
"timestamp": 1721378650
},
{
"id": "7e6b4f40ab5ecb5e226d6d163af71e838ddf82fa",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "7b8305257d74233c3fef5192787f1e6b80c7f417",
"timestamp": 1721423850
},
{
"id": "19ed0c708a13bf9195233866251ed985a8d86d40",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "a266e989396f97f688b1301e60815e64b5ccd820",
"timestamp": 1721503357
},
{
"id": "a136a0eafa1c00d4f47710d31ba9f5f56fc9cb22",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "74504594800a9bd89b112147769a662c2e992eb5",
"timestamp": 1721504381
},
{
"id": "e15a2b7c592d7bd1996d02241c1084b4c995aa99",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "c969d83d07e857f1f32de731c03cee006cf76f1a",
"timestamp": 1721507846
},
{
"id": "74cc06848439fa857671470f2d97cd533969d5aa",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "27e76c65b867f1bdec9e26bac5148f456c1088e3",
"timestamp": 1721508655
},
{
"id": "0bcf3c1a0e027a9de94ff224a9d9d48219be1de4",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "e8e85dfdfc0d26963bab08f2c4c2a792f5daa6c0",
"timestamp": 1721509049
},
{
"id": "3c328a7b79605e29f6b34612a4bb8ca4e8be1451",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "Use `.iter()` instead of `.into_iter()` to avoid cloning.\n\nRemove Action design and offer methods directly.\n\nMove Validation to write method of TempConfig.\n\nUse functions directly in cli.",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "89137954b96b921c8760cb989cad4f11d94e2bdf",
"timestamp": 1722165756
},
{
"id": "1761e43ce39bb43c9cbf8799aaa9159f48d47fa7",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "WIP: code review\n\n* Moved config related code into a `config` module so that it's easier to work\n with\n* Created a `ModifyError` enum for handling the modification errors\n* Some wording changes on the error messages\n* There was a bug where `rad config add` of a non-existent path would not create\n an array. This was fixed and a test case was added\n* Changed `iter` to return the trait object instead\n* Changed `last` to return a reference\n* Use `split_last` to construct the `ConfigPath::parent`\n* Left a TODO since the API is technically unsafe since someone can construct a\n `ConfigValue::Float` with NaN if they construct it directly",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "0eb91d824c49201fc86751dbf9002e3949f12ab0",
"timestamp": 1722269595
},
{
"id": "97fc3acccadea93f22d52f11fd5575fb9304446a",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "93022dd3abb67bce8ee5f6334a57aa8c958efe1a",
"timestamp": 1722862906
},
{
"id": "48a12786dc0d66cf861b378676390e9f5f7a248f",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "37ad416bbfe7c7937d6f4090dc1ba696a81de460",
"timestamp": 1722863313
},
{
"id": "f7b19153443fb1005b9e692eeefc9b1c308258f9",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "dae14f8b18582e650c17c12dd5a003e88cf1e307",
"timestamp": 1722863642
},
{
"id": "a18be31b1566204da940d0179e3c2e5b03656899",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "REVIEW\n\n- Use `term::args::string` to parse key/value inputs\n- No need to print anything when deleting a key\n- Print `null` value\n- Remove `last` and `parent` methods in favour of `split_last` method\n- General cleanup and formatting of docs\n- Leave FIXME for corner case of `ConfigPath` that may want to refer to a key\n with a `.` in it",
"base": "54551b117435a006acddefbf3850b02d6ee84ffa",
"oid": "41738fcd2ebc352aa9b826bf8727e054443dd008",
"timestamp": 1723207229
},
{
"id": "82adfa70baa417ef1ff7052cd8811ad046951b22",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "A few small improvements and changes in the API.\n\n`delete` -> `unset`\n`add` -> `push`",
"base": "a838c3ea01dc0741b22236c9d2aed7f6cb0c1d86",
"oid": "61bceaed534afddd215ce095cd8fd742adea02fd",
"timestamp": 1729696729
},
{
"id": "3e77a3df652daa0d6b3f94d5e0751d575bbdbd0e",
"author": {
"id": "did:key:z6MkgFWv1K9Lqvi5VHm4mtfDo5MvanWVNYU1gkvT9Rwr1Lu7",
"alias": "Kuehle"
},
"description": "Fix trailing line.",
"base": "a838c3ea01dc0741b22236c9d2aed7f6cb0c1d86",
"oid": "0c9a7419dcfd265b6c1efe85c915d126feaef649",
"timestamp": 1729696782
}
]
}
}
{
"response": "triggered",
"run_id": {
"id": "9a06b9f3-0c60-4e99-8bcd-559da1c95f37"
},
"info_url": "https://cci.rad.levitte.org//9a06b9f3-0c60-4e99-8bcd-559da1c95f37.html"
}
Started at: 2025-10-21 17:35:59.511351+02:00
Commands:
$ rad clone rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 .
✓ Creating checkout in ./...
✓ Remote cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT added
✓ Remote-tracking branch cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT/master created for z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT
✓ Remote cloudhead@z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW added
✓ Remote-tracking branch cloudhead@z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW/master created for z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW
✓ Remote fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM added
✓ Remote-tracking branch fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM/master created for z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM
✓ Remote erikli@z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz added
✓ Remote-tracking branch erikli@z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz/master created for z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz
✓ Remote lorenz@z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz added
✓ Remote-tracking branch lorenz@z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz/master created for z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz
✓ Repository successfully cloned under /opt/radcis/ci.rad.levitte.org/cci/state/9a06b9f3-0c60-4e99-8bcd-559da1c95f37/w/
╭────────────────────────────────────╮
│ heartwood │
│ Radicle Heartwood Protocol & Stack │
│ 125 issues · 15 patches │
╰────────────────────────────────────╯
Run `cd ./.` to go to the repository directory.
Exit code: 0
$ rad patch checkout af2103d6c857571a51a76590d3cb7e1712cecc73
✓ Switched to branch patch/af2103d at revision f7b1915
✓ Branch patch/af2103d setup to track rad/patches/af2103d6c857571a51a76590d3cb7e1712cecc73
Exit code: 0
$ git config advice.detachedHead false
Exit code: 0
$ git checkout dae14f8b18582e650c17c12dd5a003e88cf1e307
HEAD is now at dae14f8b Encapsulate config value behaviour
Exit code: 0
$ git show dae14f8b18582e650c17c12dd5a003e88cf1e307
commit dae14f8b18582e650c17c12dd5a003e88cf1e307
Author: Johannes Kühlewindt <johannes.kuehlewindt@gmail.com>
Date: Mon Aug 5 14:59:23 2024 +0200
Encapsulate config value behaviour
diff --git a/radicle/src/profile/config.rs b/radicle/src/profile/config.rs
index 84c86468..d575a6c5 100644
--- a/radicle/src/profile/config.rs
+++ b/radicle/src/profile/config.rs
@@ -267,9 +267,14 @@ impl TryInto<Config> for TempConfig {
}
}
-// TODO: this being pub means one can construct an invalid `ConfigValue::Float`
+/// A struct that ensures all values are safe for JSON serialization, including handling special
+/// floating point values like `NaN` and `Infinity`. Use the `From<&str>` implementation to create an instance.
+pub struct ConfigValue(RawConfigValue);
+
+/// This enum represents raw configuration values and should not be used directly.
+/// Use the `ConfigValue` type, which validates values using its `From<&str>` implementation.
#[derive(Debug, Clone)]
-pub enum ConfigValue {
+enum RawConfigValue {
Integer(i64),
Float(f64),
Bool(bool),
@@ -280,17 +285,18 @@ impl From<&str> for ConfigValue {
/// Guess the type of a Value.
fn from(value: &str) -> Self {
if let Ok(b) = value.parse::<bool>() {
- ConfigValue::Bool(b)
+ ConfigValue(RawConfigValue::Bool(b))
} else if let Ok(n) = value.parse::<i64>() {
- ConfigValue::Integer(n)
+ ConfigValue(RawConfigValue::Integer(n))
} else if let Ok(n) = value.parse::<f64>() {
+ // NaN and Infinite can't be properly serialized to JSON
if n.is_finite() {
- ConfigValue::Float(n)
+ ConfigValue(RawConfigValue::Float(n))
} else {
- ConfigValue::String(n.to_string())
+ ConfigValue(RawConfigValue::String(value.to_string()))
}
} else {
- ConfigValue::String(value.to_string())
+ ConfigValue(RawConfigValue::String(value.to_string()))
}
}
}
@@ -304,13 +310,13 @@ impl From<String> for ConfigValue {
impl From<ConfigValue> for json::Value {
fn from(value: ConfigValue) -> Self {
match value {
- ConfigValue::Bool(v) => json::Value::Bool(v),
- ConfigValue::Integer(v) => json::Value::Number(v.into()),
- ConfigValue::Float(v) => {
+ ConfigValue(RawConfigValue::Bool(v)) => json::Value::Bool(v),
+ ConfigValue(RawConfigValue::Integer(v)) => json::Value::Number(v.into()),
+ ConfigValue(RawConfigValue::Float(v)) => {
// Safety: ConfigValue ensures the Float won't be Infinite or NaN
json::Value::Number(json::Number::from_f64(v).unwrap())
}
- ConfigValue::String(v) => json::Value::String(v),
+ ConfigValue(RawConfigValue::String(v)) => json::Value::String(v),
}
}
}
Exit code: 0
shell: 'cargo --version rustc --version cargo fmt --check cargo clippy --all-targets --workspace -- --deny clippy::all cargo build --all-targets --workspace cargo doc --workspace cargo test --workspace --no-fail-fast '
Commands:
$ podman run --name 9a06b9f3-0c60-4e99-8bcd-559da1c95f37 -v /opt/radcis/ci.rad.levitte.org/cci/state/9a06b9f3-0c60-4e99-8bcd-559da1c95f37/s:/9a06b9f3-0c60-4e99-8bcd-559da1c95f37/s:ro -v /opt/radcis/ci.rad.levitte.org/cci/state/9a06b9f3-0c60-4e99-8bcd-559da1c95f37/w:/9a06b9f3-0c60-4e99-8bcd-559da1c95f37/w -w /9a06b9f3-0c60-4e99-8bcd-559da1c95f37/w -v /opt/radcis/ci.rad.levitte.org/.radicle:/${id}/.radicle:ro -e RAD_HOME=/${id}/.radicle rust:bookworm bash /9a06b9f3-0c60-4e99-8bcd-559da1c95f37/s/script.sh
+ cargo --version
info: syncing channel updates for '1.77-x86_64-unknown-linux-gnu'
info: latest update on 2024-04-09, rust version 1.77.2 (25ef9e3d8 2024-04-09)
info: downloading component 'cargo'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: installing component 'cargo'
info: installing component 'rust-std'
info: installing component 'rustc'
cargo 1.77.2 (e52e36006 2024-03-26)
+ rustc --version
rustc 1.77.2 (25ef9e3d8 2024-04-09)
+ cargo fmt --check
error: 'cargo-fmt' is not installed for the toolchain '1.77-x86_64-unknown-linux-gnu'.
To install, run `rustup component add --toolchain 1.77-x86_64-unknown-linux-gnu rustfmt`
Exit code: 1
{
"response": "finished",
"result": "failure"
}