use std::path::Path;
use skif_core::{Category, Fix, FixOp, FixSafety, Fixability, RuleMeta, Severity, diagnostic, slash};
use skif_lint::Emitter;
use super::JsRule;
use super::support::file_location;
use crate::analysis::JsAnalysis;
pub static META: RuleMeta = RuleMeta::new(
"unused-files",
Category::Js,
Some(Severity::Warning),
Fixability::Unsafe,
"A project file is not reachable from any entry file.",
);
pub struct UnusedFiles;
fn unreachable_message(path: &Path) -> String {
format!("`{}` is not reachable from any entry file", slash(path))
}
impl JsRule for UnusedFiles {
fn meta(&self) -> &'static RuleMeta {
&META
}
fn check(&self, analysis: &JsAnalysis<'_>, out: &mut Emitter<'_>) {
for file in &analysis.unused_files {
let mut builder = diagnostic(&META, unreachable_message(&file.path), file_location(file.path.clone()))
.help("delete it, or add it to `entry` when a tool loads it");
if let Some(package) = analysis.workspace.package(file.owner) {
builder = builder.package(package.display_name());
}
out.emit(
builder
.fix(Fix::new(
format!("Delete `{}`", slash(&file.path)),
FixSafety::Unsafe,
vec![FixOp::delete_file(file.path.clone())],
))
.build(),
);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_message_names_the_file_with_forward_slashes() {
let path = Path::new("packages").join("lib").join("src").join("unused.ts");
assert_eq!(
unreachable_message(&path),
"`packages/lib/src/unused.ts` is not reachable from any entry file"
);
}
}