Contributions, including bugfixes and addition of new features, are welcomed!
The pyani package is currently maintained on GitHub under two main branches:
masteris the source code underpinning the most recent/current release of pyani. It should always be in sync with the latest release found at https://github.com/widdowquinn/pyani/releases. The only time this code should not be in sync with the release is when there are modifications to documentation, or for a release candidate immediately preceding a release.developmentis the current bleeding-edge version ofpyani. It should (almost) always be in a working and usable condition, but may not be complete and/or some features may be missing or still under development.
Additional branches may also be found on GitHub, with bug fixes and or new features in varying stages of completeness.
pyani is shared under the MIT License (see LICENSE file for details), and any contributions you make will be licensed under this agreement.
Please fork the repository to your own GitHub account (you will need to create a GitHub account if you do not already have one), and clone the repository from your fork. Using SSH (recommended):
git clone git@github.com:<YOUR USERNAME>/pyani.git
cd pyanior HTTPS:
git clone https://github.com/<YOUR USERNAME>/pyani.git
cd curveballpyani development makes use of the following tools and packages:
Anaconda/Minicondafor virtual environment managementgitfor version controlpytestfor testingpre-committo manage pre-commit hooksdoc8,flake8andpylintfor code lintingblackfor code formattingbanditto identify security issuescodecovto measure code coverage
To set up a local development environment with these tools configured for pyani development, first create and activate a new conda environment:
conda create --yes --name pyani_dev python=3.7 && conda activate pyani_devthen set up conda channels for the required dependencies:
conda config --add channels defaults
conda config --add channels bioconda
conda config --add channels conda-forgeand then use the command
make setup_envThis will install all dependencies for running and developing pyani, as well as pre-commit hooks. Once installation is complete, run the test suite to check installation, availability of dependencies, and code coverage:
make testIf you want to be able to edit source files and have those changes take immediate effect when calling pyani (useful for testing), clone the GitHub repository with:
git clone https://github.com/widdowquinn/pyani.gitthen inside the new pyani directory run:
pip install -e .This is the pip install --editable command, which links the installed package to the specified location (here ., i.e. the current directory) rather than the usual package location (site-packages). When using this option, edits to the source code are immediately available in the installed package. This allows you to test changes to the source code as you make them, without the need for an additional uninstall/install step.
You can remove the conda development environment with the following commands:
conda deactivate
conda remove -n pyani_dev --allThe root directory of the repository has subdirectories specific for testing, packaging, and deploying pyani:
pyanisource code is under thepyanisubdirectory- code for the CLI scripts is in the
pyani/scriptssubdirectory
- code for the CLI scripts is in the
- tests (written for the
pytestframework) and test/target data are in thetestssubdirectory - documentation is found under the
docssubdirectory
Package documentation for pyani is found in the docs subdirectory. Both the package documentation and docstrings are written in reStructured Text (i.e. RST), and to build the documentation you will need to install Sphinx.
Although you can build the documentation in multiple formats, the default is the HTML website. Tho build the package docs and view them in your browser you can use the command:
make docsfrom the repository root directory
If you plan to make a pull request, please begin by forking this repository, and creating a new branch with a short, descriptive name, instead of using the development, version_0_2, version_0_3, main, or master branch.
A workflow might look like this:
- Identify something you think you can change or add
- Fork this repository into your own account (but please add write access for repository maintainers)
- Obtain source code and set up a development environment as described above
- Create a new branch with a short, descriptive name (for the thing you're fixing/adding), and work on this branch locally
- When you're finished, check the changes/additions with
flake8/blackand test locally withpytest -v. - Commit the branch, and submit a pull request
- Continue the discussion in the
Pull requestssection of this repository on GitHub.
All tests must pass before a pull request will be merged at GitHub.
Please keep each pull request as atomic as possible - fixing or adding a single conceptually-complete issue/functionality. If you would like to add several features or fix several issues, please use a separate pull request for each one, where possible.
- If you are proposing a fix to an issue, please give your branch a name that reflects this. For example, if you were proposing to fix issue #150, please call your branch
issue_150(or some similar variation). - If you are handling a pull request from a fork, with a view to merging, please indicate the PR number somewhere in the local branch name when you pull the forked version into the repository. For example, if you were handling pull request #250 which refers to a fork from
kenny_loggins/pyani, please call your local branchpr_250(or some similar variation).
When you have finished editing source or documentation, please check that everything you modified is committed:
git statusPlease also review the differences that have been introduced relative to the origin/master or origin/development branch (as appropriate):
git diff origin/masterPlease check your git log and consider rebasing or squashing any commits that have not been pushed:
git logSo far as is possible, we aim to follow the coding conventions as described in PEP8 and PEP257, but we have adopted black code styling, which does vary from the PEPs in places.
We are moving to writing all docstrings as reStructuredText, for usage with Sphinx.
We use the flake8, doc8, and pylint tools for style checks. These will be installed if you have used make setup_env to set up your development environment.
git commit messages are an important way to manage a readable revision history. We use the following conventions:
-
If a commit fixes an issue, state this in the commit message
GitHubProjects picks up on terms likefixes #123andcloses #987. Using these phrases makes project management much easier.
-
Every commit gets a short description
- The short description should be in imperative form and around 50 characters or less
- The short description can, but need not, include the name of the file that is modified
- There should be a short account of what the change does
- The short discription should not only contain the name of the file that is modified
For example, if the commit updates some documentation, the following are good short descriptions:
update citations.rst to add new referencesupdate docs to add new references; fixes #567add new references to citations.rst
The following are bad short descriptions
-
update citations.rst(does not say what was done) -
there were some new references so I added them(not in imperative form) -
citations.rst(does not say what was done) -
part of some doc updates(does not say what was done) -
Some commits get long/extended descriptions
- Long descriptions should be included where there is more information to share than can be fit in the short description
- Long descriptions are free-form
- Long descriptions should explain the why of the change. They may also explain the what at a high level, but should not be excessively detailed.
- They are "long descriptions", but they should be concise, precise and clear
- Paragraphs are fine
- Bullet points are fine
A good long description could be
This fix improves efficiency of the veeblefetzer. The main change is replacing a nested loop with asyncio calls to a new function
fetzveebles(). This commit makes affectsveebles.py, and new tests are added intest_veeblefetzer.py.fixes #246
A bad long description might be
So, because it was taking too long to fetz all the veebles I looked at the structure. It took a while to identify the main problem, which was that there were a bunch of nested loops. I timed these and it turned out that one of them really hit performance. So I looked into a load of options (like multiprocessing, threading and so on) but, inspired by a Stack Overflow post (URL HERE:) I decided to try asyncio. After some trial and error I managed to get something working with that. I also wrote some tests. I also think this might fix one of the issues.
The flake8 and black styles are enforced as pre-commit hooks using the pre-commit package (included in requirements-dev.txt and requirements-pip.txt).
The black and flake8 hooks are defined in .pre-commit-config.yaml. Custom settings for flake8 are held in .flake8.
To enable pre-commit checks in the codebase on your local machine (once pre-commit has been installed), execute the following command in the root directory of this repository:
pre-commit installThis is done automatically if you use make setup_env to set up your development environment.
New features or functions will not be accepted without tests. Bug fixes should ideally include an additional test to establish that the bug has been squashed. We expect that you will have run tests locally before a pull request is made.
Tests will also be run as part of continuous integration, and changes will not be accepted until continuous integration tests have been passed.
Tests are located in the tests subdirectory of this repository.
We currently use pytest for testing, and codecov to establish how much of the codebase is covered by tests. These can be installed as follows:
conda install pytest codecovpytest can then be run on the codebase with
pytest --cov-report=html --cov=pyani -v tests/When you submit a pull request on GitHub, automated tests will be run, and results reported on the pull request. All tests must pass before a pull request will be merged.
We currently use GitHub Actions to run tests. The configuration file can be found in the repository under .github/workflows/.
Currently, pyani is tested under Python 3.9 through 3.12, and coverage is reported at Codacy.
We aim to comply with PEP440 and semantic versioning.