diff options
| -rw-r--r-- | .github/workflows/build_test.yaml | 30 | ||||
| -rw-r--r-- | .github/workflows/check_rustfmt_clippy.yaml | 26 | ||||
| -rw-r--r-- | .github/workflows/clippy_rustfmt_test.yaml | 16 | ||||
| -rw-r--r-- | Cargo.lock | 313 | ||||
| -rw-r--r-- | Cargo.toml | 4 | ||||
| -rw-r--r-- | src/client.rs | 11 | ||||
| -rw-r--r-- | src/config.rs | 6 | ||||
| -rw-r--r-- | src/git.rs | 2 | ||||
| -rw-r--r-- | src/key_handling/encryption.rs | 12 | ||||
| -rw-r--r-- | src/key_handling/users.rs | 24 | ||||
| -rw-r--r-- | src/login.rs | 8 | ||||
| -rw-r--r-- | src/repo_ref.rs | 19 | ||||
| -rw-r--r-- | src/sub_commands/init.rs | 10 | ||||
| -rw-r--r-- | src/sub_commands/list.rs | 12 | ||||
| -rw-r--r-- | src/sub_commands/push.rs | 2 | ||||
| -rw-r--r-- | src/sub_commands/send.rs | 30 | ||||
| -rw-r--r-- | test_utils/Cargo.toml | 4 | ||||
| -rw-r--r-- | test_utils/src/lib.rs | 8 | ||||
| -rw-r--r-- | tests/list.rs | 238 | ||||
| -rw-r--r-- | tests/pull.rs | 162 |
20 files changed, 584 insertions, 353 deletions
diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml deleted file mode 100644 index 5d2555d..0000000 --- a/.github/workflows/build_test.yaml +++ /dev/null | |||
| @@ -1,30 +0,0 @@ | |||
| 1 | on: push | ||
| 2 | |||
| 3 | name: build test | ||
| 4 | |||
| 5 | jobs: | ||
| 6 | ci: | ||
| 7 | runs-on: ubuntu-latest | ||
| 8 | timeout-minutes: 8 | ||
| 9 | strategy: | ||
| 10 | matrix: | ||
| 11 | rust: | ||
| 12 | - stable | ||
| 13 | - nightly | ||
| 14 | |||
| 15 | steps: | ||
| 16 | - uses: actions/checkout@v2 | ||
| 17 | |||
| 18 | - uses: actions-rs/toolchain@v1 | ||
| 19 | with: | ||
| 20 | profile: minimal | ||
| 21 | toolchain: ${{ matrix.rust }} | ||
| 22 | override: true | ||
| 23 | |||
| 24 | - uses: actions-rs/cargo@v1 | ||
| 25 | with: | ||
| 26 | command: build | ||
| 27 | |||
| 28 | - uses: actions-rs/cargo@v1 | ||
| 29 | with: | ||
| 30 | command: test | ||
diff --git a/.github/workflows/check_rustfmt_clippy.yaml b/.github/workflows/check_rustfmt_clippy.yaml deleted file mode 100644 index eec744e..0000000 --- a/.github/workflows/check_rustfmt_clippy.yaml +++ /dev/null | |||
| @@ -1,26 +0,0 @@ | |||
| 1 | on: push | ||
| 2 | |||
| 3 | name: check rustfmt | ||
| 4 | |||
| 5 | jobs: | ||
| 6 | ci: | ||
| 7 | runs-on: ubuntu-latest | ||
| 8 | strategy: | ||
| 9 | matrix: | ||
| 10 | rust: | ||
| 11 | - nightly | ||
| 12 | |||
| 13 | steps: | ||
| 14 | - uses: actions/checkout@v2 | ||
| 15 | |||
| 16 | - uses: actions-rs/toolchain@v1 | ||
| 17 | with: | ||
| 18 | profile: minimal | ||
| 19 | toolchain: ${{ matrix.rust }} | ||
| 20 | override: true | ||
| 21 | components: rustfmt | ||
| 22 | |||
| 23 | - uses: actions-rs/cargo@v1 | ||
| 24 | with: | ||
| 25 | command: fmt | ||
| 26 | args: --all -- --check | ||
diff --git a/.github/workflows/clippy_rustfmt_test.yaml b/.github/workflows/clippy_rustfmt_test.yaml new file mode 100644 index 0000000..5253814 --- /dev/null +++ b/.github/workflows/clippy_rustfmt_test.yaml | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | on: push | ||
| 2 | |||
| 3 | name: build test | ||
| 4 | |||
| 5 | jobs: | ||
| 6 | ci: | ||
| 7 | runs-on: ubuntu-latest | ||
| 8 | timeout-minutes: 8 | ||
| 9 | steps: | ||
| 10 | - uses: actions/checkout@v3 | ||
| 11 | - uses: cachix/install-nix-action@v22 | ||
| 12 | with: | ||
| 13 | nix_path: nixpkgs=channel:nixos-unstable | ||
| 14 | - run: nix develop --command cargo clippy | ||
| 15 | - run: nix develop --command cargo fmt --all -- --check | ||
| 16 | - run: nix develop --command cargo test | ||
| @@ -51,6 +51,18 @@ dependencies = [ | |||
| 51 | ] | 51 | ] |
| 52 | 52 | ||
| 53 | [[package]] | 53 | [[package]] |
| 54 | name = "ahash" | ||
| 55 | version = "0.8.11" | ||
| 56 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 57 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" | ||
| 58 | dependencies = [ | ||
| 59 | "cfg-if", | ||
| 60 | "once_cell", | ||
| 61 | "version_check", | ||
| 62 | "zerocopy", | ||
| 63 | ] | ||
| 64 | |||
| 65 | [[package]] | ||
| 54 | name = "aho-corasick" | 66 | name = "aho-corasick" |
| 55 | version = "1.1.3" | 67 | version = "1.1.3" |
| 56 | source = "registry+https://github.com/rust-lang/crates.io-index" | 68 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -60,6 +72,12 @@ dependencies = [ | |||
| 60 | ] | 72 | ] |
| 61 | 73 | ||
| 62 | [[package]] | 74 | [[package]] |
| 75 | name = "allocator-api2" | ||
| 76 | version = "0.2.16" | ||
| 77 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 78 | checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" | ||
| 79 | |||
| 80 | [[package]] | ||
| 63 | name = "anstream" | 81 | name = "anstream" |
| 64 | version = "0.6.13" | 82 | version = "0.6.13" |
| 65 | source = "registry+https://github.com/rust-lang/crates.io-index" | 83 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -301,9 +319,9 @@ dependencies = [ | |||
| 301 | 319 | ||
| 302 | [[package]] | 320 | [[package]] |
| 303 | name = "async-utility" | 321 | name = "async-utility" |
| 304 | version = "0.1.1" | 322 | version = "0.2.0" |
| 305 | source = "registry+https://github.com/rust-lang/crates.io-index" | 323 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 306 | checksum = "3716c0d3970fe92d79a8f4cda2caf91113574505dff5b18e455e549d4b078e98" | 324 | checksum = "a349201d80b4aa18d17a34a182bdd7f8ddf845e9e57d2ea130a12e10ef1e3a47" |
| 307 | dependencies = [ | 325 | dependencies = [ |
| 308 | "futures-util", | 326 | "futures-util", |
| 309 | "gloo-timers", | 327 | "gloo-timers", |
| @@ -313,20 +331,20 @@ dependencies = [ | |||
| 313 | 331 | ||
| 314 | [[package]] | 332 | [[package]] |
| 315 | name = "async-wsocket" | 333 | name = "async-wsocket" |
| 316 | version = "0.1.0" | 334 | version = "0.3.0" |
| 317 | source = "registry+https://github.com/rust-lang/crates.io-index" | 335 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 318 | checksum = "82d55992e9155e571208dc012c2a5c056572d1ab167bc299a63810ebf910226c" | 336 | checksum = "d253e375ea899cb131b92a474587e217634e7ea927c24d8098eecbcad0c5c97a" |
| 319 | dependencies = [ | 337 | dependencies = [ |
| 320 | "async-utility", | 338 | "async-utility", |
| 321 | "futures-util", | 339 | "futures-util", |
| 322 | "thiserror", | 340 | "thiserror", |
| 323 | "tokio", | 341 | "tokio", |
| 324 | "tokio-rustls", | 342 | "tokio-rustls 0.25.0", |
| 325 | "tokio-socks", | 343 | "tokio-socks", |
| 326 | "tokio-tungstenite", | 344 | "tokio-tungstenite 0.21.0", |
| 327 | "url-fork", | 345 | "url", |
| 328 | "wasm-ws", | 346 | "wasm-ws", |
| 329 | "webpki-roots", | 347 | "webpki-roots 0.26.1", |
| 330 | ] | 348 | ] |
| 331 | 349 | ||
| 332 | [[package]] | 350 | [[package]] |
| @@ -341,6 +359,15 @@ dependencies = [ | |||
| 341 | ] | 359 | ] |
| 342 | 360 | ||
| 343 | [[package]] | 361 | [[package]] |
| 362 | name = "atomic-destructor" | ||
| 363 | version = "0.1.1" | ||
| 364 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 365 | checksum = "4653a42bf04120a1d4e92452e006b4e3af4ab4afff8fb4af0f1bbb98418adf3e" | ||
| 366 | dependencies = [ | ||
| 367 | "tracing", | ||
| 368 | ] | ||
| 369 | |||
| 370 | [[package]] | ||
| 344 | name = "atomic-waker" | 371 | name = "atomic-waker" |
| 345 | version = "1.1.2" | 372 | version = "1.1.2" |
| 346 | source = "registry+https://github.com/rust-lang/crates.io-index" | 373 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1169,7 +1196,7 @@ dependencies = [ | |||
| 1169 | "futures-core", | 1196 | "futures-core", |
| 1170 | "futures-sink", | 1197 | "futures-sink", |
| 1171 | "futures-util", | 1198 | "futures-util", |
| 1172 | "http", | 1199 | "http 0.2.12", |
| 1173 | "indexmap", | 1200 | "indexmap", |
| 1174 | "slab", | 1201 | "slab", |
| 1175 | "tokio", | 1202 | "tokio", |
| @@ -1182,6 +1209,10 @@ name = "hashbrown" | |||
| 1182 | version = "0.14.3" | 1209 | version = "0.14.3" |
| 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1184 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" | 1211 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" |
| 1212 | dependencies = [ | ||
| 1213 | "ahash", | ||
| 1214 | "allocator-api2", | ||
| 1215 | ] | ||
| 1185 | 1216 | ||
| 1186 | [[package]] | 1217 | [[package]] |
| 1187 | name = "heck" | 1218 | name = "heck" |
| @@ -1243,13 +1274,24 @@ dependencies = [ | |||
| 1243 | ] | 1274 | ] |
| 1244 | 1275 | ||
| 1245 | [[package]] | 1276 | [[package]] |
| 1277 | name = "http" | ||
| 1278 | version = "1.1.0" | ||
| 1279 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1280 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" | ||
| 1281 | dependencies = [ | ||
| 1282 | "bytes", | ||
| 1283 | "fnv", | ||
| 1284 | "itoa", | ||
| 1285 | ] | ||
| 1286 | |||
| 1287 | [[package]] | ||
| 1246 | name = "http-body" | 1288 | name = "http-body" |
| 1247 | version = "0.4.6" | 1289 | version = "0.4.6" |
| 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1249 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" | 1291 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" |
| 1250 | dependencies = [ | 1292 | dependencies = [ |
| 1251 | "bytes", | 1293 | "bytes", |
| 1252 | "http", | 1294 | "http 0.2.12", |
| 1253 | "pin-project-lite", | 1295 | "pin-project-lite", |
| 1254 | ] | 1296 | ] |
| 1255 | 1297 | ||
| @@ -1276,7 +1318,7 @@ dependencies = [ | |||
| 1276 | "futures-core", | 1318 | "futures-core", |
| 1277 | "futures-util", | 1319 | "futures-util", |
| 1278 | "h2", | 1320 | "h2", |
| 1279 | "http", | 1321 | "http 0.2.12", |
| 1280 | "http-body", | 1322 | "http-body", |
| 1281 | "httparse", | 1323 | "httparse", |
| 1282 | "httpdate", | 1324 | "httpdate", |
| @@ -1296,11 +1338,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1296 | checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" | 1338 | checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" |
| 1297 | dependencies = [ | 1339 | dependencies = [ |
| 1298 | "futures-util", | 1340 | "futures-util", |
| 1299 | "http", | 1341 | "http 0.2.12", |
| 1300 | "hyper", | 1342 | "hyper", |
| 1301 | "rustls", | 1343 | "rustls 0.21.10", |
| 1302 | "tokio", | 1344 | "tokio", |
| 1303 | "tokio-rustls", | 1345 | "tokio-rustls 0.24.1", |
| 1304 | ] | 1346 | ] |
| 1305 | 1347 | ||
| 1306 | [[package]] | 1348 | [[package]] |
| @@ -1508,6 +1550,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1508 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" | 1550 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" |
| 1509 | 1551 | ||
| 1510 | [[package]] | 1552 | [[package]] |
| 1553 | name = "lnurl-pay" | ||
| 1554 | version = "0.3.0" | ||
| 1555 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1556 | checksum = "b628658116d331c9567f6cb22415d726125ff6e328d1fb1b422b1b58afeaec21" | ||
| 1557 | dependencies = [ | ||
| 1558 | "bech32", | ||
| 1559 | "reqwest", | ||
| 1560 | "serde", | ||
| 1561 | "serde_json", | ||
| 1562 | ] | ||
| 1563 | |||
| 1564 | [[package]] | ||
| 1511 | name = "lock_api" | 1565 | name = "lock_api" |
| 1512 | version = "0.4.11" | 1566 | version = "0.4.11" |
| 1513 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1524,6 +1578,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1524 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" | 1578 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" |
| 1525 | 1579 | ||
| 1526 | [[package]] | 1580 | [[package]] |
| 1581 | name = "lru" | ||
| 1582 | version = "0.12.3" | ||
| 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1584 | checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" | ||
| 1585 | dependencies = [ | ||
| 1586 | "hashbrown", | ||
| 1587 | ] | ||
| 1588 | |||
| 1589 | [[package]] | ||
| 1527 | name = "memchr" | 1590 | name = "memchr" |
| 1528 | version = "2.7.1" | 1591 | version = "2.7.1" |
| 1529 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1592 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1702,9 +1765,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" | |||
| 1702 | 1765 | ||
| 1703 | [[package]] | 1766 | [[package]] |
| 1704 | name = "nostr" | 1767 | name = "nostr" |
| 1705 | version = "0.27.0" | 1768 | version = "0.29.0" |
| 1706 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1769 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1707 | checksum = "3e47228d958fd65ef3e04650a3b1dd80f16f10f0243c80ed969556dead0f48c8" | 1770 | checksum = "255485c2f41cf8f39d4e4a1901199549f54e32def81a71a8afe05f75809f441d" |
| 1708 | dependencies = [ | 1771 | dependencies = [ |
| 1709 | "aes 0.8.4", | 1772 | "aes 0.8.4", |
| 1710 | "base64", | 1773 | "base64", |
| @@ -1712,16 +1775,19 @@ dependencies = [ | |||
| 1712 | "bitcoin", | 1775 | "bitcoin", |
| 1713 | "cbc", | 1776 | "cbc", |
| 1714 | "chacha20", | 1777 | "chacha20", |
| 1778 | "chacha20poly1305", | ||
| 1715 | "getrandom", | 1779 | "getrandom", |
| 1716 | "instant", | 1780 | "instant", |
| 1717 | "js-sys", | 1781 | "js-sys", |
| 1718 | "negentropy", | 1782 | "negentropy", |
| 1719 | "once_cell", | 1783 | "once_cell", |
| 1720 | "reqwest", | 1784 | "reqwest", |
| 1785 | "scrypt", | ||
| 1721 | "serde", | 1786 | "serde", |
| 1722 | "serde_json", | 1787 | "serde_json", |
| 1723 | "tracing", | 1788 | "tracing", |
| 1724 | "url-fork", | 1789 | "unicode-normalization", |
| 1790 | "url", | ||
| 1725 | "wasm-bindgen", | 1791 | "wasm-bindgen", |
| 1726 | "wasm-bindgen-futures", | 1792 | "wasm-bindgen-futures", |
| 1727 | "web-sys", | 1793 | "web-sys", |
| @@ -1729,11 +1795,12 @@ dependencies = [ | |||
| 1729 | 1795 | ||
| 1730 | [[package]] | 1796 | [[package]] |
| 1731 | name = "nostr-database" | 1797 | name = "nostr-database" |
| 1732 | version = "0.27.0" | 1798 | version = "0.29.0" |
| 1733 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1799 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1734 | checksum = "aa0550256c8d4f0aaf74891ac986bd5ba46b2957c2c7e20f51838fa5819285f8" | 1800 | checksum = "8e15ab55f96ea5e560af0c75f1d942b1064266d443d11b2afbe51ca9ad78a018" |
| 1735 | dependencies = [ | 1801 | dependencies = [ |
| 1736 | "async-trait", | 1802 | "async-trait", |
| 1803 | "lru", | ||
| 1737 | "nostr", | 1804 | "nostr", |
| 1738 | "thiserror", | 1805 | "thiserror", |
| 1739 | "tokio", | 1806 | "tokio", |
| @@ -1741,22 +1808,65 @@ dependencies = [ | |||
| 1741 | ] | 1808 | ] |
| 1742 | 1809 | ||
| 1743 | [[package]] | 1810 | [[package]] |
| 1744 | name = "nostr-sdk" | 1811 | name = "nostr-relay-pool" |
| 1745 | version = "0.27.0" | 1812 | version = "0.29.2" |
| 1746 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1813 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1747 | checksum = "3cf190e41230721f0ce64f5ea72ed36cbc431d3b305eb166e24a94f5d7e4a425" | 1814 | checksum = "a1b306bc99d49064950a16a06d35c7c19af94d8b4052fad0dfe02e41e529d5d3" |
| 1748 | dependencies = [ | 1815 | dependencies = [ |
| 1749 | "async-utility", | 1816 | "async-utility", |
| 1750 | "async-wsocket", | 1817 | "async-wsocket", |
| 1818 | "atomic-destructor", | ||
| 1751 | "nostr", | 1819 | "nostr", |
| 1752 | "nostr-database", | 1820 | "nostr-database", |
| 1753 | "once_cell", | ||
| 1754 | "thiserror", | 1821 | "thiserror", |
| 1755 | "tokio", | 1822 | "tokio", |
| 1756 | "tracing", | 1823 | "tracing", |
| 1757 | ] | 1824 | ] |
| 1758 | 1825 | ||
| 1759 | [[package]] | 1826 | [[package]] |
| 1827 | name = "nostr-sdk" | ||
| 1828 | version = "0.29.0" | ||
| 1829 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1830 | checksum = "81ed0ab9cbc3b20d3dba99337f2e0739f052ebe32133d690e212022a06a22044" | ||
| 1831 | dependencies = [ | ||
| 1832 | "async-utility", | ||
| 1833 | "lnurl-pay", | ||
| 1834 | "nostr", | ||
| 1835 | "nostr-database", | ||
| 1836 | "nostr-relay-pool", | ||
| 1837 | "nostr-signer", | ||
| 1838 | "nostr-zapper", | ||
| 1839 | "nwc", | ||
| 1840 | "thiserror", | ||
| 1841 | "tokio", | ||
| 1842 | "tracing", | ||
| 1843 | ] | ||
| 1844 | |||
| 1845 | [[package]] | ||
| 1846 | name = "nostr-signer" | ||
| 1847 | version = "0.29.0" | ||
| 1848 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1849 | checksum = "307bdc7c26887d7e65632e66872989a19892dfe9f2c6dbd9a1d3f959c5c524d5" | ||
| 1850 | dependencies = [ | ||
| 1851 | "async-utility", | ||
| 1852 | "nostr", | ||
| 1853 | "nostr-relay-pool", | ||
| 1854 | "thiserror", | ||
| 1855 | "tokio", | ||
| 1856 | ] | ||
| 1857 | |||
| 1858 | [[package]] | ||
| 1859 | name = "nostr-zapper" | ||
| 1860 | version = "0.29.0" | ||
| 1861 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1862 | checksum = "061d5eb00b430747a984ea9e41cd82c849832151b4263d8230c9c220dc2c62f8" | ||
| 1863 | dependencies = [ | ||
| 1864 | "async-trait", | ||
| 1865 | "nostr", | ||
| 1866 | "thiserror", | ||
| 1867 | ] | ||
| 1868 | |||
| 1869 | [[package]] | ||
| 1760 | name = "num" | 1870 | name = "num" |
| 1761 | version = "0.4.1" | 1871 | version = "0.4.1" |
| 1762 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1872 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1848,6 +1958,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1848 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" | 1958 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" |
| 1849 | 1959 | ||
| 1850 | [[package]] | 1960 | [[package]] |
| 1961 | name = "nwc" | ||
| 1962 | version = "0.29.0" | ||
| 1963 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1964 | checksum = "d1894ffe54a1e5adf8dbb22b5a290c0748ec4a88aa07fa69c4359010edea49ed" | ||
| 1965 | dependencies = [ | ||
| 1966 | "async-utility", | ||
| 1967 | "nostr", | ||
| 1968 | "nostr-relay-pool", | ||
| 1969 | "nostr-zapper", | ||
| 1970 | "thiserror", | ||
| 1971 | "tracing", | ||
| 1972 | ] | ||
| 1973 | |||
| 1974 | [[package]] | ||
| 1851 | name = "object" | 1975 | name = "object" |
| 1852 | version = "0.32.2" | 1976 | version = "0.32.2" |
| 1853 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1977 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -2300,7 +2424,7 @@ dependencies = [ | |||
| 2300 | "futures-core", | 2424 | "futures-core", |
| 2301 | "futures-util", | 2425 | "futures-util", |
| 2302 | "h2", | 2426 | "h2", |
| 2303 | "http", | 2427 | "http 0.2.12", |
| 2304 | "http-body", | 2428 | "http-body", |
| 2305 | "hyper", | 2429 | "hyper", |
| 2306 | "hyper-rustls", | 2430 | "hyper-rustls", |
| @@ -2311,7 +2435,7 @@ dependencies = [ | |||
| 2311 | "once_cell", | 2435 | "once_cell", |
| 2312 | "percent-encoding", | 2436 | "percent-encoding", |
| 2313 | "pin-project-lite", | 2437 | "pin-project-lite", |
| 2314 | "rustls", | 2438 | "rustls 0.21.10", |
| 2315 | "rustls-pemfile", | 2439 | "rustls-pemfile", |
| 2316 | "serde", | 2440 | "serde", |
| 2317 | "serde_json", | 2441 | "serde_json", |
| @@ -2319,14 +2443,14 @@ dependencies = [ | |||
| 2319 | "sync_wrapper", | 2443 | "sync_wrapper", |
| 2320 | "system-configuration", | 2444 | "system-configuration", |
| 2321 | "tokio", | 2445 | "tokio", |
| 2322 | "tokio-rustls", | 2446 | "tokio-rustls 0.24.1", |
| 2323 | "tokio-socks", | 2447 | "tokio-socks", |
| 2324 | "tower-service", | 2448 | "tower-service", |
| 2325 | "url", | 2449 | "url", |
| 2326 | "wasm-bindgen", | 2450 | "wasm-bindgen", |
| 2327 | "wasm-bindgen-futures", | 2451 | "wasm-bindgen-futures", |
| 2328 | "web-sys", | 2452 | "web-sys", |
| 2329 | "webpki-roots", | 2453 | "webpki-roots 0.25.4", |
| 2330 | "winreg", | 2454 | "winreg", |
| 2331 | ] | 2455 | ] |
| 2332 | 2456 | ||
| @@ -2420,11 +2544,25 @@ checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" | |||
| 2420 | dependencies = [ | 2544 | dependencies = [ |
| 2421 | "log", | 2545 | "log", |
| 2422 | "ring", | 2546 | "ring", |
| 2423 | "rustls-webpki", | 2547 | "rustls-webpki 0.101.7", |
| 2424 | "sct", | 2548 | "sct", |
| 2425 | ] | 2549 | ] |
| 2426 | 2550 | ||
| 2427 | [[package]] | 2551 | [[package]] |
| 2552 | name = "rustls" | ||
| 2553 | version = "0.22.2" | ||
| 2554 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2555 | checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" | ||
| 2556 | dependencies = [ | ||
| 2557 | "log", | ||
| 2558 | "ring", | ||
| 2559 | "rustls-pki-types", | ||
| 2560 | "rustls-webpki 0.102.2", | ||
| 2561 | "subtle", | ||
| 2562 | "zeroize", | ||
| 2563 | ] | ||
| 2564 | |||
| 2565 | [[package]] | ||
| 2428 | name = "rustls-pemfile" | 2566 | name = "rustls-pemfile" |
| 2429 | version = "1.0.4" | 2567 | version = "1.0.4" |
| 2430 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2568 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -2434,6 +2572,12 @@ dependencies = [ | |||
| 2434 | ] | 2572 | ] |
| 2435 | 2573 | ||
| 2436 | [[package]] | 2574 | [[package]] |
| 2575 | name = "rustls-pki-types" | ||
| 2576 | version = "1.3.1" | ||
| 2577 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2578 | checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" | ||
| 2579 | |||
| 2580 | [[package]] | ||
| 2437 | name = "rustls-webpki" | 2581 | name = "rustls-webpki" |
| 2438 | version = "0.101.7" | 2582 | version = "0.101.7" |
| 2439 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2583 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -2444,6 +2588,17 @@ dependencies = [ | |||
| 2444 | ] | 2588 | ] |
| 2445 | 2589 | ||
| 2446 | [[package]] | 2590 | [[package]] |
| 2591 | name = "rustls-webpki" | ||
| 2592 | version = "0.102.2" | ||
| 2593 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 2594 | checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" | ||
| 2595 | dependencies = [ | ||
| 2596 | "ring", | ||
| 2597 | "rustls-pki-types", | ||
| 2598 | "untrusted", | ||
| 2599 | ] | ||
| 2600 | |||
| 2601 | [[package]] | ||
| 2447 | name = "ryu" | 2602 | name = "ryu" |
| 2448 | version = "1.0.17" | 2603 | version = "1.0.17" |
| 2449 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2604 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -2699,7 +2854,7 @@ dependencies = [ | |||
| 2699 | "flume", | 2854 | "flume", |
| 2700 | "futures-util", | 2855 | "futures-util", |
| 2701 | "tokio", | 2856 | "tokio", |
| 2702 | "tokio-tungstenite", | 2857 | "tokio-tungstenite 0.20.1", |
| 2703 | ] | 2858 | ] |
| 2704 | 2859 | ||
| 2705 | [[package]] | 2860 | [[package]] |
| @@ -2856,7 +3011,7 @@ dependencies = [ | |||
| 2856 | "rexpect 0.5.0 (git+https://github.com/rust-cli/rexpect.git?rev=9eb61dd)", | 3011 | "rexpect 0.5.0 (git+https://github.com/rust-cli/rexpect.git?rev=9eb61dd)", |
| 2857 | "simple-websockets", | 3012 | "simple-websockets", |
| 2858 | "strip-ansi-escapes", | 3013 | "strip-ansi-escapes", |
| 2859 | "tungstenite", | 3014 | "tungstenite 0.20.1", |
| 2860 | ] | 3015 | ] |
| 2861 | 3016 | ||
| 2862 | [[package]] | 3017 | [[package]] |
| @@ -2930,7 +3085,18 @@ version = "0.24.1" | |||
| 2930 | source = "registry+https://github.com/rust-lang/crates.io-index" | 3085 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2931 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" | 3086 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" |
| 2932 | dependencies = [ | 3087 | dependencies = [ |
| 2933 | "rustls", | 3088 | "rustls 0.21.10", |
| 3089 | "tokio", | ||
| 3090 | ] | ||
| 3091 | |||
| 3092 | [[package]] | ||
| 3093 | name = "tokio-rustls" | ||
| 3094 | version = "0.25.0" | ||
| 3095 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 3096 | checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" | ||
| 3097 | dependencies = [ | ||
| 3098 | "rustls 0.22.2", | ||
| 3099 | "rustls-pki-types", | ||
| 2934 | "tokio", | 3100 | "tokio", |
| 2935 | ] | 3101 | ] |
| 2936 | 3102 | ||
| @@ -2954,11 +3120,24 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" | |||
| 2954 | dependencies = [ | 3120 | dependencies = [ |
| 2955 | "futures-util", | 3121 | "futures-util", |
| 2956 | "log", | 3122 | "log", |
| 2957 | "rustls", | ||
| 2958 | "tokio", | 3123 | "tokio", |
| 2959 | "tokio-rustls", | 3124 | "tungstenite 0.20.1", |
| 2960 | "tungstenite", | 3125 | ] |
| 2961 | "webpki-roots", | 3126 | |
| 3127 | [[package]] | ||
| 3128 | name = "tokio-tungstenite" | ||
| 3129 | version = "0.21.0" | ||
| 3130 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 3131 | checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" | ||
| 3132 | dependencies = [ | ||
| 3133 | "futures-util", | ||
| 3134 | "log", | ||
| 3135 | "rustls 0.22.2", | ||
| 3136 | "rustls-pki-types", | ||
| 3137 | "tokio", | ||
| 3138 | "tokio-rustls 0.25.0", | ||
| 3139 | "tungstenite 0.21.0", | ||
| 3140 | "webpki-roots 0.26.1", | ||
| 2962 | ] | 3141 | ] |
| 2963 | 3142 | ||
| 2964 | [[package]] | 3143 | [[package]] |
| @@ -3044,11 +3223,31 @@ dependencies = [ | |||
| 3044 | "byteorder", | 3223 | "byteorder", |
| 3045 | "bytes", | 3224 | "bytes", |
| 3046 | "data-encoding", | 3225 | "data-encoding", |
| 3047 | "http", | 3226 | "http 0.2.12", |
| 3048 | "httparse", | 3227 | "httparse", |
| 3049 | "log", | 3228 | "log", |
| 3050 | "rand", | 3229 | "rand", |
| 3051 | "rustls", | 3230 | "sha1", |
| 3231 | "thiserror", | ||
| 3232 | "url", | ||
| 3233 | "utf-8", | ||
| 3234 | ] | ||
| 3235 | |||
| 3236 | [[package]] | ||
| 3237 | name = "tungstenite" | ||
| 3238 | version = "0.21.0" | ||
| 3239 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 3240 | checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" | ||
| 3241 | dependencies = [ | ||
| 3242 | "byteorder", | ||
| 3243 | "bytes", | ||
| 3244 | "data-encoding", | ||
| 3245 | "http 1.1.0", | ||
| 3246 | "httparse", | ||
| 3247 | "log", | ||
| 3248 | "rand", | ||
| 3249 | "rustls 0.22.2", | ||
| 3250 | "rustls-pki-types", | ||
| 3052 | "sha1", | 3251 | "sha1", |
| 3053 | "thiserror", | 3252 | "thiserror", |
| 3054 | "url", | 3253 | "url", |
| @@ -3130,17 +3329,6 @@ dependencies = [ | |||
| 3130 | "form_urlencoded", | 3329 | "form_urlencoded", |
| 3131 | "idna", | 3330 | "idna", |
| 3132 | "percent-encoding", | 3331 | "percent-encoding", |
| 3133 | ] | ||
| 3134 | |||
| 3135 | [[package]] | ||
| 3136 | name = "url-fork" | ||
| 3137 | version = "3.0.1" | ||
| 3138 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 3139 | checksum = "7fa3323c39b8e786154d3000b70ae9af0e9bd746c9791456da0d4a1f68ad89d6" | ||
| 3140 | dependencies = [ | ||
| 3141 | "form_urlencoded", | ||
| 3142 | "idna", | ||
| 3143 | "percent-encoding", | ||
| 3144 | "serde", | 3332 | "serde", |
| 3145 | ] | 3333 | ] |
| 3146 | 3334 | ||
| @@ -3318,6 +3506,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 3318 | checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" | 3506 | checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" |
| 3319 | 3507 | ||
| 3320 | [[package]] | 3508 | [[package]] |
| 3509 | name = "webpki-roots" | ||
| 3510 | version = "0.26.1" | ||
| 3511 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 3512 | checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" | ||
| 3513 | dependencies = [ | ||
| 3514 | "rustls-pki-types", | ||
| 3515 | ] | ||
| 3516 | |||
| 3517 | [[package]] | ||
| 3321 | name = "winapi" | 3518 | name = "winapi" |
| 3322 | version = "0.3.9" | 3519 | version = "0.3.9" |
| 3323 | source = "registry+https://github.com/rust-lang/crates.io-index" | 3520 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -3567,6 +3764,26 @@ dependencies = [ | |||
| 3567 | ] | 3764 | ] |
| 3568 | 3765 | ||
| 3569 | [[package]] | 3766 | [[package]] |
| 3767 | name = "zerocopy" | ||
| 3768 | version = "0.7.32" | ||
| 3769 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 3770 | checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" | ||
| 3771 | dependencies = [ | ||
| 3772 | "zerocopy-derive", | ||
| 3773 | ] | ||
| 3774 | |||
| 3775 | [[package]] | ||
| 3776 | name = "zerocopy-derive" | ||
| 3777 | version = "0.7.32" | ||
| 3778 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 3779 | checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" | ||
| 3780 | dependencies = [ | ||
| 3781 | "proc-macro2", | ||
| 3782 | "quote", | ||
| 3783 | "syn 2.0.53", | ||
| 3784 | ] | ||
| 3785 | |||
| 3786 | [[package]] | ||
| 3570 | name = "zeroize" | 3787 | name = "zeroize" |
| 3571 | version = "1.7.0" | 3788 | version = "1.7.0" |
| 3572 | source = "registry+https://github.com/rust-lang/crates.io-index" | 3789 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -23,8 +23,8 @@ futures = "0.3.28" | |||
| 23 | git2 = "0.18.1" | 23 | git2 = "0.18.1" |
| 24 | indicatif = "0.17.7" | 24 | indicatif = "0.17.7" |
| 25 | keyring = "2.0.5" | 25 | keyring = "2.0.5" |
| 26 | nostr = "0.27.0" | 26 | nostr = "0.29" |
| 27 | nostr-sdk = "0.27.0" | 27 | nostr-sdk = "0.29" |
| 28 | passwords = "3.1.13" | 28 | passwords = "3.1.13" |
| 29 | scrypt = "0.11.0" | 29 | scrypt = "0.11.0" |
| 30 | serde = { version = "1.0.181", features = ["derive"] } | 30 | serde = { version = "1.0.181", features = ["derive"] } |
diff --git a/src/client.rs b/src/client.rs index 539d45a..2dbd238 100644 --- a/src/client.rs +++ b/src/client.rs | |||
| @@ -19,7 +19,7 @@ use indicatif::{MultiProgress, ProgressBar, ProgressState, ProgressStyle}; | |||
| 19 | #[cfg(test)] | 19 | #[cfg(test)] |
| 20 | use mockall::*; | 20 | use mockall::*; |
| 21 | use nostr::Event; | 21 | use nostr::Event; |
| 22 | use nostr_sdk::ClientSigner; | 22 | use nostr_sdk::NostrSigner; |
| 23 | 23 | ||
| 24 | #[allow(clippy::struct_field_names)] | 24 | #[allow(clippy::struct_field_names)] |
| 25 | pub struct Client { | 25 | pub struct Client { |
| @@ -101,7 +101,7 @@ impl Connect for Client { | |||
| 101 | 101 | ||
| 102 | async fn set_keys(&mut self, keys: &nostr::Keys) { | 102 | async fn set_keys(&mut self, keys: &nostr::Keys) { |
| 103 | self.client | 103 | self.client |
| 104 | .set_signer(Some(ClientSigner::Keys(keys.clone()))) | 104 | .set_signer(Some(NostrSigner::Keys(keys.clone()))) |
| 105 | .await; | 105 | .await; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| @@ -124,8 +124,9 @@ impl Connect for Client { | |||
| 124 | 124 | ||
| 125 | async fn send_event_to(&self, url: &str, event: Event) -> Result<nostr::EventId> { | 125 | async fn send_event_to(&self, url: &str, event: Event) -> Result<nostr::EventId> { |
| 126 | self.client.add_relay(url).await?; | 126 | self.client.add_relay(url).await?; |
| 127 | #[allow(clippy::large_futures)] | ||
| 127 | self.client.connect_relay(url).await?; | 128 | self.client.connect_relay(url).await?; |
| 128 | Ok(self.client.send_event_to(url, event).await?) | 129 | Ok(self.client.send_event_to(vec![url], event).await?) |
| 129 | } | 130 | } |
| 130 | 131 | ||
| 131 | async fn get_events( | 132 | async fn get_events( |
| @@ -144,7 +145,7 @@ impl Connect for Client { | |||
| 144 | let m = MultiProgress::new(); | 145 | let m = MultiProgress::new(); |
| 145 | let pb_style = ProgressStyle::with_template(" {spinner} {prefix} {msg} {timeout_in}")? | 146 | let pb_style = ProgressStyle::with_template(" {spinner} {prefix} {msg} {timeout_in}")? |
| 146 | .with_key("timeout_in", |state: &ProgressState, w: &mut dyn Write| { | 147 | .with_key("timeout_in", |state: &ProgressState, w: &mut dyn Write| { |
| 147 | if state.elapsed().as_secs() > 3 { | 148 | if state.elapsed().as_secs() > 3 && state.elapsed().as_secs() < GET_EVENTS_TIMEOUT { |
| 148 | write!( | 149 | write!( |
| 149 | w, | 150 | w, |
| 150 | "timeout in {:.1}s", | 151 | "timeout in {:.1}s", |
| @@ -200,6 +201,7 @@ impl Connect for Client { | |||
| 200 | } else { | 201 | } else { |
| 201 | None | 202 | None |
| 202 | }; | 203 | }; |
| 204 | #[allow(clippy::large_futures)] | ||
| 203 | match get_events_of(relay, filters, &pb).await { | 205 | match get_events_of(relay, filters, &pb).await { |
| 204 | Err(error) => { | 206 | Err(error) => { |
| 205 | if let Some(pb) = pb { | 207 | if let Some(pb) = pb { |
| @@ -246,6 +248,7 @@ async fn get_events_of( | |||
| 246 | pb: &Option<ProgressBar>, | 248 | pb: &Option<ProgressBar>, |
| 247 | ) -> Result<Vec<Event>> { | 249 | ) -> Result<Vec<Event>> { |
| 248 | if !relay.is_connected().await { | 250 | if !relay.is_connected().await { |
| 251 | #[allow(clippy::large_futures)] | ||
| 249 | relay.connect(None).await; | 252 | relay.connect(None).await; |
| 250 | } | 253 | } |
| 251 | 254 | ||
diff --git a/src/config.rs b/src/config.rs index 2370e34..7fca446 100644 --- a/src/config.rs +++ b/src/config.rs | |||
| @@ -4,7 +4,7 @@ use anyhow::{anyhow, Context, Result}; | |||
| 4 | use directories::ProjectDirs; | 4 | use directories::ProjectDirs; |
| 5 | #[cfg(test)] | 5 | #[cfg(test)] |
| 6 | use mockall::*; | 6 | use mockall::*; |
| 7 | use nostr::{secp256k1::XOnlyPublicKey, ToBech32}; | 7 | use nostr::{PublicKey, ToBech32}; |
| 8 | use serde::{self, Deserialize, Serialize}; | 8 | use serde::{self, Deserialize, Serialize}; |
| 9 | 9 | ||
| 10 | #[derive(Default)] | 10 | #[derive(Default)] |
| @@ -69,7 +69,7 @@ pub struct MyConfig { | |||
| 69 | 69 | ||
| 70 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] | 70 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] |
| 71 | pub struct UserRef { | 71 | pub struct UserRef { |
| 72 | pub public_key: XOnlyPublicKey, | 72 | pub public_key: PublicKey, |
| 73 | pub encrypted_key: String, | 73 | pub encrypted_key: String, |
| 74 | pub metadata: UserMetadata, | 74 | pub metadata: UserMetadata, |
| 75 | pub relays: UserRelays, | 75 | pub relays: UserRelays, |
| @@ -77,7 +77,7 @@ pub struct UserRef { | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | impl UserRef { | 79 | impl UserRef { |
| 80 | pub fn new(public_key: XOnlyPublicKey, encrypted_key: String) -> Self { | 80 | pub fn new(public_key: PublicKey, encrypted_key: String) -> Self { |
| 81 | Self { | 81 | Self { |
| 82 | public_key, | 82 | public_key, |
| 83 | encrypted_key, | 83 | encrypted_key, |
| @@ -4,7 +4,7 @@ use std::{env::current_dir, path::Path}; | |||
| 4 | 4 | ||
| 5 | use anyhow::{bail, Context, Result}; | 5 | use anyhow::{bail, Context, Result}; |
| 6 | use git2::{DiffOptions, Oid, Revwalk}; | 6 | use git2::{DiffOptions, Oid, Revwalk}; |
| 7 | use nostr::prelude::{sha1::Hash as Sha1Hash, Hash}; | 7 | use nostr_sdk::hashes::{sha1::Hash as Sha1Hash, Hash}; |
| 8 | 8 | ||
| 9 | use crate::sub_commands::list::{get_commit_id_from_patch, tag_value}; | 9 | use crate::sub_commands::list::{get_commit_id_from_patch, tag_value}; |
| 10 | 10 | ||
diff --git a/src/key_handling/encryption.rs b/src/key_handling/encryption.rs index 0ef7f69..54002fa 100644 --- a/src/key_handling/encryption.rs +++ b/src/key_handling/encryption.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | use std::str::FromStr; | ||
| 2 | |||
| 1 | use anyhow::{anyhow, bail, ensure, Context, Result}; | 3 | use anyhow::{anyhow, bail, ensure, Context, Result}; |
| 2 | use chacha20poly1305::{ | 4 | use chacha20poly1305::{ |
| 3 | aead::{rand_core::RngCore, Aead, AeadCore, KeyInit, OsRng, Payload}, | 5 | aead::{rand_core::RngCore, Aead, AeadCore, KeyInit, OsRng, Payload}, |
| @@ -6,6 +8,7 @@ use chacha20poly1305::{ | |||
| 6 | #[cfg(test)] | 8 | #[cfg(test)] |
| 7 | use mockall::*; | 9 | use mockall::*; |
| 8 | use nostr::{prelude::*, Keys}; | 10 | use nostr::{prelude::*, Keys}; |
| 11 | use nostr_sdk::bech32::{self, FromBase32, ToBase32}; | ||
| 9 | use rand::{distributions::Alphanumeric, thread_rng, Rng}; | 12 | use rand::{distributions::Alphanumeric, thread_rng, Rng}; |
| 10 | use zeroize::Zeroize; | 13 | use zeroize::Zeroize; |
| 11 | 14 | ||
| @@ -120,10 +123,11 @@ impl EncryptDecrypt for Encryptor { | |||
| 120 | bail!("invalid encrypted key"); | 123 | bail!("invalid encrypted key"); |
| 121 | } | 124 | } |
| 122 | 125 | ||
| 123 | let key = Keys::from_sk_str( | 126 | let key = |
| 124 | std::str::from_utf8(&inner_secret).context("inner secret is not [u8]")?, | 127 | Keys::from_str(std::str::from_utf8(&inner_secret).context("inner secret is not [u8]")?) |
| 125 | ) | 128 | .context( |
| 126 | .context("incorrect password. Key decrypted with password did not produce a valid nsec.")?; | 129 | "incorrect password. Key decrypted with password did not produce a valid nsec.", |
| 130 | )?; | ||
| 127 | 131 | ||
| 128 | inner_secret.zeroize(); | 132 | inner_secret.zeroize(); |
| 129 | 133 | ||
diff --git a/src/key_handling/users.rs b/src/key_handling/users.rs index 2e88fba..1dd75a8 100644 --- a/src/key_handling/users.rs +++ b/src/key_handling/users.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use std::time::SystemTime; | 1 | use std::{str::FromStr, time::SystemTime}; |
| 2 | 2 | ||
| 3 | use anyhow::{Context, Result}; | 3 | use anyhow::{Context, Result}; |
| 4 | use async_trait::async_trait; | 4 | use async_trait::async_trait; |
| @@ -32,13 +32,13 @@ pub trait UserManagement { | |||
| 32 | &self, | 32 | &self, |
| 33 | #[cfg(test)] client: &MockConnect, | 33 | #[cfg(test)] client: &MockConnect, |
| 34 | #[cfg(not(test))] client: &Client, | 34 | #[cfg(not(test))] client: &Client, |
| 35 | public_key: &XOnlyPublicKey, | 35 | public_key: &PublicKey, |
| 36 | after: u64, | 36 | after: u64, |
| 37 | ) -> Result<UserRef>; | 37 | ) -> Result<UserRef>; |
| 38 | fn get_user_from_cache(&self, public_key: &XOnlyPublicKey) -> Result<UserRef>; | 38 | fn get_user_from_cache(&self, public_key: &PublicKey) -> Result<UserRef>; |
| 39 | fn add_user_to_config( | 39 | fn add_user_to_config( |
| 40 | &self, | 40 | &self, |
| 41 | public_key: XOnlyPublicKey, | 41 | public_key: PublicKey, |
| 42 | encrypted_secret_key: Option<String>, | 42 | encrypted_secret_key: Option<String>, |
| 43 | overwrite: bool, | 43 | overwrite: bool, |
| 44 | ) -> Result<()>; | 44 | ) -> Result<()>; |
| @@ -59,7 +59,7 @@ impl UserManagement for UserManager { | |||
| 59 | .input(PromptInputParms::default().with_prompt(prompt)) | 59 | .input(PromptInputParms::default().with_prompt(prompt)) |
| 60 | .context("failed to get nsec input from interactor")?, | 60 | .context("failed to get nsec input from interactor")?, |
| 61 | }; | 61 | }; |
| 62 | match Keys::from_sk_str(&pk) { | 62 | match Keys::from_str(&pk) { |
| 63 | Ok(key) => { | 63 | Ok(key) => { |
| 64 | break key; | 64 | break key; |
| 65 | } | 65 | } |
| @@ -99,7 +99,7 @@ impl UserManagement for UserManager { | |||
| 99 | 99 | ||
| 100 | fn add_user_to_config( | 100 | fn add_user_to_config( |
| 101 | &self, | 101 | &self, |
| 102 | public_key: XOnlyPublicKey, | 102 | public_key: PublicKey, |
| 103 | encrypted_secret_key: Option<String>, | 103 | encrypted_secret_key: Option<String>, |
| 104 | overwrite: bool, | 104 | overwrite: bool, |
| 105 | ) -> Result<()> { | 105 | ) -> Result<()> { |
| @@ -129,7 +129,7 @@ impl UserManagement for UserManager { | |||
| 129 | .context("failed to save application configuration with new user details in") | 129 | .context("failed to save application configuration with new user details in") |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | fn get_user_from_cache(&self, public_key: &XOnlyPublicKey) -> Result<UserRef> { | 132 | fn get_user_from_cache(&self, public_key: &PublicKey) -> Result<UserRef> { |
| 133 | let cfg = self | 133 | let cfg = self |
| 134 | .config_manager | 134 | .config_manager |
| 135 | .load() | 135 | .load() |
| @@ -148,7 +148,7 @@ impl UserManagement for UserManager { | |||
| 148 | &self, | 148 | &self, |
| 149 | #[cfg(test)] client: &MockConnect, | 149 | #[cfg(test)] client: &MockConnect, |
| 150 | #[cfg(not(test))] client: &Client, | 150 | #[cfg(not(test))] client: &Client, |
| 151 | public_key: &XOnlyPublicKey, | 151 | public_key: &PublicKey, |
| 152 | use_cache_unless_checked_more_than_x_secs_ago: u64, | 152 | use_cache_unless_checked_more_than_x_secs_ago: u64, |
| 153 | ) -> Result<UserRef> { | 153 | ) -> Result<UserRef> { |
| 154 | let cfg = self | 154 | let cfg = self |
| @@ -249,7 +249,11 @@ impl UserManagement for UserManager { | |||
| 249 | relays: new_relays_event | 249 | relays: new_relays_event |
| 250 | .tags | 250 | .tags |
| 251 | .iter() | 251 | .iter() |
| 252 | .filter(|t| t.kind().eq(&nostr::TagKind::R)) | 252 | .filter(|t| { |
| 253 | t.kind().eq(&nostr::TagKind::SingleLetter( | ||
| 254 | SingleLetterTag::lowercase(Alphabet::R), | ||
| 255 | )) | ||
| 256 | }) | ||
| 253 | .map(|t| UserRelayRef { | 257 | .map(|t| UserRelayRef { |
| 254 | url: t.as_vec()[1].clone(), | 258 | url: t.as_vec()[1].clone(), |
| 255 | read: t.as_vec().len() == 2 || t.as_vec()[2].eq("read"), | 259 | read: t.as_vec().len() == 2 || t.as_vec()[2].eq("read"), |
| @@ -471,7 +475,7 @@ mod tests { | |||
| 471 | .expect_encrypt_key() | 475 | .expect_encrypt_key() |
| 472 | .once() | 476 | .once() |
| 473 | .withf(|k, p| { | 477 | .withf(|k, p| { |
| 474 | k.eq(&Keys::from_sk_str(TEST_KEY_1_NSEC).unwrap()) && p.eq(TEST_PASSWORD) | 478 | k.eq(&Keys::from_str(TEST_KEY_1_NSEC).unwrap()) && p.eq(TEST_PASSWORD) |
| 475 | }) | 479 | }) |
| 476 | .returning(|_, _| Ok(TEST_KEY_1_ENCRYPTED.into())); | 480 | .returning(|_, _| Ok(TEST_KEY_1_ENCRYPTED.into())); |
| 477 | 481 | ||
diff --git a/src/login.rs b/src/login.rs index b0fe230..4cdf3c1 100644 --- a/src/login.rs +++ b/src/login.rs | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | use std::str::FromStr; | ||
| 2 | |||
| 1 | use anyhow::{bail, Context, Result}; | 3 | use anyhow::{bail, Context, Result}; |
| 2 | use nostr::{prelude::FromSkStr, secp256k1::XOnlyPublicKey}; | 4 | use nostr::PublicKey; |
| 3 | use zeroize::Zeroize; | 5 | use zeroize::Zeroize; |
| 4 | 6 | ||
| 5 | #[cfg(not(test))] | 7 | #[cfg(not(test))] |
| @@ -25,7 +27,7 @@ pub async fn launch( | |||
| 25 | // if nsec parameter | 27 | // if nsec parameter |
| 26 | let key = if let Some(nsec_unwrapped) = nsec { | 28 | let key = if let Some(nsec_unwrapped) = nsec { |
| 27 | // get key or fail without prompts | 29 | // get key or fail without prompts |
| 28 | let key = nostr::Keys::from_sk_str(nsec_unwrapped).context("invalid nsec parameter")?; | 30 | let key = nostr::Keys::from_str(nsec_unwrapped).context("invalid nsec parameter")?; |
| 29 | 31 | ||
| 30 | // if password, add user to enable password login in future | 32 | // if password, add user to enable password login in future |
| 31 | if password.is_some() { | 33 | if password.is_some() { |
| @@ -91,7 +93,7 @@ pub async fn launch( | |||
| 91 | } | 93 | } |
| 92 | 94 | ||
| 93 | async fn get_user_details( | 95 | async fn get_user_details( |
| 94 | public_key: &XOnlyPublicKey, | 96 | public_key: &PublicKey, |
| 95 | #[cfg(test)] client: &crate::client::MockConnect, | 97 | #[cfg(test)] client: &crate::client::MockConnect, |
| 96 | #[cfg(not(test))] client: &Client, | 98 | #[cfg(not(test))] client: &Client, |
| 97 | ) -> Result<UserRef> { | 99 | ) -> Result<UserRef> { |
diff --git a/src/repo_ref.rs b/src/repo_ref.rs index c7b42fa..2dab79c 100644 --- a/src/repo_ref.rs +++ b/src/repo_ref.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use std::{fs::File, io::BufReader, str::FromStr}; | 1 | use std::{fs::File, io::BufReader, str::FromStr}; |
| 2 | 2 | ||
| 3 | use anyhow::{bail, Context, Result}; | 3 | use anyhow::{bail, Context, Result}; |
| 4 | use nostr::{nips::nip19::Nip19, secp256k1::XOnlyPublicKey, FromBech32, Tag, ToBech32}; | 4 | use nostr::{nips::nip19::Nip19, FromBech32, PublicKey, Tag, ToBech32}; |
| 5 | use serde::{Deserialize, Serialize}; | 5 | use serde::{Deserialize, Serialize}; |
| 6 | 6 | ||
| 7 | #[cfg(not(test))] | 7 | #[cfg(not(test))] |
| @@ -23,7 +23,7 @@ pub struct RepoRef { | |||
| 23 | pub git_server: String, | 23 | pub git_server: String, |
| 24 | pub web: Vec<String>, | 24 | pub web: Vec<String>, |
| 25 | pub relays: Vec<String>, | 25 | pub relays: Vec<String>, |
| 26 | pub maintainers: Vec<XOnlyPublicKey>, | 26 | pub maintainers: Vec<PublicKey>, |
| 27 | // code languages and hashtags | 27 | // code languages and hashtags |
| 28 | } | 28 | } |
| 29 | 29 | ||
| @@ -78,7 +78,7 @@ impl TryFrom<nostr::Event> for RepoRef { | |||
| 78 | } | 78 | } |
| 79 | for pk in maintainers { | 79 | for pk in maintainers { |
| 80 | r.maintainers.push( | 80 | r.maintainers.push( |
| 81 | nostr_sdk::prelude::XOnlyPublicKey::from_str(&pk) | 81 | nostr_sdk::prelude::PublicKey::from_str(&pk) |
| 82 | .context(format!("cannot convert entry from maintainers tag {pk} into a valid nostr public key. it should be in hex format")) | 82 | .context(format!("cannot convert entry from maintainers tag {pk} into a valid nostr public key. it should be in hex format")) |
| 83 | .context("invalid repository event")?, | 83 | .context("invalid repository event")?, |
| 84 | ); | 84 | ); |
| @@ -200,8 +200,9 @@ pub async fn fetch( | |||
| 200 | nostr::Filter::default().kind(nostr::Kind::Custom(REPO_REF_KIND)); | 200 | nostr::Filter::default().kind(nostr::Kind::Custom(REPO_REF_KIND)); |
| 201 | match nip19 { | 201 | match nip19 { |
| 202 | Nip19::Coordinate(c) => { | 202 | Nip19::Coordinate(c) => { |
| 203 | repo_event_filter = | 203 | repo_event_filter = repo_event_filter |
| 204 | repo_event_filter.identifier(c.identifier).author(c.pubkey); | 204 | .identifier(c.identifier) |
| 205 | .author(c.public_key); | ||
| 205 | for r in c.relays { | 206 | for r in c.relays { |
| 206 | relays.push(r); | 207 | relays.push(r); |
| 207 | } | 208 | } |
| @@ -246,11 +247,11 @@ pub fn get_repo_config_from_yaml(git_repo: &Repo) -> Result<RepoConfigYaml> { | |||
| 246 | Ok(repo_config_yaml) | 247 | Ok(repo_config_yaml) |
| 247 | } | 248 | } |
| 248 | 249 | ||
| 249 | pub fn extract_pks(pk_strings: Vec<String>) -> Result<Vec<XOnlyPublicKey>> { | 250 | pub fn extract_pks(pk_strings: Vec<String>) -> Result<Vec<PublicKey>> { |
| 250 | let mut pks: Vec<XOnlyPublicKey> = vec![]; | 251 | let mut pks: Vec<PublicKey> = vec![]; |
| 251 | for s in pk_strings { | 252 | for s in pk_strings { |
| 252 | pks.push( | 253 | pks.push( |
| 253 | nostr_sdk::prelude::XOnlyPublicKey::from_bech32(s.clone()) | 254 | nostr_sdk::prelude::PublicKey::from_bech32(s.clone()) |
| 254 | .context(format!("cannot convert {s} into a valid nostr public key"))?, | 255 | .context(format!("cannot convert {s} into a valid nostr public key"))?, |
| 255 | ); | 256 | ); |
| 256 | } | 257 | } |
| @@ -259,7 +260,7 @@ pub fn extract_pks(pk_strings: Vec<String>) -> Result<Vec<XOnlyPublicKey>> { | |||
| 259 | 260 | ||
| 260 | pub fn save_repo_config_to_yaml( | 261 | pub fn save_repo_config_to_yaml( |
| 261 | git_repo: &Repo, | 262 | git_repo: &Repo, |
| 262 | maintainers: Vec<XOnlyPublicKey>, | 263 | maintainers: Vec<PublicKey>, |
| 263 | relays: Vec<String>, | 264 | relays: Vec<String>, |
| 264 | ) -> Result<()> { | 265 | ) -> Result<()> { |
| 265 | let path = git_repo.get_path()?.join("maintainers.yaml"); | 266 | let path = git_repo.get_path()?.join("maintainers.yaml"); |
diff --git a/src/sub_commands/init.rs b/src/sub_commands/init.rs index 4f098c0..56129a6 100644 --- a/src/sub_commands/init.rs +++ b/src/sub_commands/init.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use anyhow::{Context, Result}; | 1 | use anyhow::{Context, Result}; |
| 2 | use nostr::{secp256k1::XOnlyPublicKey, FromBech32, ToBech32}; | 2 | use nostr::{FromBech32, PublicKey, ToBech32}; |
| 3 | 3 | ||
| 4 | use super::send::send_events; | 4 | use super::send::send_events; |
| 5 | #[cfg(not(test))] | 5 | #[cfg(not(test))] |
| @@ -163,7 +163,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 163 | args.web.clone() | 163 | args.web.clone() |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | let maintainers: Vec<XOnlyPublicKey> = { | 166 | let maintainers: Vec<PublicKey> = { |
| 167 | let mut dont_ask = !args.other_maintainers.is_empty(); | 167 | let mut dont_ask = !args.other_maintainers.is_empty(); |
| 168 | let mut maintainers_string = if !args.other_maintainers.is_empty() { | 168 | let mut maintainers_string = if !args.other_maintainers.is_empty() { |
| 169 | [args.other_maintainers.clone()].concat().join(" ") | 169 | [args.other_maintainers.clone()].concat().join(" ") |
| @@ -185,7 +185,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 185 | }; | 185 | }; |
| 186 | // add current user if not present | 186 | // add current user if not present |
| 187 | if maintainers.iter().any(|m| { | 187 | if maintainers.iter().any(|m| { |
| 188 | if let Ok(m_pubkey) = XOnlyPublicKey::from_bech32(m) { | 188 | if let Ok(m_pubkey) = PublicKey::from_bech32(m) { |
| 189 | user_ref.public_key.eq(&m_pubkey) | 189 | user_ref.public_key.eq(&m_pubkey) |
| 190 | } else { | 190 | } else { |
| 191 | false | 191 | false |
| @@ -210,9 +210,9 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 210 | .map(std::string::ToString::to_string) | 210 | .map(std::string::ToString::to_string) |
| 211 | .collect(); | 211 | .collect(); |
| 212 | } | 212 | } |
| 213 | let mut maintainers: Vec<XOnlyPublicKey> = vec![]; | 213 | let mut maintainers: Vec<PublicKey> = vec![]; |
| 214 | for m in maintainers_string.split(' ') { | 214 | for m in maintainers_string.split(' ') { |
| 215 | if let Ok(m_pubkey) = XOnlyPublicKey::from_bech32(m) { | 215 | if let Ok(m_pubkey) = PublicKey::from_bech32(m) { |
| 216 | maintainers.push(m_pubkey); | 216 | maintainers.push(m_pubkey); |
| 217 | } else { | 217 | } else { |
| 218 | println!("not a valid set of npubs seperated by a space"); | 218 | println!("not a valid set of npubs seperated by a space"); |
diff --git a/src/sub_commands/list.rs b/src/sub_commands/list.rs index 2d81164..1a30b9b 100644 --- a/src/sub_commands/list.rs +++ b/src/sub_commands/list.rs | |||
| @@ -730,9 +730,12 @@ pub async fn find_proposal_events( | |||
| 730 | vec![ | 730 | vec![ |
| 731 | nostr::Filter::default() | 731 | nostr::Filter::default() |
| 732 | .kind(nostr::Kind::Custom(PATCH_KIND)) | 732 | .kind(nostr::Kind::Custom(PATCH_KIND)) |
| 733 | .custom_tag(nostr::Alphabet::T, vec!["root"]) | ||
| 734 | .custom_tag( | 733 | .custom_tag( |
| 735 | nostr::Alphabet::A, | 734 | nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), |
| 735 | vec!["root"], | ||
| 736 | ) | ||
| 737 | .custom_tag( | ||
| 738 | nostr::SingleLetterTag::lowercase(nostr::Alphabet::A), | ||
| 736 | repo_ref | 739 | repo_ref |
| 737 | .maintainers | 740 | .maintainers |
| 738 | .iter() | 741 | .iter() |
| @@ -742,7 +745,10 @@ pub async fn find_proposal_events( | |||
| 742 | // events | 745 | // events |
| 743 | nostr::Filter::default() | 746 | nostr::Filter::default() |
| 744 | .kind(nostr::Kind::Custom(PATCH_KIND)) | 747 | .kind(nostr::Kind::Custom(PATCH_KIND)) |
| 745 | .custom_tag(nostr::Alphabet::T, vec!["root"]) | 748 | .custom_tag( |
| 749 | nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), | ||
| 750 | vec!["root"], | ||
| 751 | ) | ||
| 746 | .reference(root_commit), | 752 | .reference(root_commit), |
| 747 | ], | 753 | ], |
| 748 | ) | 754 | ) |
diff --git a/src/sub_commands/push.rs b/src/sub_commands/push.rs index 651b250..bb50ee2 100644 --- a/src/sub_commands/push.rs +++ b/src/sub_commands/push.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use anyhow::{bail, Context, Result}; | 1 | use anyhow::{bail, Context, Result}; |
| 2 | use nostr::prelude::sha1::Hash as Sha1Hash; | 2 | use nostr_sdk::hashes::sha1::Hash as Sha1Hash; |
| 3 | 3 | ||
| 4 | #[cfg(not(test))] | 4 | #[cfg(not(test))] |
| 5 | use crate::client::Client; | 5 | use crate::client::Client; |
diff --git a/src/sub_commands/send.rs b/src/sub_commands/send.rs index 35c2c81..d9caf9b 100644 --- a/src/sub_commands/send.rs +++ b/src/sub_commands/send.rs | |||
| @@ -5,9 +5,10 @@ use console::Style; | |||
| 5 | use futures::future::join_all; | 5 | use futures::future::join_all; |
| 6 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; | 6 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; |
| 7 | use nostr::{ | 7 | use nostr::{ |
| 8 | nips::nip19::Nip19, prelude::sha1::Hash as Sha1Hash, EventBuilder, FromBech32, Marker, Tag, | 8 | nips::{nip01::Coordinate, nip19::Nip19}, |
| 9 | TagKind, UncheckedUrl, | 9 | EventBuilder, FromBech32, Marker, Tag, TagKind, UncheckedUrl, |
| 10 | }; | 10 | }; |
| 11 | use nostr_sdk::hashes::sha1::Hash as Sha1Hash; | ||
| 11 | 12 | ||
| 12 | use super::list::tag_value; | 13 | use super::list::tag_value; |
| 13 | #[cfg(not(test))] | 14 | #[cfg(not(test))] |
| @@ -541,11 +542,13 @@ pub fn generate_cover_letter_and_patch_events( | |||
| 541 | vec![ | 542 | vec![ |
| 542 | // TODO: why not tag all maintainer identifiers? | 543 | // TODO: why not tag all maintainer identifiers? |
| 543 | Tag::A { | 544 | Tag::A { |
| 544 | kind: nostr::Kind::Custom(REPO_REF_KIND), | 545 | coordinate: Coordinate { |
| 545 | public_key: *repo_ref.maintainers.first() | 546 | kind: nostr::Kind::Custom(REPO_REF_KIND), |
| 546 | .context("repo reference should always have at least one maintainer - the issuer of the repo event") | 547 | public_key: *repo_ref.maintainers.first() |
| 547 | ?, | 548 | .context("repo reference should always have at least one maintainer")?, |
| 548 | identifier: repo_ref.identifier.to_string(), | 549 | identifier: repo_ref.identifier.to_string(), |
| 550 | relays: repo_ref.relays.clone(), | ||
| 551 | }, | ||
| 549 | relay_url: repo_ref.relays.first().map(nostr::UncheckedUrl::from).clone(), | 552 | relay_url: repo_ref.relays.first().map(nostr::UncheckedUrl::from).clone(), |
| 550 | }, | 553 | }, |
| 551 | Tag::Reference(format!("{root_commit}")), | 554 | Tag::Reference(format!("{root_commit}")), |
| @@ -797,11 +800,14 @@ pub fn generate_patch_event( | |||
| 797 | [ | 800 | [ |
| 798 | vec![ | 801 | vec![ |
| 799 | Tag::A { | 802 | Tag::A { |
| 800 | kind: nostr::Kind::Custom(REPO_REF_KIND), | 803 | coordinate: Coordinate { |
| 801 | public_key: *repo_ref.maintainers.first() | 804 | kind: nostr::Kind::Custom(REPO_REF_KIND), |
| 802 | .context("repo reference should always have at least one maintainer - the issuer of the repo event") | 805 | public_key: *repo_ref.maintainers.first() |
| 803 | ?, | 806 | .context("repo reference should always have at least one maintainer - the issuer of the repo event") |
| 804 | identifier: repo_ref.identifier.to_string(), | 807 | ?, |
| 808 | identifier: repo_ref.identifier.to_string(), | ||
| 809 | relays: repo_ref.relays.clone(), | ||
| 810 | }, | ||
| 805 | relay_url: relay_hint.clone(), | 811 | relay_url: relay_hint.clone(), |
| 806 | }, | 812 | }, |
| 807 | Tag::Reference(format!("{root_commit}")), | 813 | Tag::Reference(format!("{root_commit}")), |
diff --git a/test_utils/Cargo.toml b/test_utils/Cargo.toml index 8928f67..c4e1b1a 100644 --- a/test_utils/Cargo.toml +++ b/test_utils/Cargo.toml | |||
| @@ -9,8 +9,8 @@ assert_cmd = "2.0.12" | |||
| 9 | dialoguer = "0.10.4" | 9 | dialoguer = "0.10.4" |
| 10 | directories = "5.0.1" | 10 | directories = "5.0.1" |
| 11 | git2 = "0.18.1" | 11 | git2 = "0.18.1" |
| 12 | nostr = "0.27.0" | 12 | nostr = "0.29" |
| 13 | nostr-sdk = { version = "0.27.0", features = ["blocking"] } | 13 | nostr-sdk = "0.29" |
| 14 | once_cell = "1.18.0" | 14 | once_cell = "1.18.0" |
| 15 | rand = "0.8" | 15 | rand = "0.8" |
| 16 | rexpect = { git = "https://github.com/rust-cli/rexpect.git", rev = "9eb61dd" } | 16 | rexpect = { 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 a0c67df..ad187be 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | use std::{ffi::OsStr, path::PathBuf}; | 1 | use std::{ffi::OsStr, path::PathBuf, str::FromStr}; |
| 2 | 2 | ||
| 3 | use anyhow::{bail, ensure, Context, Result}; | 3 | use anyhow::{bail, ensure, Context, Result}; |
| 4 | use dialoguer::theme::{ColorfulTheme, Theme}; | 4 | use dialoguer::theme::{ColorfulTheme, Theme}; |
| 5 | use directories::ProjectDirs; | 5 | use directories::ProjectDirs; |
| 6 | use nostr::{self, prelude::FromSkStr, Kind, Tag}; | 6 | use nostr::{self, Kind, Tag}; |
| 7 | use once_cell::sync::Lazy; | 7 | use once_cell::sync::Lazy; |
| 8 | use rexpect::session::{Options, PtySession}; | 8 | use rexpect::session::{Options, PtySession}; |
| 9 | use strip_ansi_escapes::strip_str; | 9 | use strip_ansi_escapes::strip_str; |
| @@ -26,7 +26,7 @@ pub static TEST_KEY_1_DISPLAY_NAME: &str = "bob"; | |||
| 26 | pub static TEST_KEY_1_ENCRYPTED: &str = "ncryptsec1qyq607h3cykxc3f2a44u89cdk336fptccn3fm5pf3nmf93d3c86qpunc7r6klwcn6lyszjy72wxwqq9aljg4pm6atvjrds9e248yhv76xfnt464265kgnjsvg8rlg06wg4sp9uljzfpu8zuaztcvfn2j8ggdrg8mldh850cy75efsyqqansert9wqmn4e6khpgvfz7h5le9"; | 26 | pub static TEST_KEY_1_ENCRYPTED: &str = "ncryptsec1qyq607h3cykxc3f2a44u89cdk336fptccn3fm5pf3nmf93d3c86qpunc7r6klwcn6lyszjy72wxwqq9aljg4pm6atvjrds9e248yhv76xfnt464265kgnjsvg8rlg06wg4sp9uljzfpu8zuaztcvfn2j8ggdrg8mldh850cy75efsyqqansert9wqmn4e6khpgvfz7h5le9"; |
| 27 | pub static TEST_KEY_1_ENCRYPTED_WEAK: &str = "ncryptsec1qy8ke0tjqnn8wt3w6lnc86c27ry3qrptxctjfcgruryxy0at238kwyjwsswd7z88thysruzw3awlrsxjvw5uptcd7vt70ft9rtkx00m8cgy3khm4hxa5d2gfnc6athnfruy2eyl6pkas8k34jg85z7xjqqadzfzh9rp0fzxqtw0tvxksac3n8yc98uksvuf93e0lcvqy8j6"; | 27 | pub static TEST_KEY_1_ENCRYPTED_WEAK: &str = "ncryptsec1qy8ke0tjqnn8wt3w6lnc86c27ry3qrptxctjfcgruryxy0at238kwyjwsswd7z88thysruzw3awlrsxjvw5uptcd7vt70ft9rtkx00m8cgy3khm4hxa5d2gfnc6athnfruy2eyl6pkas8k34jg85z7xjqqadzfzh9rp0fzxqtw0tvxksac3n8yc98uksvuf93e0lcvqy8j6"; |
| 28 | pub static TEST_KEY_1_KEYS: Lazy<nostr::Keys> = | 28 | pub static TEST_KEY_1_KEYS: Lazy<nostr::Keys> = |
| 29 | Lazy::new(|| nostr::Keys::from_sk_str(TEST_KEY_1_NSEC).unwrap()); | 29 | Lazy::new(|| nostr::Keys::from_str(TEST_KEY_1_NSEC).unwrap()); |
| 30 | 30 | ||
| 31 | pub fn generate_test_key_1_metadata_event(name: &str) -> nostr::Event { | 31 | pub fn generate_test_key_1_metadata_event(name: &str) -> nostr::Event { |
| 32 | nostr::event::EventBuilder::metadata(&nostr::Metadata::new().name(name)) | 32 | nostr::event::EventBuilder::metadata(&nostr::Metadata::new().name(name)) |
| @@ -95,7 +95,7 @@ pub static TEST_KEY_2_NPUB: &str = | |||
| 95 | pub static TEST_KEY_2_DISPLAY_NAME: &str = "carole"; | 95 | pub static TEST_KEY_2_DISPLAY_NAME: &str = "carole"; |
| 96 | pub static TEST_KEY_2_ENCRYPTED: &str = "...2"; | 96 | pub static TEST_KEY_2_ENCRYPTED: &str = "...2"; |
| 97 | pub static TEST_KEY_2_KEYS: Lazy<nostr::Keys> = | 97 | pub static TEST_KEY_2_KEYS: Lazy<nostr::Keys> = |
| 98 | Lazy::new(|| nostr::Keys::from_sk_str(TEST_KEY_2_NSEC).unwrap()); | 98 | Lazy::new(|| nostr::Keys::from_str(TEST_KEY_2_NSEC).unwrap()); |
| 99 | 99 | ||
| 100 | pub fn generate_test_key_2_metadata_event(name: &str) -> nostr::Event { | 100 | pub fn generate_test_key_2_metadata_event(name: &str) -> nostr::Event { |
| 101 | nostr::event::EventBuilder::metadata(&nostr::Metadata::new().name(name)) | 101 | nostr::event::EventBuilder::metadata(&nostr::Metadata::new().name(name)) |
diff --git a/tests/list.rs b/tests/list.rs index 4f55645..61c2201 100644 --- a/tests/list.rs +++ b/tests/list.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use anyhow::Result; | 1 | use anyhow::Result; |
| 2 | use futures::join; | 2 | use futures::join; |
| 3 | use nostr_sdk::client::blocking::Client; | 3 | use nostr_sdk::client::Client; |
| 4 | use serial_test::serial; | 4 | use serial_test::serial; |
| 5 | use test_utils::{git::GitTestRepo, relay::Relay, *}; | 5 | use test_utils::{git::GitTestRepo, relay::Relay, *}; |
| 6 | 6 | ||
| @@ -23,6 +23,7 @@ fn cli_tester_create_proposals() -> Result<GitTestRepo> { | |||
| 23 | Some((PROPOSAL_TITLE_1, "proposal a description")), | 23 | Some((PROPOSAL_TITLE_1, "proposal a description")), |
| 24 | None, | 24 | None, |
| 25 | )?; | 25 | )?; |
| 26 | std::thread::sleep(std::time::Duration::from_millis(1000)); | ||
| 26 | cli_tester_create_proposal( | 27 | cli_tester_create_proposal( |
| 27 | &git_repo, | 28 | &git_repo, |
| 28 | FEATURE_BRANCH_NAME_2, | 29 | FEATURE_BRANCH_NAME_2, |
| @@ -30,6 +31,7 @@ fn cli_tester_create_proposals() -> Result<GitTestRepo> { | |||
| 30 | Some((PROPOSAL_TITLE_2, "proposal b description")), | 31 | Some((PROPOSAL_TITLE_2, "proposal b description")), |
| 31 | None, | 32 | None, |
| 32 | )?; | 33 | )?; |
| 34 | std::thread::sleep(std::time::Duration::from_millis(1000)); | ||
| 33 | cli_tester_create_proposal( | 35 | cli_tester_create_proposal( |
| 34 | &git_repo, | 36 | &git_repo, |
| 35 | FEATURE_BRANCH_NAME_3, | 37 | FEATURE_BRANCH_NAME_3, |
| @@ -72,7 +74,7 @@ fn cli_tester_create_proposal( | |||
| 72 | in_reply_to: Option<String>, | 74 | in_reply_to: Option<String>, |
| 73 | ) -> Result<()> { | 75 | ) -> Result<()> { |
| 74 | create_and_populate_branch(test_repo, branch_name, prefix, false)?; | 76 | create_and_populate_branch(test_repo, branch_name, prefix, false)?; |
| 75 | 77 | std::thread::sleep(std::time::Duration::from_millis(1000)); | |
| 76 | if let Some(in_reply_to) = in_reply_to { | 78 | if let Some(in_reply_to) = in_reply_to { |
| 77 | let mut p = CliTester::new_from_dir( | 79 | let mut p = CliTester::new_from_dir( |
| 78 | &test_repo.dir, | 80 | &test_repo.dir, |
| @@ -190,7 +192,7 @@ mod cannot_find_repo_event { | |||
| 190 | input.succeeds_with( | 192 | input.succeeds_with( |
| 191 | &Coordinate { | 193 | &Coordinate { |
| 192 | kind: nostr::Kind::Custom(REPOSITORY_KIND), | 194 | kind: nostr::Kind::Custom(REPOSITORY_KIND), |
| 193 | pubkey: TEST_KEY_1_KEYS.public_key(), | 195 | public_key: TEST_KEY_1_KEYS.public_key(), |
| 194 | identifier: repo_event.identifier().unwrap().to_string(), | 196 | identifier: repo_event.identifier().unwrap().to_string(), |
| 195 | relays: vec!["ws://localhost:8056".to_string()], | 197 | relays: vec!["ws://localhost:8056".to_string()], |
| 196 | } | 198 | } |
| @@ -489,7 +491,7 @@ mod when_main_branch_is_uptodate { | |||
| 489 | "checked out proposal as '{FEATURE_BRANCH_NAME_3}' branch\r\n" | 491 | "checked out proposal as '{FEATURE_BRANCH_NAME_3}' branch\r\n" |
| 490 | ))?; | 492 | ))?; |
| 491 | p.expect_end()?; | 493 | p.expect_end()?; |
| 492 | 494 | println!("blablagothere"); | |
| 493 | for p in [51, 52, 53, 55, 56] { | 495 | for p in [51, 52, 53, 55, 56] { |
| 494 | relay::shutdown_relay(8000 + p)?; | 496 | relay::shutdown_relay(8000 + p)?; |
| 495 | } | 497 | } |
| @@ -726,6 +728,7 @@ mod when_main_branch_is_uptodate { | |||
| 726 | 728 | ||
| 727 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | 729 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { |
| 728 | let originating_repo = cli_tester_create_proposals()?; | 730 | let originating_repo = cli_tester_create_proposals()?; |
| 731 | std::thread::sleep(std::time::Duration::from_millis(1000)); | ||
| 729 | cli_tester_create_proposal( | 732 | cli_tester_create_proposal( |
| 730 | &originating_repo, | 733 | &originating_repo, |
| 731 | FEATURE_BRANCH_NAME_4, | 734 | FEATURE_BRANCH_NAME_4, |
| @@ -1589,6 +1592,8 @@ mod when_main_branch_is_uptodate { | |||
| 1589 | mod when_latest_revision_rebases_branch { | 1592 | mod when_latest_revision_rebases_branch { |
| 1590 | use std::time::Duration; | 1593 | use std::time::Duration; |
| 1591 | 1594 | ||
| 1595 | use tokio::{runtime::Handle, task::JoinHandle}; | ||
| 1596 | |||
| 1592 | use super::*; | 1597 | use super::*; |
| 1593 | 1598 | ||
| 1594 | async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> { | 1599 | async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> { |
| @@ -1609,23 +1614,28 @@ mod when_main_branch_is_uptodate { | |||
| 1609 | r55.events.push(generate_test_key_1_metadata_event("fred")); | 1614 | r55.events.push(generate_test_key_1_metadata_event("fred")); |
| 1610 | r55.events.push(generate_test_key_1_relay_list_event()); | 1615 | r55.events.push(generate_test_key_1_relay_list_event()); |
| 1611 | 1616 | ||
| 1612 | let cli_tester_handle = std::thread::spawn( | 1617 | let cli_tester_handle: JoinHandle<Result<(GitTestRepo, GitTestRepo)>> = |
| 1613 | move || -> Result<(GitTestRepo, GitTestRepo)> { | 1618 | tokio::task::spawn_blocking(move || { |
| 1614 | // create 3 proposals | 1619 | // create 3 proposals |
| 1615 | let _ = cli_tester_create_proposals()?; | 1620 | let _ = cli_tester_create_proposals()?; |
| 1616 | // get proposal id of first | 1621 | // get proposal id of first |
| 1617 | let client = Client::new(&nostr::Keys::generate()); | 1622 | // get proposal id of first |
| 1618 | client.add_relay("ws://localhost:8055")?; | 1623 | let client = Client::default(); |
| 1619 | client.connect_relay("ws://localhost:8055")?; | 1624 | Handle::current().block_on(client.add_relay("ws://localhost:8055"))?; |
| 1620 | let proposals = client.get_events_of( | 1625 | Handle::current() |
| 1626 | .block_on(client.connect_relay("ws://localhost:8055"))?; | ||
| 1627 | let proposals = Handle::current().block_on(client.get_events_of( | ||
| 1621 | vec![ | 1628 | vec![ |
| 1622 | nostr::Filter::default() | 1629 | nostr::Filter::default() |
| 1623 | .kind(nostr::Kind::Custom(PATCH_KIND)) | 1630 | .kind(nostr::Kind::Custom(PATCH_KIND)) |
| 1624 | .custom_tag(nostr::Alphabet::T, vec!["root"]), | 1631 | .custom_tag( |
| 1625 | ], | 1632 | nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), |
| 1633 | vec!["root"], | ||
| 1634 | ), | ||
| 1635 | ], | ||
| 1626 | Some(Duration::from_millis(500)), | 1636 | Some(Duration::from_millis(500)), |
| 1627 | )?; | 1637 | ))?; |
| 1628 | client.disconnect()?; | 1638 | Handle::current().block_on(client.disconnect())?; |
| 1629 | 1639 | ||
| 1630 | let proposal_1_id = proposals | 1640 | let proposal_1_id = proposals |
| 1631 | .iter() | 1641 | .iter() |
| @@ -1699,8 +1709,7 @@ mod when_main_branch_is_uptodate { | |||
| 1699 | relay::shutdown_relay(8000 + p)?; | 1709 | relay::shutdown_relay(8000 + p)?; |
| 1700 | } | 1710 | } |
| 1701 | Ok((second_originating_repo, test_repo)) | 1711 | Ok((second_originating_repo, test_repo)) |
| 1702 | }, | 1712 | }); |
| 1703 | ); | ||
| 1704 | 1713 | ||
| 1705 | // launch relay | 1714 | // launch relay |
| 1706 | let _ = join!( | 1715 | let _ = join!( |
| @@ -1710,7 +1719,7 @@ mod when_main_branch_is_uptodate { | |||
| 1710 | r55.listen_until_close(), | 1719 | r55.listen_until_close(), |
| 1711 | r56.listen_until_close(), | 1720 | r56.listen_until_close(), |
| 1712 | ); | 1721 | ); |
| 1713 | let res = cli_tester_handle.join().unwrap()?; | 1722 | let res = cli_tester_handle.await??; |
| 1714 | 1723 | ||
| 1715 | Ok(res) | 1724 | Ok(res) |
| 1716 | } | 1725 | } |
| @@ -1737,96 +1746,105 @@ mod when_main_branch_is_uptodate { | |||
| 1737 | r55.events.push(generate_test_key_1_metadata_event("fred")); | 1746 | r55.events.push(generate_test_key_1_metadata_event("fred")); |
| 1738 | r55.events.push(generate_test_key_1_relay_list_event()); | 1747 | r55.events.push(generate_test_key_1_relay_list_event()); |
| 1739 | 1748 | ||
| 1740 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | 1749 | let cli_tester_handle: JoinHandle<Result<()>> = tokio::task::spawn_blocking( |
| 1741 | // create 3 proposals | 1750 | move || { |
| 1742 | let _ = cli_tester_create_proposals()?; | 1751 | // create 3 proposals |
| 1743 | // get proposal id of first | 1752 | let _ = cli_tester_create_proposals()?; |
| 1744 | let client = Client::new(&nostr::Keys::generate()); | 1753 | // get proposal id of first |
| 1745 | client.add_relay("ws://localhost:8055")?; | 1754 | let client = Client::default(); |
| 1746 | client.connect_relay("ws://localhost:8055")?; | 1755 | Handle::current() |
| 1747 | let proposals = client.get_events_of( | 1756 | .block_on(client.add_relay("ws://localhost:8055"))?; |
| 1748 | vec![ | 1757 | Handle::current() |
| 1749 | nostr::Filter::default() | 1758 | .block_on(client.connect_relay("ws://localhost:8055"))?; |
| 1750 | .kind(nostr::Kind::Custom(PATCH_KIND)) | 1759 | let proposals = |
| 1751 | .custom_tag(nostr::Alphabet::T, vec!["root"]), | 1760 | Handle::current().block_on(client.get_events_of( |
| 1752 | ], | 1761 | vec![ |
| 1753 | Some(Duration::from_millis(500)), | 1762 | nostr::Filter::default() |
| 1754 | )?; | 1763 | .kind(nostr::Kind::Custom(PATCH_KIND)) |
| 1755 | client.disconnect()?; | 1764 | .custom_tag( |
| 1756 | 1765 | nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), | |
| 1757 | let proposal_1_id = proposals | 1766 | vec!["root"], |
| 1758 | .iter() | 1767 | ), |
| 1759 | .find(|e| { | 1768 | ], |
| 1760 | e.tags | 1769 | Some(Duration::from_millis(500)), |
| 1761 | .iter() | 1770 | ))?; |
| 1762 | .any(|t| t.as_vec()[1].eq(&FEATURE_BRANCH_NAME_1)) | 1771 | Handle::current().block_on(client.disconnect())?; |
| 1763 | }) | 1772 | |
| 1764 | .unwrap() | 1773 | let proposal_1_id = proposals |
| 1765 | .id; | 1774 | .iter() |
| 1766 | // recreate proposal 1 on top of a another commit (like a rebase on top | 1775 | .find(|e| { |
| 1767 | // of one extra commit) | 1776 | e.tags |
| 1768 | let second_originating_repo = GitTestRepo::default(); | 1777 | .iter() |
| 1769 | second_originating_repo.populate()?; | 1778 | .any(|t| t.as_vec()[1].eq(&FEATURE_BRANCH_NAME_1)) |
| 1770 | std::fs::write( | 1779 | }) |
| 1771 | second_originating_repo.dir.join("amazing.md"), | 1780 | .unwrap() |
| 1772 | "some content", | 1781 | .id; |
| 1773 | )?; | 1782 | // recreate proposal 1 on top of a another commit (like a rebase on |
| 1774 | second_originating_repo | 1783 | // top of one extra commit) |
| 1775 | .stage_and_commit("commit for rebasing on top of")?; | 1784 | let second_originating_repo = GitTestRepo::default(); |
| 1776 | cli_tester_create_proposal( | 1785 | second_originating_repo.populate()?; |
| 1777 | &second_originating_repo, | 1786 | std::fs::write( |
| 1778 | FEATURE_BRANCH_NAME_1, | 1787 | second_originating_repo.dir.join("amazing.md"), |
| 1779 | "a", | 1788 | "some content", |
| 1780 | Some((PROPOSAL_TITLE_1, "proposal a description")), | 1789 | )?; |
| 1781 | Some(proposal_1_id.to_string()), | 1790 | second_originating_repo |
| 1782 | )?; | 1791 | .stage_and_commit("commit for rebasing on top of")?; |
| 1783 | 1792 | cli_tester_create_proposal( | |
| 1784 | // pretend we have downloaded the origianl version of the first proposal | 1793 | &second_originating_repo, |
| 1785 | let test_repo = GitTestRepo::default(); | 1794 | FEATURE_BRANCH_NAME_1, |
| 1786 | test_repo.populate()?; | 1795 | "a", |
| 1787 | create_and_populate_branch( | 1796 | Some((PROPOSAL_TITLE_1, "proposal a description")), |
| 1788 | &test_repo, | 1797 | Some(proposal_1_id.to_string()), |
| 1789 | FEATURE_BRANCH_NAME_1, | 1798 | )?; |
| 1790 | "a", | 1799 | |
| 1791 | false, | 1800 | // pretend we have downloaded the origianl version of the first |
| 1792 | )?; | 1801 | // proposal |
| 1793 | // pretend we have pulled the updated main branch | 1802 | let test_repo = GitTestRepo::default(); |
| 1794 | test_repo.checkout("main")?; | 1803 | test_repo.populate()?; |
| 1795 | std::fs::write(test_repo.dir.join("amazing.md"), "some content")?; | 1804 | create_and_populate_branch( |
| 1796 | test_repo.stage_and_commit("commit for rebasing on top of")?; | 1805 | &test_repo, |
| 1797 | 1806 | FEATURE_BRANCH_NAME_1, | |
| 1798 | let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); | 1807 | "a", |
| 1799 | p.expect("finding proposals...\r\n")?; | 1808 | false, |
| 1800 | let mut c = p.expect_choice( | 1809 | )?; |
| 1801 | "all proposals", | 1810 | // pretend we have pulled the updated main branch |
| 1802 | vec![ | 1811 | test_repo.checkout("main")?; |
| 1803 | format!("\"{PROPOSAL_TITLE_3}\""), | 1812 | std::fs::write(test_repo.dir.join("amazing.md"), "some content")?; |
| 1804 | format!("\"{PROPOSAL_TITLE_2}\""), | 1813 | test_repo.stage_and_commit("commit for rebasing on top of")?; |
| 1805 | format!("\"{PROPOSAL_TITLE_1}\""), | 1814 | |
| 1806 | ], | 1815 | let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); |
| 1807 | )?; | 1816 | p.expect("finding proposals...\r\n")?; |
| 1808 | c.succeeds_with(2, true, None)?; | 1817 | let mut c = p.expect_choice( |
| 1809 | p.expect("finding commits...\r\n")?; | 1818 | "all proposals", |
| 1810 | p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?; | 1819 | vec![ |
| 1811 | let mut c = p.expect_choice( | 1820 | format!("\"{PROPOSAL_TITLE_3}\""), |
| 1812 | "", | 1821 | format!("\"{PROPOSAL_TITLE_2}\""), |
| 1813 | vec![ | 1822 | format!("\"{PROPOSAL_TITLE_1}\""), |
| 1814 | format!("checkout and overwrite existing proposal branch"), | 1823 | ], |
| 1815 | format!("checkout existing outdated proposal branch"), | 1824 | )?; |
| 1816 | format!("apply to current branch with `git am`"), | 1825 | c.succeeds_with(2, true, None)?; |
| 1817 | format!("download to ./patches"), | 1826 | p.expect("finding commits...\r\n")?; |
| 1818 | format!("back"), | 1827 | p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?; |
| 1819 | ], | 1828 | let mut c = p.expect_choice( |
| 1820 | )?; | 1829 | "", |
| 1821 | c.succeeds_with(0, false, Some(0))?; | 1830 | vec![ |
| 1822 | p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?; | 1831 | format!("checkout and overwrite existing proposal branch"), |
| 1823 | p.expect_end()?; | 1832 | format!("checkout existing outdated proposal branch"), |
| 1824 | 1833 | format!("apply to current branch with `git am`"), | |
| 1825 | for p in [51, 52, 53, 55, 56] { | 1834 | format!("download to ./patches"), |
| 1826 | relay::shutdown_relay(8000 + p)?; | 1835 | format!("back"), |
| 1827 | } | 1836 | ], |
| 1828 | Ok(()) | 1837 | )?; |
| 1829 | }); | 1838 | c.succeeds_with(0, false, Some(0))?; |
| 1839 | p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?; | ||
| 1840 | p.expect_end()?; | ||
| 1841 | |||
| 1842 | for p in [51, 52, 53, 55, 56] { | ||
| 1843 | relay::shutdown_relay(8000 + p)?; | ||
| 1844 | } | ||
| 1845 | Ok(()) | ||
| 1846 | }, | ||
| 1847 | ); | ||
| 1830 | 1848 | ||
| 1831 | // launch relay | 1849 | // launch relay |
| 1832 | let _ = join!( | 1850 | let _ = join!( |
| @@ -1836,7 +1854,7 @@ mod when_main_branch_is_uptodate { | |||
| 1836 | r55.listen_until_close(), | 1854 | r55.listen_until_close(), |
| 1837 | r56.listen_until_close(), | 1855 | r56.listen_until_close(), |
| 1838 | ); | 1856 | ); |
| 1839 | cli_tester_handle.join().unwrap()?; | 1857 | cli_tester_handle.await??; |
| 1840 | println!("{:?}", r55.events); | 1858 | println!("{:?}", r55.events); |
| 1841 | Ok(()) | 1859 | Ok(()) |
| 1842 | } | 1860 | } |
diff --git a/tests/pull.rs b/tests/pull.rs index 50dddbf..bf132e7 100644 --- a/tests/pull.rs +++ b/tests/pull.rs | |||
| @@ -712,7 +712,8 @@ mod when_branch_is_checked_out { | |||
| 712 | mod when_latest_event_rebases_branch { | 712 | mod when_latest_event_rebases_branch { |
| 713 | use std::time::Duration; | 713 | use std::time::Duration; |
| 714 | 714 | ||
| 715 | use nostr_sdk::blocking::Client; | 715 | use nostr_sdk::Client; |
| 716 | use tokio::{runtime::Handle, task::JoinHandle}; | ||
| 716 | 717 | ||
| 717 | use super::*; | 718 | use super::*; |
| 718 | 719 | ||
| @@ -734,23 +735,26 @@ mod when_branch_is_checked_out { | |||
| 734 | r55.events.push(generate_test_key_1_metadata_event("fred")); | 735 | r55.events.push(generate_test_key_1_metadata_event("fred")); |
| 735 | r55.events.push(generate_test_key_1_relay_list_event()); | 736 | r55.events.push(generate_test_key_1_relay_list_event()); |
| 736 | 737 | ||
| 737 | let cli_tester_handle = | 738 | let cli_tester_handle: JoinHandle<Result<(GitTestRepo, GitTestRepo)>> = |
| 738 | std::thread::spawn(move || -> Result<(GitTestRepo, GitTestRepo)> { | 739 | tokio::task::spawn_blocking(move || { |
| 739 | // create 3 proposals | 740 | // create 3 proposals |
| 740 | let _ = cli_tester_create_proposals()?; | 741 | let _ = cli_tester_create_proposals()?; |
| 741 | // get proposal id of first | 742 | // get proposal id of first |
| 742 | let client = Client::new(&nostr::Keys::generate()); | 743 | let client = Client::default(); |
| 743 | client.add_relay("ws://localhost:8055")?; | 744 | Handle::current().block_on(client.add_relay("ws://localhost:8055"))?; |
| 744 | client.connect_relay("ws://localhost:8055")?; | 745 | Handle::current().block_on(client.connect_relay("ws://localhost:8055"))?; |
| 745 | let proposals = client.get_events_of( | 746 | let proposals = Handle::current().block_on(client.get_events_of( |
| 746 | vec![ | 747 | vec![ |
| 747 | nostr::Filter::default() | 748 | nostr::Filter::default() |
| 748 | .kind(nostr::Kind::Custom(PATCH_KIND)) | 749 | .kind(nostr::Kind::Custom(PATCH_KIND)) |
| 749 | .custom_tag(nostr::Alphabet::T, vec!["root"]), | 750 | .custom_tag( |
| 750 | ], | 751 | nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), |
| 752 | vec!["root"], | ||
| 753 | ), | ||
| 754 | ], | ||
| 751 | Some(Duration::from_millis(500)), | 755 | Some(Duration::from_millis(500)), |
| 752 | )?; | 756 | ))?; |
| 753 | client.disconnect()?; | 757 | Handle::current().block_on(client.disconnect())?; |
| 754 | 758 | ||
| 755 | let proposal_1_id = proposals | 759 | let proposal_1_id = proposals |
| 756 | .iter() | 760 | .iter() |
| @@ -805,7 +809,7 @@ mod when_branch_is_checked_out { | |||
| 805 | r55.listen_until_close(), | 809 | r55.listen_until_close(), |
| 806 | r56.listen_until_close(), | 810 | r56.listen_until_close(), |
| 807 | ); | 811 | ); |
| 808 | let res = cli_tester_handle.join().unwrap()?; | 812 | let res = cli_tester_handle.await??; |
| 809 | 813 | ||
| 810 | Ok(res) | 814 | Ok(res) |
| 811 | } | 815 | } |
| @@ -832,69 +836,75 @@ mod when_branch_is_checked_out { | |||
| 832 | r55.events.push(generate_test_key_1_metadata_event("fred")); | 836 | r55.events.push(generate_test_key_1_metadata_event("fred")); |
| 833 | r55.events.push(generate_test_key_1_relay_list_event()); | 837 | r55.events.push(generate_test_key_1_relay_list_event()); |
| 834 | 838 | ||
| 835 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | 839 | let cli_tester_handle: JoinHandle<Result<()>> = tokio::task::spawn_blocking( |
| 836 | // create 3 proposals | 840 | move || { |
| 837 | let _ = cli_tester_create_proposals()?; | 841 | // create 3 proposals |
| 838 | // get proposal id of first | 842 | let _ = cli_tester_create_proposals()?; |
| 839 | let client = Client::new(&nostr::Keys::generate()); | 843 | // get proposal id of first |
| 840 | client.add_relay("ws://localhost:8055")?; | 844 | let client = Client::default(); |
| 841 | client.connect_relay("ws://localhost:8055")?; | 845 | Handle::current().block_on(client.add_relay("ws://localhost:8055"))?; |
| 842 | let proposals = client.get_events_of( | 846 | Handle::current().block_on(client.connect_relay("ws://localhost:8055"))?; |
| 843 | vec![ | 847 | let proposals = Handle::current().block_on(client.get_events_of( |
| 844 | nostr::Filter::default() | 848 | vec![ |
| 845 | .kind(nostr::Kind::Custom(PATCH_KIND)) | 849 | nostr::Filter::default() |
| 846 | .custom_tag(nostr::Alphabet::T, vec!["root"]), | 850 | .kind(nostr::Kind::Custom(PATCH_KIND)) |
| 847 | ], | 851 | .custom_tag( |
| 848 | Some(Duration::from_millis(500)), | 852 | nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), |
| 849 | )?; | 853 | vec!["root"], |
| 850 | client.disconnect()?; | 854 | ), |
| 851 | 855 | ], | |
| 852 | let proposal_1_id = proposals | 856 | Some(Duration::from_millis(500)), |
| 853 | .iter() | 857 | ))?; |
| 854 | .find(|e| { | 858 | Handle::current().block_on(client.disconnect())?; |
| 855 | e.tags | 859 | |
| 856 | .iter() | 860 | let proposal_1_id = proposals |
| 857 | .any(|t| t.as_vec()[1].eq(&FEATURE_BRANCH_NAME_1)) | 861 | .iter() |
| 858 | }) | 862 | .find(|e| { |
| 859 | .unwrap() | 863 | e.tags |
| 860 | .id; | 864 | .iter() |
| 861 | // recreate proposal 1 on top of a another commit (like a rebase on top | 865 | .any(|t| t.as_vec()[1].eq(&FEATURE_BRANCH_NAME_1)) |
| 862 | // of one extra commit) | 866 | }) |
| 863 | let second_originating_repo = GitTestRepo::default(); | 867 | .unwrap() |
| 864 | second_originating_repo.populate()?; | 868 | .id; |
| 865 | std::fs::write( | 869 | // recreate proposal 1 on top of a another commit (like a rebase on top |
| 866 | second_originating_repo.dir.join("amazing.md"), | 870 | // of one extra commit) |
| 867 | "some content", | 871 | let second_originating_repo = GitTestRepo::default(); |
| 868 | )?; | 872 | second_originating_repo.populate()?; |
| 869 | second_originating_repo.stage_and_commit("commit for rebasing on top of")?; | 873 | std::fs::write( |
| 870 | cli_tester_create_proposal( | 874 | second_originating_repo.dir.join("amazing.md"), |
| 871 | &second_originating_repo, | 875 | "some content", |
| 872 | FEATURE_BRANCH_NAME_1, | 876 | )?; |
| 873 | "a", | 877 | second_originating_repo |
| 874 | Some((PROPOSAL_TITLE_1, "proposal a description")), | 878 | .stage_and_commit("commit for rebasing on top of")?; |
| 875 | Some(proposal_1_id.to_string()), | 879 | cli_tester_create_proposal( |
| 876 | )?; | 880 | &second_originating_repo, |
| 877 | 881 | FEATURE_BRANCH_NAME_1, | |
| 878 | // pretend we have downloaded the origianl version of the first proposal | 882 | "a", |
| 879 | let test_repo = GitTestRepo::default(); | 883 | Some((PROPOSAL_TITLE_1, "proposal a description")), |
| 880 | test_repo.populate()?; | 884 | Some(proposal_1_id.to_string()), |
| 881 | create_and_populate_branch(&test_repo, FEATURE_BRANCH_NAME_1, "a", false)?; | 885 | )?; |
| 882 | // pretend we have pulled the updated main branch | 886 | |
| 883 | test_repo.checkout("main")?; | 887 | // pretend we have downloaded the origianl version of the first proposal |
| 884 | std::fs::write(test_repo.dir.join("amazing.md"), "some content")?; | 888 | let test_repo = GitTestRepo::default(); |
| 885 | test_repo.stage_and_commit("commit for rebasing on top of")?; | 889 | test_repo.populate()?; |
| 886 | test_repo.checkout(FEATURE_BRANCH_NAME_1)?; | 890 | create_and_populate_branch(&test_repo, FEATURE_BRANCH_NAME_1, "a", false)?; |
| 891 | // pretend we have pulled the updated main branch | ||
| 892 | test_repo.checkout("main")?; | ||
| 893 | std::fs::write(test_repo.dir.join("amazing.md"), "some content")?; | ||
| 894 | test_repo.stage_and_commit("commit for rebasing on top of")?; | ||
| 895 | test_repo.checkout(FEATURE_BRANCH_NAME_1)?; | ||
| 887 | 896 | ||
| 888 | let mut p = CliTester::new_from_dir(&test_repo.dir, ["pull"]); | 897 | let mut p = CliTester::new_from_dir(&test_repo.dir, ["pull"]); |
| 889 | p.expect("finding proposal root event...\r\n")?; | 898 | p.expect("finding proposal root event...\r\n")?; |
| 890 | p.expect("found proposal root event. finding commits...\r\n")?; | 899 | p.expect("found proposal root event. finding commits...\r\n")?; |
| 891 | p.expect_end_with("pulled new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?; | 900 | p.expect_end_with("pulled new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?; |
| 892 | 901 | ||
| 893 | for p in [51, 52, 53, 55, 56] { | 902 | for p in [51, 52, 53, 55, 56] { |
| 894 | relay::shutdown_relay(8000 + p)?; | 903 | relay::shutdown_relay(8000 + p)?; |
| 895 | } | 904 | } |
| 896 | Ok(()) | 905 | Ok(()) |
| 897 | }); | 906 | }, |
| 907 | ); | ||
| 898 | 908 | ||
| 899 | // launch relay | 909 | // launch relay |
| 900 | let _ = join!( | 910 | let _ = join!( |
| @@ -904,7 +914,7 @@ mod when_branch_is_checked_out { | |||
| 904 | r55.listen_until_close(), | 914 | r55.listen_until_close(), |
| 905 | r56.listen_until_close(), | 915 | r56.listen_until_close(), |
| 906 | ); | 916 | ); |
| 907 | cli_tester_handle.join().unwrap()?; | 917 | cli_tester_handle.await??; |
| 908 | println!("{:?}", r55.events); | 918 | println!("{:?}", r55.events); |
| 909 | Ok(()) | 919 | Ok(()) |
| 910 | } | 920 | } |