Contributing¶
Development Setup¶
Prerequisites¶
- Python 3.10 or later (supports 3.10 - 3.13)
- Git
- pyenv (recommended for managing Python versions)
Clone and Install¶
git clone https://github.com/troylar/devsync.git
cd devsync
# Install in editable mode with dev dependencies
pip install -e .[dev]
Or use the invoke task:
This installs the devsync CLI in your current environment, along with all development dependencies (pytest, black, ruff, mypy, invoke).
Running Tests¶
# Run all tests
invoke test
# Run with coverage report
invoke test --coverage
# Run only unit tests
invoke test-unit
# Run only integration tests
invoke test-integration
# Run a specific test file
pytest tests/unit/test_models.py -v
# Run tests matching a pattern
pytest -k "test_conflict" -v
Test Structure¶
tests/
conftest.py # Shared fixtures (temp_dir, mock repos, etc.)
unit/ # Fast, isolated tests (no I/O, no network)
test_models.py
test_checksum.py
test_ai_tools.py
...
integration/ # Tests with file I/O and Git operations
test_library.py
test_repository.py
test_tracker.py
...
Conventions:
- Use fixtures from
conftest.py, especiallytemp_dirfor any file operations - Integration tests may perform actual Git operations and file I/O
- All tests must clean up temporary files
- Minimum 80% code coverage target
Code Quality¶
# Run all checks (lint + format check + typecheck)
invoke quality
# Run all checks and auto-fix what can be fixed
invoke quality --fix
# Individual tools
invoke lint # Ruff linting
invoke lint --fix # Auto-fix lint issues
invoke format # Black formatting
invoke format --check # Check formatting without changes
invoke typecheck # mypy type checking
Code Style¶
| Tool | Configuration |
|---|---|
| Black | Line length: 120 characters |
| Ruff | Rules: E, F, I, N, W |
| mypy | Strict mode (disallow_untyped_defs=true) |
| Python | 3.10+ -- use list[str] not List[str], use X \| Y not Union[X, Y] |
Conventions:
- All functions must have type hints
- Use dataclasses for data models
- Use
Enumfor constants (AIToolType,ConflictResolution,InstallationScope) - Google-style docstrings for all public functions and classes
- Line length: 120 characters maximum
Commit Conventions¶
Format¶
Types¶
| Type | Purpose |
|---|---|
feat | New feature |
fix | Bug fix |
test | Adding or updating tests |
refactor | Code refactoring (no behavior change) |
docs | Documentation changes |
chore | Maintenance (version bumps, CI config, etc.) |
perf | Performance improvement |
Scope¶
Use the module name: cli, core, storage, ai_tools, llm, utils.
Examples¶
feat(cli): add batch install command
fix(storage): handle missing tracker file on first run
test(ai_tools): add Codex section marker tests
refactor(core): extract checksum logic into utility module
docs: update CLI reference with new flags
chore: bump version to 0.11.0
Issue References¶
Reference GitHub issues in commit messages:
# Closes an issue when merged
git commit -m "fix(cli): handle empty library gracefully
Fixes #42"
# References an issue without closing it
git commit -m "test(storage): add tracker edge case tests
Refs #42"
Branch Strategy¶
main-- Always deployable, protected branch- Feature branches -- Named
issue-###-short-description
CI/CD¶
GitHub Actions runs on every push and pull request:
- Python versions: 3.10, 3.11, 3.12, 3.13
- Platforms: ubuntu-latest, macos-latest, windows-latest
- Steps: lint, format check, typecheck, tests with coverage
- Coverage: uploaded to Codecov
The workflow is defined in .github/workflows/ci.yml.
Local Pre-Push Hook¶
Enable the pre-push hook to catch issues before pushing:
Pull Request Workflow¶
-
Create a GitHub issue first. All work must be tied to an issue.
-
Create a feature branch from
main: -
Make your changes. Write tests. Run quality checks:
-
Commit with issue references:
-
Push and open a PR:
-
Wait for CI to pass, then request review.
Adding a New AI Tool¶
- Create
devsync/ai_tools/newtool.pyinheriting fromAITool - Implement the required abstract methods:
tool_type,tool_name,is_installed(),get_instructions_directory(),get_instruction_file_extension(),get_project_instructions_directory() - Add the tool to
AIToolTypeenum indevsync/core/models.py - Register in
devsync/ai_tools/detector.py - Add an
IDECapabilityentry indevsync/ai_tools/capability_registry.py - Add a translator if the tool uses a non-standard format
- Add tests in
tests/unit/test_ai_tools.py
Adding a New CLI Command¶
The v2 CLI has six commands: setup, tools, extract, install, list, uninstall. These are defined in the following files:
| Command | File |
|---|---|
setup | devsync/cli/setup.py |
tools | devsync/cli/tools.py |
extract | devsync/cli/extract.py |
install | devsync/cli/install_v2.py |
list | devsync/cli/list_v2.py |
uninstall | devsync/cli/uninstall.py |
To add a new command:
- Create a command file in
devsync/cli/(e.g.,devsync/cli/my_command.py) - Define the command function with Typer decorators
- Register in
devsync/cli/main.py - Add tests in
tests/unit/test_cli.py