Initial upload: dependency freshness checker CLI tool
Some checks failed
CI / test (push) Failing after 11s
Some checks failed
CI / test (push) Failing after 11s
This commit is contained in:
91
src/depcheck/models.py
Normal file
91
src/depcheck/models.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
"""Data models for depcheck."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from enum import Enum
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
class Severity(str, Enum):
|
||||||
|
"""Severity levels for vulnerabilities and updates."""
|
||||||
|
|
||||||
|
CRITICAL = "critical"
|
||||||
|
HIGH = "high"
|
||||||
|
MEDIUM = "medium"
|
||||||
|
LOW = "low"
|
||||||
|
INFO = "info"
|
||||||
|
|
||||||
|
|
||||||
|
class PackageManager(str, Enum):
|
||||||
|
"""Supported package managers."""
|
||||||
|
|
||||||
|
NPM = "npm"
|
||||||
|
PIP = "pip"
|
||||||
|
GO = "go"
|
||||||
|
CARGO = "cargo"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Dependency:
|
||||||
|
"""Represents a single dependency."""
|
||||||
|
|
||||||
|
name: str
|
||||||
|
current_version: str
|
||||||
|
package_manager: PackageManager
|
||||||
|
latest_version: Optional[str] = None
|
||||||
|
is_outdated: bool = False
|
||||||
|
vulnerabilities: list = field(default_factory=list)
|
||||||
|
category: str = "dependencies"
|
||||||
|
source_file: Optional[str] = None
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash((self.name, self.package_manager.value, self.current_version))
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if not isinstance(other, Dependency):
|
||||||
|
return False
|
||||||
|
return (
|
||||||
|
self.name == other.name
|
||||||
|
and self.package_manager == other.package_manager
|
||||||
|
and self.current_version == other.current_version
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Vulnerability:
|
||||||
|
"""Represents a security vulnerability."""
|
||||||
|
|
||||||
|
cve_id: str
|
||||||
|
severity: Severity
|
||||||
|
description: str
|
||||||
|
affected_versions: str
|
||||||
|
fixed_version: Optional[str] = None
|
||||||
|
references: list[str] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ScanResult:
|
||||||
|
"""Result of a dependency scan."""
|
||||||
|
|
||||||
|
dependencies: list[Dependency] = field(default_factory=list)
|
||||||
|
vulnerabilities: list[tuple[Dependency, Vulnerability]] = field(default_factory=list)
|
||||||
|
scan_errors: list[str] = field(default_factory=list)
|
||||||
|
package_manager: Optional[PackageManager] = None
|
||||||
|
source_file: Optional[str] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def outdated_count(self) -> int:
|
||||||
|
return sum(1 for d in self.dependencies if d.is_outdated)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def vulnerable_count(self) -> int:
|
||||||
|
return len(self.vulnerabilities)
|
||||||
|
|
||||||
|
def get_highest_severity(self) -> Optional[Severity]:
|
||||||
|
if not self.vulnerabilities:
|
||||||
|
return None
|
||||||
|
severity_order = [Severity.CRITICAL, Severity.HIGH, Severity.MEDIUM, Severity.LOW]
|
||||||
|
for severity in severity_order:
|
||||||
|
for dep, vuln in self.vulnerabilities:
|
||||||
|
if vuln.severity == severity:
|
||||||
|
return severity
|
||||||
|
return None
|
||||||
Reference in New Issue
Block a user