Skip to content
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Add fmt and clippy
run: rustup component add rustfmt clippy
- uses: dtolnay/rust-toolchain@1.51.0
with:
components: clippy, rustfmt
- name: Print rust version
run: rustup show
- name: Print clippy version
run: cargo clippy --version
- name: Lint
run: make lint
- name: Run tests
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[package]
name = "gitopen"
version = "0.1.0"
version = "1.1.0"
authors = ["oren0e <none>"]
edition = "2018"

[dependencies]
webbrowser = "0.5.5"
anyhow = "1.0.44"
regex = "1.5.4"
clap = "2.33.3"
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
74 changes: 74 additions & 0 deletions src/actions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
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 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", &current_branch_text_stripped])
.stderr(Stdio::piped())
.output()?;
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(())
}

#[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 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"));
assert!(&captured[1].ends_with("add-more-pokemons"));
}
}
34 changes: 23 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
use crate::match_logic::parse_url_from_git;
extern crate clap;
use clap::{crate_version, 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(crate_version!())
.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(())
}
}