// use std::path::Path; use anyhow::{Context, Result}; use model::{Config, FoundMarkers, Line, Marker, MarkerKind}; use patterns::{issue_pattern, marker_pattern}; mod model; mod patterns; fn main() -> Result<()> { println!("Forgejo TODO Checker!"); let config = Config::builder() .fs(kxio::fs::new( std::env::var("GITHUB_WORKSPACE") .context("GITHUB_WORKSPACE")? .into(), )) .repo(std::env::var("GITHUB_REPOSITORY").context("GITHUB_REPOSITORY")?) .server(std::env::var("GITHUB_SERVER_URL").context("GITHUB_SERVER_URL")?) .prefix_pattern(marker_pattern()?) .issue_pattern(issue_pattern()?) .maybe_auth_token(std::env::var("REPO_TOKEN").ok()) .build(); println!("Repo: {}", config.repo()); println!("Prefix: {}", config.prefix_pattern()); println!("Issues: {}", config.issue_pattern()); let mut found_markers = FoundMarkers::default(); for file in ignore::Walk::new(config.fs().base()).flatten() { let path = file.path(); if config.fs().path_is_file(path)? { scan_file(path, &config, &mut found_markers)?; } } println!("{found_markers:?}"); // TODO: add authentication when provided // let issues = ureq::get(&api).call()?.into_string()?; // TODO: parse issues to get list of open issue numbers // TODO: loop over list of expected issues and drop any where they do exist and are open // TODO: if remaining list is not empty - add all to error list // // TODO: if error list is empty - exit okay // TODO: if error list is not empty - log erros and exit not okay Ok(()) } fn scan_file(file: &Path, config: &Config, found_markers: &mut FoundMarkers) -> Result<()> { println!("file: {}", file.to_string_lossy()); config .fs() .file_read_to_string(file)? .lines() .enumerate() .filter_map(|(n, line)| prefix_match(n, line, file, config)) .for_each(|marker| { println!("- {}", marker.line().value()); if let Some(issue) = config .issue_pattern() .find(marker.line().value()) .map(|issue| issue.as_str()) .and_then(|issue| issue.parse::().ok()) { found_markers.add_issue_marker(marker.into_issue_marker(issue)); } else { found_markers.add_marker(marker); } }); Ok(()) } fn prefix_match(num: usize, line: &str, path: &Path, config: &Config) -> Option { let find = config.prefix_pattern().find(line)?; let kind = match find.as_str() { "TODO" => Some(MarkerKind::Todo), "FIXME" => Some(MarkerKind::Fixme), _ => None, }?; Some( Marker::builder() .kind(kind) .file(path.to_path_buf()) .line(Line::builder().num(num).value(line.to_owned()).build()) .build(), ) }