From b09865c87fe52329b4dc43c1318b4a16074bafa2 Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 19:00:00 +0200 Subject: [PATCH 01/10] Add clap to cargo.toml and change version to 1.1.0 in cargo.toml --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 38b4f8c..5f705ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gitopen" -version = "0.1.0" +version = "1.1.0" authors = ["oren0e "] edition = "2018" @@ -8,3 +8,4 @@ edition = "2018" webbrowser = "0.5.5" anyhow = "1.0.44" regex = "1.5.4" +clap = "2.33.3" From 7efd2a6d86bbb1bcb9a4e1e3d662d03a63045586 Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 19:02:29 +0200 Subject: [PATCH 02/10] Move action functions to separate module and add the push and pr function --- src/actions.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/actions.rs diff --git a/src/actions.rs b/src/actions.rs new file mode 100644 index 0000000..75f292e --- /dev/null +++ b/src/actions.rs @@ -0,0 +1,61 @@ +use crate::match_logic::parse_url_from_git; +use anyhow::anyhow; +use anyhow::Result as AnyhowResult; +use regex::Regex; +use std::process::{Command, Stdio}; + +pub fn open_repo() -> AnyhowResult<()> { + let git_repo = Command::new("git") + .args(&["config", "--get", "remote.origin.url"]) + .stdout(Stdio::piped()) + .output()?; + + let stdout = String::from_utf8(git_repo.stdout)?; + let parsed_url = parse_url_from_git(stdout)?; + webbrowser::open(&parsed_url)?; + Ok(()) +} + +pub fn push_and_open_pr() -> AnyhowResult<()> { + let current_branch = Command::new("git") + .args(&["branch", "--show-current"]) + .stdout(Stdio::piped()) + .output()?; + let output_from_push = Command::new("git") + .args(&["push", "origin", &String::from_utf8(current_branch.stdout)?]) + .stdout(Stdio::piped()) + .output()?; + let pr_re = Regex::new(r"remote:.*(https.*)\n.*")?; + let output_from_push_text = String::from_utf8(output_from_push.stdout)?; + let captured = pr_re + .captures(&output_from_push_text) + .ok_or_else(|| anyhow!("Error capturing PR url"))?; + webbrowser::open(&captured[1])?; + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_correct_pr_parsing_from_output() { + let output = r#"Counting objects: 4, done. +Delta compression using up to 12 threads. +Compressing objects: 100% (4/4), done. +Writing objects: 100% (4/4), 3.01 KiB | 3.01 MiB/s, done. +Total 4 (delta 2), reused 0 (delta 0) +remote: Resolving deltas: 100% (2/2), completed with 2 local objects. +remote: +remote: Create a pull request for 'feat/add-more-pokemons' on GitHub by visiting: +remote: https://github.com/tobiasbueschel/awesome-pokemon/pull/new/feat/add-more-pokemons +remote: +To github.com:tobiasbueschel/awesome-pokemon.git + * [new branch] feat/add-more-pokemons -> feat/add-more-pokemons"#; + let re = Regex::new(r"remote:.*(https.*)\n.*").unwrap(); + let captured = re.captures(&output).unwrap(); + println!("{:?}", &captured[1]); + assert!(&captured[1].starts_with("https")); + assert!(&captured[1].ends_with("add-more-pokemons")); + } +} From 683922b144518d9bf59040bef228633661581a48 Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 19:03:12 +0200 Subject: [PATCH 03/10] Remove actions from main and add clap logic --- src/main.rs | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5c757ab..2309b45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,29 @@ -use crate::match_logic::parse_url_from_git; +extern crate clap; +use clap::{App, Arg}; + +use crate::actions::{open_repo, push_and_open_pr}; use anyhow::Result as AnyhowResult; -use std::process::{Command, Stdio}; +mod actions; mod match_logic; fn main() -> AnyhowResult<()> { - let git_repo = Command::new("git") - .args(&["config", "--get", "remote.origin.url"]) - .stdout(Stdio::piped()) - .output()?; - - let stdout = String::from_utf8(git_repo.stdout)?; - let parsed_url = parse_url_from_git(stdout)?; - webbrowser::open(&parsed_url)?; - Ok(()) + let matches = App::new("Gitopen") + .version("1.1.0") + .author("Oren Epshtain") + .about("Utility to open repo from terminal and pull requests after push") + .arg( + Arg::with_name("push_and_pr") + .short("p") + .long("push-open-pr") + .help("Pushes to current branch and opens corresponding PR"), + ) + .get_matches(); + if matches.is_present("push_and_pr") { + push_and_open_pr()?; + Ok(()) + } else { + open_repo()?; + Ok(()) + } } From 7ffd2752bffd36560bbe2e6d30859177c515721e Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 19:19:51 +0200 Subject: [PATCH 04/10] Strip new line character from current branch --- src/actions.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/actions.rs b/src/actions.rs index 75f292e..3050b89 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -21,8 +21,9 @@ pub fn push_and_open_pr() -> AnyhowResult<()> { .args(&["branch", "--show-current"]) .stdout(Stdio::piped()) .output()?; + let current_branch_text = &String::from_utf8(current_branch.stdout)?; let output_from_push = Command::new("git") - .args(&["push", "origin", &String::from_utf8(current_branch.stdout)?]) + .args(&["push", "origin", ¤t_branch_text.trim()]) .stdout(Stdio::piped()) .output()?; let pr_re = Regex::new(r"remote:.*(https.*)\n.*")?; From 90e68b75596f27913c42e9f5995c90e06a18e305 Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 20:20:45 +0200 Subject: [PATCH 05/10] Use stderr instead of stdout to capture response from git server --- src/actions.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/actions.rs b/src/actions.rs index 3050b89..41462d7 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -22,15 +22,21 @@ pub fn push_and_open_pr() -> AnyhowResult<()> { .stdout(Stdio::piped()) .output()?; let current_branch_text = &String::from_utf8(current_branch.stdout)?; + let current_branch_text_stripped = current_branch_text.trim(); let output_from_push = Command::new("git") - .args(&["push", "origin", ¤t_branch_text.trim()]) - .stdout(Stdio::piped()) + .args(&["push", "origin", ¤t_branch_text_stripped]) + .stderr(Stdio::piped()) .output()?; - let pr_re = Regex::new(r"remote:.*(https.*)\n.*")?; - let output_from_push_text = String::from_utf8(output_from_push.stdout)?; + let pr_re = Regex::new(&format!( + r"remote:.*(https.*{}).*\n", + current_branch_text_stripped + ))?; + let output_from_push_text = String::from_utf8(output_from_push.stderr)?; + println!("{:?}", &output_from_push_text); let captured = pr_re .captures(&output_from_push_text) .ok_or_else(|| anyhow!("Error capturing PR url"))?; + println!("{:?}", &captured[1]); webbrowser::open(&captured[1])?; Ok(()) } From dba7002987d57607ccf19224404b7dfe2d5b2b6a Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 20:36:26 +0200 Subject: [PATCH 06/10] Add printing version info to CI --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c667bec..e8e510c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,8 +13,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: Print rust version + run: rustup show - name: Add fmt and clippy run: rustup component add rustfmt clippy + - name: Print clippy version + run: cargo clippy --version - name: Lint run: make lint - name: Run tests From 592595c3214417f3e97ee9c04ea38c69737d8511 Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 20:45:57 +0200 Subject: [PATCH 07/10] Use dtolnay github action for fixing rust version and using components --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8e510c..ad8d748 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,10 +13,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: dtolnay/rust-toolchain@1.51.0 + with: + components: clippy, rustfmt - name: Print rust version run: rustup show - - name: Add fmt and clippy - run: rustup component add rustfmt clippy - name: Print clippy version run: cargo clippy --version - name: Lint From aefc8e83eab3cd8008746a24e3fb2d875c9c640d Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 20:53:04 +0200 Subject: [PATCH 08/10] Change test of push server output parsing --- src/actions.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/actions.rs b/src/actions.rs index 41462d7..2cd2840 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -59,7 +59,13 @@ remote: https://github.com/tobiasbueschel/awesome-pokemon/pull/new/feat/add remote: To github.com:tobiasbueschel/awesome-pokemon.git * [new branch] feat/add-more-pokemons -> feat/add-more-pokemons"#; - let re = Regex::new(r"remote:.*(https.*)\n.*").unwrap(); + let current_branch = "feat/add-more-pokemons\n"; + let current_branch_text_stripped = current_branch.trim(); + let re = Regex::new(&format!( + r"remote:.*(https.*{}).*\n", + current_branch_text_stripped + )) + .unwrap(); let captured = re.captures(&output).unwrap(); println!("{:?}", &captured[1]); assert!(&captured[1].starts_with("https")); From fec52f408f67b3591cbb76c07b756d6535d679d7 Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 21:03:47 +0200 Subject: [PATCH 09/10] Update readme --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dc91dce..3a80139 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,9 @@ Note: You have to have rust installed with cargo to be able to install this util # Usage -When in git repository in terminal, run `gitopen`. +There are 2 basic usages: + +- When in git repository in terminal, run `gitopen`. +- After you've opened a branch and you are ready to push and open a PR, run `gitopen -p`. This will push the changes to the current branch and open the PR in the browser. + +For help, use `gitopen --help` From 0a88428756e4a298a0cd56d9dbc6f324f150cdf5 Mon Sep 17 00:00:00 2001 From: oren0e Date: Thu, 4 Nov 2021 21:21:31 +0200 Subject: [PATCH 10/10] Take version automatically from cargo toml file --- src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2309b45..7b6cc59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ extern crate clap; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use crate::actions::{open_repo, push_and_open_pr}; use anyhow::Result as AnyhowResult; @@ -9,7 +9,7 @@ mod match_logic; fn main() -> AnyhowResult<()> { let matches = App::new("Gitopen") - .version("1.1.0") + .version(crate_version!()) .author("Oren Epshtain") .about("Utility to open repo from terminal and pull requests after push") .arg(