Source code for atloop.retrieval.project_profile

"""Project profile detection."""

from dataclasses import dataclass
from typing import Dict, List, Optional

from atloop.tools.runtime import ToolRuntime


[docs] @dataclass class ProjectProfile: """Project profile information.""" language: Optional[str] = None # python, node, go, rust, java package_manager: Optional[str] = None # pip, npm, yarn, pnpm, cargo, go mod test_commands: List[str] = None # List of test command candidates format_commands: List[str] = None # List of format command candidates lint_commands: List[str] = None # List of lint command candidates
[docs] def __post_init__(self): """Initialize default values.""" if self.test_commands is None: self.test_commands = [] if self.format_commands is None: self.format_commands = [] if self.lint_commands is None: self.lint_commands = []
[docs] def to_dict(self) -> Dict: """Convert to dictionary.""" return { "language": self.language, "package_manager": self.package_manager, "test_commands": self.test_commands, "format_commands": self.format_commands, "lint_commands": self.lint_commands, }
[docs] class ProjectProfileDetector: """Detect project profile from workspace."""
[docs] def __init__(self, tool_runtime: ToolRuntime): """ Initialize project profile detector. Args: tool_runtime: Tool runtime instance """ self.tool_runtime = tool_runtime
[docs] def detect(self) -> ProjectProfile: """ Detect project profile. Returns: ProjectProfile instance """ profile = ProjectProfile() # Check for Python if ( self._file_exists("pyproject.toml") or self._file_exists("requirements.txt") or self._file_exists("setup.py") ): profile.language = "python" profile.package_manager = "pip" profile.test_commands = ["pytest -q", "python -m pytest -q", "python -m unittest"] profile.format_commands = ["black .", "autopep8 --in-place --recursive ."] profile.lint_commands = ["ruff check .", "pylint .", "flake8 ."] return profile # Check for Node.js if self._file_exists("package.json"): profile.language = "node" # Check package manager package_json = self._read_file("package.json") if package_json: if '"pnpm"' in package_json or "pnpm-lock.yaml" in self._list_files(): profile.package_manager = "pnpm" profile.test_commands = ["pnpm test", "pnpm run test"] elif '"yarn"' in package_json or "yarn.lock" in self._list_files(): profile.package_manager = "yarn" profile.test_commands = ["yarn test", "yarn run test"] else: profile.package_manager = "npm" profile.test_commands = ["npm test", "npm run test"] else: profile.package_manager = "npm" profile.test_commands = ["npm test", "npm run test"] profile.format_commands = ["prettier --write .", "npx prettier --write ."] profile.lint_commands = ["eslint .", "npx eslint ."] return profile # Check for Go if self._file_exists("go.mod"): profile.language = "go" profile.package_manager = "go mod" profile.test_commands = ["go test ./...", "go test -v ./..."] profile.format_commands = ["gofmt -w .", "go fmt ./..."] profile.lint_commands = ["golangci-lint run", "golint ./..."] return profile # Check for Rust if self._file_exists("Cargo.toml"): profile.language = "rust" profile.package_manager = "cargo" profile.test_commands = ["cargo test", "cargo test --verbose"] profile.format_commands = ["cargo fmt"] profile.lint_commands = ["cargo clippy"] return profile # Check for Java if self._file_exists("pom.xml"): profile.language = "java" profile.package_manager = "maven" profile.test_commands = ["mvn test", "mvn verify"] profile.format_commands = [] profile.lint_commands = ["mvn checkstyle:check"] return profile if self._file_exists("build.gradle") or self._file_exists("build.gradle.kts"): profile.language = "java" profile.package_manager = "gradle" profile.test_commands = ["gradle test", "./gradlew test"] profile.format_commands = [] profile.lint_commands = [] return profile
def _file_exists(self, filename: str) -> bool: """Check if file exists.""" import shlex filename_escaped = shlex.quote(filename) result = self.tool_runtime.run( f"test -f {filename_escaped} 2>/dev/null && echo 'exists' || echo 'not'", timeout_sec=5 ) return result.ok and "exists" in result.stdout def _read_file(self, filename: str) -> Optional[str]: """Read file content.""" import shlex filename_escaped = shlex.quote(filename) result = self.tool_runtime.run( f"head -n 50 {filename_escaped} 2>/dev/null || cat {filename_escaped} 2>/dev/null", timeout_sec=5, ) if result.ok: return result.stdout return None def _list_files(self) -> str: """List files in current directory.""" result = self.tool_runtime.run("ls -a 2>/dev/null || echo ''", timeout_sec=5) if result.ok: return result.stdout return ""