Thanks for your interest in contributing! Pacsea is a fast, keyboard-first TUI for discovering and installing Arch and AUR packages.
By participating, you agree to follow our Code of Conduct.
For newcomers looking to contribute, we recommend starting with issues labeled "Good First Issue" in our issue tracker.
- Bug reports and fixes
- Feature requests and implementations
- Documentation and examples
- UI/UX polish and accessibility improvements
- Translations and localization
- Target platform: Pacsea focuses on Arch Linux and Arch-based distributions (e.g., EndeavourOS, Manjaro, CachyOS, Artix). End-to-end install/update features rely on Arch tools like
pacmanand an AUR helper (paruoryay). - Safety: During development, prefer
--dry-runand/or a disposable VM/container to avoid unintended changes. - Security: If your report involves a security issue, use our Security Policy.
- Install Rust (stable):
sudo pacman -S rustup && rustup default stable - Clone the repository:
git clone https://github.com/Firstp1ck/Pacsea cd Pacsea
# Basic run (dry-run mode recommended for development)
cargo run -- --dry-run
# With debug logging
RUST_LOG=pacsea=debug cargo run -- --dry-run
# Or use verbose flag
cargo run -- --dry-run --verboseTests must be run single-threaded to avoid race conditions:
cargo test -- --test-threads=1
# or
RUST_TEST_THREADS=1 cargo testBefore committing, ensure all of the following pass:
-
Format code:
cargo fmt --all
-
Lint with Clippy:
cargo clippy --all-targets --all-features -- -D warnings
The project uses strict Clippy settings configured in
Cargo.toml:[lints.clippy] cognitive_complexity = "warn" pedantic = { level = "deny", priority = -1 } nursery = { level = "deny", priority = -1 } unwrap_used = "deny"
Additional settings in
clippy.toml:cognitive-complexity-threshold = 25too-many-lines-threshold = 150
-
Check compilation:
cargo check
-
Run tests:
cargo test -- --test-threads=1 -
Check complexity (for new code):
# Run complexity tests to ensure new functions meet thresholds cargo test complexity -- --nocapture
Complexity thresholds:
- Cyclomatic complexity: Should be < 25 for new functions
- Data flow complexity: Should be < 25 for new functions
See Development wiki for detailed complexity analysis.
For all new code (functions, methods, structs, enums):
-
Rust documentation comments are required:
/// What: Brief description of what the function does. /// /// Inputs: /// - `param1`: Description of parameter 1 /// - `param2`: Description of parameter 2 /// /// Output: /// - Description of return value or side effects /// /// Details: /// - Additional context, edge cases, or important notes pub fn example_function(param1: Type1, param2: Type2) -> Result<Type3> { // implementation }
-
Documentation should include:
- What: What the function/method does
- Inputs: All parameters with descriptions
- Output: Return value, side effects, or state changes
- Details: Important implementation details, edge cases, or usage notes
For bug fixes:
- Create failing tests first that reproduce the issue
- Fix the bug
- Verify tests pass
- Add additional tests for edge cases if applicable
For new features:
- Add unit tests for new functions/methods
- Add integration tests for new workflows
- Test error cases and edge conditions
- Ensure tests are meaningful and cover the functionality
Test guidelines:
- Tests should be deterministic and not rely on external state
- Use
--dry-runin tests that would modify the system
feat/<short-description>— New featuresfix/<short-description>— Bug fixesdocs/<short-description>— Documentation onlyrefactor/<short-description>— Code refactoringtest/<short-description>— Test additions/updateschore/<short-description>— Build/infrastructure changes
Prefer Conventional Commits format:
<type>: <short summary>
<optional longer description>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesrefactor: Code refactoring (no functional change)perf: Performance improvementstest: Test additions or updateschore: Build/infrastructure changesui: Visual/interaction changesbreaking change: Incompatible behavior changes
Examples:
feat: add fuzzy search functionality
- Implemented fzf-style matching for package searches
- Added CTRL+F toggle for fuzzy search mode
- Updated localization files for new feature
fix: resolve reverse dependencies in preflight modal
Fixes issue where reverse dependencies were not shown when
removing packages. Now correctly displays packages that depend
on the package being removed.
Guidelines:
- Keep commits focused and reasonably small
- Add rationale in the body if the change is non-obvious
- Reference issue numbers if applicable:
Closes #123orFixes #456
-
Ensure all quality checks pass:
-
cargo fmt --all(no changes needed) -
cargo clippy --all-targets --all-features -- -D warnings(clean) -
cargo check(compiles successfully) -
cargo test -- --test-threads=1(all tests pass) - Complexity checks pass for new code
-
-
Code requirements:
- All new functions/methods have rustdoc comments (What, Inputs, Output, Details)
- Code follows project conventions (see below)
- No
unwrap()orexpect()in non-test code (use proper error handling) - Complexity thresholds met (cyclomatic < 25, data flow < 25)
-
Testing:
- Added/updated tests where it makes sense
- For bug fixes: created failing tests first, then fixed the issue
- Tests are meaningful and cover the functionality
-
Documentation:
- Updated README if behavior, options, or keybinds changed
- Updated wiki pages if needed (see Wiki)
- Updated config examples if config keys changed
- For UI changes: included screenshots and updated
Images/if applicable
-
Compatibility:
- Changes respect
--dry-runflag - Code degrades gracefully if
pacman/paru/yayare unavailable - No breaking changes (or clearly documented if intentional)
- Changes respect
Use the following structure for your PR description (see Documents/PR_DESCRIPTION.md for a template):
## Summary
Brief description of what this PR does.
**Bug Fixes:**
1. Description of bug fix 1
2. Description of bug fix 2
**New Features:**
1. Description of new feature 1
2. Description of new feature 2
## Type of change
- [ ] feat (new feature)
- [ ] fix (bug fix)
- [ ] docs (documentation only)
- [ ] refactor (no functional change)
- [ ] perf (performance)
- [ ] test (add/update tests)
- [ ] chore (build/infra/CI)
- [ ] ui (visual/interaction changes)
- [ ] breaking change (incompatible behavior)
## Related issues
Closes #123
## How to test
Step-by-step testing instructions.
## Checklist
- [ ] Code compiles locally
- [ ] `cargo fmt --all` ran without changes
- [ ] `cargo clippy --all-targets --all-features -- -D warnings` is clean
- [ ] `cargo test -- --test-threads=1` passes
- [ ] Added or updated tests where it makes sense
- [ ] Updated docs if behavior, options, or keybinds changed
- [ ] For UI changes: included screenshots and updated `Images/` if applicable
- [ ] Changes respect `--dry-run` and degrade gracefully if `pacman`/`paru`/`yay` are unavailable
- [ ] If config keys changed: updated README/wiki sections for `settings.conf`, `theme.conf`, and `keybinds.conf`
- [ ] Not a packaging change for AUR (otherwise propose in `pacsea-bin` or `pacsea-git` repos)
## Notes for reviewers
Any additional context, implementation details, or decisions that reviewers should know.
## Breaking changes
None (or description of breaking changes if applicable)
## Configuration
If new config keys were added, document them here.- Language: Rust (edition 2024)
- Naming: Clear, descriptive names. Favor clarity over brevity.
- Error handling: Use
Resulttypes. Avoidunwrap()/expect()in non-test code. - Early returns: Prefer early returns over deep nesting.
- Logging: Use
tracingfor diagnostics. Avoid noisy logs at info level.
- Keyboard-first: Minimal keystrokes, Vim-friendly navigation
- Help overlay: Update help overlay if shortcuts change
- Keybind docs: Update Keyboard Shortcuts wiki if keybinds change
- Config keys: If you add/change config keys:
- Update
config/settings.conf,config/theme.conf, orconfig/keybinds.confexamples - Update Configuration wiki
- Update README if it's a major feature
- Ensure backward compatibility when possible
- Update
- Dry-run: All commands must respect
--dry-runflag - Graceful degradation: Commands must degrade gracefully if
pacman/paru/yayare unavailable - Error messages: Provide clear, actionable error messages
When updating documentation:
-
README.md: Keep high-level, reference wiki for details
-
Wiki pages: Update relevant wiki pages with detailed information:
-
Config examples: Update example config files in
config/directory
Include the following information:
- Pacsea version (e.g.,
0.5.2or commit hash) - Arch Linux version or distribution
- Terminal emulator and version
- Display server (Wayland/X11)
- AUR helper (
paru/yay) and version - Steps to reproduce
- Expected vs. actual behavior
- Logs (run with
RUST_LOG=pacsea=debugor--verbose)
Example:
**Version**: 0.5.2
**Distribution**: Arch Linux (kernel 6.x)
**Terminal**: alacritty 0.13.x
**Display**: Wayland
**AUR Helper**: paru 1.11.x
**Steps to reproduce:**
1. Launch pacsea
2. Search for "firefox"
3. Press Space to add to install list
4. Press Enter
**Expected**: Preflight modal opens
**Actual**: Application crashes
**Logs:**
[Include relevant log output]- Describe the problem being solved
- Describe the desired UX/behavior
- Include mockups or keybind suggestions if applicable
- Consider edge cases and compatibility
Open issues in the issue tracker.
- AUR packages live in separate repos:
pacsea-binandpacsea-git - Propose packaging changes in those repos rather than here
- Version bumps should be coordinated with AUR package maintainers
- Code of Conduct: See CODE_OF_CONDUCT.md. For conduct issues, contact firstpick1992@proton.me.
- Security Policy: See SECURITY.md for how to report vulnerabilities.
- Check the Wiki for documentation
- Review existing issues and PRs
- Ask questions in Discussions
Thank you for helping improve Pacsea!