this repo has no description

Set title and description of created pr

+191 -146
+151 -123
Cargo.lock
··· 33 33 ] 34 34 35 35 [[package]] 36 - name = "anstream" 37 - version = "0.6.19" 38 - source = "registry+https://github.com/rust-lang/crates.io-index" 39 - checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" 40 - dependencies = [ 41 - "anstyle", 42 - "anstyle-parse", 43 - "anstyle-query", 44 - "anstyle-wincon", 45 - "colorchoice", 46 - "is_terminal_polyfill", 47 - "utf8parse", 48 - ] 49 - 50 - [[package]] 51 - name = "anstyle" 52 - version = "1.0.11" 53 - source = "registry+https://github.com/rust-lang/crates.io-index" 54 - checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" 55 - 56 - [[package]] 57 - name = "anstyle-parse" 58 - version = "0.2.7" 59 - source = "registry+https://github.com/rust-lang/crates.io-index" 60 - checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 61 - dependencies = [ 62 - "utf8parse", 63 - ] 64 - 65 - [[package]] 66 - name = "anstyle-query" 67 - version = "1.1.3" 68 - source = "registry+https://github.com/rust-lang/crates.io-index" 69 - checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" 70 - dependencies = [ 71 - "windows-sys 0.59.0", 72 - ] 73 - 74 - [[package]] 75 - name = "anstyle-wincon" 76 - version = "3.0.9" 77 - source = "registry+https://github.com/rust-lang/crates.io-index" 78 - checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" 79 - dependencies = [ 80 - "anstyle", 81 - "once_cell_polyfill", 82 - "windows-sys 0.59.0", 83 - ] 84 - 85 - [[package]] 86 36 name = "arc-swap" 87 37 version = "1.7.1" 88 38 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 175 125 ] 176 126 177 127 [[package]] 178 - name = "clap" 179 - version = "4.5.41" 180 - source = "registry+https://github.com/rust-lang/crates.io-index" 181 - checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" 182 - dependencies = [ 183 - "clap_builder", 184 - "clap_derive", 185 - ] 186 - 187 - [[package]] 188 - name = "clap_builder" 189 - version = "4.5.41" 190 - source = "registry+https://github.com/rust-lang/crates.io-index" 191 - checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" 192 - dependencies = [ 193 - "anstream", 194 - "anstyle", 195 - "clap_lex", 196 - "strsim", 197 - ] 198 - 199 - [[package]] 200 - name = "clap_derive" 201 - version = "4.5.41" 202 - source = "registry+https://github.com/rust-lang/crates.io-index" 203 - checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" 204 - dependencies = [ 205 - "heck", 206 - "proc-macro2", 207 - "quote", 208 - "syn", 209 - ] 210 - 211 - [[package]] 212 - name = "clap_lex" 213 - version = "0.7.5" 214 - source = "registry+https://github.com/rust-lang/crates.io-index" 215 - checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" 216 - 217 - [[package]] 218 128 name = "color-eyre" 219 129 version = "0.6.5" 220 130 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 242 152 ] 243 153 244 154 [[package]] 245 - name = "colorchoice" 246 - version = "1.0.4" 155 + name = "console" 156 + version = "0.15.11" 247 157 source = "registry+https://github.com/rust-lang/crates.io-index" 248 - checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 158 + checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" 159 + dependencies = [ 160 + "encode_unicode", 161 + "libc", 162 + "once_cell", 163 + "unicode-width", 164 + "windows-sys 0.59.0", 165 + ] 249 166 250 167 [[package]] 251 168 name = "core-foundation" ··· 273 190 ] 274 191 275 192 [[package]] 193 + name = "dialoguer" 194 + version = "0.11.0" 195 + source = "registry+https://github.com/rust-lang/crates.io-index" 196 + checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" 197 + dependencies = [ 198 + "console", 199 + "shell-words", 200 + "tempfile", 201 + "thiserror 1.0.69", 202 + "zeroize", 203 + ] 204 + 205 + [[package]] 276 206 name = "displaydoc" 277 207 version = "0.2.5" 278 208 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 290 220 checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 291 221 292 222 [[package]] 223 + name = "encode_unicode" 224 + version = "1.0.0" 225 + source = "registry+https://github.com/rust-lang/crates.io-index" 226 + checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" 227 + 228 + [[package]] 229 + name = "errno" 230 + version = "0.3.13" 231 + source = "registry+https://github.com/rust-lang/crates.io-index" 232 + checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" 233 + dependencies = [ 234 + "libc", 235 + "windows-sys 0.59.0", 236 + ] 237 + 238 + [[package]] 293 239 name = "eyre" 294 240 version = "0.6.12" 295 241 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 300 246 ] 301 247 302 248 [[package]] 249 + name = "fastrand" 250 + version = "2.3.0" 251 + source = "registry+https://github.com/rust-lang/crates.io-index" 252 + checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 253 + 254 + [[package]] 303 255 name = "fnv" 304 256 version = "1.0.7" 305 257 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 412 364 "cfg-if", 413 365 "js-sys", 414 366 "libc", 415 - "wasi", 367 + "wasi 0.11.1+wasi-snapshot-preview1", 416 368 "wasm-bindgen", 369 + ] 370 + 371 + [[package]] 372 + name = "getrandom" 373 + version = "0.3.3" 374 + source = "registry+https://github.com/rust-lang/crates.io-index" 375 + checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 376 + dependencies = [ 377 + "cfg-if", 378 + "libc", 379 + "r-efi", 380 + "wasi 0.14.2+wasi-0.2.4", 417 381 ] 418 382 419 383 [[package]] ··· 698 662 ] 699 663 700 664 [[package]] 701 - name = "is_terminal_polyfill" 702 - version = "1.70.1" 703 - source = "registry+https://github.com/rust-lang/crates.io-index" 704 - checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 705 - 706 - [[package]] 707 665 name = "itoa" 708 666 version = "1.0.15" 709 667 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 713 671 name = "jj-sync-prs" 714 672 version = "0.1.0" 715 673 dependencies = [ 716 - "clap", 717 674 "color-eyre", 675 + "dialoguer", 718 676 "futures", 719 677 "octocrab", 720 678 "serde", ··· 760 718 checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" 761 719 762 720 [[package]] 721 + name = "linux-raw-sys" 722 + version = "0.9.4" 723 + source = "registry+https://github.com/rust-lang/crates.io-index" 724 + checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" 725 + 726 + [[package]] 763 727 name = "litemap" 764 728 version = "0.8.0" 765 729 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 803 767 checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" 804 768 dependencies = [ 805 769 "libc", 806 - "wasi", 770 + "wasi 0.11.1+wasi-snapshot-preview1", 807 771 "windows-sys 0.59.0", 808 772 ] 809 773 ··· 898 862 checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 899 863 900 864 [[package]] 901 - name = "once_cell_polyfill" 902 - version = "1.70.1" 903 - source = "registry+https://github.com/rust-lang/crates.io-index" 904 - checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" 905 - 906 - [[package]] 907 865 name = "openssl-probe" 908 866 version = "0.1.6" 909 867 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1020 978 ] 1021 979 1022 980 [[package]] 981 + name = "r-efi" 982 + version = "5.3.0" 983 + source = "registry+https://github.com/rust-lang/crates.io-index" 984 + checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 985 + 986 + [[package]] 1023 987 name = "redox_syscall" 1024 988 version = "0.5.13" 1025 989 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1036 1000 dependencies = [ 1037 1001 "cc", 1038 1002 "cfg-if", 1039 - "getrandom", 1003 + "getrandom 0.2.16", 1040 1004 "libc", 1041 1005 "untrusted", 1042 1006 "windows-sys 0.52.0", ··· 1049 1013 checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" 1050 1014 1051 1015 [[package]] 1016 + name = "rustix" 1017 + version = "1.0.7" 1018 + source = "registry+https://github.com/rust-lang/crates.io-index" 1019 + checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" 1020 + dependencies = [ 1021 + "bitflags", 1022 + "errno", 1023 + "libc", 1024 + "linux-raw-sys", 1025 + "windows-sys 0.59.0", 1026 + ] 1027 + 1028 + [[package]] 1052 1029 name = "rustls" 1053 1030 version = "0.23.28" 1054 1031 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1218 1195 ] 1219 1196 1220 1197 [[package]] 1198 + name = "shell-words" 1199 + version = "1.1.0" 1200 + source = "registry+https://github.com/rust-lang/crates.io-index" 1201 + checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" 1202 + 1203 + [[package]] 1221 1204 name = "shlex" 1222 1205 version = "1.3.0" 1223 1206 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1240 1223 dependencies = [ 1241 1224 "num-bigint", 1242 1225 "num-traits", 1243 - "thiserror", 1226 + "thiserror 2.0.12", 1244 1227 "time", 1245 1228 ] 1246 1229 ··· 1294 1277 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1295 1278 1296 1279 [[package]] 1297 - name = "strsim" 1298 - version = "0.11.1" 1299 - source = "registry+https://github.com/rust-lang/crates.io-index" 1300 - checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1301 - 1302 - [[package]] 1303 1280 name = "subtle" 1304 1281 version = "2.6.1" 1305 1282 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1334 1311 ] 1335 1312 1336 1313 [[package]] 1314 + name = "tempfile" 1315 + version = "3.20.0" 1316 + source = "registry+https://github.com/rust-lang/crates.io-index" 1317 + checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" 1318 + dependencies = [ 1319 + "fastrand", 1320 + "getrandom 0.3.3", 1321 + "once_cell", 1322 + "rustix", 1323 + "windows-sys 0.59.0", 1324 + ] 1325 + 1326 + [[package]] 1327 + name = "thiserror" 1328 + version = "1.0.69" 1329 + source = "registry+https://github.com/rust-lang/crates.io-index" 1330 + checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1331 + dependencies = [ 1332 + "thiserror-impl 1.0.69", 1333 + ] 1334 + 1335 + [[package]] 1337 1336 name = "thiserror" 1338 1337 version = "2.0.12" 1339 1338 source = "registry+https://github.com/rust-lang/crates.io-index" 1340 1339 checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 1341 1340 dependencies = [ 1342 - "thiserror-impl", 1341 + "thiserror-impl 2.0.12", 1342 + ] 1343 + 1344 + [[package]] 1345 + name = "thiserror-impl" 1346 + version = "1.0.69" 1347 + source = "registry+https://github.com/rust-lang/crates.io-index" 1348 + checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1349 + dependencies = [ 1350 + "proc-macro2", 1351 + "quote", 1352 + "syn", 1343 1353 ] 1344 1354 1345 1355 [[package]] ··· 1572 1582 checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1573 1583 1574 1584 [[package]] 1585 + name = "unicode-width" 1586 + version = "0.2.1" 1587 + source = "registry+https://github.com/rust-lang/crates.io-index" 1588 + checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" 1589 + 1590 + [[package]] 1575 1591 name = "untrusted" 1576 1592 version = "0.9.0" 1577 1593 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1596 1612 checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1597 1613 1598 1614 [[package]] 1599 - name = "utf8parse" 1600 - version = "0.2.2" 1601 - source = "registry+https://github.com/rust-lang/crates.io-index" 1602 - checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1603 - 1604 - [[package]] 1605 1615 name = "valuable" 1606 1616 version = "0.1.1" 1607 1617 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1623 1633 checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" 1624 1634 1625 1635 [[package]] 1636 + name = "wasi" 1637 + version = "0.14.2+wasi-0.2.4" 1638 + source = "registry+https://github.com/rust-lang/crates.io-index" 1639 + checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 1640 + dependencies = [ 1641 + "wit-bindgen-rt", 1642 + ] 1643 + 1644 + [[package]] 1626 1645 name = "wasm-bindgen" 1627 1646 version = "0.2.100" 1628 1647 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1831 1850 version = "0.52.6" 1832 1851 source = "registry+https://github.com/rust-lang/crates.io-index" 1833 1852 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1853 + 1854 + [[package]] 1855 + name = "wit-bindgen-rt" 1856 + version = "0.39.0" 1857 + source = "registry+https://github.com/rust-lang/crates.io-index" 1858 + checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 1859 + dependencies = [ 1860 + "bitflags", 1861 + ] 1834 1862 1835 1863 [[package]] 1836 1864 name = "writeable"
+1 -1
Cargo.toml
··· 4 4 edition = "2024" 5 5 6 6 [dependencies] 7 - clap = { version = "4.5.41", features = ["derive"] } 8 7 color-eyre = "0.6.5" 8 + dialoguer = "0.11.0" 9 9 futures = "0.3.31" 10 10 octocrab = { version = "0.44.1", features = ["stream"] } 11 11 serde = { version = "1.0.219", features = ["derive"] }
+39 -22
src/main.rs
··· 2 2 use std::pin::pin; 3 3 use std::{ffi::OsStr, path::Path}; 4 4 5 - use clap::Parser; 6 5 use color_eyre::eyre::{Context as _, ContextCompat}; 6 + use dialoguer::{Confirm, Editor}; 7 7 use futures::TryStreamExt as _; 8 8 use octocrab::{Octocrab, models::pulls::PullRequest}; 9 9 use serde::Deserialize; ··· 12 12 13 13 mod graph; 14 14 15 - #[derive(Parser, Debug)] 16 - struct Cli { 17 - #[arg(short, long)] 18 - create_new: bool, 19 - } 20 - 21 15 #[tokio::main(flavor = "current_thread")] 22 16 async fn main() -> color_eyre::Result<()> { 23 17 color_eyre::install()?; 24 - 25 - let cli = Cli::parse(); 26 18 27 19 let graph = build_branch_graph().context("failed to build graph")?; 28 20 ··· 47 39 48 40 for stack_root in graph.iter_edges_from("main") { 49 41 find_or_create_prs( 50 - stack_root, "main", &graph, &repo_info, &octocrab, &cli, &mut pulls, 42 + stack_root, "main", &graph, &repo_info, &octocrab, &mut pulls, 51 43 ) 52 44 .await 53 45 .context("failed to sync prs")?; ··· 221 213 graph: &Graph, 222 214 repo_info: &RepoInfo, 223 215 octocrab: &Octocrab, 224 - cli: &Cli, 225 216 pulls: &mut Vec<PullRequest>, 226 217 ) -> color_eyre::Result<()> { 227 - find_or_create_pr(target, branch, pulls, octocrab, repo_info, cli) 218 + find_or_create_pr(target, branch, pulls, octocrab, repo_info) 228 219 .await 229 220 .with_context(|| format!("failed to find or create pr from {branch} into {target}"))?; 230 221 231 222 for child in graph.iter_edges_from(branch) { 232 223 Box::pin(find_or_create_prs( 233 - child, branch, graph, repo_info, octocrab, cli, pulls, 224 + child, branch, graph, repo_info, octocrab, pulls, 234 225 )) 235 226 .await 236 227 .with_context(|| format!("failed to find or create pr from {branch} into {target}"))?; ··· 260 251 pulls: &mut Vec<PullRequest>, 261 252 octocrab: &Octocrab, 262 253 repo_info: &RepoInfo, 263 - cli: &Cli, 264 254 ) -> color_eyre::Result<()> { 265 255 if let Some((idx, pull)) = pulls 266 256 .iter() ··· 290 280 })?; 291 281 pulls[idx] = updated; 292 282 } 293 - } else if cli.create_new { 294 - let pull = octocrab 295 - .pulls(&repo_info.owner, &repo_info.name) 296 - .create(branch, branch, target) 297 - .draft(true) 298 - .send() 299 - .await 300 - .with_context(|| format!("failed to create PR from {target}<-{branch}"))?; 283 + } else if Confirm::new() 284 + .with_prompt(format!( 285 + "PR from {target}<-{branch} doesn't exist. Do you want to create it?" 286 + )) 287 + .default(true) 288 + .interact()? 289 + { 290 + let repo_pulls = octocrab.pulls(&repo_info.owner, &repo_info.name); 291 + 292 + let pull = if let Some((title, body)) = get_pr_title_and_body()? { 293 + repo_pulls.create(title, branch, target).body(body) 294 + } else { 295 + repo_pulls.create(branch, branch, target) 296 + } 297 + .draft(true) 298 + .send() 299 + .await 300 + .with_context(|| format!("failed to create PR from {target}<-{branch}"))?; 301 + 301 302 if let Some(url) = &pull.html_url { 302 303 eprintln!("Created PR from {target}<-{branch}: {url}"); 303 304 } else { ··· 383 384 384 385 Ok(()) 385 386 } 387 + 388 + fn get_pr_title_and_body() -> color_eyre::Result<Option<(String, String)>> { 389 + if let Some(text) = Editor::new() 390 + .extension(".md") 391 + .edit("Enter PR title...\n\n...and description here")? 392 + { 393 + let mut lines = text.lines(); 394 + let Some(title) = lines.next() else { 395 + return Ok(None); 396 + }; 397 + let msg = lines.skip(1).collect::<Vec<_>>().join("\n"); 398 + Ok(Some((title.to_owned(), msg))) 399 + } else { 400 + Ok(None) 401 + } 402 + }