1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
|
..
This file is part of khmer, https://github.com/dib-lab/khmer/, and is
Copyright (C) 2014-2015 Michigan State University
Copyright (C) 2015-2016 The Regents of the University of California.
It is licensed under the three-clause BSD license; see LICENSE.
Contact: khmer-project@idyll.org
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the Michigan State University nor the names
of its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Contact: khmer-project@idyll.org
Guidelines for continued development
====================================
The khmer :doc:`Getting Started <getting-started>` documentation is intended for
first-time contributors, and is designed to make that first contribution as easy
and as painless as possible. For those with an interest in making continued
contributions (or those with an obligation to maintain and contribute to the
codebase), this document describes the coding guidelines we follow, as well as
some tips that will improve the development process for everyone involved.
Beyond your first contribution
------------------------------
If your :doc:`first contribution to khmer <getting-started>` has been
accepted and merged into the codebase, you may be wondering what to do next. You
can poke around at additional "low-hanging fruit" issues, but if you'd like to
sink your teeth into something more substantial, here are a few suggestions.
* If you're knowledgeable in C++ and/or Python and/or documentation
and/or biology, we'd love to attract further contributions to khmer.
Please visit the issues list and browse about and find something
interesting looking.
* One general thing we'd like to do is increase our test coverage.
You can go find test coverage information `at Codecov.io
<https://codecov.io/gh/dib-lab/khmer>`__ by scrolling to the bottom and
clicking on individual files; or, ask us on khmer-project@idyll.org for
suggestions.
* Ask us! Ask khmer-project@idyll.org for suggestions on what to do next.
We can suggest particularly ripe low-hanging fruit, or find some other
issues that suit your interests and background.
* You can also help other people out by watching for new issues or
looking at pull requests. Remember to be nice and polite!
Programming languages
---------------------
All Python code in khmer must run correctly in both Python version 2 and 3.
For C++ code, any feature in C++11 is fine to use. Specifically we support
features found in GCC 4.8.2. Our automated tests use gcc 4.8.4 on linux. See
https://github.com/dib-lab/khmer/issues/598 for an in-depth discussion. Please
do not use features from C++14 or newer.
Code style standards
--------------------
All plain-text files should have line widths of 80 characters or less unless
that is not supported for the particular file format.
For C++, we use `Todd Hoff's coding standard
<http://www.possibility.com/Cpp/CppCodingStandard.html>`__, and
`astyle -A10 / "One True Brace Style"
<http://astyle.sourceforge.net/astyle.html>`__ indentation and
bracing. Note: @CTB needs Emacs settings that work for this.
Vim users may want to set the ARTISTIC_STYLE_OPTIONS shell variable to "-A10
--max-code-length=80" and run ```:%!astyle``` to reformat. The four space
indentation can be set with::
set expandtab
set shiftwidth=4
set softtabstop=4
For Python, `PEP 8 <http://www.python.org/dev/peps/pep-0008/>`__ is our
standard. The ```pep8``` and ```autopep8``` Makefile targets are helpful.
Code, scripts, and documentation must have their spelling checked.
Python-based `codespell` can be applied to multiple files easily. `codespell`
can be installed via the following::
pip install codespell
To run codespell over only what has been changed on the branch `my-branch`::
git diff master..my-branch > diff_file
codespell diff_file
To run codespell over a single file::
codespell path/to/file
To make codespell fix the issues it finds automatically::
codespell -w path/to/file
Please note that as `codespell` works off of a listing of possible
misspellings it may not catch all errors. If you find a spelling error that
is not caught by `codespell` feel free to open a pull request at the `project
page <https://github.com/lucasdemarchi/codespell>`_ to add it to the
dictionary.
Vim users can run::
:setlocal spell spelllang=en_us
Use `]s` and `[s` to navigate between misspellings and `z=` to suggest a
correctly spelled word. `zg` will add a word as a good word.
GNU `aspell` can also be used to check the spelling in a single file::
aspell check --mode ccpp $filename
Cython Style
~~~~~~~~~~~~
Cython code can become messy very quickly, and as such, we have guidelines
for style and structure.
When wrapping code from liboxli:
- `extern` definition should begin with `Cp`; for example, `CpHashtable` wraps
`oxli::Hashtable`.
- If the extension class wrapping the liboxli class stores it as a pointer,
it should be named `_this`. If it wraps a stack object directly, it should
be named `_obj`.
For imports,
- `__future__` imports at the top, as usual.
- `libc` cimports next,
- then `libcpp` imports and cimports.
- followed by cimports
- and finally, regular imports.
Generally,
- Pure C methods should be underscore prefixed.
- `cpdef` methods do not need to be underscore prefixed.
Resolving merge conflicts
-------------------------
It is possible that when you do a `git pull` you will get a "merge
conflict" -- This is what happens when something changed in the branch you're
pulling in in the same place you made a change in your local copy. This
frequently happens in the `ChangeLog` file.
Git will complain loudly about merges and tell you specifically in which
files they occurred. If you open the file, you'll see something vaguely
like this in the place where the merge occurred::
<<<<<<< HEAD
Changes made on the branch that is being merged into. In most cases,
this is the branch that you have currently checked out
=======
Changes made on the branch that is being merged in, almost certainly
master.
>>>>>>> abcde1234
Though there are a variety of tools to assist with resolving merge
conflicts they can be quite complicated at first glance and it is usually
easy enough to manually resolve the conflict.
To resolve the conflict you simply have to manually 'meld' the changes
together and remove the merge markers.
After this you'll have to add and commit the merge just like any other set
of changes. It's also recommended that you run tests.
Virtual environments
--------------------
The khmer package, like many software packages, relies on other third-party
software. Some of this software has been bundled together with khmer and is
compiled when you invoke ``make`` on the command line. But some of the software
khmer depends on is distributed as Python packages separately from khmer.
Python `virtual environments <https://pypi.python.org/pypi/virtualenv>`_ were
designed to isolate a stable development environment for a particular project.
This makes it possible to maintain different versions of a Python package for
different projects on your computer.
The installation instructions in the :doc:`Getting Started <getting-started>`
docs install the ``virtualenv`` command on your computer. After completing those
instructions, you can create a virtual environment with the command::
virtualenv -p python2 env/
(You can substitute `python3` for `python2` if Python version 3 is installed on
your system.) This command will create a new directory `env/` containing your
new virtual environment. The command::
source env/bin/activate
will activate the virtual environment. Now any Python packages that you install
with ``pip`` or ``make install-dep`` will be installed into your isolated
virtual environment.
Note that any time you create a new terminal session, using the virtual
environment requires that you re-activate it.
Pull request cleanup (commit squashing)
---------------------------------------
Submitters are invited to reduce the numbers of commits in their pull requests
either via `git rebase -i dib/master` or this recipe::
git pull # make sure the local is up to date
git pull dib master # get up to date
# fix any merge conflicts
git status # sanity check
git diff dib/master # does the diff look correct? (no merge markers)
git reset --soft dib/master # un-commit the differences from dib/master
git status # sanity check
git commit --all # package all differences in one commit
git status # sanity check
git push # should fail
git push --force # override what's in GitHub's copy of the branch/pull request
Code Review
-----------
Please read `11 Best Practices for Peer Code Review
<http://smartbear.com/SmartBear/media/pdfs/WP-CC-11-Best-Practices-of-Peer-Code-Review.pdf>`__.
See also `Code reviews: the lab meeting for code
<http://fperez.org/py4science/code_reviews.html>`__ and
`the PyCogent coding guidelines
<http://pycogent.org/coding_guidelines.html>`__.
CPython Checklist
-----------------
Here's a checklist for new CPython types with future-proofing for Python 3::
- [ ] the CPython object name is of the form `khmer_${OBJECTNAME}_Object`
- [ ] Named struct with `PyObject_HEAD` macro
- [ ] `static PyTypeObject khmer_${OBJECTNAME}_Type` with the following
entries
- [ ] `PyVarObject_HEAD_INIT(NULL, 0)` as the object init (this includes
the `ob_size` field).
- [ ] all fields should have their name in a comment for readability
- [ ] The `tp_name` filed is a dotted name with both the module name and
the name of the type within the module. Example: `khmer.ReadAligner`
- [ ] Deallocator defined and cast to `(destructor)` in tp_dealloc
- [ ] The object's deallocator must be
`Py_TYPE(obj)->tp_free((PyObject*)obj);`
- [ ] Do _not_ define a `tp_getattr`
- [ ] BONUS: write methods to present the state of the object via
`tp_str` & `tp_repr`
- [ ] _Do_ pass in the array of methods in `tp_methods`
- [ ] _Do_ define a new method in `tp_new`
- [ ] PyMethodDef arrays contain doc strings
- [ ] Methods are cast to `PyCFunctions`s
- [ ] Type methods use their type Object in the method signature.
- [ ] Type creation method decrements the reference to self
(`Py_DECREF(self);`) before each error-path exit (`return NULL;`)
- [ ] No factory methods. Example: `khmer_new_readaligner`
- [ ] Type object is passed to `PyType_Ready` and its return code is checked
in `MOD_INIT()`
- [ ] The reference count for the type object is incremented before adding
it to the module: `Py_INCREF(&khmer_${OBJECTNAME}_Type);`.
|