Contributions, including bugfixes and addition of new features, are welcomed!
The pyani
package is currently maintained on GitHub under two main branches:
master
is 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.development
is 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 [email protected]:<YOUR USERNAME>/pyani.git
cd pyani
or HTTPS:
git clone https://github.com/<YOUR USERNAME>/pyani.git
cd curveball
pyani
development makes use of the following tools and packages:
Anaconda
/Miniconda
for virtual environment managementgit
for version controlpytest
for testingpre-commit
to manage pre-commit hooksdoc8
,flake8
andpylint
for code lintingblack
for code formattingbandit
to identify security issuescodecov
to 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_dev
then set up conda
channels for the required dependencies:
conda config --add channels defaults
conda config --add channels bioconda
conda config --add channels conda-forge
and then use the command
make setup_env
This 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 test
If 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.git
then 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 --all
The root directory of the repository has subdirectories specific for testing, packaging, and deploying pyani
:
pyani
source code is under thepyani
subdirectory- code for the CLI scripts is in the
pyani/scripts
subdirectory
- code for the CLI scripts is in the
- tests (written for the
pytest
framework) and test/target data are in thetests
subdirectory - documentation is found under the
docs
subdirectory
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 docs
from 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
/black
and test locally withpytest -v
. - Commit the branch, and submit a pull request
- Continue the discussion in the
Pull requests
section 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 status
Please also review the differences that have been introduced relative to the origin/master
or origin/development
branch (as appropriate):
git diff origin/master
Please check your git
log and consider rebasing or squashing any commits that have not been pushed:
git log
So 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
GitHub
Projects picks up on terms likefixes #123
andcloses #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 references
update docs to add new references; fixes #567
add 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 install
This 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 codecov
pytest
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 CircleCI to run tests. The configuration file can be found in the repository as .circleci/config.yml
.
Currently, pyani
is tested under Python 3.6 and 3.7, and coverage is reported at CodeCov
.
We aim to comply with PEP440
and semantic versioning.