pub mod finding;
pub mod profile;
pub(crate) mod rules;
pub mod source_tree;
pub mod universal;
use std::path::Path;
pub use finding::{Finding, Severity};
pub use profile::{CustomProfile, PathPattern, Profile, check_profile};
pub use source_tree::{ObjectKey, SourceTree};
pub use universal::{
LINT_AT_PLAN_RULES, check_changeset, check_cluster_changeset, check_plan_time_catalog,
check_universal, check_universal_with_cluster,
};
#[derive(Debug, Clone)]
pub struct LintInputs<'a> {
pub tree: &'a SourceTree,
pub managed: &'a ManagedConfig,
pub profile: &'a Profile,
pub schema_dir: &'a Path,
}
#[derive(Debug, Clone, Default)]
pub struct ManagedConfig {
pub schemas: Vec<crate::identifier::Identifier>,
}
pub fn run(inputs: &LintInputs<'_>) -> Vec<Finding> {
let mut out = check_universal(inputs.tree, inputs.managed);
out.extend(check_profile(
inputs.profile,
inputs.tree,
inputs.schema_dir,
));
out
}
impl SourceTree {
pub fn parse(root: &Path, ignores: &[glob::Pattern]) -> Result<Self, crate::parse::ParseError> {
let (catalog, string_locations) =
crate::parse::parse_directory_with_locations(root, ignores)?;
let mut object_locations = std::collections::HashMap::new();
for s in &catalog.schemas {
if let Some(loc) = string_locations.get(&s.name.to_string()) {
object_locations.insert(ObjectKey::Schema(s.name.clone()), loc.clone());
}
}
for t in &catalog.tables {
if let Some(loc) = string_locations.get(&t.qname.to_string()) {
object_locations.insert(ObjectKey::Table(t.qname.clone()), loc.clone());
}
}
for i in &catalog.indexes {
if let Some(loc) = string_locations.get(&i.qname.to_string()) {
object_locations.insert(ObjectKey::Index(i.qname.clone()), loc.clone());
}
}
for seq in &catalog.sequences {
if let Some(loc) = string_locations.get(&seq.qname.to_string()) {
object_locations.insert(ObjectKey::Sequence(seq.qname.clone()), loc.clone());
}
}
Ok(Self::new(catalog, object_locations))
}
}