Skip to content

Commit 64daa3b

Browse files
committed
fix: read req files with non canonical names
1 parent c1e0c90 commit 64daa3b

File tree

3 files changed

+128
-3
lines changed

3 files changed

+128
-3
lines changed

app/domain/repo_analyzer/requirement_files/analyzer_registry.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,26 @@ def initialize(self) -> None:
4545
}
4646

4747
def get_analyzer(self, filename: str) -> RequirementFileAnalyzer | None:
48-
return self.analyzers.get(filename)
48+
file_basename = filename.split("/")[-1]
49+
50+
if file_basename in self.analyzers:
51+
return self.analyzers[file_basename]
52+
53+
file_lower = file_basename.lower()
54+
55+
if "requirements" in file_lower and file_basename.endswith(".txt"):
56+
return self.analyzers["requirements.txt"]
57+
58+
if "gemfile" in file_lower and not file_basename.endswith((".lock", ".txt")):
59+
return self.analyzers.get("Gemfile")
60+
61+
if "package" in file_lower and file_basename.endswith(".json") and "lock" not in file_lower:
62+
return self.analyzers.get("package.json")
63+
64+
if "package-lock" in file_lower and file_basename.endswith(".json"):
65+
return self.analyzers.get("package-lock.json")
66+
67+
return None
4968

5069
def analyze(
5170
self,

tests/unit/domain/analyzers/test_analyzer_registry.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def test_get_analyzer_packages_config(self):
103103
def test_get_analyzer_with_path_prefix(self):
104104
registry = AnalyzerRegistry()
105105
analyzer = registry.get_analyzer("/master/requirements.txt")
106-
assert analyzer is None
106+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
107107

108108
analyzer = registry.get_analyzer("requirements.txt")
109109
assert isinstance(analyzer, RequirementsTxtAnalyzer)
@@ -120,7 +120,7 @@ def test_get_analyzer_case_sensitive(self):
120120
assert isinstance(analyzer, GemfileAnalyzer)
121121

122122
analyzer = registry.get_analyzer("gemfile")
123-
assert analyzer is None
123+
assert isinstance(analyzer, GemfileAnalyzer)
124124

125125
def test_registry_contains_all_analyzers(self):
126126
registry = AnalyzerRegistry()
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import pytest
2+
3+
from app.domain.repo_analyzer.requirement_files.analyzer_registry import (
4+
AnalyzerRegistry,
5+
)
6+
from app.domain.repo_analyzer.requirement_files.gemfile_analyzer import GemfileAnalyzer
7+
from app.domain.repo_analyzer.requirement_files.package_json_analyzer import (
8+
PackageJsonAnalyzer,
9+
)
10+
from app.domain.repo_analyzer.requirement_files.requirements_txt_analyzer import (
11+
RequirementsTxtAnalyzer,
12+
)
13+
14+
15+
class TestAnalyzerRegistryPatternMatching:
16+
@pytest.fixture
17+
def registry(self):
18+
return AnalyzerRegistry()
19+
20+
def test_exact_match_requirements_txt(self, registry):
21+
analyzer = registry.get_analyzer("requirements.txt")
22+
assert analyzer is not None
23+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
24+
25+
def test_pattern_match_safe_requirements(self, registry):
26+
analyzer = registry.get_analyzer("safe_requirements.txt")
27+
assert analyzer is not None
28+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
29+
30+
def test_pattern_match_vulnerable_requirements(self, registry):
31+
analyzer = registry.get_analyzer("vulnerable_requirements.txt")
32+
assert analyzer is not None
33+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
34+
35+
def test_pattern_match_dev_requirements(self, registry):
36+
analyzer = registry.get_analyzer("dev-requirements.txt")
37+
assert analyzer is not None
38+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
39+
40+
def test_pattern_match_test_requirements(self, registry):
41+
analyzer = registry.get_analyzer("test_requirements.txt")
42+
assert analyzer is not None
43+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
44+
45+
def test_pattern_match_prod_requirements(self, registry):
46+
analyzer = registry.get_analyzer("prod.requirements.txt")
47+
assert analyzer is not None
48+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
49+
50+
def test_pattern_match_with_path(self, registry):
51+
analyzer = registry.get_analyzer("path/to/safe_requirements.txt")
52+
assert analyzer is not None
53+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
54+
55+
def test_case_insensitive_requirements(self, registry):
56+
analyzer = registry.get_analyzer("Safe_Requirements.txt")
57+
assert analyzer is not None
58+
assert isinstance(analyzer, RequirementsTxtAnalyzer)
59+
60+
def test_exact_match_package_json(self, registry):
61+
analyzer = registry.get_analyzer("package.json")
62+
assert analyzer is not None
63+
assert isinstance(analyzer, PackageJsonAnalyzer)
64+
65+
def test_pattern_match_fails_for_wrong_extension(self, registry):
66+
analyzer = registry.get_analyzer("requirements.py")
67+
assert analyzer is None
68+
69+
def test_pattern_match_fails_for_non_requirement_file(self, registry):
70+
analyzer = registry.get_analyzer("random.txt")
71+
assert analyzer is None
72+
73+
def test_exact_match_gemfile(self, registry):
74+
analyzer = registry.get_analyzer("Gemfile")
75+
assert analyzer is not None
76+
assert isinstance(analyzer, GemfileAnalyzer)
77+
78+
def test_pattern_match_gemfile_variants(self, registry):
79+
analyzer = registry.get_analyzer("gemfile.dev")
80+
assert analyzer is not None
81+
assert isinstance(analyzer, GemfileAnalyzer)
82+
83+
def test_singleton_pattern(self):
84+
registry1 = AnalyzerRegistry()
85+
registry2 = AnalyzerRegistry()
86+
assert registry1 is registry2
87+
88+
def test_all_standard_analyzers_registered(self, registry):
89+
standard_files = [
90+
"requirements.txt",
91+
"pyproject.toml",
92+
"setup.py",
93+
"setup.cfg",
94+
"package.json",
95+
"package-lock.json",
96+
"Gemfile",
97+
"Gemfile.lock",
98+
"Cargo.toml",
99+
"Cargo.lock",
100+
"pom.xml",
101+
"packages.config",
102+
]
103+
104+
for filename in standard_files:
105+
analyzer = registry.get_analyzer(filename)
106+
assert analyzer is not None, f"No analyzer found for {filename}"

0 commit comments

Comments
 (0)