diff options
Diffstat (limited to 'crates/discord-bot')
| -rw-r--r-- | crates/discord-bot/Cargo.toml | 10 | ||||
| -rw-r--r-- | crates/discord-bot/src/commands/track.rs | 29 | ||||
| -rw-r--r-- | crates/discord-bot/src/config.rs | 51 | ||||
| -rw-r--r-- | crates/discord-bot/src/consts.rs | 5 | ||||
| -rw-r--r-- | crates/discord-bot/src/jobs.rs | 22 | ||||
| -rw-r--r-- | crates/discord-bot/src/lib.rs | 3 |
6 files changed, 59 insertions, 61 deletions
diff --git a/crates/discord-bot/Cargo.toml b/crates/discord-bot/Cargo.toml index e45d30e..4eff6ac 100644 --- a/crates/discord-bot/Cargo.toml +++ b/crates/discord-bot/Cargo.toml @@ -14,14 +14,14 @@ name = "nixpkgs-tracker-bot" path = "src/main.rs" [dependencies] -dotenvy = "0.15.7" -env_logger = "0.11.5" -eyre = "0.6.12" +dotenvy = "0.15" +env_logger = "0.11" +eyre = "0.6" git-tracker.workspace = true log.workspace = true nixpkgs-tracker-http.workspace = true -serenity = { version = "0.12.2", features = ["unstable_discord_api"] } -tokio = { version = "1.40.0", features = [ +serenity = { version = "0.12", features = ["unstable_discord_api"] } +tokio = { version = "1.40", features = [ "macros", "rt-multi-thread", "signal" diff --git a/crates/discord-bot/src/commands/track.rs b/crates/discord-bot/src/commands/track.rs index f071ebf..0f0e0be 100644 --- a/crates/discord-bot/src/commands/track.rs +++ b/crates/discord-bot/src/commands/track.rs @@ -1,4 +1,4 @@ -use crate::{config::Config, consts::NIXPKGS_REMOTE, http::GitHubClientExt}; +use crate::{config::Config, http::GitHubClientExt}; use std::sync::Arc; @@ -70,25 +70,18 @@ where return Ok(()); }; - let status_results = git_tracker::collect_statuses_in( - &config.nixpkgs_path, - &commit_sha, - &config.nixpkgs_branches, - )?; - - // find branches containing our PR and trim the remote ref prefix - let found_branches: Vec<String> = status_results + let repository = config.repository(); + let branch_results = repository.branches_contain_sha(config.nixpkgs_branches(), &commit_sha)?; + let fields: Vec<_> = branch_results .iter() - .filter(|&(_, has_pr)| *has_pr) - .map(|(branch_name, _)| { - // remove the ref prefix that we add in our Config struct - let start_pos = format!("{NIXPKGS_REMOTE}/").len(); - branch_name[start_pos..].to_string() + .map(|(name, has_commit)| { + let emoji = if *has_commit { "✅" } else { "❌" }; + (*name, emoji, true) }) .collect(); // if we didn't find any, bail - if found_branches.is_empty() { + if fields.is_empty() { let response = CreateInteractionResponseFollowup::new() .content("This PR has been merged...but I can't seem to find it anywhere. I might not be tracking it's base branch"); command.create_followup(&ctx, response).await?; @@ -100,11 +93,7 @@ where .title(format!("Nixpkgs PR #{} Status", pull_request.number)) .url(&pull_request.html_url) .description(&pull_request.title) - .fields( - found_branches - .iter() - .map(|branch_name| (branch_name, "✅", true)), - ); + .fields(fields); if let Some(merged_at) = pull_request.merged_at { if let Ok(timestamp) = Timestamp::parse(&merged_at) { diff --git a/crates/discord-bot/src/config.rs b/crates/discord-bot/src/config.rs index 5076eb9..afc7845 100644 --- a/crates/discord-bot/src/config.rs +++ b/crates/discord-bot/src/config.rs @@ -1,25 +1,21 @@ -use crate::consts::NIXPKGS_REMOTE; +use git_tracker::TrackedRepository; -use std::env; +use std::{env, path::PathBuf, sync::Arc}; + +const DEFAULT_NIXPKGS_URL: &str = "https://github.com/NixOS/nixpkgs"; + +const DEFAULT_NIXPKGS_REMOTE: &str = "origin"; /// The Discord client's configuration #[derive(Clone, Debug)] pub struct Config { - /// Path to clone a new or use an existing nixpkgs repository - pub nixpkgs_path: String, - // A comma separated list of nixpkgs branch to track commits for - pub nixpkgs_branches: Vec<String>, + /// Comma separated list of nixpkgs branch to track commits for + nixpkgs_branches: Vec<String>, + /// Repository tracker + repository: Arc<TrackedRepository>, } impl Config { - /// Take in a comma separated list and split it into a [`Vec<String>`] - fn split_string_list(branches: &str) -> Vec<String> { - branches - .split(',') - .map(|branch| format!("{NIXPKGS_REMOTE}/{}", branch.trim())) - .collect() - } - /// Create a new instance of [`Config`] based on variables from the environment /// /// # Errors @@ -27,12 +23,33 @@ impl Config { /// Will return [`Err`] if a variable is not found pub fn from_env() -> Result<Self, env::VarError> { let nixpkgs_path = env::var("BOT_NIXPKGS_PATH")?; - let nixpkgs_branches_raw = env::var("BOT_NIXPKGS_BRANCHES")?; - let nixpkgs_branches = Self::split_string_list(&nixpkgs_branches_raw); + + let nixpkgs_branches = env::var("BOT_NIXPKGS_BRANCHES")? + .split(',') + .map(ToString::to_string) + .collect(); + + let nixpkgs_remote = + env::var("BOT_NIXPKGS_REMOTE").unwrap_or(DEFAULT_NIXPKGS_REMOTE.to_string()); + let nixpkgs_url = env::var("BOT_NIXPKGS_URL").unwrap_or(DEFAULT_NIXPKGS_URL.to_string()); + + let repository = TrackedRepository::new( + PathBuf::from(nixpkgs_path.clone()), + nixpkgs_url, + nixpkgs_remote, + ); Ok(Self { - nixpkgs_path, nixpkgs_branches, + repository: Arc::new(repository), }) } + + pub fn repository(&self) -> &TrackedRepository { + &self.repository + } + + pub fn nixpkgs_branches(&self) -> &Vec<String> { + &self.nixpkgs_branches + } } diff --git a/crates/discord-bot/src/consts.rs b/crates/discord-bot/src/consts.rs deleted file mode 100644 index 9396da0..0000000 --- a/crates/discord-bot/src/consts.rs +++ /dev/null @@ -1,5 +0,0 @@ -/// URL to the nixpkgs repository -pub const NIXPKGS_URL: &str = "https://github.com/NixOS/nixpkgs"; - -/// The Git remote for upstream nixpkgs in our local copy -pub const NIXPKGS_REMOTE: &str = "origin"; diff --git a/crates/discord-bot/src/jobs.rs b/crates/discord-bot/src/jobs.rs index 40d34cc..f35c471 100644 --- a/crates/discord-bot/src/jobs.rs +++ b/crates/discord-bot/src/jobs.rs @@ -1,9 +1,8 @@ -use crate::{config::Config, consts::NIXPKGS_REMOTE, consts::NIXPKGS_URL}; +use crate::config::Config; -use std::{path::Path, time::Duration}; +use std::time::Duration; use eyre::Result; -use git_tracker::ManagedRepository; use log::error; const TTL_SECS: u64 = 60 * 5; // 5 minutes @@ -13,20 +12,19 @@ const TTL_SECS: u64 = 60 * 5; // 5 minutes /// # Errors /// /// Will return [`Err`] if any jobs fail -pub fn dispatch(config: Config) -> Result<()> { - let managed_repository = ManagedRepository { - path: Path::new(&config.nixpkgs_path).to_path_buf(), - tracked_branches: config.nixpkgs_branches, - upstream_remote_url: NIXPKGS_URL.to_string(), - upstream_remote_name: NIXPKGS_REMOTE.to_string(), - }; +pub fn dispatch(config: &Config) -> Result<()> { + let repository = config.repository(); + if repository.open().is_err() { + repository.clone_repository()?; + } + repository.fetch()?; - managed_repository.fetch_or_update()?; + let repository_clone = repository.clone(); tokio::spawn(async move { loop { tokio::time::sleep(Duration::from_secs(TTL_SECS)).await; - if let Err(why) = managed_repository.fetch_or_update() { + if let Err(why) = repository_clone.fetch() { error!("Could not fetch or update repository!\n{why:?}"); }; } diff --git a/crates/discord-bot/src/lib.rs b/crates/discord-bot/src/lib.rs index 7ac2e98..3248db5 100644 --- a/crates/discord-bot/src/lib.rs +++ b/crates/discord-bot/src/lib.rs @@ -6,7 +6,6 @@ use serenity::prelude::{Client, GatewayIntents, TypeMapKey}; mod commands; mod config; -mod consts; mod handler; mod jobs; @@ -76,7 +75,7 @@ pub async fn client() -> Result<Client> { }); // run our jobs - jobs::dispatch(config)?; + jobs::dispatch(&config)?; Ok(client) } |
