From 070f5b2d49f8fbafa9a4cc7f2a39a3d04dbe3012 Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 13 Nov 2024 18:58:21 +0100 Subject: [PATCH] feat: allow giving prs as github links --- Cargo.lock | 39 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 43 ++++++++++++++++++++++++++++++++----------- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ac1a98..5c2560e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "anstream" version = "0.6.18" @@ -786,6 +795,7 @@ version = "0.1.0" dependencies = [ "clap", "color-eyre", + "regex", "reqwest", "serde", "serde_json", @@ -931,6 +941,35 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "reqwest" version = "0.12.9" diff --git a/Cargo.toml b/Cargo.toml index 3c1ca6b..3046d6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] clap = { version = "4.5.20", features = ["derive"] } color-eyre = "0.6.3" +regex = "1.11.1" reqwest = "0.12.9" serde = { version = "1.0.214", features = ["derive"] } serde_json = "1.0.132" diff --git a/src/main.rs b/src/main.rs index 1b654f3..86eb367 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,8 @@ use std::{ }; use clap::{Args, Parser, Subcommand}; -use color_eyre::eyre::Result; +use color_eyre::eyre::{bail, Result}; +use regex::Regex; use reqwest::Client; use serde::Deserialize; @@ -67,7 +68,19 @@ struct Compare { status: String, } -async fn get_pr(pr: &str, client: &Client) -> Result { +fn parse_pr(pr: &str) -> Result { + let re = Regex::new(r"^[0-9]*$")?; + let re2 = Regex::new(r"^https://github.com/NixOS/nixpkgs/pull/([0-9]*)$")?; + if let Some(caps) = re.captures(pr) { + Ok(caps[1].parse::()?) + } else if let Some(caps) = re2.captures(pr) { + Ok(caps[1].parse::()?) + } else { + bail!("Could not parse pr number!") + } +} + +async fn get_pr(pr: u32, client: &Client) -> Result { let request = client .get(format!( "https://api.github.com/repos/nixos/nixpkgs/pulls/{}", @@ -94,7 +107,7 @@ async fn contains(branch: &str, pr: &PR, client: &Client) -> Result { } Ok(false) } -async fn get_diff(pr: &str, path: &str, client: &Client) -> Result<()> { +async fn get_diff(pr: u32, path: &str, client: &Client) -> Result<()> { let req = client .get(format!("https://github.com/nixos/nixpkgs/pull/{}.diff", pr)) .send(); @@ -108,34 +121,42 @@ async fn main() -> Result<()> { let cli = Cli::parse(); let client = Client::builder().user_agent("nixp-meta tool").build()?; match &cli.command { - CliCommands::Track(track) => { - let pr = get_pr(&track.pr, &client).await?; + CliCommands::Track(opts) => { + let pr = parse_pr(&opts.pr)?; + let pr = get_pr(pr, &client).await?; println!("{}", pr.title); for &i in BRANCHES { println!("{}: {}", i, contains(i, &pr, &client).await?); } } CliCommands::GetDiff(opts) => { - get_diff(&opts.pr, &opts.path, &client).await?; + let pr = parse_pr(&opts.pr)?; + get_diff(pr, &opts.path, &client).await?; } CliCommands::UpdatePrs(opts) => { - let mut trackable: Vec = Vec::new(); + let mut trackable: Vec = Vec::new(); { let file = File::open(opts.pr_file.clone())?; for l in io::BufReader::new(file).lines() { - let l = l?; - let pr = get_pr(&l, &client).await?; + let l = l?.parse::()?; + let pr = get_pr(l, &client).await?; println!("Fetching diff for PR #{}: {}", l, pr.title); if contains(&opts.branch, &pr, &client).await? { println!("PR has reached {}, removing diff", opts.branch); fs::remove_file(format!("{}/{}.diff", opts.path, l))?; } else { - get_diff(&l, &opts.path, &client).await?; + get_diff(l, &opts.path, &client).await?; trackable.push(l.clone()); } } } - fs::write(&opts.pr_file, trackable.join("\n"))?; + fs::write( + &opts.pr_file, + trackable + .iter() + .map(|x| format!("{}\n", x)) + .collect::(), + )?; } }; Ok(())