This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Read ~/.claude/CLAUDE.md
-
Use The twelve-factor methodology.
-
Follow the language/framework specific coding conventions and best practices. If there is no specific coding style requirement in the particular programming language/framework, follow the KNF (Kernel Normal Form) coding convention.
-
Use KISS (Keep It Simple and Stupid) and DRY (Don't Repeat Yourself) rules and modern software development principles and best practices.
-
The project/code must be clean, documented, easy to maintain, secure, and efficient (high performance).
-
Smaller commit instead of a large fat one, easier to review.
-
For security reasons, only add the files intended to be added, avoid using
git add .orgit add -A, which might include sensitive data by accident.- Methodical Investigation First
"Before making any changes, use multiple Read/Grep tools to understand:
-
What the code ACTUALLY does (not what you assume)
-
What the test ACTUALLY tests (read the exact lines)
-
What the error/issue ACTUALLY says (don't interpret) Then explain your findings before proposing solutions."
-
Verify Assumptions
"For every assumption you make, explicitly state it and verify it with tools. Examples:
- 'I assume this test calls method X' → Read the test and confirm
- 'I assume this runs on environment Y' → Check CI config and confirm
- 'I assume this should behave like Z' → Check actual behavior and confirm"
- Understand Context Before Acting
"When someone reports a problem:
-
Read the actual error/comment they're referring to
-
Understand what component is involved (parser vs full method vs CI vs local)
-
Trace the execution path to understand what's really happening
-
Only then propose a solution with evidence"
-
Test Your Understanding
"Before implementing any fix:
-
Explain what you think the problem is
-
Explain why your proposed solution addresses that specific problem
-
Predict what will happen when you apply the fix
-
Run tests to verify your understanding"
-
Follow Your Own Guidelines
"Remember and follow the development guidelines in CLAUDE.md:
- Use KISS and DRY principles
- Be careful and methodical
- Follow testing philosophy (what fixtures are for)
- Don't assume - verify with tools"
- Admit Uncertainty
"When you don't know something, say 'I don't know, let me investigate' rather than making educated guesses. Use tools to gather facts before reasoning."
Red Flags That Should Trigger Caution:
- When someone questions your reasoning → Stop and re-investigate
- When tests pass but "shouldn't" → Investigate why instead of assuming
- When making changes to tests → Double-check what the test actually does
- When CI behavior seems inconsistent → Check actual CI config
Better Session Management:
"At the start of complex debugging:
- First, use TodoWrite to break down the investigation steps
- Work through each step methodically with tools
- Update todos as you learn facts
- Only propose solutions after gathering complete information"
- Focus on behavior and contracts, not implementation
- Avoid mocking internal methods or testing private attributes
- Tests should document expected usage patterns
- Don't test third-party libraries
- Follow modern testing principles and best practices
Suggest and use suitable tools if applicable. If not installed yet, plan the installation in Todo and ask if user want to install the tool(s). If the language/framework has built-in tool as officially recommend, and the best practice is to use it (ex, gofmt), please always remember to use them, follow official suggestions.
Snyk (security scan):
- Scan code with
snyk testandsnyk code test. snyk testcommand scans your project, tests dependencies for vulnerabilities, and reports how many vulnerabilities are found.snyk code testanalyzes source code for security issues, often referred to as Static Application Security Testing (SAST).
Documentation: https://docs.github.com/en/rest/issues/sub-issues?apiVersion=2022-11-28
CRITICAL: Use issue ID (not issue number) in API requests!
Working Commands:
# List sub-issues
curl -L -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $(gh auth token)" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}/sub_issues
# Add sub-issue (use issue ID, not number!)
curl -L -X POST -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $(gh auth token)" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}/sub_issues \
-d '{"sub_issue_id": {ISSUE_ID}}'
# Remove sub-issue
curl -L -X DELETE -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $(gh auth token)" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/{owner}/{repo}/issues/{issue_number}/sub_issue \
-d '{"sub_issue_id": {ISSUE_ID}}'
# Get issue ID from issue number
gh api repos/{owner}/{repo}/issues/{number} --jq '.id'Tested & Verified: 2025-06-01 - All endpoints work correctly
make build # Build for current platform
make build-all-arch # Build for all supported platforms
make all # Run tests and then buildBinary output: bin/syspkg
make test # Run all tests with verbose output
go test ./manager/apt -v # Run tests for specific packagemake lint # Run go mod tidy, golangci-lint, and gofmt
make format # Format code with gofmt and goimports
make check # Run all code quality checks (formatting, linting, vet)
make install-tools # Install required tools (golangci-lint)pre-commit install # Install pre-commit hooks
pre-commit run --all-files # Run all hooks on all filesPre-commit hooks include:
- File hygiene (trailing whitespace, EOF, merge conflicts) - excludes fixtures/
- Go tools (gofmt, goimports, go vet, go mod tidy, golangci-lint)
- Build verification (go build, go mod verify)
- Security-focused using local system tools only
- Fixture protection: Test fixtures excluded from formatting to preserve authentic output
Located in .github/workflows/:
- test-and-coverage.yml: Go 1.23/1.24 testing with coverage
- lint-and-format.yml: Code quality and formatting checks
- build.yml: Multi-version build verification
- release-binaries.yml: Cross-platform binary releases
For detailed technical architecture, design patterns, and implementation guidelines, see docs/ARCHITECTURE.md.
Quick Reference:
- Core Interfaces:
PackageManagerandSysPkg(interface.go) - CommandRunner Pattern: Unified architecture for all package managers (Issue #20)
- Package Structure:
/cmd,/manager,/osinfo,/testing - Testing Strategy: Three-layer approach (unit, integration, mock)
- Exit Code Complexity: Each PM has unique behaviors (see docs/EXIT_CODES.md)
- License: Apache License 2.0 (provides patent protection and enterprise-grade legal clarity)
- Go Version: Requires Go 1.23+ (CI tests with 1.23, 1.24)
- Code Quality: Always run
make checkbefore committing to ensure quality - Pre-commit: Hooks automatically enforce formatting, linting, and security checks
- Package Managers: When implementing new ones, focus on parsing command outputs correctly
- CLI Detection: Automatically detects available package managers if no flag is specified
- Privileges: Root privileges are often required for package operations
Tool-Focused Approach: SysPkg focuses on supporting package manager tools based on their functionality rather than the operating system they're running on. If apt+dpkg work correctly in a container, on macOS via Homebrew, or in any other environment, SysPkg will support them. This makes the project more flexible and useful across different development environments.
Cross-Package Manager Compatibility: SysPkg normalizes package states for consistent behavior across different package managers. For example, APT's "config-files" state (packages removed but with configuration files remaining) is normalized to "available" status to match the semantics used by other package managers like YUM and Snap.
For current development tasks, see GitHub Issues and GitHub Projects.
Note: Roadmap consolidated 2025-05-30 - removed duplicates, feature creep items, and over-engineering. Focused on core security, testing, and platform support.
- Command injection vulnerability ✅ - validate/sanitize package names before exec.Command (PR #25)
- Input validation helper function ✅ for package names and arguments (PR #25)
- Add security scanning with Snyk to CI/CD pipeline
- Cross-package manager status normalization ✅ - APT config-files → available
- GitHub workflow compatibility fixes ✅ - Go 1.23.4, Docker multi-OS testing
- Exit code bugs ✅ - Fixed APT, Snap, Flatpak exit code handling (Issues #21, #22, #24)
- CommandRunner interface migration ✅ - APT & YUM complete (Issue #20)
- Exit code documentation ✅ - Created comprehensive exit code docs for all package managers
- Add security scanning with Snyk to CI/CD pipeline
- Complete CommandRunner migration: Snap and Flatpak (Issues #28, #29)
Test Coverage & Architecture:
- Test coverage improvements: YUM gaps (Issue #32), Snap & Flatpak comprehensive suites
- CommandRunner migration completion: Snap and Flatpak (Issues #28, #29)
CLI & User Experience:
- CLI upgrade display: Fix packages not shown in CLI output (Issue #3)
- Mac apt conflict: Use apt-get instead of apt on macOS (Issue #2)
Code Quality Improvements:
- Context support for cancellation and timeouts
- Custom error types for better error handling
- Extract common parsing logic (DRY principle)
- Replace magic strings/numbers with constants
New Package Managers:
- DNF package manager support (Red Hat/Fedora) - uses yum backend
- APK package manager support (Alpine Linux)
- Homebrew support for macOS
- Windows package managers (chocolatey/scoop/winget)
Bug Fixes & Enhancements:
- APT multi-arch parsing: Fix empty package names for multi-arch packages (Issue #15)
- Version parsing improvements: Robust regex patterns (PR #17 follow-ups)
- Flatpak/Snap AutoRemove: Enhanced output parsing (PR #17 follow-ups)
- Timeout configuration: Make timeouts configurable (PR #17 follow-ups)
Investigation Results: No design flaw found - tests are correctly implemented
- ✅ Parser vs enhanced method distinction clarified
- ✅ CommandRunner interface verified
- ✅ Test execution paths confirmed
- ✅ Fixtures validated as authentic
- ✅ Integration tests created
Completed Testing Work:
- ✅ YUM comprehensive implementation (Issue #16)
- ✅ APT fixture cleanup and behavior testing
- ✅ Integration tests and testing strategy documentation
- ✅ Cross-platform parsing robustness
Completed Documentation:
- ✅ API and behavior documentation enhanced
- ✅ Error handling best practices documented
- ✅ YUM documentation updates
- ✅ Documentation reorganization with proper cross-references
Current active work (tracked in local TODO.md and GitHub Issues):
- Test Coverage Improvements: YUM gaps (Issue #32), Snap & Flatpak comprehensive suites (Issues #28, #29)
- CommandRunner Migration: Snap and Flatpak to complete architectural consistency (Issues #28, #29)
- Documentation: Continued improvements and maintenance
SysPkg uses a comprehensive multi-layered testing approach to ensure package managers work correctly across different operating systems.
Configuration-Driven Testing: testing/os-matrix.yaml defines which package managers should be tested on which OS distributions.
Supported Testing Environments:
- Ubuntu/Debian: APT, Flatpak, Snap
- RHEL/Rocky/Alma: YUM (v8), DNF (v9+)
- Fedora: DNF, Flatpak
- Alpine: APK
- Arch (planned): Pacman
make test-unit- Parser functions with OS-specific fixtures
- OS detection logic
- Command construction
- No actual package manager execution
make test-integration- Real package manager availability checks
- Command output capture for test fixtures
- Limited package operations (list, search, show)
make test-docker-all # All OS
make test-docker-ubuntu # APT testing
make test-docker-rocky # YUM testing
make test-docker-alma # YUM testing
make test-docker-fedora # DNF testing
make test-docker-alpine # APK testingDocker Benefits:
- Test YUM on Rocky Linux/AlmaLinux
- Test APT on various Ubuntu/Debian versions
- Generate real command outputs for fixtures
- Isolated, reproducible test environments
- Actual package installation/removal
- Privileged operations
- Snap/systemd dependent features
Automatic Detection: Tests automatically detect the current OS and determine which package managers to test:
env, err := testenv.GetTestEnvironment()
if err != nil {
t.Fatalf("failed to get test environment: %v", err)
}
if skip, reason := env.ShouldSkipTest("yum"); skip {
t.Skip(reason)
}Test Tags: Tests use build tags for selective execution:
unit: Parser and core logic testsintegration: Real command execution (limited)system: Full package operations (privileged)apt,yum,dnf,apk: Package manager specific
Docker Matrix: Tests run across multiple OSes in parallel:
strategy:
matrix:
include:
- os: ubuntu, pm: apt
- os: rockylinux, pm: yum
- os: fedora, pm: dnf
- os: alpine, pm: apkNative Tests: For systemd-dependent features like Snap:
- os: ubuntu, runner: ubuntu-latest, pm: snapFor detailed development workflows, see CONTRIBUTING.md
Quick reference:
- Daily development:
make test(smart OS-aware testing) - Package manager work:
make test-docker-rocky(YUM),make test-docker-fedora(DNF) - Comprehensive validation:
make test-docker-all - Fixture updates:
make test-fixtures
Fixtures are automatically generated from real package manager outputs across different OSes:
testing/fixtures/apt/search-vim-ubuntu22.txttesting/fixtures/yum/search-vim-rocky8.txttesting/fixtures/dnf/search-vim-fedora39.txt
This ensures parsers work correctly with real-world output variations across distributions.
See testing/docker/, testing/os-matrix.yaml, and CONTRIBUTING.md for complete details.