upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock104
-rw-r--r--Cargo.toml4
-rw-r--r--src/git.rs4
-rw-r--r--src/key_handling/users.rs48
-rw-r--r--src/repo_ref.rs47
-rw-r--r--src/sub_commands/list.rs2
-rw-r--r--src/sub_commands/send.rs338
-rw-r--r--test_utils/Cargo.toml4
-rw-r--r--test_utils/src/lib.rs69
-rw-r--r--test_utils/src/relay.rs26
-rw-r--r--tests/init.rs26
-rw-r--r--tests/list.rs1
-rw-r--r--tests/send.rs16
13 files changed, 349 insertions, 340 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 51ef7a7..bf0032e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -330,17 +330,17 @@ dependencies = [
330 330
331[[package]] 331[[package]]
332name = "async-wsocket" 332name = "async-wsocket"
333version = "0.4.0" 333version = "0.5.1"
334source = "registry+https://github.com/rust-lang/crates.io-index" 334source = "registry+https://github.com/rust-lang/crates.io-index"
335checksum = "5c38341e6ee670913fb9dc3aba40c22d616261da4dc0928326d3168ebf576fb0" 335checksum = "79c6465dab65a363da7353383af13a22fb05ce173d9b460c38322590e9245400"
336dependencies = [ 336dependencies = [
337 "async-utility", 337 "async-utility",
338 "futures-util", 338 "futures-util",
339 "thiserror", 339 "thiserror",
340 "tokio", 340 "tokio",
341 "tokio-rustls", 341 "tokio-rustls 0.26.0",
342 "tokio-socks", 342 "tokio-socks",
343 "tokio-tungstenite 0.21.0", 343 "tokio-tungstenite 0.23.0",
344 "url", 344 "url",
345 "wasm-ws", 345 "wasm-ws",
346 "webpki-roots", 346 "webpki-roots",
@@ -359,9 +359,9 @@ dependencies = [
359 359
360[[package]] 360[[package]]
361name = "atomic-destructor" 361name = "atomic-destructor"
362version = "0.1.1" 362version = "0.2.0"
363source = "registry+https://github.com/rust-lang/crates.io-index" 363source = "registry+https://github.com/rust-lang/crates.io-index"
364checksum = "4653a42bf04120a1d4e92452e006b4e3af4ab4afff8fb4af0f1bbb98418adf3e" 364checksum = "7d919cb60ba95c87ba42777e9e246c4e8d658057299b437b7512531ce0a09a23"
365dependencies = [ 365dependencies = [
366 "tracing", 366 "tracing",
367] 367]
@@ -1330,10 +1330,10 @@ dependencies = [
1330 "http 1.1.0", 1330 "http 1.1.0",
1331 "hyper", 1331 "hyper",
1332 "hyper-util", 1332 "hyper-util",
1333 "rustls", 1333 "rustls 0.22.3",
1334 "rustls-pki-types", 1334 "rustls-pki-types",
1335 "tokio", 1335 "tokio",
1336 "tokio-rustls", 1336 "tokio-rustls 0.25.0",
1337 "tower-service", 1337 "tower-service",
1338] 1338]
1339 1339
@@ -1776,8 +1776,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
1776 1776
1777[[package]] 1777[[package]]
1778name = "nostr" 1778name = "nostr"
1779version = "0.30.0" 1779version = "0.32.0"
1780source = "git+https://github.com/DanConwayDev/nostr?branch=expose-nip49-log-n#6ef397b6c4cd5edd6e6c31ff33d8a978b5b04f8c" 1780source = "registry+https://github.com/rust-lang/crates.io-index"
1781checksum = "1534cec170e72b57b82323422ac243716d9817d13ed77f3b952eb5133ebef060"
1781dependencies = [ 1782dependencies = [
1782 "aes 0.8.4", 1783 "aes 0.8.4",
1783 "base64 0.21.7", 1784 "base64 0.21.7",
@@ -1805,8 +1806,9 @@ dependencies = [
1805 1806
1806[[package]] 1807[[package]]
1807name = "nostr-database" 1808name = "nostr-database"
1808version = "0.30.0" 1809version = "0.32.0"
1809source = "git+https://github.com/DanConwayDev/nostr?branch=expose-nip49-log-n#6ef397b6c4cd5edd6e6c31ff33d8a978b5b04f8c" 1810source = "registry+https://github.com/rust-lang/crates.io-index"
1811checksum = "a88a72f92fbd5d2514db36e07a864646f1c1f44931c4a5ea195f6961029af4b3"
1810dependencies = [ 1812dependencies = [
1811 "async-trait", 1813 "async-trait",
1812 "lru", 1814 "lru",
@@ -1818,8 +1820,9 @@ dependencies = [
1818 1820
1819[[package]] 1821[[package]]
1820name = "nostr-relay-pool" 1822name = "nostr-relay-pool"
1821version = "0.30.0" 1823version = "0.32.0"
1822source = "git+https://github.com/DanConwayDev/nostr?branch=expose-nip49-log-n#6ef397b6c4cd5edd6e6c31ff33d8a978b5b04f8c" 1824source = "registry+https://github.com/rust-lang/crates.io-index"
1825checksum = "d7b7bf72b02a24ccc7cf87033fa5ddfd57001c7d8c2e757321a7ca7a6df39876"
1823dependencies = [ 1826dependencies = [
1824 "async-utility", 1827 "async-utility",
1825 "async-wsocket", 1828 "async-wsocket",
@@ -1833,10 +1836,12 @@ dependencies = [
1833 1836
1834[[package]] 1837[[package]]
1835name = "nostr-sdk" 1838name = "nostr-sdk"
1836version = "0.30.0" 1839version = "0.32.0"
1837source = "git+https://github.com/DanConwayDev/nostr?branch=expose-nip49-log-n#6ef397b6c4cd5edd6e6c31ff33d8a978b5b04f8c" 1840source = "registry+https://github.com/rust-lang/crates.io-index"
1841checksum = "005915a59ee6401f23ba510c3a9ac4a07b457f80dfe1dc05cd2c8fdbde439246"
1838dependencies = [ 1842dependencies = [
1839 "async-utility", 1843 "async-utility",
1844 "atomic-destructor",
1840 "lnurl-pay", 1845 "lnurl-pay",
1841 "nostr", 1846 "nostr",
1842 "nostr-database", 1847 "nostr-database",
@@ -1851,8 +1856,9 @@ dependencies = [
1851 1856
1852[[package]] 1857[[package]]
1853name = "nostr-signer" 1858name = "nostr-signer"
1854version = "0.30.0" 1859version = "0.32.0"
1855source = "git+https://github.com/DanConwayDev/nostr?branch=expose-nip49-log-n#6ef397b6c4cd5edd6e6c31ff33d8a978b5b04f8c" 1860source = "registry+https://github.com/rust-lang/crates.io-index"
1861checksum = "525574dc32fa07d64d04a6c72b534d97455b1ad954c29753c820c834c94e3704"
1856dependencies = [ 1862dependencies = [
1857 "async-utility", 1863 "async-utility",
1858 "nostr", 1864 "nostr",
@@ -1864,8 +1870,9 @@ dependencies = [
1864 1870
1865[[package]] 1871[[package]]
1866name = "nostr-zapper" 1872name = "nostr-zapper"
1867version = "0.30.0" 1873version = "0.32.0"
1868source = "git+https://github.com/DanConwayDev/nostr?branch=expose-nip49-log-n#6ef397b6c4cd5edd6e6c31ff33d8a978b5b04f8c" 1874source = "registry+https://github.com/rust-lang/crates.io-index"
1875checksum = "430c2527c0efd2e7f1a421b0c7df01a03b334a79c60c39cc7a1ca684f720f2bf"
1869dependencies = [ 1876dependencies = [
1870 "async-trait", 1877 "async-trait",
1871 "nostr", 1878 "nostr",
@@ -1965,8 +1972,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
1965 1972
1966[[package]] 1973[[package]]
1967name = "nwc" 1974name = "nwc"
1968version = "0.30.0" 1975version = "0.32.0"
1969source = "git+https://github.com/DanConwayDev/nostr?branch=expose-nip49-log-n#6ef397b6c4cd5edd6e6c31ff33d8a978b5b04f8c" 1976source = "registry+https://github.com/rust-lang/crates.io-index"
1977checksum = "c6fb91e4be3f6b872fc23c7714bbb500a58a1d59f458eb6eb9dd249fbec42fc2"
1970dependencies = [ 1978dependencies = [
1971 "async-utility", 1979 "async-utility",
1972 "nostr", 1980 "nostr",
@@ -2441,7 +2449,7 @@ dependencies = [
2441 "once_cell", 2449 "once_cell",
2442 "percent-encoding", 2450 "percent-encoding",
2443 "pin-project-lite", 2451 "pin-project-lite",
2444 "rustls", 2452 "rustls 0.22.3",
2445 "rustls-pemfile", 2453 "rustls-pemfile",
2446 "rustls-pki-types", 2454 "rustls-pki-types",
2447 "serde", 2455 "serde",
@@ -2449,7 +2457,7 @@ dependencies = [
2449 "serde_urlencoded", 2457 "serde_urlencoded",
2450 "sync_wrapper", 2458 "sync_wrapper",
2451 "tokio", 2459 "tokio",
2452 "tokio-rustls", 2460 "tokio-rustls 0.25.0",
2453 "tokio-socks", 2461 "tokio-socks",
2454 "tower-service", 2462 "tower-service",
2455 "url", 2463 "url",
@@ -2557,6 +2565,20 @@ dependencies = [
2557] 2565]
2558 2566
2559[[package]] 2567[[package]]
2568name = "rustls"
2569version = "0.23.7"
2570source = "registry+https://github.com/rust-lang/crates.io-index"
2571checksum = "ebbbdb961df0ad3f2652da8f3fdc4b36122f568f968f45ad3316f26c025c677b"
2572dependencies = [
2573 "once_cell",
2574 "ring",
2575 "rustls-pki-types",
2576 "rustls-webpki",
2577 "subtle",
2578 "zeroize",
2579]
2580
2581[[package]]
2560name = "rustls-pemfile" 2582name = "rustls-pemfile"
2561version = "2.1.2" 2583version = "2.1.2"
2562source = "registry+https://github.com/rust-lang/crates.io-index" 2584source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3039,7 +3061,18 @@ version = "0.25.0"
3039source = "registry+https://github.com/rust-lang/crates.io-index" 3061source = "registry+https://github.com/rust-lang/crates.io-index"
3040checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" 3062checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
3041dependencies = [ 3063dependencies = [
3042 "rustls", 3064 "rustls 0.22.3",
3065 "rustls-pki-types",
3066 "tokio",
3067]
3068
3069[[package]]
3070name = "tokio-rustls"
3071version = "0.26.0"
3072source = "registry+https://github.com/rust-lang/crates.io-index"
3073checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
3074dependencies = [
3075 "rustls 0.23.7",
3043 "rustls-pki-types", 3076 "rustls-pki-types",
3044 "tokio", 3077 "tokio",
3045] 3078]
@@ -3070,17 +3103,17 @@ dependencies = [
3070 3103
3071[[package]] 3104[[package]]
3072name = "tokio-tungstenite" 3105name = "tokio-tungstenite"
3073version = "0.21.0" 3106version = "0.23.0"
3074source = "registry+https://github.com/rust-lang/crates.io-index" 3107source = "registry+https://github.com/rust-lang/crates.io-index"
3075checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" 3108checksum = "becd34a233e7e31a3dbf7c7241b38320f57393dcae8e7324b0167d21b8e320b0"
3076dependencies = [ 3109dependencies = [
3077 "futures-util", 3110 "futures-util",
3078 "log", 3111 "log",
3079 "rustls", 3112 "rustls 0.23.7",
3080 "rustls-pki-types", 3113 "rustls-pki-types",
3081 "tokio", 3114 "tokio",
3082 "tokio-rustls", 3115 "tokio-rustls 0.26.0",
3083 "tungstenite 0.21.0", 3116 "tungstenite 0.23.0",
3084 "webpki-roots", 3117 "webpki-roots",
3085] 3118]
3086 3119
@@ -3188,9 +3221,9 @@ dependencies = [
3188 3221
3189[[package]] 3222[[package]]
3190name = "tungstenite" 3223name = "tungstenite"
3191version = "0.21.0" 3224version = "0.23.0"
3192source = "registry+https://github.com/rust-lang/crates.io-index" 3225source = "registry+https://github.com/rust-lang/crates.io-index"
3193checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" 3226checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8"
3194dependencies = [ 3227dependencies = [
3195 "byteorder", 3228 "byteorder",
3196 "bytes", 3229 "bytes",
@@ -3199,11 +3232,10 @@ dependencies = [
3199 "httparse", 3232 "httparse",
3200 "log", 3233 "log",
3201 "rand", 3234 "rand",
3202 "rustls", 3235 "rustls 0.23.7",
3203 "rustls-pki-types", 3236 "rustls-pki-types",
3204 "sha1", 3237 "sha1",
3205 "thiserror", 3238 "thiserror",
3206 "url",
3207 "utf-8", 3239 "utf-8",
3208] 3240]
3209 3241
@@ -3427,9 +3459,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
3427 3459
3428[[package]] 3460[[package]]
3429name = "wasm-ws" 3461name = "wasm-ws"
3430version = "0.1.1" 3462version = "0.2.1"
3431source = "registry+https://github.com/rust-lang/crates.io-index" 3463source = "registry+https://github.com/rust-lang/crates.io-index"
3432checksum = "f5b3a482e27ff54809c0848629d9033179705c5ea2f58e26cf45dc77c34c4984" 3464checksum = "688c5806d1b06b4f3d90d015e23364dc5d3af412ee64abba6dde8fdc01637e33"
3433dependencies = [ 3465dependencies = [
3434 "async_io_stream", 3466 "async_io_stream",
3435 "futures", 3467 "futures",
diff --git a/Cargo.toml b/Cargo.toml
index 1316357..a57f9d4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,8 +23,8 @@ futures = "0.3.28"
23git2 = "0.18.1" 23git2 = "0.18.1"
24indicatif = "0.17.7" 24indicatif = "0.17.7"
25keyring = "2.0.5" 25keyring = "2.0.5"
26nostr = { git = "https://github.com/DanConwayDev/nostr", branch="expose-nip49-log-n" } 26nostr = "0.32.0"
27nostr-sdk = { git = "https://github.com/DanConwayDev/nostr", branch="expose-nip49-log-n" } 27nostr-sdk = "0.32.0"
28passwords = "3.1.13" 28passwords = "3.1.13"
29scrypt = "0.11.0" 29scrypt = "0.11.0"
30serde = { version = "1.0.181", features = ["derive"] } 30serde = { version = "1.0.181", features = ["derive"] }
diff --git a/src/git.rs b/src/git.rs
index e797cb8..fb3b353 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -948,8 +948,8 @@ mod tests {
948 fn test(time: git2::Time) -> Result<()> { 948 fn test(time: git2::Time) -> Result<()> {
949 assert_eq!( 949 assert_eq!(
950 extract_sig_from_patch_tags( 950 extract_sig_from_patch_tags(
951 &[nostr::Tag::Generic( 951 &[nostr::Tag::custom(
952 nostr::TagKind::Custom("author".to_string()), 952 nostr::TagKind::Custom("author".to_string().into()),
953 prep(&time)?, 953 prep(&time)?,
954 )], 954 )],
955 "author", 955 "author",
diff --git a/src/key_handling/users.rs b/src/key_handling/users.rs
index 1dd75a8..a79a977 100644
--- a/src/key_handling/users.rs
+++ b/src/key_handling/users.rs
@@ -567,15 +567,18 @@ mod tests {
567 nostr::Kind::RelayList, 567 nostr::Kind::RelayList,
568 "", 568 "",
569 [ 569 [
570 nostr::Tag::RelayMetadata( 570 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
571 "wss://fredswrite1.relay".into(), 571 relay_url: nostr::Url::from_str("wss://fredswrite1.relay/").unwrap(),
572 Some(nostr::RelayMetadata::Write), 572 metadata: Some(RelayMetadata::Write),
573 ), 573 }),
574 nostr::Tag::RelayMetadata( 574 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
575 "wss://fredsread1.relay".into(), 575 relay_url: nostr::Url::from_str("wss://fredsread1.relay/").unwrap(),
576 Some(nostr::RelayMetadata::Read), 576 metadata: Some(RelayMetadata::Read),
577 ), 577 }),
578 nostr::Tag::RelayMetadata("wss://fredsreadwrite.relay".into(), None), 578 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
579 relay_url: nostr::Url::from_str("wss://fredsreadwrite.relay/").unwrap(),
580 metadata: None,
581 }),
579 ], 582 ],
580 ) 583 )
581 .to_event(&TEST_KEY_1_KEYS) 584 .to_event(&TEST_KEY_1_KEYS)
@@ -587,15 +590,18 @@ mod tests {
587 nostr::Kind::RelayList, 590 nostr::Kind::RelayList,
588 "", 591 "",
589 [ 592 [
590 nostr::Tag::RelayMetadata( 593 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
591 "wss://carolswrite1.relay".into(), 594 relay_url: nostr::Url::from_str("wss://carolswrite1.relay/").unwrap(),
592 Some(nostr::RelayMetadata::Write), 595 metadata: Some(RelayMetadata::Write),
593 ), 596 }),
594 nostr::Tag::RelayMetadata( 597 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
595 "wss://carolsread1.relay".into(), 598 relay_url: nostr::Url::from_str("wss://carolsread1.relay/").unwrap(),
596 Some(nostr::RelayMetadata::Read), 599 metadata: Some(RelayMetadata::Read),
597 ), 600 }),
598 nostr::Tag::RelayMetadata("wss://carolsreadwrite.relay".into(), None), 601 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
602 relay_url: nostr::Url::from_str("wss://carolsreadwrite.relay/").unwrap(),
603 metadata: None,
604 }),
599 ], 605 ],
600 ) 606 )
601 .to_event(&TEST_KEY_2_KEYS) 607 .to_event(&TEST_KEY_2_KEYS)
@@ -652,7 +658,7 @@ mod tests {
652 658
653 fn expected_userrelayrefs_write1() -> UserRelayRef { 659 fn expected_userrelayrefs_write1() -> UserRelayRef {
654 UserRelayRef { 660 UserRelayRef {
655 url: "wss://fredswrite1.relay".into(), 661 url: "wss://fredswrite1.relay/".into(),
656 read: false, 662 read: false,
657 write: true, 663 write: true,
658 } 664 }
@@ -661,7 +667,7 @@ mod tests {
661 667
662 fn expected_userrelayrefs_read_write1() -> UserRelayRef { 668 fn expected_userrelayrefs_read_write1() -> UserRelayRef {
663 UserRelayRef { 669 UserRelayRef {
664 url: "wss://fredsreadwrite.relay".into(), 670 url: "wss://fredsreadwrite.relay/".into(),
665 read: true, 671 read: true,
666 write: true, 672 write: true,
667 } 673 }
@@ -672,7 +678,7 @@ mod tests {
672 vec![ 678 vec![
673 expected_userrelayrefs_write1(), 679 expected_userrelayrefs_write1(),
674 UserRelayRef { 680 UserRelayRef {
675 url: "wss://fredsread1.relay".into(), 681 url: "wss://fredsread1.relay/".into(),
676 read: true, 682 read: true,
677 write: false, 683 write: false,
678 }, 684 },
diff --git a/src/repo_ref.rs b/src/repo_ref.rs
index d314e6d..9fb1f0c 100644
--- a/src/repo_ref.rs
+++ b/src/repo_ref.rs
@@ -1,7 +1,7 @@
1use std::{fs::File, io::BufReader, str::FromStr}; 1use std::{fs::File, io::BufReader, str::FromStr};
2 2
3use anyhow::{bail, Context, Result}; 3use anyhow::{bail, Context, Result};
4use nostr::{nips::nip19::Nip19, FromBech32, PublicKey, Tag, ToBech32}; 4use nostr::{nips::nip19::Nip19, FromBech32, PublicKey, Tag, TagStandard, ToBech32};
5use serde::{Deserialize, Serialize}; 5use serde::{Deserialize, Serialize};
6 6
7#[cfg(not(test))] 7#[cfg(not(test))]
@@ -31,7 +31,7 @@ impl TryFrom<nostr::Event> for RepoRef {
31 type Error = anyhow::Error; 31 type Error = anyhow::Error;
32 32
33 fn try_from(event: nostr::Event) -> Result<Self> { 33 fn try_from(event: nostr::Event) -> Result<Self> {
34 if !event.kind.as_u64().eq(&REPO_REF_KIND) { 34 if !event.kind.as_u16().eq(&REPO_REF_KIND) {
35 bail!("incorrect kind"); 35 bail!("incorrect kind");
36 } 36 }
37 let mut r = Self::default(); 37 let mut r = Self::default();
@@ -49,12 +49,12 @@ impl TryFrom<nostr::Event> for RepoRef {
49 } 49 }
50 50
51 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("clone")) { 51 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("clone")) {
52 r.git_server = t.as_vec().clone(); 52 r.git_server = t.clone().to_vec();
53 r.git_server.remove(0); 53 r.git_server.remove(0);
54 } 54 }
55 55
56 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("web")) { 56 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("web")) {
57 r.web = t.as_vec().clone(); 57 r.web = t.clone().to_vec();
58 r.web.remove(0); 58 r.web.remove(0);
59 } 59 }
60 60
@@ -67,12 +67,12 @@ impl TryFrom<nostr::Event> for RepoRef {
67 } 67 }
68 68
69 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("relays")) { 69 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("relays")) {
70 r.relays = t.as_vec().clone(); 70 r.relays = t.clone().to_vec();
71 r.relays.remove(0); 71 r.relays.remove(0);
72 } 72 }
73 73
74 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("maintainers")) { 74 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("maintainers")) {
75 let mut maintainers = t.as_vec().clone(); 75 let mut maintainers = t.clone().to_vec();
76 maintainers.remove(0); 76 maintainers.remove(0);
77 if !maintainers.contains(&event.pubkey.to_string()) { 77 if !maintainers.contains(&event.pubkey.to_string()) {
78 r.maintainers.push(event.pubkey); 78 r.maintainers.push(event.pubkey);
@@ -90,7 +90,7 @@ impl TryFrom<nostr::Event> for RepoRef {
90 } 90 }
91} 91}
92 92
93pub static REPO_REF_KIND: u64 = 30_617; 93pub static REPO_REF_KIND: u16 = 30_617;
94 94
95impl RepoRef { 95impl RepoRef {
96 pub fn to_event(&self, keys: &nostr::Keys) -> Result<nostr::Event> { 96 pub fn to_event(&self, keys: &nostr::Keys) -> Result<nostr::Event> {
@@ -99,7 +99,7 @@ impl RepoRef {
99 "", 99 "",
100 [ 100 [
101 vec![ 101 vec![
102 Tag::Identifier(if self.identifier.to_string().is_empty() { 102 Tag::identifier(if self.identifier.to_string().is_empty() {
103 // fiatjaf thought a random string. its not in the draft nip. 103 // fiatjaf thought a random string. its not in the draft nip.
104 // thread_rng() 104 // thread_rng()
105 // .sample_iter(&Alphanumeric) 105 // .sample_iter(&Alphanumeric)
@@ -117,27 +117,30 @@ impl RepoRef {
117 } else { 117 } else {
118 self.identifier.to_string() 118 self.identifier.to_string()
119 }), 119 }),
120 Tag::Reference(self.root_commit.to_string()), 120 Tag::from_standardized(TagStandard::Reference(self.root_commit.to_string())),
121 Tag::Name(self.name.clone()), 121 Tag::from_standardized(TagStandard::Name(self.name.clone())),
122 Tag::Description(self.description.clone()), 122 Tag::from_standardized(TagStandard::Description(self.description.clone())),
123 Tag::Generic( 123 Tag::custom(
124 nostr::TagKind::Custom("clone".to_string()), 124 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("clone")),
125 self.git_server.clone(), 125 self.git_server.clone(),
126 ), 126 ),
127 Tag::Generic(nostr::TagKind::Custom("web".to_string()), self.web.clone()), 127 Tag::custom(
128 Tag::Generic( 128 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("web")),
129 nostr::TagKind::Custom("relays".to_string()), 129 self.web.clone(),
130 ),
131 Tag::custom(
132 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("relays")),
130 self.relays.clone(), 133 self.relays.clone(),
131 ), 134 ),
132 Tag::Generic( 135 Tag::custom(
133 nostr::TagKind::Custom("maintainers".to_string()), 136 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("maintainers")),
134 self.maintainers 137 self.maintainers
135 .iter() 138 .iter()
136 .map(std::string::ToString::to_string) 139 .map(std::string::ToString::to_string)
137 .collect(), 140 .collect::<Vec<String>>(),
138 ), 141 ),
139 Tag::Generic( 142 Tag::custom(
140 nostr::TagKind::Custom("alt".to_string()), 143 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("alt")),
141 vec![format!("git repository: {}", self.name.clone())], 144 vec![format!("git repository: {}", self.name.clone())],
142 ), 145 ),
143 ], 146 ],
@@ -188,7 +191,7 @@ pub async fn fetch(
188 // somewhere within .git folder for future use and seek to get that next time 191 // somewhere within .git folder for future use and seek to get that next time
189 if let Some(event) = events 192 if let Some(event) = events
190 .iter() 193 .iter()
191 .filter(|e| e.kind.as_u64() == REPO_REF_KIND) 194 .filter(|e| e.kind.as_u16() == REPO_REF_KIND)
192 .max_by_key(|e| e.created_at) 195 .max_by_key(|e| e.created_at)
193 { 196 {
194 break event.clone(); 197 break event.clone();
diff --git a/src/sub_commands/list.rs b/src/sub_commands/list.rs
index 1a30b9b..24979fe 100644
--- a/src/sub_commands/list.rs
+++ b/src/sub_commands/list.rs
@@ -801,7 +801,7 @@ pub async fn find_commits_for_proposal_root_events(
801 .context("cannot fetch patch events")? 801 .context("cannot fetch patch events")?
802 .iter() 802 .iter()
803 .filter(|e| { 803 .filter(|e| {
804 e.kind.as_u64() == PATCH_KIND 804 e.kind.as_u16() == PATCH_KIND
805 && e.tags.iter().any(|t| { 805 && e.tags.iter().any(|t| {
806 t.as_vec().len() > 2 806 t.as_vec().len() > 2
807 && proposal_root_events 807 && proposal_root_events
diff --git a/src/sub_commands/send.rs b/src/sub_commands/send.rs
index 189dc53..c8d900c 100644
--- a/src/sub_commands/send.rs
+++ b/src/sub_commands/send.rs
@@ -5,10 +5,10 @@ use console::Style;
5use futures::future::join_all; 5use futures::future::join_all;
6use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; 6use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
7use nostr::{ 7use nostr::{
8 nips::{nip01::Coordinate, nip19::Nip19}, 8 nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19},
9 EventBuilder, FromBech32, Marker, Tag, TagKind, ToBech32, UncheckedUrl, 9 EventBuilder, FromBech32, Tag, TagKind, ToBech32, UncheckedUrl,
10}; 10};
11use nostr_sdk::hashes::sha1::Hash as Sha1Hash; 11use nostr_sdk::{hashes::sha1::Hash as Sha1Hash, TagStandard};
12 12
13use super::list::tag_value; 13use super::list::tag_value;
14#[cfg(not(test))] 14#[cfg(not(test))]
@@ -265,6 +265,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
265} 265}
266 266
267#[allow(clippy::module_name_repetitions)] 267#[allow(clippy::module_name_repetitions)]
268#[allow(clippy::too_many_lines)]
268pub async fn send_events( 269pub async fn send_events(
269 #[cfg(test)] client: &crate::client::MockConnect, 270 #[cfg(test)] client: &crate::client::MockConnect,
270 #[cfg(not(test))] client: &Client, 271 #[cfg(not(test))] client: &Client,
@@ -273,21 +274,41 @@ pub async fn send_events(
273 repo_read_relays: Vec<String>, 274 repo_read_relays: Vec<String>,
274 animate: bool, 275 animate: bool,
275) -> Result<()> { 276) -> Result<()> {
276 let (_, _, _, mut all) = unique_and_duplicate_all(&my_write_relays, &repo_read_relays); 277 let fallback = [
277 278 client.get_fallback_relays().clone(),
278 let mut fallback = client.get_fallback_relays().clone(); 279 if events.iter().any(|e| e.kind().as_u16().eq(&REPO_REF_KIND)) {
279 280 client.get_blaster_relays().clone()
280 // blast repo events 281 } else {
281 if events.iter().any(|e| e.kind().as_u64().eq(&REPO_REF_KIND)) { 282 vec![]
282 for r in client.get_blaster_relays() { 283 },
283 fallback.push(r.to_string()); 284 ]
285 .concat();
286 let mut relays: Vec<&String> = vec![];
287
288 let all = &[
289 repo_read_relays.clone(),
290 my_write_relays.clone(),
291 fallback.clone(),
292 ]
293 .concat();
294 // add duplicates first
295 for r in &repo_read_relays {
296 let r_clean = remove_trailing_slash(r);
297 if !my_write_relays
298 .iter()
299 .filter(|x| r_clean.eq(&remove_trailing_slash(x)))
300 .count()
301 > 1
302 && !relays.iter().any(|x| r_clean.eq(&remove_trailing_slash(x)))
303 {
304 relays.push(r);
284 } 305 }
285 } 306 }
286 307
287 // then remaining fallback list 308 for r in all {
288 for r in &fallback { 309 let r_clean = remove_trailing_slash(r);
289 if !all.iter().any(|r2| r2.eq(&r)) { 310 if !relays.iter().any(|x| r_clean.eq(&remove_trailing_slash(x))) {
290 all.push(r); 311 relays.push(r);
291 } 312 }
292 } 313 }
293 314
@@ -319,25 +340,36 @@ pub async fn send_events(
319 "x".to_string() 340 "x".to_string()
320 })?; 341 })?;
321 342
322 join_all(all.iter().map(|&relay| async { 343 #[allow(clippy::borrow_deref_ref)]
344 join_all(relays.iter().map(|&relay| async {
345 let relay_clean = remove_trailing_slash(&*relay);
323 let details = format!( 346 let details = format!(
324 "{}{}{} {}", 347 "{}{}{} {}",
325 if my_write_relays.iter().any(|r| relay.eq(r)) { 348 if my_write_relays
349 .iter()
350 .any(|r| relay_clean.eq(&remove_trailing_slash(r)))
351 {
326 " [my-relay]" 352 " [my-relay]"
327 } else { 353 } else {
328 "" 354 ""
329 }, 355 },
330 if repo_read_relays.iter().any(|r| relay.eq(r)) { 356 if repo_read_relays
357 .iter()
358 .any(|r| relay_clean.eq(&remove_trailing_slash(r)))
359 {
331 " [repo-relay]" 360 " [repo-relay]"
332 } else { 361 } else {
333 "" 362 ""
334 }, 363 },
335 if fallback.iter().any(|r| relay.eq(r)) { 364 if fallback
365 .iter()
366 .any(|r| relay_clean.eq(&remove_trailing_slash(r)))
367 {
336 " [default]" 368 " [default]"
337 } else { 369 } else {
338 "" 370 ""
339 }, 371 },
340 *relay, 372 relay_clean,
341 ); 373 );
342 let pb = m.add( 374 let pb = m.add(
343 ProgressBar::new(events.len() as u64) 375 ProgressBar::new(events.len() as u64)
@@ -378,36 +410,12 @@ pub async fn send_events(
378 Ok(()) 410 Ok(())
379} 411}
380 412
381/// returns `(unique_vec1, unique_vec2, duplicates, all)` 413fn remove_trailing_slash(s: &String) -> String {
382fn unique_and_duplicate_all<'a, S>( 414 match s.as_str().strip_suffix('/') {
383 vec1: &'a Vec<S>, 415 Some(s) => s,
384 vec2: &'a Vec<S>, 416 None => s,
385) -> (Vec<&'a S>, Vec<&'a S>, Vec<&'a S>, Vec<&'a S>)
386where
387 S: PartialEq,
388{
389 let mut vec1_u = vec![];
390 let mut vec2_u = vec![];
391 let mut dup = vec![];
392 let mut all = vec![];
393 for s1 in vec1 {
394 if vec2.iter().any(|s2| s1.eq(s2)) {
395 dup.push(s1);
396 } else {
397 vec1_u.push(s1);
398 }
399 } 417 }
400 for s2 in vec2 { 418 .to_string()
401 if !vec1.iter().any(|s1| s2.eq(s1)) {
402 vec2_u.push(s2);
403 }
404 }
405 for a in [&dup, &vec1_u, &vec2_u] {
406 for e in a {
407 all.push(&**e);
408 }
409 }
410 (vec1_u, vec2_u, dup, all)
411} 419}
412 420
413fn choose_commits(git_repo: &Repo, proposed_commits: Vec<Sha1Hash>) -> Result<Vec<Sha1Hash>> { 421fn choose_commits(git_repo: &Repo, proposed_commits: Vec<Sha1Hash>) -> Result<Vec<Sha1Hash>> {
@@ -501,53 +509,6 @@ fn summarise_commit_for_selection(git_repo: &Repo, commit: &Sha1Hash) -> Result<
501 )) 509 ))
502} 510}
503 511
504mod tests_unique_and_duplicate {
505
506 #[test]
507 fn correct_number_of_unique_and_duplicate_items() {
508 let v1 = vec![
509 "t1".to_string(),
510 "t2".to_string(),
511 "t3".to_string(),
512 "t4".to_string(),
513 "t5".to_string(),
514 ];
515 let v2 = vec![
516 "t3".to_string(),
517 "t4".to_string(),
518 "t5".to_string(),
519 "t6".to_string(),
520 ];
521
522 let (v1_u, v2_u, d, a) = super::unique_and_duplicate_all(&v1, &v2);
523
524 assert_eq!(v1_u.len(), 2);
525 assert_eq!(v2_u.len(), 1);
526 assert_eq!(d.len(), 3);
527 assert_eq!(a.len(), 6);
528 }
529 #[test]
530 fn all_begins_with_duplicates() {
531 let v1 = vec![
532 "t1".to_string(),
533 "t2".to_string(),
534 "t3".to_string(),
535 "t4".to_string(),
536 "t5".to_string(),
537 ];
538 let v2 = vec![
539 "t3".to_string(),
540 "t4".to_string(),
541 "t5".to_string(),
542 "t6".to_string(),
543 ];
544
545 let (_, _, d, a) = super::unique_and_duplicate_all(&v1, &v2);
546
547 assert_eq!(a[0], d[0]);
548 }
549}
550
551async fn get_root_proposal_id_and_mentions_from_in_reply_to( 512async fn get_root_proposal_id_and_mentions_from_in_reply_to(
552 #[cfg(test)] client: &crate::client::MockConnect, 513 #[cfg(test)] client: &crate::client::MockConnect,
553 #[cfg(not(test))] client: &Client, 514 #[cfg(not(test))] client: &Client,
@@ -555,20 +516,23 @@ async fn get_root_proposal_id_and_mentions_from_in_reply_to(
555 in_reply_to: &[String], 516 in_reply_to: &[String],
556) -> Result<(Option<String>, Vec<nostr::Tag>)> { 517) -> Result<(Option<String>, Vec<nostr::Tag>)> {
557 let root_proposal_id = if let Some(first) = in_reply_to.first() { 518 let root_proposal_id = if let Some(first) = in_reply_to.first() {
558 match event_tag_from_nip19_or_hex(first, "in-reply-to", nostr::Marker::Root, true, false)? { 519 match event_tag_from_nip19_or_hex(first, "in-reply-to", Marker::Root, true, false)?
559 Tag::Event { 520 .as_standardized()
521 {
522 Some(nostr_sdk::TagStandard::Event {
560 event_id, 523 event_id,
561 relay_url: _, 524 relay_url: _,
562 marker: _, 525 marker: _,
563 } => { 526 public_key: _,
527 }) => {
564 let events = client 528 let events = client
565 .get_events( 529 .get_events(
566 repo_relays.to_vec(), 530 repo_relays.to_vec(),
567 vec![nostr::Filter::new().id(event_id)], 531 vec![nostr::Filter::new().id(*event_id)],
568 ) 532 )
569 .await 533 .await
570 .context("whilst getting events specified in --in-reply-to")?; 534 .context("whilst getting events specified in --in-reply-to")?;
571 if let Some(first) = events.iter().find(|e| e.id.eq(&event_id)) { 535 if let Some(first) = events.iter().find(|e| e.id.eq(event_id)) {
572 if event_is_patch_set_root(first) { 536 if event_is_patch_set_root(first) {
573 Some(event_id.to_string()) 537 Some(event_id.to_string())
574 } else { 538 } else {
@@ -591,16 +555,10 @@ async fn get_root_proposal_id_and_mentions_from_in_reply_to(
591 for (i, reply_to) in in_reply_to.iter().enumerate() { 555 for (i, reply_to) in in_reply_to.iter().enumerate() {
592 if i.ne(&0) || root_proposal_id.is_none() { 556 if i.ne(&0) || root_proposal_id.is_none() {
593 mention_tags.push( 557 mention_tags.push(
594 event_tag_from_nip19_or_hex( 558 event_tag_from_nip19_or_hex(reply_to, "in-reply-to", Marker::Mention, true, false)
595 reply_to, 559 .context(format!(
596 "in-reply-to", 560 "{reply_to} in 'in-reply-to' not a valid nostr reference"
597 nostr::Marker::Mention, 561 ))?,
598 true,
599 false,
600 )
601 .context(format!(
602 "{reply_to} in 'in-reply-to' not a valid nostr reference"
603 ))?,
604 ); 562 );
605 } 563 }
606 } 564 }
@@ -608,7 +566,7 @@ async fn get_root_proposal_id_and_mentions_from_in_reply_to(
608 Ok((root_proposal_id, mention_tags)) 566 Ok((root_proposal_id, mention_tags))
609} 567}
610 568
611pub static PATCH_KIND: u64 = 1617; 569pub static PATCH_KIND: u16 = 1617;
612 570
613#[allow(clippy::too_many_lines)] 571#[allow(clippy::too_many_lines)]
614pub fn generate_cover_letter_and_patch_events( 572pub fn generate_cover_letter_and_patch_events(
@@ -637,33 +595,30 @@ pub fn generate_cover_letter_and_patch_events(
637 [ 595 [
638 vec![ 596 vec![
639 // TODO: why not tag all maintainer identifiers? 597 // TODO: why not tag all maintainer identifiers?
640 Tag::A { 598 Tag::coordinate(Coordinate {
641 coordinate: Coordinate { 599 kind: nostr::Kind::Custom(REPO_REF_KIND),
642 kind: nostr::Kind::Custom(REPO_REF_KIND), 600 public_key: *repo_ref.maintainers.first()
643 public_key: *repo_ref.maintainers.first() 601 .context("repo reference should always have at least one maintainer")?,
644 .context("repo reference should always have at least one maintainer")?, 602 identifier: repo_ref.identifier.to_string(),
645 identifier: repo_ref.identifier.to_string(), 603 relays: repo_ref.relays.clone(),
646 relays: repo_ref.relays.clone(), 604 }),
647 }, 605 Tag::from_standardized(TagStandard::Reference(format!("{root_commit}"))),
648 relay_url: repo_ref.relays.first().map(nostr::UncheckedUrl::from).clone(), 606 Tag::hashtag("cover-letter"),
649 }, 607 Tag::custom(
650 Tag::Reference(format!("{root_commit}")), 608 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("alt")),
651 Tag::Hashtag("cover-letter".to_string()),
652 Tag::Generic(
653 nostr::TagKind::Custom("alt".to_string()),
654 vec![format!("git patch cover letter: {}", title.clone())], 609 vec![format!("git patch cover letter: {}", title.clone())],
655 ), 610 ),
656 ], 611 ],
657 if let Some(event_ref) = root_proposal_id.clone() { 612 if let Some(event_ref) = root_proposal_id.clone() {
658 vec![ 613 vec![
659 Tag::Hashtag("root".to_string()), 614 Tag::hashtag("root"),
660 Tag::Hashtag("revision-root".to_string()), 615 Tag::hashtag("revision-root"),
661 // TODO check if id is for a root proposal (perhaps its for an issue?) 616 // TODO check if id is for a root proposal (perhaps its for an issue?)
662 event_tag_from_nip19_or_hex(&event_ref,"proposal",nostr::Marker::Reply, false, false)?, 617 event_tag_from_nip19_or_hex(&event_ref,"proposal",Marker::Reply, false, false)?,
663 ] 618 ]
664 } else { 619 } else {
665 vec![ 620 vec![
666 Tag::Hashtag("root".to_string()), 621 Tag::hashtag("root"),
667 ] 622 ]
668 }, 623 },
669 mentions.to_vec(), 624 mentions.to_vec(),
@@ -677,10 +632,12 @@ pub fn generate_cover_letter_and_patch_events(
677 && !branch_name.eq("origin/main") 632 && !branch_name.eq("origin/main")
678 && !branch_name.eq("origin/master") 633 && !branch_name.eq("origin/master")
679 { 634 {
680 vec![Tag::Generic( 635 vec![
681 TagKind::Custom("branch-name".to_string()), 636 Tag::custom(
682 vec![branch_name], 637 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("branch-name")),
683 )] 638 vec![branch_name],
639 ),
640 ]
684 } 641 }
685 else { vec![] } 642 else { vec![] }
686 } else { 643 } else {
@@ -740,7 +697,7 @@ pub fn generate_cover_letter_and_patch_events(
740fn event_tag_from_nip19_or_hex( 697fn event_tag_from_nip19_or_hex(
741 reference: &str, 698 reference: &str,
742 reference_name: &str, 699 reference_name: &str,
743 marker: nostr::Marker, 700 marker: Marker,
744 allow_npub_reference: bool, 701 allow_npub_reference: bool,
745 prompt_for_correction: bool, 702 prompt_for_correction: bool,
746) -> Result<nostr::Tag> { 703) -> Result<nostr::Tag> {
@@ -754,44 +711,44 @@ fn event_tag_from_nip19_or_hex(
754 if let Ok(nip19) = Nip19::from_bech32(bech32.clone()) { 711 if let Ok(nip19) = Nip19::from_bech32(bech32.clone()) {
755 match nip19 { 712 match nip19 {
756 Nip19::Event(n) => { 713 Nip19::Event(n) => {
757 break Ok(nostr::Tag::Event { 714 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event {
758 event_id: n.event_id, 715 event_id: n.event_id,
759 relay_url: n.relays.first().map(UncheckedUrl::new), 716 relay_url: n.relays.first().map(UncheckedUrl::new),
760 marker: Some(marker), 717 marker: Some(marker),
761 }); 718 public_key: None,
719 }));
762 } 720 }
763 Nip19::EventId(id) => { 721 Nip19::EventId(id) => {
764 break Ok(nostr::Tag::Event { 722 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event {
765 event_id: id, 723 event_id: id,
766 relay_url: None, 724 relay_url: None,
767 marker: Some(marker), 725 marker: Some(marker),
768 }); 726 public_key: None,
727 }));
769 } 728 }
770 Nip19::Coordinate(coordinate) => { 729 Nip19::Coordinate(coordinate) => {
771 break Ok(nostr::Tag::A { 730 break Ok(Tag::coordinate(coordinate));
772 coordinate,
773 relay_url: None,
774 });
775 } 731 }
776 Nip19::Profile(profile) => { 732 Nip19::Profile(profile) => {
777 if allow_npub_reference { 733 if allow_npub_reference {
778 break Ok(nostr::Tag::public_key(profile.public_key)); 734 break Ok(Tag::public_key(profile.public_key));
779 } 735 }
780 } 736 }
781 Nip19::Pubkey(public_key) => { 737 Nip19::Pubkey(public_key) => {
782 if allow_npub_reference { 738 if allow_npub_reference {
783 break Ok(nostr::Tag::public_key(public_key)); 739 break Ok(Tag::public_key(public_key));
784 } 740 }
785 } 741 }
786 _ => {} 742 _ => {}
787 } 743 }
788 } 744 }
789 if let Ok(id) = nostr::EventId::from_str(&bech32) { 745 if let Ok(id) = nostr::EventId::from_str(&bech32) {
790 break Ok(nostr::Tag::Event { 746 break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event {
791 event_id: id, 747 event_id: id,
792 relay_url: None, 748 relay_url: None,
793 marker: Some(marker), 749 marker: Some(marker),
794 }); 750 public_key: None,
751 }));
795 } 752 }
796 if prompt_for_correction { 753 if prompt_for_correction {
797 println!("not a valid {reference_name} event reference"); 754 println!("not a valid {reference_name} event reference");
@@ -813,7 +770,7 @@ pub fn event_is_cover_letter(event: &nostr::Event) -> bool {
813 // TODO: look for Subject:[ PATCH 0/n ] but watch out for: 770 // TODO: look for Subject:[ PATCH 0/n ] but watch out for:
814 // [PATCH v1 0/n ] or 771 // [PATCH v1 0/n ] or
815 // [PATCH subsystem v2 0/n ] 772 // [PATCH subsystem v2 0/n ]
816 event.kind.as_u64().eq(&PATCH_KIND) 773 event.kind.as_u16().eq(&PATCH_KIND)
817 && event.iter_tags().any(|t| t.as_vec()[1].eq("root")) 774 && event.iter_tags().any(|t| t.as_vec()[1].eq("root"))
818 && event.iter_tags().any(|t| t.as_vec()[1].eq("cover-letter")) 775 && event.iter_tags().any(|t| t.as_vec()[1].eq("cover-letter"))
819} 776}
@@ -883,16 +840,16 @@ pub fn event_to_cover_letter(event: &nostr::Event) -> Result<CoverLetter> {
883} 840}
884 841
885pub fn event_is_patch_set_root(event: &nostr::Event) -> bool { 842pub fn event_is_patch_set_root(event: &nostr::Event) -> bool {
886 event.kind.as_u64().eq(&PATCH_KIND) && event.iter_tags().any(|t| t.as_vec()[1].eq("root")) 843 event.kind.as_u16().eq(&PATCH_KIND) && event.iter_tags().any(|t| t.as_vec()[1].eq("root"))
887} 844}
888 845
889pub fn event_is_revision_root(event: &nostr::Event) -> bool { 846pub fn event_is_revision_root(event: &nostr::Event) -> bool {
890 event.kind.as_u64().eq(&PATCH_KIND) 847 event.kind.as_u16().eq(&PATCH_KIND)
891 && event.iter_tags().any(|t| t.as_vec()[1].eq("revision-root")) 848 && event.iter_tags().any(|t| t.as_vec()[1].eq("revision-root"))
892} 849}
893 850
894pub fn patch_supports_commit_ids(event: &nostr::Event) -> bool { 851pub fn patch_supports_commit_ids(event: &nostr::Event) -> bool {
895 event.kind.as_u64().eq(&PATCH_KIND) 852 event.kind.as_u16().eq(&PATCH_KIND)
896 && event 853 && event
897 .iter_tags() 854 .iter_tags()
898 .any(|t| t.as_vec()[0].eq("commit-pgp-sig")) 855 .any(|t| t.as_vec()[0].eq("commit-pgp-sig"))
@@ -925,55 +882,54 @@ pub fn generate_patch_event(
925 .context(format!("cannot make patch for commit {commit}"))?, 882 .context(format!("cannot make patch for commit {commit}"))?,
926 [ 883 [
927 vec![ 884 vec![
928 Tag::A { 885 Tag::coordinate(Coordinate {
929 coordinate: Coordinate { 886 kind: nostr::Kind::Custom(REPO_REF_KIND),
930 kind: nostr::Kind::Custom(REPO_REF_KIND), 887 public_key: *repo_ref.maintainers.first()
931 public_key: *repo_ref.maintainers.first() 888 .context("repo reference should always have at least one maintainer - the issuer of the repo event")
932 .context("repo reference should always have at least one maintainer - the issuer of the repo event") 889 ?,
933 ?, 890 identifier: repo_ref.identifier.to_string(),
934 identifier: repo_ref.identifier.to_string(), 891 relays: repo_ref.relays.clone(),
935 relays: repo_ref.relays.clone(), 892 }),
936 }, 893 Tag::from_standardized(TagStandard::Reference(root_commit.to_string())),
937 relay_url: relay_hint.clone(),
938 },
939 Tag::Reference(format!("{root_commit}")),
940 // commit id reference is a trade-off. its now 894 // commit id reference is a trade-off. its now
941 // unclear which one is the root commit id but it 895 // unclear which one is the root commit id but it
942 // enables easier location of code comments againt 896 // enables easier location of code comments againt
943 // code that makes it into the main branch, assuming 897 // code that makes it into the main branch, assuming
944 // the commit id is correct 898 // the commit id is correct
945 Tag::Reference(commit.to_string()), 899 Tag::from_standardized(TagStandard::Reference(commit.to_string())),
946 Tag::Generic( 900 Tag::custom(
947 nostr::TagKind::Custom("alt".to_string()), 901 TagKind::Custom(std::borrow::Cow::Borrowed("alt")),
948 vec![format!("git patch: {}", git_repo.get_commit_message_summary(commit).unwrap_or_default())], 902 vec![format!("git patch: {}", git_repo.get_commit_message_summary(commit).unwrap_or_default())],
949 ), 903 ),
950 ], 904 ],
951 905
952 if let Some(thread_event_id) = thread_event_id { 906 if let Some(thread_event_id) = thread_event_id {
953 vec![Tag::Event { 907 vec![Tag::from_standardized(nostr_sdk::TagStandard::Event {
954 event_id: thread_event_id, 908 event_id: thread_event_id,
955 relay_url: relay_hint.clone(), 909 relay_url: relay_hint.clone(),
956 marker: Some(Marker::Root), 910 marker: Some(Marker::Root),
957 }] 911 public_key: None,
912 })]
958 } else if let Some(event_ref) = root_proposal_id.clone() { 913 } else if let Some(event_ref) = root_proposal_id.clone() {
959 vec![ 914 vec![
960 Tag::Hashtag("root".to_string()), 915 Tag::hashtag("root"),
961 Tag::Hashtag("revision-root".to_string()), 916 Tag::hashtag("revision-root"),
962 // TODO check if id is for a root proposal (perhaps its for an issue?) 917 // TODO check if id is for a root proposal (perhaps its for an issue?)
963 event_tag_from_nip19_or_hex(&event_ref,"proposal",nostr::Marker::Reply, false, false)?, 918 event_tag_from_nip19_or_hex(&event_ref,"proposal", Marker::Reply, false, false)?,
964 ] 919 ]
965 } else { 920 } else {
966 vec![ 921 vec![
967 Tag::Hashtag("root".to_string()), 922 Tag::hashtag("root"),
968 ] 923 ]
969 }, 924 },
970 mentions.to_vec(), 925 mentions.to_vec(),
971 if let Some(id) = parent_patch_event_id { 926 if let Some(id) = parent_patch_event_id {
972 vec![Tag::Event { 927 vec![Tag::from_standardized(nostr_sdk::TagStandard::Event {
973 event_id: id, 928 event_id: id,
974 relay_url: relay_hint.clone(), 929 relay_url: relay_hint.clone(),
975 marker: Some(Marker::Reply), 930 marker: Some(Marker::Reply),
976 }] 931 public_key: None,
932 })]
977 } else { 933 } else {
978 vec![] 934 vec![]
979 }, 935 },
@@ -981,8 +937,8 @@ pub fn generate_patch_event(
981 if let Some(branch_name) = branch_name { 937 if let Some(branch_name) = branch_name {
982 if thread_event_id.is_none() { 938 if thread_event_id.is_none() {
983 vec![ 939 vec![
984 Tag::Generic( 940 Tag::custom(
985 TagKind::Custom("branch-name".to_string()), 941 TagKind::Custom(std::borrow::Cow::Borrowed("branch-name")),
986 vec![branch_name.to_string()], 942 vec![branch_name.to_string()],
987 ) 943 )
988 ] 944 ]
@@ -1002,33 +958,35 @@ pub fn generate_patch_event(
1002 .collect(), 958 .collect(),
1003 vec![ 959 vec![
1004 // a fallback is now in place to extract this from the patch 960 // a fallback is now in place to extract this from the patch
1005 Tag::Generic( 961 Tag::custom(
1006 TagKind::Custom("commit".to_string()), 962 TagKind::Custom(std::borrow::Cow::Borrowed("commit")),
1007 vec![commit.to_string()], 963 vec![commit.to_string()],
1008 ), 964 ),
1009 // this is required as patches cannot be relied upon to include the 'base commit' 965 // this is required as patches cannot be relied upon to include the 'base commit'
1010 Tag::Generic( 966 Tag::custom(
1011 TagKind::Custom("parent-commit".to_string()), 967 TagKind::Custom(std::borrow::Cow::Borrowed("parent-commit")),
1012 vec![commit_parent.to_string()], 968 vec![commit_parent.to_string()],
1013 ), 969 ),
1014 // this is required to ensure the commit id matches 970 // this is required to ensure the commit id matches
1015 Tag::Generic( 971 Tag::custom(
1016 TagKind::Custom("commit-pgp-sig".to_string()), 972 TagKind::Custom(std::borrow::Cow::Borrowed("commit-pgp-sig")),
1017 vec![ 973 vec![
1018 git_repo 974 git_repo
1019 .extract_commit_pgp_signature(commit) 975 .extract_commit_pgp_signature(commit)
1020 .unwrap_or_default(), 976 .unwrap_or_default(),
1021 ], 977 ],
1022 ), 978 ),
1023 // removing description tag will not cause anything to break 979 // removing description tag will not cause anything to break
1024 Tag::Description(git_repo.get_commit_message(commit)?.to_string()), 980 Tag::from_standardized(nostr_sdk::TagStandard::Description(
1025 Tag::Generic( 981 git_repo.get_commit_message(commit)?.to_string()
1026 TagKind::Custom("author".to_string()), 982 )),
983 Tag::custom(
984 TagKind::Custom(std::borrow::Cow::Borrowed("author")),
1027 git_repo.get_commit_author(commit)?, 985 git_repo.get_commit_author(commit)?,
1028 ), 986 ),
1029 // this is required to ensure the commit id matches 987 // this is required to ensure the commit id matches
1030 Tag::Generic( 988 Tag::custom(
1031 TagKind::Custom("committer".to_string()), 989 TagKind::Custom(std::borrow::Cow::Borrowed("committer")),
1032 git_repo.get_commit_comitter(commit)?, 990 git_repo.get_commit_comitter(commit)?,
1033 ), 991 ),
1034 ], 992 ],
@@ -1246,8 +1204,8 @@ mod tests {
1246 nostr::event::Kind::Custom(PATCH_KIND), 1204 nostr::event::Kind::Custom(PATCH_KIND),
1247 format!("From ea897e987ea9a7a98e7a987e97987ea98e7a3334 Mon Sep 17 00:00:00 2001\nSubject: [PATCH 0/2] {title}\n\n{description}"), 1205 format!("From ea897e987ea9a7a98e7a987e97987ea98e7a3334 Mon Sep 17 00:00:00 2001\nSubject: [PATCH 0/2] {title}\n\n{description}"),
1248 [ 1206 [
1249 Tag::Hashtag("cover-letter".to_string()), 1207 Tag::hashtag("cover-letter"),
1250 Tag::Hashtag("root".to_string()), 1208 Tag::hashtag("root"),
1251 ], 1209 ],
1252 ) 1210 )
1253 .to_event(&nostr::Keys::generate())?) 1211 .to_event(&nostr::Keys::generate())?)
diff --git a/test_utils/Cargo.toml b/test_utils/Cargo.toml
index 0784b1a..43f3629 100644
--- a/test_utils/Cargo.toml
+++ b/test_utils/Cargo.toml
@@ -9,8 +9,8 @@ assert_cmd = "2.0.12"
9dialoguer = "0.10.4" 9dialoguer = "0.10.4"
10directories = "5.0.1" 10directories = "5.0.1"
11git2 = "0.18.1" 11git2 = "0.18.1"
12nostr = { git = "https://github.com/DanConwayDev/nostr", branch="expose-nip49-log-n" } 12nostr = "0.32.0"
13nostr-sdk = { git = "https://github.com/DanConwayDev/nostr", branch="expose-nip49-log-n" } 13nostr-sdk = "0.32.0"
14once_cell = "1.18.0" 14once_cell = "1.18.0"
15rand = "0.8" 15rand = "0.8"
16rexpect = { git = "https://github.com/rust-cli/rexpect.git", rev = "9eb61dd" } 16rexpect = { git = "https://github.com/rust-cli/rexpect.git", rev = "9eb61dd" }
diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs
index daed8fa..1d881cf 100644
--- a/test_utils/src/lib.rs
+++ b/test_utils/src/lib.rs
@@ -3,8 +3,8 @@ use std::{ffi::OsStr, path::PathBuf, str::FromStr};
3use anyhow::{bail, ensure, Context, Result}; 3use anyhow::{bail, ensure, Context, Result};
4use dialoguer::theme::{ColorfulTheme, Theme}; 4use dialoguer::theme::{ColorfulTheme, Theme};
5use directories::ProjectDirs; 5use directories::ProjectDirs;
6use nostr::{self, Kind, Tag}; 6use nostr::{self, nips::nip65::RelayMetadata, Kind, Tag};
7use nostr_sdk::serde_json; 7use nostr_sdk::{serde_json, TagStandard};
8use once_cell::sync::Lazy; 8use once_cell::sync::Lazy;
9use rexpect::session::{Options, PtySession}; 9use rexpect::session::{Options, PtySession};
10use strip_ansi_escapes::strip_str; 10use strip_ansi_escapes::strip_str;
@@ -12,8 +12,8 @@ use strip_ansi_escapes::strip_str;
12pub mod git; 12pub mod git;
13pub mod relay; 13pub mod relay;
14 14
15pub static PATCH_KIND: u64 = 1617; 15pub static PATCH_KIND: u16 = 1617;
16pub static REPOSITORY_KIND: u64 = 30617; 16pub static REPOSITORY_KIND: u16 = 30617;
17 17
18pub static TEST_KEY_1_NSEC: &str = 18pub static TEST_KEY_1_NSEC: &str =
19 "nsec1ppsg5sm2aexq06juxmu9evtutr6jkwkhp98exxxvwamhru9lyx9s3rwseq"; 19 "nsec1ppsg5sm2aexq06juxmu9evtutr6jkwkhp98exxxvwamhru9lyx9s3rwseq";
@@ -54,15 +54,18 @@ pub fn generate_test_key_1_relay_list_event() -> nostr::Event {
54 nostr::Kind::RelayList, 54 nostr::Kind::RelayList,
55 "", 55 "",
56 [ 56 [
57 nostr::Tag::RelayMetadata( 57 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
58 "ws://localhost:8053".into(), 58 relay_url: nostr::Url::from_str("ws://localhost:8053").unwrap(),
59 Some(nostr::RelayMetadata::Write), 59 metadata: Some(RelayMetadata::Write),
60 ), 60 }),
61 nostr::Tag::RelayMetadata( 61 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
62 "ws://localhost:8054".into(), 62 relay_url: nostr::Url::from_str("ws://localhost:8054").unwrap(),
63 Some(nostr::RelayMetadata::Read), 63 metadata: Some(RelayMetadata::Read),
64 ), 64 }),
65 nostr::Tag::RelayMetadata("ws://localhost:8055".into(), None), 65 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
66 relay_url: nostr::Url::from_str("ws://localhost:8055").unwrap(),
67 metadata: None,
68 }),
66 ], 69 ],
67 ) 70 )
68 .to_event(&TEST_KEY_1_KEYS) 71 .to_event(&TEST_KEY_1_KEYS)
@@ -74,14 +77,14 @@ pub fn generate_test_key_1_relay_list_event_same_as_fallback() -> nostr::Event {
74 nostr::Kind::RelayList, 77 nostr::Kind::RelayList,
75 "", 78 "",
76 [ 79 [
77 nostr::Tag::RelayMetadata( 80 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
78 "ws://localhost:8051".into(), 81 relay_url: nostr::Url::from_str("ws://localhost:8051").unwrap(),
79 Some(nostr::RelayMetadata::Write), 82 metadata: Some(RelayMetadata::Write),
80 ), 83 }),
81 nostr::Tag::RelayMetadata( 84 nostr::Tag::from_standardized(nostr::TagStandard::RelayMetadata {
82 "ws://localhost:8052".into(), 85 relay_url: nostr::Url::from_str("ws://localhost:8052").unwrap(),
83 Some(nostr::RelayMetadata::Write), 86 metadata: Some(RelayMetadata::Write),
84 ), 87 }),
85 ], 88 ],
86 ) 89 )
87 .to_event(&TEST_KEY_1_KEYS) 90 .to_event(&TEST_KEY_1_KEYS)
@@ -141,33 +144,33 @@ pub fn generate_repo_ref_event() -> nostr::Event {
141 nostr::Kind::Custom(REPOSITORY_KIND), 144 nostr::Kind::Custom(REPOSITORY_KIND),
142 "", 145 "",
143 [ 146 [
144 Tag::Identifier( 147 Tag::identifier(
145 // root_commit.to_string() 148 // root_commit.to_string()
146 format!("{}-consider-it-random", root_commit), 149 format!("{}-consider-it-random", root_commit),
147 ), 150 ),
148 Tag::Reference(root_commit.into()), 151 Tag::from_standardized(TagStandard::Reference(root_commit.to_string())),
149 Tag::Name("example name".into()), 152 Tag::from_standardized(TagStandard::Name("example name".into())),
150 Tag::Description("example description".into()), 153 Tag::from_standardized(TagStandard::Description("example description".into())),
151 Tag::Generic( 154 Tag::custom(
152 nostr::TagKind::Custom("clone".to_string()), 155 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("clone")),
153 vec!["git:://123.gitexample.com/test".to_string()], 156 vec!["git:://123.gitexample.com/test".to_string()],
154 ), 157 ),
155 Tag::Generic( 158 Tag::custom(
156 nostr::TagKind::Custom("web".to_string()), 159 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("web")),
157 vec![ 160 vec![
158 "https://exampleproject.xyz".to_string(), 161 "https://exampleproject.xyz".to_string(),
159 "https://gitworkshop.dev/123".to_string(), 162 "https://gitworkshop.dev/123".to_string(),
160 ], 163 ],
161 ), 164 ),
162 Tag::Generic( 165 Tag::custom(
163 nostr::TagKind::Custom("relays".to_string()), 166 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("relays")),
164 vec![ 167 vec![
165 "ws://localhost:8055".to_string(), 168 "ws://localhost:8055".to_string(),
166 "ws://localhost:8056".to_string(), 169 "ws://localhost:8056".to_string(),
167 ], 170 ],
168 ), 171 ),
169 Tag::Generic( 172 Tag::custom(
170 nostr::TagKind::Custom("maintainers".to_string()), 173 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("maintainers")),
171 vec![ 174 vec![
172 TEST_KEY_1_KEYS.public_key().to_string(), 175 TEST_KEY_1_KEYS.public_key().to_string(),
173 TEST_KEY_2_KEYS.public_key().to_string(), 176 TEST_KEY_2_KEYS.public_key().to_string(),
diff --git a/test_utils/src/relay.rs b/test_utils/src/relay.rs
index e47ab5d..82a8f8d 100644
--- a/test_utils/src/relay.rs
+++ b/test_utils/src/relay.rs
@@ -255,21 +255,27 @@ pub fn expect_send_with_progress(
255 " - {} -------------------- 0/{event_count}", 255 " - {} -------------------- 0/{event_count}",
256 &relays[0].0 256 &relays[0].0
257 ))?; 257 ))?;
258 for relay in &relays { 258 let last_relay_outcome = outcome_message(relays.last().unwrap());
259 // if successful 259 let mut s = String::new();
260 if relay.1 { 260 loop {
261 p.expect_eventually(format!(" y {}", relay.0))?; 261 s.push_str(&p.expect_eventually(&last_relay_outcome)?);
262 } else { 262 s.push_str(&last_relay_outcome);
263 p.expect_eventually(format!(" x {} {}", relay.0, relay.2))?; 263 if relays.iter().all(|r| s.contains(&outcome_message(r))) {
264 // all responses have been received with correct outcome
265 break;
264 } 266 }
265 // could check that before only contains titles:
266 // - # y x n/n and whitespace
267 // let before = p.expect_eventually(format!(" â {title}"))?;
268 // assert_eq!("", before.trim());
269 } 267 }
270 Ok(()) 268 Ok(())
271} 269}
272 270
271fn outcome_message(relay: &(&str, bool, &str)) -> String {
272 if relay.1 {
273 format!(" y {}", relay.0)
274 } else {
275 format!(" x {} {}", relay.0, relay.2)
276 }
277}
278
273pub fn expect_send_with_progress_exact_interaction( 279pub fn expect_send_with_progress_exact_interaction(
274 p: &mut CliTester, 280 p: &mut CliTester,
275 titles: Vec<&str>, 281 titles: Vec<&str>,
diff --git a/tests/init.rs b/tests/init.rs
index 1beeaa5..43d5637 100644
--- a/tests/init.rs
+++ b/tests/init.rs
@@ -136,7 +136,7 @@ mod when_repo_not_previously_claimed {
136 relay 136 relay
137 .events 137 .events
138 .iter() 138 .iter()
139 .filter(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 139 .filter(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
140 .count(), 140 .count(),
141 1, 141 1,
142 ); 142 );
@@ -153,7 +153,7 @@ mod when_repo_not_previously_claimed {
153 relay 153 relay
154 .events 154 .events
155 .iter() 155 .iter()
156 .filter(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 156 .filter(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
157 .count(), 157 .count(),
158 1, 158 1,
159 ); 159 );
@@ -170,7 +170,7 @@ mod when_repo_not_previously_claimed {
170 relay 170 relay
171 .events 171 .events
172 .iter() 172 .iter()
173 .filter(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 173 .filter(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
174 .count(), 174 .count(),
175 1, 175 1,
176 ); 176 );
@@ -185,7 +185,7 @@ mod when_repo_not_previously_claimed {
185 assert_eq!( 185 assert_eq!(
186 r57.events 186 r57.events
187 .iter() 187 .iter()
188 .filter(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 188 .filter(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
189 .count(), 189 .count(),
190 1, 190 1,
191 ); 191 );
@@ -286,7 +286,7 @@ mod when_repo_not_previously_claimed {
286 let event: &nostr::Event = relay 286 let event: &nostr::Event = relay
287 .events 287 .events
288 .iter() 288 .iter()
289 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 289 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
290 .unwrap(); 290 .unwrap();
291 291
292 assert!( 292 assert!(
@@ -306,7 +306,7 @@ mod when_repo_not_previously_claimed {
306 let event: &nostr::Event = relay 306 let event: &nostr::Event = relay
307 .events 307 .events
308 .iter() 308 .iter()
309 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 309 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
310 .unwrap(); 310 .unwrap();
311 311
312 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("r") 312 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("r")
@@ -323,7 +323,7 @@ mod when_repo_not_previously_claimed {
323 let event: &nostr::Event = relay 323 let event: &nostr::Event = relay
324 .events 324 .events
325 .iter() 325 .iter()
326 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 326 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
327 .unwrap(); 327 .unwrap();
328 328
329 assert!( 329 assert!(
@@ -344,7 +344,7 @@ mod when_repo_not_previously_claimed {
344 let event: &nostr::Event = relay 344 let event: &nostr::Event = relay
345 .events 345 .events
346 .iter() 346 .iter()
347 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 347 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
348 .unwrap(); 348 .unwrap();
349 349
350 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("alt") 350 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("alt")
@@ -361,7 +361,7 @@ mod when_repo_not_previously_claimed {
361 let event: &nostr::Event = relay 361 let event: &nostr::Event = relay
362 .events 362 .events
363 .iter() 363 .iter()
364 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 364 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
365 .unwrap(); 365 .unwrap();
366 366
367 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("description") 367 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("description")
@@ -378,7 +378,7 @@ mod when_repo_not_previously_claimed {
378 let event: &nostr::Event = relay 378 let event: &nostr::Event = relay
379 .events 379 .events
380 .iter() 380 .iter()
381 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 381 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
382 .unwrap(); 382 .unwrap();
383 383
384 assert!( 384 assert!(
@@ -397,7 +397,7 @@ mod when_repo_not_previously_claimed {
397 let event: &nostr::Event = relay 397 let event: &nostr::Event = relay
398 .events 398 .events
399 .iter() 399 .iter()
400 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 400 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
401 .unwrap(); 401 .unwrap();
402 let relays_tag = event 402 let relays_tag = event
403 .tags 403 .tags
@@ -419,7 +419,7 @@ mod when_repo_not_previously_claimed {
419 let event: &nostr::Event = relay 419 let event: &nostr::Event = relay
420 .events 420 .events
421 .iter() 421 .iter()
422 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 422 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
423 .unwrap(); 423 .unwrap();
424 let web_tag = event 424 let web_tag = event
425 .tags 425 .tags
@@ -441,7 +441,7 @@ mod when_repo_not_previously_claimed {
441 let event: &nostr::Event = relay 441 let event: &nostr::Event = relay
442 .events 442 .events
443 .iter() 443 .iter()
444 .find(|e| e.kind.as_u64().eq(&REPOSITORY_KIND)) 444 .find(|e| e.kind.as_u16().eq(&REPOSITORY_KIND))
445 .unwrap(); 445 .unwrap();
446 let maintainers_tag = event 446 let maintainers_tag = event
447 .tags 447 .tags
diff --git a/tests/list.rs b/tests/list.rs
index 61c2201..cd071a9 100644
--- a/tests/list.rs
+++ b/tests/list.rs
@@ -181,6 +181,7 @@ mod cannot_find_repo_event {
181 event_id: repo_event.id, 181 event_id: repo_event.id,
182 author: Some(TEST_KEY_1_KEYS.public_key()), 182 author: Some(TEST_KEY_1_KEYS.public_key()),
183 relays: vec!["ws://localhost:8056".to_string()], 183 relays: vec!["ws://localhost:8056".to_string()],
184 kind: None,
184 } 185 }
185 .to_bech32()?, 186 .to_bech32()?,
186 )?; 187 )?;
diff --git a/tests/send.rs b/tests/send.rs
index aa16949..22216a8 100644
--- a/tests/send.rs
+++ b/tests/send.rs
@@ -82,12 +82,12 @@ mod when_commits_behind_ask_to_proceed {
82} 82}
83 83
84fn is_cover_letter(event: &nostr::Event) -> bool { 84fn is_cover_letter(event: &nostr::Event) -> bool {
85 event.kind.as_u64().eq(&PATCH_KIND) 85 event.kind.as_u16().eq(&PATCH_KIND)
86 && event.iter_tags().any(|t| t.as_vec()[1].eq("cover-letter")) 86 && event.iter_tags().any(|t| t.as_vec()[1].eq("cover-letter"))
87} 87}
88 88
89fn is_patch(event: &nostr::Event) -> bool { 89fn is_patch(event: &nostr::Event) -> bool {
90 event.kind.as_u64().eq(&PATCH_KIND) 90 event.kind.as_u16().eq(&PATCH_KIND)
91 && !event.iter_tags().any(|t| t.as_vec()[1].eq("cover-letter")) 91 && !event.iter_tags().any(|t| t.as_vec()[1].eq("cover-letter"))
92} 92}
93 93
@@ -393,12 +393,12 @@ mod when_cover_letter_details_specified_with_range_of_head_2_sends_cover_letter_
393 #[tokio::test] 393 #[tokio::test]
394 #[serial] 394 #[serial]
395 async fn p_tags_for_maintainers() -> Result<()> { 395 async fn p_tags_for_maintainers() -> Result<()> {
396 let maintainers = &generate_repo_ref_event() 396 let event = generate_repo_ref_event();
397 let maintainers = &event
397 .iter_tags() 398 .iter_tags()
398 .find(|t| t.as_vec()[0].eq(&"maintainers")) 399 .find(|t| t.as_vec()[0].eq(&"maintainers"))
399 .unwrap() 400 .unwrap()
400 .as_vec() 401 .as_vec()[1..];
401 .clone()[1..];
402 let (_, _, r53, r55, r56) = prep_run_create_proposal(true).await?; 402 let (_, _, r53, r55, r56) = prep_run_create_proposal(true).await?;
403 for relay in [&r53, &r55, &r56] { 403 for relay in [&r53, &r55, &r56] {
404 for m in maintainers { 404 for m in maintainers {
@@ -546,12 +546,12 @@ mod when_cover_letter_details_specified_with_range_of_head_2_sends_cover_letter_
546 #[tokio::test] 546 #[tokio::test]
547 #[serial] 547 #[serial]
548 async fn p_tags_for_maintainers() -> Result<()> { 548 async fn p_tags_for_maintainers() -> Result<()> {
549 let maintainers = &generate_repo_ref_event() 549 let event = generate_repo_ref_event();
550 let maintainers = &event
550 .iter_tags() 551 .iter_tags()
551 .find(|t| t.as_vec()[0].eq(&"maintainers")) 552 .find(|t| t.as_vec()[0].eq(&"maintainers"))
552 .unwrap() 553 .unwrap()
553 .as_vec() 554 .as_vec()[1..];
554 .clone()[1..];
555 for m in maintainers { 555 for m in maintainers {
556 assert!( 556 assert!(
557 prep() 557 prep()