From ab260d45d8352b86b11ab50d090d6f89dd65e01a Mon Sep 17 00:00:00 2001 From: Colin Lienard Date: Wed, 3 Jan 2024 21:03:18 +0100 Subject: [PATCH 1/4] Rework code From 784c3ef58ec3f2acd63c77f22d9af4ec985c3dc0 Mon Sep 17 00:00:00 2001 From: Colin Lienard Date: Wed, 3 Jan 2024 21:19:43 +0100 Subject: [PATCH 2/4] changes --- src/config.rs | 24 ++++------ src/git.rs | 109 ++++++++++++++++++++++----------------------- src/github.rs | 69 ++++++++++++++--------------- src/main.rs | 119 ++++++++++++++++++-------------------------------- 4 files changed, 137 insertions(+), 184 deletions(-) diff --git a/src/config.rs b/src/config.rs index 92024bf..48a32f9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -28,17 +28,11 @@ impl Config { let (dir_path, token_path, _) = Config::get_paths(); - match fs::read_dir(&dir_path) { - Ok(_) => {} - Err(_) => { - fs::create_dir(&dir_path)?; - } - }; - match fs::read(&token_path) { - Ok(_) => {} - Err(_) => { - fs::File::create(&token_path)?; - } + if fs::read_dir(&dir_path).is_err() { + fs::create_dir(&dir_path)?; + } + if fs::read(&token_path).is_err() { + fs::File::create(&token_path)?; } fs::write(&token_path, token)?; @@ -139,14 +133,14 @@ impl Config { "Rework" => "rework", "Ignore" => "feature", "Bump" => "core", - &_ => todo!(), + _ => return Err(InquireError::Custom("Invalid input".into())), }; let branch = branch_prefix.to_owned() + "/" + &linear_branch; Ok(Config { pr_name, branch }) } - pub fn confirm(config: &Config) -> Result { + pub fn confirm(&self) -> Result { println!( "\ This will: @@ -155,8 +149,8 @@ This will: 3. Push to the remote repository. 4. Create a pull request named {}. 5. Assign you the pull request.", - config.branch.bright_cyan(), - config.pr_name.bright_cyan(), + self.branch.bright_cyan(), + self.pr_name.bright_cyan(), ); Confirm::new("Confirm? (y/n)").prompt() } diff --git a/src/git.rs b/src/git.rs index a39f9f4..3db8db4 100644 --- a/src/git.rs +++ b/src/git.rs @@ -4,73 +4,68 @@ use std::{ process::{Command, Stdio}, }; -pub struct Git {} +pub fn create_branch(branch: &str) -> Result { + process_command(Command::new("git").arg("switch").arg("-c").arg(branch)) +} -impl Git { - pub fn create_branch(branch: &str) -> Result { - Git::process_command(Command::new("git").arg("switch").arg("-c").arg(branch)) - } +pub fn create_commit(msg: &str) -> Result { + process_command( + Command::new("git") + .arg("commit") + .arg("--allow-empty") + .arg("-m") + .arg(msg), + ) +} - pub fn create_commit(msg: &str) -> Result { - Git::process_command( - Command::new("git") - .arg("commit") - .arg("--allow-empty") - .arg("-m") - .arg(msg), - ) - } +pub fn push(branch: &str) -> Result { + process_command(Command::new("git").arg("push").arg("origin").arg(branch)) +} - pub fn push(branch: &str) -> Result { - Git::process_command(Command::new("git").arg("push").arg("origin").arg(branch)) +pub fn get_current_repo() -> Result { + let git_config = fs::read_to_string(".git/config")?; + for line in git_config.lines() { + if line.contains("url = ") { + let url = line.split("url = ").collect::>()[1]; + let repo = url.replace("https://github.com/", "").replace(".git", ""); + return Ok(repo); + } } + Err(Error::new( + ErrorKind::Other, + "Could not find the repository.".to_string(), + )) +} - pub fn get_current_repo() -> Result { - let git_config = fs::read_to_string(".git/config")?; - for line in git_config.lines() { - if line.contains("url = ") { - let url = line.split("url = ").collect::>()[1]; - let repo = url.replace("https://github.com/", "").replace(".git", ""); - return Ok(repo); - } +pub fn get_default_branch() -> Result { + let origin = process_command(Command::new("git").arg("remote").arg("show").arg("origin"))?; + for line in origin.lines() { + if line.contains("HEAD branch:") { + let branch = line.split("HEAD branch: ").collect::>()[1]; + return Ok(branch.to_string()); } - Err(Error::new( - ErrorKind::Other, - "Could not find the repository.".to_string(), - )) } + Err(Error::new( + ErrorKind::Other, + "Could not find the default branch.".to_string(), + )) +} - pub fn get_default_branch() -> Result { - let origin = - Git::process_command(Command::new("git").arg("remote").arg("show").arg("origin"))?; - for line in origin.lines() { - if line.contains("HEAD branch:") { - let branch = line.split("HEAD branch: ").collect::>()[1]; - return Ok(branch.to_string()); - } - } +fn process_command(command: &mut Command) -> Result { + let output = command + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output()?; + + if output.status.success() { + Ok(String::from_utf8(output.stdout).unwrap()) + } else { Err(Error::new( ErrorKind::Other, - "Could not find the default branch.".to_string(), + String::from_utf8(output.stderr).unwrap(), )) } - - fn process_command(command: &mut Command) -> Result { - let output = command - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .unwrap() - .wait_with_output()?; - - if output.status.success() { - Ok(String::from_utf8(output.stdout).unwrap()) - } else { - Err(Error::new( - ErrorKind::Other, - String::from_utf8(output.stderr).unwrap(), - )) - } - } } diff --git a/src/github.rs b/src/github.rs index df56644..f405aee 100644 --- a/src/github.rs +++ b/src/github.rs @@ -2,39 +2,38 @@ use std::collections::HashMap; use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, AUTHORIZATION, USER_AGENT}; -use crate::{config::Config, git::Git}; +use crate::{config::Config, git}; -pub struct Github { - pub token: String, +pub struct Github<'a> { + token: &'a str, + client: reqwest::Client, } -impl Github { - pub fn new(token: &str) -> Self { - let token = token.to_string(); - Self { token } +impl<'a> Github<'a> { + pub fn new(token: &'a str) -> Self { + let client = reqwest::Client::new(); + Self { token, client } } - pub async fn create_pr( - github: &Github, - config: Config, - ) -> Result> { - let repo = Git::get_current_repo()?; + pub async fn create_pr(&self, config: Config) -> Result> { + let repo = git::get_current_repo()?; let default_desc = Config::get_default_desc()?; - let base = Git::get_default_branch()?; - // let draft = String::from("true"); - - let mut body = HashMap::new(); - body.insert("title", &config.pr_name); - body.insert("head", &config.branch); - body.insert("base", &base); - body.insert("body", &default_desc); - // body.insert("draft", &draft); - - let client = reqwest::Client::new(); - let response = client + let base = git::get_default_branch()?; + let draft = String::from("true"); + + let body = HashMap::from([ + ("title", &config.pr_name), + ("head", &config.branch), + ("base", &base), + ("body", &default_desc), + ("draft", &draft), + ]); + + let response = self + .client .post("https://api.github.com/repos/".to_owned() + &repo + "/pulls") .body(serde_json::to_string(&body)?) - .headers(Github::construct_headers(&github.token)) + .headers(Github::construct_headers(self.token)) .send() .await?; @@ -45,17 +44,15 @@ impl Github { } pub async fn assign_to_pr( - github: &Github, + &self, username: &str, number: &str, ) -> Result<(), Box> { - let repo = Git::get_current_repo()?; + let repo = git::get_current_repo()?; - let mut body = HashMap::new(); - body.insert("assignees", vec![username]); + let body = HashMap::from([("assignees", vec![username])]); - let client = reqwest::Client::new(); - client + self.client .post( "https://api.github.com/repos/".to_owned() + &repo @@ -64,18 +61,18 @@ impl Github { + "/assignees", ) .body(serde_json::to_string(&body)?) - .headers(Github::construct_headers(&github.token)) + .headers(Github::construct_headers(self.token)) .send() .await?; Ok(()) } - pub async fn get_username(github: &Github) -> Result> { - let client = reqwest::Client::new(); - let response = client + pub async fn get_username(&self) -> Result> { + let response = self + .client .get("https://api.github.com/user") - .headers(Github::construct_headers(&github.token)) + .headers(Github::construct_headers(self.token)) .send() .await?; diff --git a/src/main.rs b/src/main.rs index 276bc9a..1d8dd27 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ use colored::*; +use config::Config; +use github::Github; use std::{env, process}; + mod config; -use config::Config; mod git; -use git::Git; mod github; -use github::Github; #[tokio::main] async fn main() { @@ -15,27 +15,24 @@ async fn main() { "create" => {} "config" => { match Config::set_github_token() { - Ok(set) => { - if set { - println!("{}", "✔️ Token set.".green()) - } else { - println!("{}", "Skipped.".dimmed()) - } - } + Ok(set) => match set { + true => println!("{}", "✔️ Token set.".green()), + false => println!("{}", "Skipped.".dimmed()), + }, Err(e) => { - eprintln!("{}", e.to_string().red()); - return; + eprintln!("{}", e); + process::exit(1); } }; match Config::set_default_desc() { - Ok(set) => { - if set { - println!("{}", "✓ Default pull request description set.".green()); - } else { - println!("{}", "Skipped.".dimmed()); - } + Ok(set) => match set { + true => println!("{}", "✓ Default pull request description set.".green()), + false => println!("{}", "Skipped.".dimmed()), + }, + Err(e) => { + eprintln!("{}", e); + process::exit(1); } - Err(e) => eprintln!("{}", e.to_string().red()), }; return; } @@ -63,75 +60,45 @@ async fn main() { process::exit(1); }); - let config = Config::ask().unwrap_or_else(|e| { + let pr_url = create(&github_token).await.unwrap_or_else(|e| { eprintln!("{}", e); process::exit(1); }); - match Config::confirm(&config).unwrap_or_else(|e| { - eprintln!("{}", e); - process::exit(1); - }) { - true => {} - false => return, - } + println!( + "🎉 Success! The pull request url is: {}", + pr_url.bright_cyan() + ); +} - match Git::create_branch(&config.branch) { - Ok(_) => println!("{}", "✔️ Branch created.".green()), - Err(e) => { - eprintln!("{}", e); - process::exit(1); - } - }; +async fn create(github_token: &str) -> Result> { + let config = Config::ask()?; - match Git::create_commit(&config.pr_name) { - Ok(_) => println!("{}", "✔️ Commit created.".green()), - Err(e) => { - eprintln!("{}", e); - process::exit(1); + match Config::confirm(&config)? { + true => {} + false => { + return Err("Aborted.".into()); } }; - match Git::push(&config.branch) { - Ok(_) => println!("{}", "✔️ Successfully pushed.".green()), - Err(e) => { - eprintln!("{}", e); - process::exit(1); - } - }; + git::create_branch(&config.branch)?; - let gh = Github::new(&github_token); - let pr_url = match Github::create_pr(&gh, config).await { - Ok(url) => { - println!("{}", "✔️ Pull request created.".green()); - url - } - Err(e) => { - eprintln!("{}", e); - process::exit(1); - } - }; + git::create_commit(&config.pr_name)?; + println!("{}", "✔️ Commit created.".green()); - let username = match Github::get_username(&gh).await { - Ok(username) => username, - Err(e) => { - eprintln!("{}", e); - process::exit(1); - } - }; + git::push(&config.branch)?; + println!("{}", "✔️ Successfully pushed.".green()); + + let gh = Github::new(github_token); + + let pr_url = gh.create_pr(config).await?; + println!("{}", "✔️ Pull request created.".green()); + + let username = gh.get_username().await?; let pr_number = pr_url.split('/').last().unwrap(); - match Github::assign_to_pr(&gh, &username, pr_number).await { - Ok(_) => println!("{}", "✔️ Successfully assigned you.".green()), - Err(e) => { - eprintln!("{}", e); - process::exit(1); - } - }; + gh.assign_to_pr(&username, pr_number).await?; + println!("{}", "✔️ Successfully assigned you.".green()); - println!( - "🎉 {} The pull request url is: {}", - "Success!".green(), - pr_url.bright_cyan() - ); + Ok(pr_url) } From 71dc095f49e17d50facab6220e9216f6a640ae89 Mon Sep 17 00:00:00 2001 From: Colin Lienard Date: Wed, 3 Jan 2024 21:23:43 +0100 Subject: [PATCH 3/4] push -u --- src/git.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/git.rs b/src/git.rs index 3db8db4..b0dbaaf 100644 --- a/src/git.rs +++ b/src/git.rs @@ -19,7 +19,13 @@ pub fn create_commit(msg: &str) -> Result { } pub fn push(branch: &str) -> Result { - process_command(Command::new("git").arg("push").arg("origin").arg(branch)) + process_command( + Command::new("git") + .arg("push") + .arg("-u") + .arg("origin") + .arg(branch), + ) } pub fn get_current_repo() -> Result { From ecd6bf33637f6c07f36f743d415afff424284adf Mon Sep 17 00:00:00 2001 From: Colin Lienard Date: Thu, 4 Jan 2024 11:21:48 +0100 Subject: [PATCH 4/4] changes --- src/config.rs | 4 ++-- src/github.rs | 13 +++++-------- src/main.rs | 1 + 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/config.rs b/src/config.rs index 48a32f9..0c39ee1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -105,7 +105,7 @@ impl Config { false => { let mut output = PR_PREFIX .iter() - .map(|current| ("- ".to_owned() + current + "...").to_string()) + .map(|current| format!("- {}...", current)) .collect::>() .join("\n"); output = @@ -135,7 +135,7 @@ impl Config { "Bump" => "core", _ => return Err(InquireError::Custom("Invalid input".into())), }; - let branch = branch_prefix.to_owned() + "/" + &linear_branch; + let branch = format!("{}/{}", branch_prefix, &linear_branch); Ok(Config { pr_name, branch }) } diff --git a/src/github.rs b/src/github.rs index f405aee..8f1e69b 100644 --- a/src/github.rs +++ b/src/github.rs @@ -31,7 +31,7 @@ impl<'a> Github<'a> { let response = self .client - .post("https://api.github.com/repos/".to_owned() + &repo + "/pulls") + .post(format!("https://api.github.com/repos/{}/pulls", &repo)) .body(serde_json::to_string(&body)?) .headers(Github::construct_headers(self.token)) .send() @@ -53,13 +53,10 @@ impl<'a> Github<'a> { let body = HashMap::from([("assignees", vec![username])]); self.client - .post( - "https://api.github.com/repos/".to_owned() - + &repo - + "/issues/" - + number - + "/assignees", - ) + .post(format!( + "https://api.github.com/repos/{}/issues/{}/assignees", + &repo, number + )) .body(serde_json::to_string(&body)?) .headers(Github::construct_headers(self.token)) .send() diff --git a/src/main.rs b/src/main.rs index 1d8dd27..414014e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,6 +82,7 @@ async fn create(github_token: &str) -> Result }; git::create_branch(&config.branch)?; + println!("{}", "✔️ Branch created.".green()); git::create_commit(&config.pr_name)?; println!("{}", "✔️ Commit created.".green());