rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
heartwoodc2863c08ab58e1098ce29ab99d6d3f902e42c8d5
Request message
.radicle/native.yaml
git clone /home/_rad/.radicle/storage/z3gqcJUoA1n9HaHKufZs5FCSGazv5 /srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src
git config advice.detachedHead false
git checkout c2863c08ab58e1098ce29ab99d6d3f902e42c8d5
git show c2863c08ab58e1098ce29ab99d6d3f902e42c8d5
bash -c set -xeuo pipefail
cargo --version
rustc --version
cargo fmt --check
cargo clippy --all-targets --workspace -- --deny warnings
cargo build --all-targets --workspace
cargo doc --workspace --no-deps
cargo test --workspace --no-fail-fast
Request message
{ "request": "trigger", "version": 1, "event_type": "push", "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" ] }, "pusher": { "id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM", "alias": "fintohaps" }, "before": "c2863c08ab58e1098ce29ab99d6d3f902e42c8d5", "after": "c2863c08ab58e1098ce29ab99d6d3f902e42c8d5", "branch": "master", "commits": [ "c2863c08ab58e1098ce29ab99d6d3f902e42c8d5" ] }
.radicle/native.yaml
shell: | cargo --version rustc --version cargo fmt --check cargo clippy --all-targets --workspace -- --deny warnings cargo build --all-targets --workspace cargo doc --workspace --no-deps cargo test --workspace --no-fail-fast
git clone /home/_rad/.radicle/storage/z3gqcJUoA1n9HaHKufZs5FCSGazv5 /srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src
Command arguments:
"git"
"clone"
"/home/_rad/.radicle/storage/z3gqcJUoA1n9HaHKufZs5FCSGazv5"
"/srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src"
In directory: /
Exit code: 0
Output (stdout and stderr):
Cloning into '/srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src'... done.
git config advice.detachedHead false
Command arguments:
"git"
"config"
"advice.detachedHead"
"false"
In directory: /srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src
Exit code: 0
git checkout c2863c08ab58e1098ce29ab99d6d3f902e42c8d5
Command arguments:
"git"
"checkout"
"c2863c08ab58e1098ce29ab99d6d3f902e42c8d5"
In directory: /srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src
Exit code: 0
Output (stdout and stderr):
HEAD is now at c2863c08ab5 radicle: extend emoji support
git show c2863c08ab58e1098ce29ab99d6d3f902e42c8d5
Command arguments:
"git"
"show"
"c2863c08ab58e1098ce29ab99d6d3f902e42c8d5"
In directory: /srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src
Exit code: 0
Output (stdout and stderr):
commit c2863c08ab58e1098ce29ab99d6d3f902e42c8d5 Author: Fintan Halpenny <fintan.halpenny@gmail.com> Date: Thu Feb 13 10:05:44 2025 +0000 radicle: extend emoji support Extend the ranges of emojis that are supported, listed [below](#new-emojis-supported). To ensure that single `char` emojis are supported, the `emojis` crate is added as a dev dependency, using it to check that a `Reaction` can be constructed for the two groups `SmileysAndEmotion` and `PeopleAndBody`. ### New Emojis Supported '🩵' 0x1FA75 '🩶' 0x1FA76 '🩷' 0x1FA77 '🫀' 0x1FAC0 '🫁' 0x1FAC1 '🫂' 0x1FAC2 '🫃' 0x1FAC3 '🫄' 0x1FAC4 '🫅' 0x1FAC5 '' 0x1FAC6 '🫠' 0x1FAE0 '🫡' 0x1FAE1 '🫢' 0x1FAE2 '🫣' 0x1FAE3 '🫤' 0x1FAE4 '🫥' 0x1FAE5 '🫦' 0x1FAE6 '🫨' 0x1FAE8 '' 0x1FAE9 '🫰' 0x1FAF0 '🫱' 0x1FAF1 '🫲' 0x1FAF2 '🫳' 0x1FAF3 '🫴' 0x1FAF4 '🫵' 0x1FAF5 '🫶' 0x1FAF6 '🫷' 0x1FAF7 '🫸' 0x1FAF8 diff --git a/Cargo.lock b/Cargo.lock index 290039d4105..4b4fb944d0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -638,6 +638,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "emojis" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e1f1df1f181f2539bac8bf027d31ca5ffbf9e559e3f2d09413b9107b5c02f4" +dependencies = [ + "phf", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1709,6 +1718,24 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.1", +] + [[package]] name = "pkcs1" version = "0.7.5" @@ -1877,6 +1904,7 @@ dependencies = [ "colored", "crossbeam-channel", "cyphernet", + "emojis", "fastrand", "git2", "libc", diff --git a/radicle/Cargo.toml b/radicle/Cargo.toml index fbc5db7c9ab..74853a1b635 100644 --- a/radicle/Cargo.toml +++ b/radicle/Cargo.toml @@ -69,6 +69,7 @@ default-features = false optional = true [dev-dependencies] +emojis = { version = "0.6" } pretty_assertions = { version = "1.3.0" } qcheck-macros = { version = "1", default-features = false } qcheck = { version = "1", default-features = false } diff --git a/radicle/src/cob/common.rs b/radicle/src/cob/common.rs index 9c7eec6801e..bdc94d30035 100644 --- a/radicle/src/cob/common.rs +++ b/radicle/src/cob/common.rs @@ -91,12 +91,18 @@ impl Reaction { pub fn new(emoji: char) -> Result<Self, ReactionError> { let val = emoji as u32; let emoticons = 0x1F600..=0x1F64F; + let hearts = 0x1FA75..=0x1FA77; + let body_update = 0x1FAC0..=0x1FAC6; + let emoticons_update = 0x1FAE0..=0x1FAF8; let misc = 0x1F300..=0x1F5FF; // Miscellaneous Symbols and Pictographs let dingbats = 0x2700..=0x27BF; let supp = 0x1F900..=0x1F9FF; // Supplemental Symbols and Pictographs let transport = 0x1F680..=0x1F6FF; if emoticons.contains(&val) + || hearts.contains(&val) + || body_update.contains(&val) + || emoticons_update.contains(&val) || misc.contains(&val) || dingbats.contains(&val) || supp.contains(&val) @@ -367,32 +373,6 @@ impl From<bool> for Authorization { } } -#[cfg(test)] -#[allow(clippy::unwrap_used)] -mod test { - use super::*; - - #[test] - fn test_color() { - let c = Color::from_str("#ffccaa").unwrap(); - assert_eq!(c.to_string(), "#ffccaa".to_owned()); - assert_eq!(serde_json::to_string(&c).unwrap(), "\"#ffccaa\"".to_owned()); - assert_eq!(serde_json::from_str::<'_, Color>("\"#ffccaa\"").unwrap(), c); - - let c = Color::from_str("#0000aa").unwrap(); - assert_eq!(c.to_string(), "#0000aa".to_owned()); - - let c = Color::from_str("#aa0000").unwrap(); - assert_eq!(c.to_string(), "#aa0000".to_owned()); - - let c = Color::from_str("#00aa00").unwrap(); - assert_eq!(c.to_string(), "#00aa00".to_owned()); - - Color::from_str("#aa00").unwrap_err(); - Color::from_str("#abc").unwrap_err(); - } -} - /// Describes a code location that can be used for comments on /// patches, issues, and diffs. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] @@ -446,3 +426,60 @@ impl std::cmp::Ord for CodeRange { } } } + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +mod test { + use std::collections::BTreeSet; + + use super::*; + + #[test] + fn test_color() { + let c = Color::from_str("#ffccaa").unwrap(); + assert_eq!(c.to_string(), "#ffccaa".to_owned()); + assert_eq!(serde_json::to_string(&c).unwrap(), "\"#ffccaa\"".to_owned()); + assert_eq!(serde_json::from_str::<'_, Color>("\"#ffccaa\"").unwrap(), c); + + let c = Color::from_str("#0000aa").unwrap(); + assert_eq!(c.to_string(), "#0000aa".to_owned()); + + let c = Color::from_str("#aa0000").unwrap(); + assert_eq!(c.to_string(), "#aa0000".to_owned()); + + let c = Color::from_str("#00aa00").unwrap(); + assert_eq!(c.to_string(), "#00aa00".to_owned()); + + Color::from_str("#aa00").unwrap_err(); + Color::from_str("#abc").unwrap_err(); + } + + #[test] + fn test_emojis() { + let emojis = emojis::Group::SmileysAndEmotion + .emojis() + .chain(emojis::Group::PeopleAndBody.emojis()) + .filter_map(|emoji| { + if emoji.as_str().chars().count() == 1 { + Some(emoji.as_str().chars().next().unwrap()) + } else { + None + } + }); + let mut failed = BTreeSet::new(); + for emoji in emojis { + if Reaction::new(emoji).is_err() { + failed.insert(emoji); + } + } + if !failed.is_empty() { + for emoji in failed { + eprintln!( + "cannot construct Reaction for '{emoji}' {:#04X}", + (emoji as u32) + ); + } + panic!("Failed to construct Reaction for these emojis"); + } + } +}
bash -c set -xeuo pipefail
cargo --version
rustc --version
cargo fmt --check
cargo clippy --all-targets --workspace -- --deny warnings
cargo build --all-targets --workspace
cargo doc --workspace --no-deps
cargo test --workspace --no-fail-fast
Command arguments:
"bash"
"-c"
"set -xeuo pipefail\ncargo --version\nrustc --version\n\ncargo fmt --check\ncargo clippy --all-targets --workspace -- --deny warnings\ncargo build --all-targets --workspace\ncargo doc --workspace --no-deps\ncargo test --workspace --no-fail-fast\n"
In directory: /srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src
Exit code: 1
Output (stdout and stderr):
+ cargo --version cargo 1.80.1 (376290515 2024-07-16) + rustc --version rustc 1.80.1 (3f5fd8dd4 2024-08-06) + cargo fmt --check Diff in /srv/http/dae80b08-fba5-4655-abe7-77e52a6b4f34/src/radicle-cli/src/commands/help.rs at line 91: term::blank(); term::print("Do you have feedback?"); - term::print(" - Chat <\x1b]8;;https://radicle.zulipchat.com\x1b\\radicle.zulipchat.com\x1b]8;;\x1b\\>"); - term::print(" - Mail <\x1b]8;;mailto:feedback@radicle.xyz\x1b\\feedback@radicle.xyz\x1b]8;;\x1b\\>"); + term::print( + " - Chat <\x1b]8;;https://radicle.zulipchat.com\x1b\\radicle.zulipchat.com\x1b]8;;\x1b\\>", + ); + term::print( + " - Mail <\x1b]8;;mailto:feedback@radicle.xyz\x1b\\feedback@radicle.xyz\x1b]8;;\x1b\\>", + ); term::print(" (Messages are automatically posted to the public #feedback channel on Zulip.)"); Ok(())