use crate::{
apis::ManagedApis,
environment::{
BlessedSource, ErrorAccumulator, GeneratedSource, ResolvedEnv,
},
output::OutputOpts,
resolved::Resolved,
spec_files_generic::{ApiFiles, AsRawFiles},
};
use dropshot_api_manager_types::ApiIdent;
use std::collections::BTreeMap;
pub(crate) fn debug_impl(
apis: &ManagedApis,
env: &ResolvedEnv,
blessed_source: &BlessedSource,
generated_source: &GeneratedSource,
output: &OutputOpts,
) -> anyhow::Result<()> {
let styles = output.styles(supports_color::Stream::Stderr);
let (local_files, errors) =
env.local_source.load(apis, &styles, &env.repo_root, &env.vcs)?;
dump_structure(&local_files, &errors);
let (blessed, errors) =
blessed_source.load(&env.repo_root, apis, &styles, &env.vcs)?;
dump_structure(&blessed, &errors);
let (generated, errors) =
generated_source.load(apis, &styles, &env.repo_root, &env.vcs)?;
dump_structure(&generated, &errors);
println!("Resolving specs");
let resolved = Resolved::new(env, apis, &blessed, &generated, &local_files);
for note in resolved.notes() {
println!("NOTE: {}", note);
}
for problem in resolved.general_problems() {
println!("PROBLEM: {}", problem);
}
for api in apis.iter_apis() {
let ident = api.ident();
println!(" API: {}", ident);
if let Some(symlink_problem) = resolved.symlink_problem(ident) {
println!(" PROBLEM: {}\n", symlink_problem);
if let Some(fix) = symlink_problem.fix() {
println!(" FIX: {}\n", fix);
}
}
for version in api.iter_versions_semver() {
let resolution = resolved
.resolution_for_api_version(ident, version)
.expect("must have a resolution for every managed API");
print!(" version {}: {}: ", version, resolution.kind());
let problems: Vec<_> = resolution.problems().collect();
if problems.is_empty() {
println!("OK");
} else {
println!("ERROR");
for p in problems {
println!(" PROBLEM: {}\n", p);
if let Some(fix) = p.fix() {
println!(" FIX: {}", fix);
}
}
}
}
}
drop(resolved);
std::thread::scope(|s| {
s.spawn(|| drop(blessed));
s.spawn(|| drop(generated));
s.spawn(|| drop(local_files));
});
Ok(())
}
fn dump_structure<T: AsRawFiles>(
spec_files: &BTreeMap<ApiIdent, ApiFiles<T>>,
error_accumulator: &ErrorAccumulator,
) {
let warnings: Vec<_> = error_accumulator.iter_warnings().collect();
println!("warnings: {}", warnings.len());
for w in warnings {
println!(" warn: {:#}", w);
}
let errors: Vec<_> = error_accumulator.iter_errors().collect();
println!("errors: {}", errors.len());
for e in errors {
println!(" error: {:#}", e);
}
for (api_ident, info) in spec_files {
println!(" API: {}", api_ident);
println!(
" latest: {}",
info.latest_link()
.map(|s| s.to_string())
.as_deref()
.unwrap_or("none")
);
for (version, files) in info.versions() {
println!(" version {}:", version);
for api_spec in files.as_raw_files() {
let version_str = api_spec
.version()
.map(|v| v.to_string())
.unwrap_or_else(|| "unparseable".to_string());
println!(
" file {} (v{})",
api_spec.spec_file_name().path(),
version_str
);
}
}
}
}