refactor: move scattered business logic into domain
- CodeGraph::merge_project_edges() replaces presentation-layer function - Language::is_test_file() centralises test file detection (was in walkdir) - AnalysisConfig::is_standard_excluded() centralises default dir exclusions (was in walkdir) - normalize_cargo_package() / normalize_python_package() in domain replace duplicated normalisers in each adapter - walkdir, cargo-workspace, python-project updated to call domain methods
This commit is contained in:
@@ -5,7 +5,7 @@ use serde::Deserialize;
|
||||
|
||||
use archlens_domain::{
|
||||
CodeElement, CodeElementKind, CodeGraph, DomainError, FilePath, ModuleName, Relationship,
|
||||
RelationshipKind, ports::ProjectAnalyzer,
|
||||
RelationshipKind, normalize_cargo_package, ports::ProjectAnalyzer,
|
||||
};
|
||||
|
||||
pub struct CargoWorkspaceAnalyzer;
|
||||
@@ -97,7 +97,7 @@ impl ProjectAnalyzer for CargoWorkspaceAnalyzer {
|
||||
.map_err(|e| DomainError::ConfigError(e.to_string()))?;
|
||||
|
||||
for dep_name in member.dependencies.keys() {
|
||||
let normalized = dep_name.replace('_', "-");
|
||||
let normalized = normalize_cargo_package(dep_name);
|
||||
if name_set.contains(&normalized)
|
||||
&& let Ok(rel) =
|
||||
Relationship::new(package_name, &normalized, RelationshipKind::Composition)
|
||||
|
||||
@@ -5,7 +5,7 @@ use serde::Deserialize;
|
||||
|
||||
use archlens_domain::{
|
||||
CodeElement, CodeElementKind, CodeGraph, DomainError, FilePath, Relationship, RelationshipKind,
|
||||
ports::ProjectAnalyzer,
|
||||
normalize_python_package, ports::ProjectAnalyzer,
|
||||
};
|
||||
|
||||
pub struct PythonProjectAnalyzer;
|
||||
@@ -59,7 +59,7 @@ fn extract_dep_name(dep: &str) -> &str {
|
||||
}
|
||||
|
||||
fn normalize(name: &str) -> String {
|
||||
name.to_lowercase().replace(['-', '.'], "_")
|
||||
normalize_python_package(name)
|
||||
}
|
||||
|
||||
impl ProjectAnalyzer for PythonProjectAnalyzer {
|
||||
|
||||
@@ -6,20 +6,6 @@ use archlens_domain::{
|
||||
AnalysisConfig, DomainError, FilePath, Language, SourceFile, ports::FileDiscovery,
|
||||
};
|
||||
|
||||
const DEFAULT_EXCLUDES: &[&str] = &[
|
||||
".venv",
|
||||
"venv",
|
||||
"node_modules",
|
||||
"__pycache__",
|
||||
".git",
|
||||
"target",
|
||||
"bin",
|
||||
"obj",
|
||||
"dist",
|
||||
".tox",
|
||||
".eggs",
|
||||
];
|
||||
|
||||
pub struct WalkdirDiscovery;
|
||||
|
||||
impl Default for WalkdirDiscovery {
|
||||
@@ -42,34 +28,13 @@ impl WalkdirDiscovery {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_test_file(path: &Path, language: Language) -> bool {
|
||||
let stem = path
|
||||
.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or_default();
|
||||
let in_tests_dir = path
|
||||
.parent()
|
||||
.map(|p| p.components().any(|c| c.as_os_str() == "tests"))
|
||||
.unwrap_or(false);
|
||||
|
||||
if in_tests_dir {
|
||||
return true;
|
||||
}
|
||||
|
||||
match language {
|
||||
Language::Rust => stem.ends_with("_test") || stem.ends_with("_tests"),
|
||||
Language::Python => stem.starts_with("test_") || stem.ends_with("_test"),
|
||||
Language::CSharp => stem.ends_with("Tests") || stem.ends_with("Test"),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_excluded(path: &Path, root: &Path, excludes: &[String]) -> bool {
|
||||
let relative = path.strip_prefix(root).unwrap_or(path);
|
||||
let relative_str = relative.to_string_lossy();
|
||||
|
||||
for component in relative.components() {
|
||||
let name = component.as_os_str().to_string_lossy();
|
||||
if DEFAULT_EXCLUDES.iter().any(|e| name == *e) {
|
||||
if AnalysisConfig::is_standard_excluded(&name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -109,7 +74,7 @@ impl FileDiscovery for WalkdirDiscovery {
|
||||
}
|
||||
|
||||
if let Some(language) = Self::detect_language(path) {
|
||||
if !config.include_tests() && Self::is_test_file(path, language) {
|
||||
if !config.include_tests() && language.is_test_file(path) {
|
||||
continue;
|
||||
}
|
||||
if let Some(changed) = config.changed_files() {
|
||||
|
||||
Reference in New Issue
Block a user