use std::path::Path;
use anyhow::{Context, Result, anyhow};
use crate::analysis::code_quality::CodeQualityAnalyzer;
use crate::auth;
use crate::cli::MachineFiles;
use crate::config::site::{Refusal, SiteConfig};
use crate::config::{self, Config};
use crate::llm::cache::Cache;
use crate::llm::chain::ProviderChain;
use super::input::Work;
pub(super) struct Locations<'a> {
pub(super) config: &'a Path,
pub(super) machine: &'a MachineFiles<'a>,
}
pub(super) enum Source {
Refused(Refusal),
Analyze(CodeQualityAnalyzer),
}
pub(super) async fn source(
locations: &Locations<'_>,
config: &mut Config,
site: Option<&SiteConfig>,
work: &Work,
cache: Cache,
cache_only: bool,
) -> Result<Source> {
if let Some(site) = site
&& site.has_refuse_markers()
&& let Some(refusal) = site
.refusal_among(&work.reviewed_directories, locations.machine.policy)
.await?
{
return Ok(Source::Refused(refusal));
}
let store = auth::AuthStore::load(locations.machine.auth).with_context(|| {
format!(
"could not read the auth store at {}",
locations.machine.auth.display()
)
})?;
auth::resolve(config, &store).await?;
let providers = config.providers();
if providers.is_empty() {
return Err(config::ConfigError::NoProviders(locations.config.to_path_buf()).into());
}
let chain =
ProviderChain::new(&providers).map_err(|e| anyhow!("could not build LLM analyzer: {e}"))?;
Ok(Source::Analyze(
CodeQualityAnalyzer::new(chain, cache).with_cache_only(cache_only),
))
}