summaryrefslogtreecommitdiffstats
path: root/doc/source/tutorials/contributing.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/source/tutorials/contributing.rst')
-rw-r--r--doc/source/tutorials/contributing.rst315
1 files changed, 315 insertions, 0 deletions
diff --git a/doc/source/tutorials/contributing.rst b/doc/source/tutorials/contributing.rst
new file mode 100644
index 0000000..33f1654
--- /dev/null
+++ b/doc/source/tutorials/contributing.rst
@@ -0,0 +1,315 @@
+Contributing to python-apt
+==========================
+:Author: Julian Andres Klode <jak@debian.org>
+:Release: |release|
+:Date: |today|
+
+Let's say you need a new feature, you can develop it, and you want to get it
+included in python-apt. Then be sure to follow the following guidelines.
+
+Available branches
+-------------------
+First of all, let's talk a bit about the git branches of python-apt. In the
+following parts, we will assume that you use git to create your changes and
+submit them.
+
+Repositories
+^^^^^^^^^^^^
+
+https://salsa.debian.org/apt-team/python-apt.git
+
+ This is the official Debian repository of python-apt.
+ You can clone it using git by doing::
+
+ git clone git://salsa.debian.org/apt-team/python-apt.git
+
+
+ All code which will be uploaded to Debian is here.
+ There are also branches for Ubuntu releases, but those may not be up-to-date.
+
+ Branch names consist of the distribution vendor, followed by a slash,
+ followed by the release of that distribution, for example: ``debian/sid``.
+
+ The current working branch is usually pointed to by ``HEAD``, it is
+ either ``debian/sid`` or ``debian/experimental``.
+
+ If both sid and experimental are active, bug fixes are either cherry-picked from
+ ``debian/experimental`` to ``debian/sid``, or a new release is cut on the sid branch
+ and then merged into experimental.
+
+ Updates to stable release branches, such as ``debian/wheezy``, are almost always
+ cherry-picked or backported from the ``debian/sid`` branch.
+
+
+.. highlight:: cpp
+
+C++ Coding style
+----------------
+This document gives coding conventions for the C++ code comprising
+the C++ extensions of Python APT. Please see the companion
+informational PEP describing style guidelines for Python code (:PEP:`8`).
+
+Note, rules are there to be broken. Two good reasons to break a
+particular rule:
+
+ (1) When applying the rule would make the code less readable, even
+ for someone who is used to reading code that follows the rules.
+
+ (2) To be consistent with surrounding code that also breaks it
+ (maybe for historic reasons) -- although this is also an
+ opportunity to clean up someone else's mess (in true XP style).
+
+This part of the document is derived from :PEP:`7` which was written by
+Guido van Rossum.
+
+
+C++ dialect
+^^^^^^^^^^^
+
+- Use ISO standard C++ (the 2011 version of the standard), headers
+ should also adhere to the 1998 version of the standard.
+
+- Use C++ style // one-line comments for single-line comments.
+
+- No compiler warnings with ``gcc -std=c++11 -Wall -Wno-write-strings``. There
+ should also be no errors with ``-pedantic`` added.
+
+
+Code lay-out
+^^^^^^^^^^^^
+
+- Use 3-space indents, in files that already use them. In new source files,
+ that were created after this rule was introduced, use 4-space indents.
+
+ At some point, the whole codebase may be converted to use only
+ 4-space indents.
+
+- No line should be longer than 79 characters. If this and the
+ previous rule together don't give you enough room to code, your
+ code is too complicated -- consider using subroutines.
+
+- No line should end in whitespace. If you think you need
+ significant trailing whitespace, think again -- somebody's
+ editor might delete it as a matter of routine.
+
+- Function definition style: function name in column 2, outermost
+ curly braces in column 1, blank line after local variable
+ declarations::
+
+ static int extra_ivars(PyTypeObject *type, PyTypeObject *base)
+ {
+ int t_size = PyType_BASICSIZE(type);
+ int b_size = PyType_BASICSIZE(base);
+
+ assert(t_size >= b_size); /* type smaller than base! */
+ ...
+ return 1;
+ }
+
+- Code structure: one space between keywords like 'if', 'for' and
+ the following left paren; no spaces inside the paren; braces as
+ shown::
+
+ if (mro != NULL) {
+ ...
+ }
+ else {
+ ...
+ }
+
+- The return statement should *not* get redundant parentheses::
+
+ return Py_None; /* correct */
+ return(Py_None); /* incorrect */
+
+- Function and macro call style: ``foo(a, b, c)`` -- no space before
+ the open paren, no spaces inside the parens, no spaces before
+ commas, one space after each comma.
+
+- Always put spaces around assignment, Boolean and comparison
+ operators. In expressions using a lot of operators, add spaces
+ around the outermost (lowest-priority) operators.
+
+- Breaking long lines: if you can, break after commas in the
+ outermost argument list. Always indent continuation lines
+ appropriately, e.g.::
+
+ PyErr_Format(PyExc_TypeError,
+ "cannot create '%.100s' instances",
+ type->tp_name);
+
+- When you break a long expression at a binary operator, the
+ operator goes at the end of the previous line, e.g.::
+
+ if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
+ type->tp_dictoffset == b_size &&
+ (size_t)t_size == b_size + sizeof(PyObject *))
+ return 0; /* "Forgive" adding a __dict__ only */
+
+- Put blank lines around functions, structure definitions, and
+ major sections inside functions.
+
+- Comments go before the code they describe.
+
+- All functions and global variables should be declared static
+ unless they are to be part of a published interface
+
+
+Naming conventions
+^^^^^^^^^^^^^^^^^^
+
+- Use a ``Py`` prefix for public functions; never for static
+ functions. The ``Py_`` prefix is reserved for global service
+ routines like ``Py_FatalError``; specific groups of routines
+ (e.g. specific object type APIs) use a longer prefix,
+ e.g. ``PyString_`` for string functions.
+
+- Public functions and variables use MixedCase with underscores,
+ like this: ``PyObject_GetAttr``, ``Py_BuildValue``, ``PyExc_TypeError``.
+
+- Internal functions and variables use lowercase with underscores, like
+ this: ``hashes_get_sha1.``
+
+- Occasionally an "internal" function has to be visible to the
+ loader; we use the _Py prefix for this, e.g.: ``_PyObject_Dump``.
+
+- Macros should have a MixedCase prefix and then use upper case,
+ for example: ``PyString_AS_STRING``, ``Py_PRINT_RAW``.
+
+
+Documentation Strings
+^^^^^^^^^^^^^^^^^^^^^
+- The first line of each function docstring should be a "signature
+ line" that gives a brief synopsis of the arguments and return
+ value. For example::
+
+ PyDoc_STRVAR(myfunction__doc__,
+ "myfunction(name: str, value) -> bool\n\n"
+ "Determine whether name and value make a valid pair.");
+
+ The signature line should be formatted using the format for function
+ annotations described in :PEP:`3107`, whereas the annotations shall reflect
+ the name of the type (e.g. ``str``). The leading ``def`` and the trailing
+ ``:`` as used for function definitions must not be included.
+
+ Always include a blank line between the signature line and the
+ text of the description.
+
+ If the return value for the function is always ``None`` (because
+ there is no meaningful return value), do not include the
+ indication of the return type.
+
+- When writing multi-line docstrings, be sure to always use
+ string literal concatenation::
+
+ PyDoc_STRVAR(myfunction__doc__,
+ "myfunction(name, value) -> bool\n\n"
+ "Determine whether name and value make a valid pair.");
+
+
+Python Coding Style
+-------------------
+The coding style for all code written in python is :PEP:`8`. Exceptions from
+this rule are the documentation, where code is sometimes formatted differently
+to explain aspects.
+
+When writing code, use tools like pylint, pyflakes, pychecker and pycodestyle
+(all available from Debian/Ubuntu) to verify that your code is
+OK. Fix all the problems which seem reasonable, and mention the unfixed issues
+when asking for merge.
+
+All code must work on both Python 2 and Python 3.
+
+Submitting your patch
+---------------------
+First of all, the patch you create should be based against the most current
+branch of python-apt (debian/sid or debian/experimental). If it is a bugfix,
+you should probably use debian/sid. If you choose the wrong branch, we will
+ask you to rebase your patches against the correct one.
+
+Once you have made your change, check that it:
+
+ * conforms to :PEP:`8` (checked with pycodestyle). It should, at least not
+ introduce new errors. (and never have whitespace at end of line)
+ * produces no new errors in pychecker, pyflakes and pylint (unless you
+ can't fix them, but please tell so when requesting the merge, so it can
+ be fixed before hitting one of the main branches).
+ * does not change the behaviour of existing code in a non-compatible way.
+ * works on both Python 2 and Python 3.
+
+If your change follows all points of the checklist, you can commit it to your
+repository. (You could commit it first, and check later, and then commit the
+fixes, but commits should be logical and it makes no sense to have to commits
+for one logical unit).
+
+The changelog message should follow standard git format. At the end of the
+message, tags understood by gbp-dch and other tags may be added. An example
+commit message could be:
+
+.. code-block:: none
+
+ apt.package: Fix blah blah
+
+ Fix a small bug where foo is doing bar, but should be doing baz
+ instead.
+
+ Closes: #bugnumber
+ LP: #ubuntu-bug-number
+ Reported-By: Bug Reporter Name <email@example.com>
+
+
+Once you have made all your changes, you can run ``git format-patch``,
+specifying the upstream commit or branch you want to create patches
+against. Then you can either:
+
+* report a bug against the python-apt package, attach the patches
+ you created in the previous step, and tag it with 'patch'. It might also be
+ a good idea to prefix the bug report with '[PATCH]'.
+
+* send the patches via ``git send-email``.
+
+For larger patch series, you can also publish a git branch on a
+public repository and request it to be pulled.
+
+If you choose that approach, you may want to base your patches against
+the latest release, and not against some random commit, for the sake of
+preserving a sane git history.
+
+Be prepared to rebase such a branch, and close any bugs you fix in the
+branch by mentioning them in the commit message using a Closes or LP
+tag.
+
+
+Documentation updates
+---------------------
+If you want to update the documentation, please follow the procedure as written
+above. You can send your content in plain text, but reStructuredText is the
+preferred format. I (Julian Andres Klode) will review your patch and include
+it.
+
+.. highlight:: sh
+
+Example patch session
+----------------------
+In the following example, we edit a file, create a patch (an enhanced
+patch), and report a wishlist bug with this patch against the python-apt
+package::
+
+ user@ pc:~$ git clone git://anonscm.debian.org/apt/python-apt.git
+ user@pc:~$ cd python-apt
+ user@pc:~/python-apt$ editor FILES
+ user@pc:~/python-apt$ pycodestyle FILES # Check with pycodestyle
+ user@pc:~/python-apt$ pylint -e FILES # Check with pylint
+ user@pc:~/python-apt$ pyflakes FILES # Check with pyflakes
+ user@pc:~/python-apt$ pychecker FILES # Check with pychecker
+ user@pc:~/python-apt$ git commit -p
+ user@pc:~/python-apt$ git format-patch origin/HEAD
+ user@pc:~/python-apt$ reportbug --severity=wishlist --tag=patch --attach=<patch> ... python-apt
+
+You may also send the patches to the mailing list instead of
+reporting the bug::
+
+ user@pc:~/python-apt$ git send-email --to=deity@lists.debian.org <patches created by format-patch>
+
+You can even push your changes to your own repository and request
+a pull request.