From f8ece9783b9e7c9c14a456893679b0d60a21f466 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Mon, 9 Feb 2026 12:12:44 +0000 Subject: [PATCH 1/3] Set up logging for more binaries --- src/bin/match-pr-to-assignment.rs | 3 +++ src/bin/trainee-tracker.rs | 13 ++----------- src/lib.rs | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/bin/match-pr-to-assignment.rs b/src/bin/match-pr-to-assignment.rs index 6f74143..e2b0dbc 100644 --- a/src/bin/match-pr-to-assignment.rs +++ b/src/bin/match-pr-to-assignment.rs @@ -8,6 +8,7 @@ use trainee_tracker::{ newtypes::Region, octocrab::octocrab_for_token, prs::get_prs, + setup_logging, }; #[tokio::main] @@ -19,6 +20,8 @@ async fn main() { exit(1); }; + setup_logging(); + let octocrab = octocrab_for_token(github_token.to_owned()).expect("Failed to get octocrab"); let Ok( diff --git a/src/bin/trainee-tracker.rs b/src/bin/trainee-tracker.rs index e6e51da..c3c2bd7 100644 --- a/src/bin/trainee-tracker.rs +++ b/src/bin/trainee-tracker.rs @@ -2,8 +2,7 @@ use axum::routing::{get, post}; use dotenv::dotenv; use tower_sessions::{Expiry, MemoryStore, SessionManagerLayer}; use tracing::info; -use tracing_subscriber::prelude::*; -use trainee_tracker::{Config, ServerState}; +use trainee_tracker::{Config, ServerState, setup_logging}; use std::net::SocketAddr; @@ -17,15 +16,7 @@ async fn main() { ); } - let stderr_log_level = tracing_subscriber::filter::LevelFilter::INFO; - let stderr_layer = tracing_subscriber::fmt::layer() - .pretty() - .with_writer(std::io::stderr); - - tracing_subscriber::registry() - .with(stderr_layer.with_filter(stderr_log_level)) - .try_init() - .expect("Failed to configure logging"); + setup_logging(); if let Err(err) = dotenv() { if !err.not_found() { diff --git a/src/lib.rs b/src/lib.rs index 7fbd8c2..31a4b3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,9 @@ use axum::response::{Html, IntoResponse, Response}; use moka::future::Cache; use slack_with_types::client::RateLimiter; use tracing::error; +use tracing_subscriber::Layer; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; use uuid::Uuid; pub mod auth; @@ -145,3 +148,15 @@ impl From for Error { Error::Fatal(error) } } + +pub fn setup_logging() { + let stderr_log_level = tracing_subscriber::filter::LevelFilter::INFO; + let stderr_layer = tracing_subscriber::fmt::layer() + .pretty() + .with_writer(std::io::stderr); + + tracing_subscriber::registry() + .with(stderr_layer.with_filter(stderr_log_level)) + .try_init() + .expect("Failed to configure logging"); +} From 3ca6b5bcb80a1615ac1755bb7d83a9855a65c42c Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Mon, 9 Feb 2026 12:13:10 +0000 Subject: [PATCH 2/3] Improve PR/assignment matching Only look at the assignment title parts of the description. Previously we were including things like "sprint 3", which all PRs contain, which was artificially inflating the matches for things like "Complete Sprint 3 exercises", causing PRs to be incorrectly matched. --- src/course.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/course.rs b/src/course.rs index 997bbca..e0f216a 100644 --- a/src/course.rs +++ b/src/course.rs @@ -27,6 +27,7 @@ use octocrab::{ }; use regex::Regex; use serde::Serialize; +use tracing::debug; use url::Url; impl CourseScheduleWithRegisterSheetId { @@ -945,11 +946,12 @@ fn match_pr_to_assignment( continue; } } - let mut pr_title_words = title_word_set(&pr.title); + let mut pr_title_words = title_word_set(pr.title.split("|").last().unwrap_or_default()); if let Some(claimed_sprint_index) = claimed_sprint_index { let claimed_sprint_number = claimed_sprint_index + 1; pr_title_words.insert(format!("sprint{}", claimed_sprint_number)); } + debug!(pr=pr.title, title_words=?pr_title_words, "Considering PR"); for (assignment_index, assignment) in sprint.assignments.iter().enumerate() { match assignment { @@ -969,6 +971,10 @@ fn match_pr_to_assignment( } } let match_count = assignment_title_words.intersection(&pr_title_words).count(); + debug!( + ?assignment_title_words, + match_count, "Comparing to assignment" + ); if !submissions[sprint_index].submissions[assignment_index].is_submitted() && match_count > best_match @@ -976,6 +982,7 @@ fn match_pr_to_assignment( .map(|best_match| best_match.match_count) .unwrap_or_default() { + debug!(match_count, "Best match!"); best_match = Some(Match { match_count, sprint_index, @@ -1047,10 +1054,10 @@ fn title_word_set(title: &str) -> IndexSet { title .to_lowercase() .split(" ") + .filter(|s| !s.is_empty()) .flat_map(|word| word.split("_")) .flat_map(|word| word.split("-")) .flat_map(|word| word.split("/")) - .flat_map(|word| word.split("|")) .map(|s| s.to_owned()) .collect() } From 0d16e6707b609d8b79d1b2d2983d54f8d3532c80 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Mon, 9 Feb 2026 12:14:11 +0000 Subject: [PATCH 3/3] Improve output format of matching debugger --- src/bin/match-pr-to-assignment.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/bin/match-pr-to-assignment.rs b/src/bin/match-pr-to-assignment.rs index e2b0dbc..e4190a3 100644 --- a/src/bin/match-pr-to-assignment.rs +++ b/src/bin/match-pr-to-assignment.rs @@ -4,7 +4,7 @@ use chrono::NaiveDate; use indexmap::IndexMap; use trainee_tracker::{ config::{CourseSchedule, CourseScheduleWithRegisterSheetId}, - course::match_prs_to_assignments, + course::{Assignment, Submission, SubmissionState, match_prs_to_assignments}, newtypes::Region, octocrab::octocrab_for_token, prs::get_prs, @@ -61,7 +61,7 @@ async fn main() { .map(|region| (Region(region.to_string()), fixed_date)) .collect() }) - .take(3) + .take(5) .collect(), ); let course_schedule = CourseSchedule { @@ -109,10 +109,23 @@ async fn main() { .iter() .zip(sprint_with_submissions.submissions.iter()) { - println!("{:?} - {:?}", assignment, submission); + if let Assignment::ExpectedPullRequest { title, .. } = assignment { + let text = match submission { + SubmissionState::Some(Submission::PullRequest { pull_request, .. }) => { + format!("{} ({})", pull_request.title, pull_request.url) + } + SubmissionState::MissingButExpected(..) => "MissingButExpected".to_owned(), + SubmissionState::MissingButNotExpected(..) => { + "MissingButNotExpected".to_owned() + } + SubmissionState::MissingStretch(..) => "MissingStretch".to_owned(), + SubmissionState::Some(..) => "Wrong submission type".to_owned(), + }; + println!("{} - {}", title, text); + } } } for unknown in matched.unknown_prs { - println!("Unknown PR: {:?}", unknown); + println!("Unknown PR: {:#?}", unknown); } }