From 9690e255ce11f90e771bfe189f64abca4ca6af86 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Wed, 4 Feb 2026 14:56:30 +0000 Subject: [PATCH] Add package manager parsers (npm, pip, go, cargo) --- src/depcheck/parsers/npm.py | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/depcheck/parsers/npm.py diff --git a/src/depcheck/parsers/npm.py b/src/depcheck/parsers/npm.py new file mode 100644 index 0000000..d8f8301 --- /dev/null +++ b/src/depcheck/parsers/npm.py @@ -0,0 +1,60 @@ +"""NPM package.json parser.""" + +import json +from pathlib import Path + +from depcheck.models import Dependency, PackageManager +from depcheck.parsers import Parser +from depcheck.utils import parse_version_string + + +class NpmParser(Parser): + """Parser for npm package.json files.""" + + package_manager = PackageManager.NPM + + def supports_file(self, file_path: Path) -> bool: + return file_path.name == "package.json" + + def get_file_patterns(self) -> list[str]: + return ["package.json"] + + def parse(self, file_path: Path) -> list[Dependency]: + dependencies: list[Dependency] = [] + + try: + content = file_path.read_text() + data = json.loads(content) + except (json.JSONDecodeError, OSError): + return dependencies + + sections = [ + ("dependencies", "dependencies"), + ("devDependencies", "devDependencies"), + ("optionalDependencies", "optionalDependencies"), + ] + + for section_key, category in sections: + section = data.get(section_key, {}) + if not isinstance(section, dict): + continue + + for name, version_info in section.items(): + if isinstance(version_info, dict): + version = version_info.get("version", "") + else: + version = str(version_info) + + version = parse_version_string(version) + if version: + dependencies.append( + Dependency( + name=name, + current_version=version, + package_manager=self.package_manager, + category=category, + source_file=str(file_path), + ) + ) + + return dependencies