diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/branches.rs | 196 | ||||
-rw-r--r-- | src/github.rs | 2 | ||||
-rw-r--r-- | src/main.rs | 4 | ||||
-rw-r--r-- | src/nixpkgs.rs | 8 | ||||
-rw-r--r-- | src/tree.rs | 18 |
5 files changed, 201 insertions, 27 deletions
diff --git a/src/branches.rs b/src/branches.rs index 3ca3d0d..b6e3d45 100644 --- a/src/branches.rs +++ b/src/branches.rs @@ -1,5 +1,6 @@ // SPDX-License-Identifier: AGPL-3.0-or-later WITH GPL-3.0-linking-exception -// SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +// SPDX-FileCopyrightText: 2021, 2023 Alyssa Ross <hi@alyssa.is> +// SPDX-FileCopyrightText: 2022 Arnout Engelen <arnout@bzzt.net> use std::borrow::Cow; use std::collections::BTreeMap; @@ -7,10 +8,12 @@ use std::collections::BTreeMap; use once_cell::sync::Lazy; use regex::{Regex, RegexSet}; -const NEXT_BRANCH_TABLE: [(&str, &str); 10] = [ +const NEXT_BRANCH_TABLE: [(&str, &str); 12] = [ + (r"\Apython-updates\z", "staging"), (r"\Astaging\z", "staging-next"), (r"\Astaging-next\z", "master"), (r"\Astaging-next-([\d.]+)\z", "release-$1"), + (r"\Ahaskell-updates\z", "master"), (r"\Amaster\z", "nixpkgs-unstable"), (r"\Amaster\z", "nixos-unstable-small"), (r"\Anixos-(.*)-small\z", "nixos-$1"), @@ -20,6 +23,25 @@ const NEXT_BRANCH_TABLE: [(&str, &str); 10] = [ (r"\Astaging-((2[1-9]|[3-90].)\.\d{2})\z", "staging-next-$1"), ]; +const BRANCH_HYDRA_LINK_TABLE: [(&str, &str); 5] = [ + (r"\Apython-updates\z", "nixpkgs/python-updates"), + (r"\Astaging-next\z", "nixpkgs/staging-next"), + // There's no staging-next-21.11 for some reason. + ( + r"\Astaging-next-([013-9]\d\.\d{2}|2(1\.05|[2-90]\.\d{2}))\z", + "nixpkgs/staging-next-$1", + ), + (r"\Ahaskell-updates\z", "nixpkgs/haskell-updates"), + (r"\Amaster\z", "nixpkgs/trunk"), +]; + +const CHANNEL_HYDRA_LINK_TABLE: [(&str, &str); 4] = [ + (r"\Anixpkgs-unstable\z", "nixpkgs/trunk/unstable"), + (r"\Anixos-unstable-small\z", "nixos/unstable-small/tested"), + (r"\Anixos-unstable\z", "nixos/trunk-combined/tested"), + (r"\Anixos-(\d.*)\z", "nixos/release-$1/tested"), +]; + static BRANCH_NEXTS: Lazy<BTreeMap<&str, Vec<&str>>> = Lazy::new(|| { NEXT_BRANCH_TABLE .iter() @@ -57,49 +79,191 @@ pub fn next_branches(branch: &str) -> Vec<Cow<str>> { .collect() } +static BRANCH_HYDRA_LINK_PATTERNS: Lazy<Vec<Regex>> = Lazy::new(|| { + BRANCH_HYDRA_LINKS + .keys() + .copied() + .map(Regex::new) + .map(Result::unwrap) + .collect() +}); + +static BRANCH_HYDRA_LINKS: Lazy<BTreeMap<&str, String>> = Lazy::new(|| { + let branch_links = BRANCH_HYDRA_LINK_TABLE.iter().map(|(pattern, jobset)| { + ( + *pattern, + format!("https://hydra.nixos.org/jobset/{jobset}#tabs-jobs"), + ) + }); + let channel_links = CHANNEL_HYDRA_LINK_TABLE.iter().map(|(pattern, job)| { + ( + *pattern, + format!("https://hydra.nixos.org/job/{job}#tabs-constituents"), + ) + }); + branch_links.chain(channel_links).collect() +}); + +static BRANCH_HYDRA_LINKS_BY_INDEX: Lazy<Vec<String>> = + Lazy::new(|| BRANCH_HYDRA_LINKS.values().cloned().collect()); + +static BRANCH_HYDRA_LINK_REGEXES: Lazy<RegexSet> = + Lazy::new(|| RegexSet::new(BRANCH_HYDRA_LINKS.keys()).unwrap()); + +pub fn branch_hydra_link(branch: &str) -> Option<String> { + BRANCH_HYDRA_LINK_REGEXES + .matches(branch) + .iter() + .next() + .and_then(|index| { + let regex = BRANCH_HYDRA_LINK_PATTERNS.get(index).unwrap(); + BRANCH_HYDRA_LINKS_BY_INDEX + .get(index) + .map(move |link| regex.replace(branch, link).to_string()) + }) +} + #[cfg(test)] mod tests { use super::*; #[test] + fn python_updates() { + let res = next_branches("python-updates"); + assert_eq!(res, vec!["staging"]); + } + + #[test] + fn staging_next() { + let branch = "staging-next"; + let res = next_branches(branch); + assert_eq!(res, vec!["master"]); + let link = branch_hydra_link(branch); + let expected = "https://hydra.nixos.org/jobset/nixpkgs/staging-next#tabs-jobs"; + assert_eq!(link.unwrap(), expected); + } + + #[test] fn staging_18_03() { - let res = next_branches("staging-18.03"); - assert_eq!(res, vec!["release-18.03"]); + let branch = "staging-18.03"; + let next = next_branches(branch); + assert_eq!(next, vec!["release-18.03"]); + let link = branch_hydra_link(branch); + assert_eq!(link, None); } #[test] fn staging_20_09() { - let res = next_branches("staging-20.09"); - assert_eq!(res, vec!["release-20.09"]); + let res = next_branches("staging-20.09"); + assert_eq!(res, vec!["release-20.09"]); } #[test] fn staging_21_05() { - let res = next_branches("staging-21.05"); - assert_eq!(res, vec!["staging-next-21.05"]); + let res = next_branches("staging-21.05"); + assert_eq!(res, vec!["staging-next-21.05"]); } #[test] fn staging_30_05() { - let res = next_branches("staging-30.05"); - assert_eq!(res, vec!["staging-next-30.05"]); + let res = next_branches("staging-30.05"); + assert_eq!(res, vec!["staging-next-30.05"]); } #[test] fn staging_00_11() { - let res = next_branches("staging-00.11"); - assert_eq!(res, vec!["staging-next-00.11"]); + let res = next_branches("staging-00.11"); + assert_eq!(res, vec!["staging-next-00.11"]); } #[test] fn staging_next_21_05() { - let res = next_branches("staging-next-21.05"); - assert_eq!(res, vec!["release-21.05"]); + let branch = "staging-next-21.05"; + let res = next_branches(branch); + assert_eq!(res, vec!["release-21.05"]); + let link = branch_hydra_link(branch); + let expected = "https://hydra.nixos.org/jobset/nixpkgs/staging-next-21.05#tabs-jobs"; + assert_eq!(link.unwrap(), expected); + } + + #[test] + fn staging_next_21_11() { + let branch = "staging-next-21.11"; + let next = next_branches(branch); + assert_eq!(next, vec!["release-21.11"]); + assert!(branch_hydra_link(branch).is_none()); + } + + #[test] + fn staging_next_22_05() { + let branch = "staging-next-22.05"; + let next = next_branches(branch); + assert_eq!(next, vec!["release-22.05"]); + let link = branch_hydra_link(branch); + let expected = "https://hydra.nixos.org/jobset/nixpkgs/staging-next-22.05#tabs-jobs"; + assert_eq!(link.unwrap(), expected); + } + + #[test] + fn staging_next_30_05() { + let branch = "staging-next-30.05"; + let next = next_branches(branch); + assert_eq!(next, vec!["release-30.05"]); + let link = branch_hydra_link(branch); + let expected = "https://hydra.nixos.org/jobset/nixpkgs/staging-next-30.05#tabs-jobs"; + assert_eq!(link.unwrap(), expected); + } + + #[test] + fn haskell_updates() { + let branch = "haskell-updates"; + let next = next_branches(branch); + assert_eq!(next, vec!["master"]); + } + + #[test] + fn master() { + let branch = "master"; + let next = next_branches(branch); + assert_eq!(next, vec!["nixpkgs-unstable", "nixos-unstable-small"]); + let link = branch_hydra_link(branch); + let expected = "https://hydra.nixos.org/jobset/nixpkgs/trunk#tabs-jobs"; + assert_eq!(link.unwrap(), expected); } #[test] fn release_20_09() { - let res = next_branches("release-20.09"); - assert_eq!(res, vec!["nixpkgs-20.09-darwin", "nixos-20.09-small"]); + let res = next_branches("release-20.09"); + assert_eq!(res, vec!["nixpkgs-20.09-darwin", "nixos-20.09-small"]); + } + + #[test] + fn nixpkgs_unstable() { + let branch = "nixpkgs-unstable"; + let next = next_branches(branch); + assert!(next.is_empty()); + let link = branch_hydra_link(branch); + let expected = "https://hydra.nixos.org/job/nixpkgs/trunk/unstable#tabs-constituents"; + assert_eq!(link.unwrap(), expected); + } + + #[test] + fn nixos_unstable_small() { + let branch = "nixos-unstable-small"; + let next = next_branches(branch); + assert_eq!(next, vec!["nixos-unstable"]); + let link = branch_hydra_link(branch); + let expected = "https://hydra.nixos.org/job/nixos/unstable-small/tested#tabs-constituents"; + assert_eq!(link.unwrap(), expected); + } + + #[test] + fn nixos_unstable() { + let branch = "nixos-unstable"; + let next = next_branches(branch); + assert_eq!(next.len(), 0); + let link = branch_hydra_link(branch); + let expected = "https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents"; + assert_eq!(link.unwrap(), expected); } } diff --git a/src/github.rs b/src/github.rs index 1128f95..e5be0d3 100644 --- a/src/github.rs +++ b/src/github.rs @@ -117,7 +117,7 @@ impl<'a> GitHub<'a> { fn authorization_header(&self) -> Result<HeaderValue, surf::Error> { let mut value = b"bearer ".to_vec(); value.extend_from_slice(self.token.as_bytes()); - Ok(HeaderValue::from_bytes(value)?) + HeaderValue::from_bytes(value) } pub async fn pr_info_for_nixpkgs_pr(&self, pr: i64) -> Result<PrInfo, Error> { diff --git a/src/main.rs b/src/main.rs index 0b70a15..b088e1f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -162,7 +162,7 @@ async fn main() { E: std::error::Error, { match result { - Ok(v) => return v, + Ok(v) => v, Err(e) => { eprintln!("pr-tracker: {}: {}", message.as_ref(), e); exit(code); @@ -188,7 +188,7 @@ async fn main() { let mut listeners: Vec<Pin<Box<dyn Future<Output = _>>>> = Vec::new(); - for fd in (3..).into_iter().take(fd_count as usize) { + for fd in (3..).take(fd_count as usize) { let s = server.clone(); if handle_error(is_socket_inet(fd), 74, "sd_is_socket_inet") { listeners.push(Box::pin(s.listen(unsafe { TcpListener::from_raw_fd(fd) }))); diff --git a/src/nixpkgs.rs b/src/nixpkgs.rs index 7e622c2..6656543 100644 --- a/src/nixpkgs.rs +++ b/src/nixpkgs.rs @@ -56,7 +56,7 @@ impl<'a> Nixpkgs<'a> { fn git_command(&self, subcommand: impl AsRef<OsStr>) -> Command { let mut command = Command::new("git"); command.arg("-C"); - command.arg(&self.path); + command.arg(self.path); command.arg(subcommand); command } @@ -64,7 +64,7 @@ impl<'a> Nixpkgs<'a> { async fn git_branch_contains(&self, commit: &str) -> Result<Vec<u8>> { let output = self .git_command("branch") - .args(&["-r", "--format=%(refname)", "--contains"]) + .args(["-r", "--format=%(refname)", "--contains"]) .arg(commit) .stderr(Stdio::inherit()) .output() @@ -79,7 +79,7 @@ impl<'a> Nixpkgs<'a> { async fn git_fetch_nixpkgs(&self) -> Result<()> { // TODO: add refspecs self.git_command("fetch") - .arg(&self.remote_name) + .arg(self.remote_name) .status() .await .map_err(Error::Io) @@ -109,7 +109,7 @@ impl<'a> Nixpkgs<'a> { }; let mut prefix = PathBuf::from("refs/remotes/"); - prefix.push(&self.remote_name); + prefix.push(self.remote_name); for branch_name in output .split(|byte| *byte == b'\n') diff --git a/src/tree.rs b/src/tree.rs index f569dba..91dc05d 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,11 +1,13 @@ // SPDX-License-Identifier: AGPL-3.0-or-later WITH GPL-3.0-linking-exception // SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +// SPDX-FileCopyrightText: 2022 Arnout Engelen <arnout@bzzt.net> use std::collections::BTreeSet; use std::ffi::{OsStr, OsString}; use askama::Template; +use crate::branches::branch_hydra_link; use crate::branches::next_branches; use crate::github; use crate::nixpkgs::Nixpkgs; @@ -15,6 +17,7 @@ use crate::nixpkgs::Nixpkgs; pub struct Tree { branch_name: String, accepted: Option<bool>, + hydra_link: Option<String>, children: Vec<Tree>, } @@ -27,9 +30,12 @@ impl Tree { .map(|b| Self::generate(b.to_string(), found_branches)) .collect(); + let link = branch_hydra_link(&branch); + Tree { accepted: None, branch_name: branch, + hydra_link: link, children: nexts, } } @@ -46,7 +52,11 @@ impl Tree { } } - pub async fn make(base_branch: String, merge_status: &github::PullRequestStatus, nixpkgs: &Nixpkgs<'_>) -> Tree { + pub async fn make( + base_branch: String, + merge_status: &github::PullRequestStatus, + nixpkgs: &Nixpkgs<'_>, + ) -> Tree { let mut missing_means_absent = true; let mut branches = BTreeSet::new(); @@ -59,9 +69,9 @@ impl Tree { if let Some(merge_commit) = merge_commit_oid { let mut containing_commits = BTreeSet::new(); - if let Err(e) = - nixpkgs.branches_containing_commit(&merge_commit, &mut containing_commits) - .await + if let Err(e) = nixpkgs + .branches_containing_commit(merge_commit, &mut containing_commits) + .await { eprintln!("pr-tracker: branches_containing_commit: {}", e); missing_means_absent = false; |