Thank you for your interest in contributing to PyTrim! This guide will help you get started with contributing to the project.
git clone https://github.com/TrimTeam/PyTrim.git
cd PyTrimOption A: Local Virtual Environment (venv)
python -m venv venv
# On Linux/macOS
source venv/bin/activate
# On Windows (PowerShell)
.\venv\Scripts\activate
pip install -e ".[dev]"
pre-commit installImportant: This project uses pre-commit hooks for code quality. You must install pre-commit hooks before making commits.
Option B: Docker Environment
This workflow enables "live-reloading," so your code changes appear instantly inside the container without needing to rebuild.
-
Build the development Docker image:
docker build --build-arg BUILD=dev -t pytrim:dev . -
Run the development container:
This command starts the container and mounts your local
PyTrimsource code into the/appdirectory.For Linux and macOS:
docker run --rm -it -v "$(pwd):/app" pytrim:devFor Windows (PowerShell):
docker run --rm -it -v "${PWD}:/app" pytrim:dev -
(Optional) Testing on an External Project
To test your live
PyTrimcode on another project, use a second-vflag to mount that project into the/projectdirectory.docker run --rm -it -v "$(pwd):/app" -v "/path/to/your/source:/project" pytrim:dev
pytestThe package is organized into several specialized modules:
-
extractors/: File type-specific dependency extractorspython_files.py: Handles setup.py filesrequirements_files.py: Processes requirements.txt and .in filestoml_files.py: Manages pyproject.toml, poetry.lock, Pipfileyaml_files.py: Processes YAML configuration filesshell_files.py: Handles shell scriptsdocker_files.py: Processes Dockerfilesini_files.py: Manages setup.cfg and tox.inidocumentation_files.py: Processes .md and .rst files
-
removers/: File type-specific dependency removershandlers/: Specialized removal logic for each file typeline_utils.py: Utility functions for line-by-line processing
-
analyzers/: Dependency analysis logicmodule_analyzer.py: Finds used modules in Python codedependency_analyzer.py: Identifies unused dependencies
-
utils/: Common utilitiespackage_utils.py: Package name normalization
-
core/: Core functionalityfile_remover.py: Python file trimmingreport_producer.py: Report generation
-
cli/: Command line interface
The following tools are run automatically on each commit due to the pre-commit hooks:
- Black for code formatting
- isort for import sorting
- flake8 for linting
- mypy for type checking
You can also run them manually:
black pytrim/ tests/
isort pytrim/ tests/
flake8 pytrim/ tests/
mypy pytrim/Please write tests for all new features and bug fixes.
# Run all tests
pytest
# Run specific test
pytest tests/unit/test_extractors.py
# Run with coverage
pytest --cov=pytrim --cov-report=html- Use Google-style docstrings
- Update documentation in
docs/for any new or changed features - Include examples in docstrings where helpful
-
Create a feature branch from the main branch.
git checkout -b feature/your-feature-name
-
Make your changes ensuring to:
- Follow code style guidelines
- Add tests for new functionality
- Update documentation
-
Commit your changes with a clear and descriptive commit message.
git commit -m "feat: Add support for a new file type" -
Push your branch and create a Pull Request against the main branch.
git push origin feature/your-feature-name
This project follows the Conventional Commits specification. This leads to a more readable and structured commit history.
Each commit message consists of a header, a body, and a footer. The header has a special format that includes a type, a scope (optional), and a subject:
<type>(optional scope): <subject>
<BLANK LINE>
[optional body]
<BLANK LINE>
[optional footer]
Please use the following types when creating your commit messages:
- build: Changes that affect the build system or external dependencies
- chore: Routine maintenance, dependency updates, general tasks
- ci: Changes to CI configuration files and scripts
- docs: Documentation-only changes
- feat: A new feature
- fix: A bug fix
- perf: A code change that improves performance
- refactor: Code restructuring without changing external behavior
- revert: A commit that reverts a previous commit
- style: Code style, formatting (no code logic change)
- test: Adding missing tests or correcting existing tests
Example:
fix(parser): correctly handle multiline dependency strings
Previously, the parser would fail on dependencies in pyproject.toml
that spanned multiple lines. This change updates the regex to
correctly capture these cases.
We welcome many types of contributions, including:
- Bug Reports: Use GitHub issues with clear reproduction steps
- Feature Requests: Describe your use case and proposed implementation
- Code Contributions: Bug fixes, new features, and performance improvements
- Documentation: Fix typos, add examples, and improve clarity
To add support for a new file type:
-
Create a new Extractor class in the
extractors/directoryclass NewFileExtractor(BaseExtractor): def can_handle(self, file_path: Path) -> bool: return file_path.suffix == '.newtype' def extract_dependencies(self, file_path: Path) -> Set[str]: # Implementation here pass
-
Create a new Remover class in the
removers/directoryclass NewFileRemover(BaseRemover): def can_handle(self, file_path: Path) -> bool: return file_path.suffix == '.newtype' def remove_dependencies(self, file_path: Path, unused_deps: List[str]) -> bool: # Implementation here pass
-
Write comprehensive tests for both the extractor and remover
-
Update documentation to reflect the new file type support
All submissions go through code review:
- Automated checks must pass (tests, style, coverage)
- Manual review for code quality and architecture
- Address reviewer feedback promptly
- Check existing documentation and examples
- Search existing GitHub issues for similar problems
- Open a new issue with detailed information
This project follows the Contributor Covenant Code of Conduct.
By contributing, you agree that your contributions will be licensed under the same license as the project.