diff --git a/Cargo.lock b/Cargo.lock index 00cfe8e..25c210b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -276,6 +276,7 @@ dependencies = [ "directories", "serde", "toml", + "urlencoding", "which", ] @@ -405,6 +406,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8parse" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index e5bda87..4b11d4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ clap = { version = "4", features = ["derive"] } directories = "6" toml = "0.8" serde = { version = "1", features = ["derive"] } +urlencoding = "2" which = "8" [profile.release] diff --git a/src/bin/rustc_josh_sync.rs b/src/bin/rustc_josh_sync.rs index 22818dd..ef8c3d5 100644 --- a/src/bin/rustc_josh_sync.rs +++ b/src/bin/rustc_josh_sync.rs @@ -4,7 +4,7 @@ use rustc_josh_sync::SyncContext; use rustc_josh_sync::config::{JoshConfig, load_config}; use rustc_josh_sync::josh::{JoshProxy, try_install_josh}; use rustc_josh_sync::sync::{GitSync, RustcPullError, UPSTREAM_REPO}; -use rustc_josh_sync::utils::prompt; +use rustc_josh_sync::utils::{get_current_head_sha, prompt}; use std::path::{Path, PathBuf}; const DEFAULT_CONFIG_PATH: &str = "josh-sync.toml"; @@ -109,10 +109,24 @@ fn main() -> anyhow::Result<()> { .context("cannot perform push")?; // Open PR with `subtree update` title to silence the `no-merges` triagebot check + let title = format!("{} subtree update", ctx.config.repo); + let head = get_current_head_sha()?; + + let merge_msg = format!( + r#"Subtree update of `{repo}` to https://github.com/{full_repo}/commit/{head}. + +Created using https://github.com/rust-lang/josh-sync. + +r? @ghost"#, + repo = ctx.config.repo, + full_repo = ctx.config.full_repo_name(), + ); + println!( r#"You can create the rustc PR using the following URL: -https://github.com/{UPSTREAM_REPO}/compare/{username}:{branch}?quick_pull=1&title={}+subtree+update&body=r?+@ghost"#, - ctx.config.repo +https://github.com/{UPSTREAM_REPO}/compare/{username}:{branch}?quick_pull=1&title={}&body={}"#, + urlencoding::encode(&title), + urlencoding::encode(&merge_msg) ); } } diff --git a/src/sync.rs b/src/sync.rs index aaa949c..d5afcb6 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -1,7 +1,7 @@ use crate::SyncContext; use crate::josh::JoshProxy; -use crate::utils::run_command_at; use crate::utils::{ensure_clean_git_state, prompt}; +use crate::utils::{get_current_head_sha, run_command_at}; use crate::utils::{run_command, stream_command}; use anyhow::{Context, Error}; use std::path::{Path, PathBuf}; @@ -64,7 +64,7 @@ impl GitSync { &self.context.config.construct_josh_filter(), ); - let orig_head = run_command(["git", "rev-parse", "HEAD"])?; + let orig_head = get_current_head_sha()?; println!( "previous upstream base: {:?}", self.context.last_upstream_sha @@ -137,8 +137,7 @@ This updates the rust-version file to {upstream_sha}."#, }; let num_roots_before = num_roots()?; - let sha = - run_command(&["git", "rev-parse", "HEAD"]).context("failed to get current commit")?; + let sha = get_current_head_sha()?; // The filtered SHA of upstream let incoming_ref = run_command(["git", "rev-parse", "FETCH_HEAD"])?; @@ -170,8 +169,7 @@ This merge was created using https://github.com/rust-lang/josh-sync. ]) .context("FAILED to merge new commits, something went wrong")?; - let current_sha = - run_command(&["git", "rev-parse", "HEAD"]).context("FAILED to get current commit")?; + let current_sha = get_current_head_sha()?; if current_sha == sha { eprintln!( "No merge was performed, no changes to pull were found. Rolling back the preparation commit." @@ -261,7 +259,7 @@ This merge was created using https://github.com/rust-lang/josh-sync. &["git", "fetch", &josh_url, &branch], &std::env::current_dir().unwrap(), )?; - let head = run_command(&["git", "rev-parse", "HEAD"])?; + let head = get_current_head_sha()?; let fetch_head = run_command(&["git", "rev-parse", "FETCH_HEAD"])?; if head != fetch_head { return Err(anyhow::anyhow!( diff --git a/src/utils.rs b/src/utils.rs index fb23724..dd9d2aa 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use std::path::Path; use std::process::Command; @@ -67,6 +68,10 @@ pub fn ensure_clean_git_state() { assert!(read.is_empty(), "working directory must be clean"); } +pub fn get_current_head_sha() -> anyhow::Result { + run_command(&["git", "rev-parse", "HEAD"]).context("failed to get current commit") +} + /// Ask a prompt to user and return true if they responded with `y`. /// Returns `default_response` on CI. pub fn prompt(prompt: &str, default_response: bool) -> bool {