Contributing to Kwant
=====================

We see Kwant not just as a package with fixed functionality, but rather as a
framework for implementing different physics-related algorithms using a common
set of concepts and, if possible, a shared interface.  We have designed it
leaving room for growth, and plan to keep extending it.

Contributions to Kwant are highly welcome.  You can help the project not only
by writing code, but also by reporting bugs, and fixing/improving the
website and the documentation.


Where help is needed
--------------------

The `Kwant issue tracker
<https://gitlab.kwant-project.org/kwant/kwant/issues>`_ serves to track bugs
in Kwant, but most issues are in fact ideas for enhancements.  The issues are
categorized with labels, so that it is possible to view `all the “easy” issues
<https://gitlab.kwant-project.org/kwant/kwant/issues?label_name=difficulty%3A+easy>`_
for example.

Please do feel free to enter new issues yourself.  If you are unsure about
some aspect It may be a good idea to discuss your idea on the development
mailing list kwant-devel@kwant-project.org before filing an issue.

If you already have some code that extends Kwant in a useful way, please
consider sharing it.  If your extension fits well with Kwant and is of wide
enough interest, we will be happy to include it into Kwant proper.  For more
specialized cases, we will find a solution as well.  (We could, for example,
add a list of Kwant-related modules to this website.)  In any case, external
contributions will be clearly marked as such, and relevant papers will be
added to the list of `suggested acknowledgements </cite.html>`_.


Getting the source code
-----------------------

The source code of released versions of Kwant is available for `download
<http://downloads.kwant-project.org/kwant/>`_.  You can follow the development
through the `Kwant page of our GitLab instance
<https://gitlab.kwant-project.org/kwant/kwant>`_.  The `Git
<http://git-scm.com/>`_ repository of Kwant can be cloned directly with the
command ::

    git clone https://gitlab.kwant-project.org/kwant/kwant.git

The Kwant git repository has two main branches: The branch *master*
contains the development towards the next release.  The branch *stable* contains
the most recent release that is considered stable, and only bugfixes are applied
to it.


Setting up for development
--------------------------

When working with the Kwant source, regular `build instructions
</doc/1/pre/install.html#building-and-installing-from-source>`_ apply.  It
would be tiresome, however, to have to reinstall the modified Kwant after each
modification.

One easy way to avoid this is to build in-place so that there is no need to
reinstall after each change.  This can be done with the following command ::

    python3 setup.py build_ext -i

No further installation is necessary.  The “inner” ``kwant`` subdirectory has
been turned into a proper Python package that can be imported from the “outer”
directory, i.e. the directory where ``setup.py`` is located.  Any script
inside that directory that imports Kwant will get the modified version.  (To
be able to import the modified Kwant from another directory one can create a
symbolic link to the package.)

The above ``build_ext`` command does not have to be rerun when a Python file
is modified.  Recompilation is only necessary whenever a Cython file
(``.pyx``) has been changed.


Modifying the source code
-------------------------

We recommend that you keep each of your changes to Kwant on a separate “topic
branch” that starts at *master*.  Try to not mix up unrelated changes in a
single branch.  To create a topic branch, use the command::

    git checkout -b my_topic master

Now you can begin to implement your idea.  As you go, register your changes
with Git as explained, for example, in the `Pro Git book
<https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository>`_
that is freely available online.

Once you feel that you would like to show your work to other interested people
(because you would like to receive feedback, or because you consider it
ready), it's time to inspect your branch.  Run ``git status`` to make sure
that you have committed all of your changes, then use a tool like ``gitk`` to
view your branch.

In the following, two methods to share your commits are described.  The first
will be familiar if you have experience with the popular GitHub service.  If
you do not, you might prefer the second method, since it is simpler.


Method 1: Using the Kwant GitLab instance
.........................................

Go the `GitLab page of the official Kwant repository
<https://gitlab.kwant-project.org/kwant/kwant>`_.  Since you do not have write
access to this repository, you have to create an own “fork” of it by clicking
on the button just right of the “star” button.

You created a public copy of the Kwant repository that is controlled by you.
Add it as a remote repository to the clone of Kwant on your computer::

    git remote add own https://gitlab.kwant-project.org/<USERNAME>/kwant.git

You can copy-and-paste your own version of the above URL from the main page of
your repository.  (If you know about SSH, you may also prefer to upload your
public ssh key to GitLab and to use SSH as transport.)  The string ``own`` is
the local name you give to the remote, it can be anything.

Now you can push your topic branch to your repository::

    git push own my_branch

This will make your branch appear in GitLab.  Now you can let us know about
your branch by `creating a merge request in GitLab
<https://gitlab.kwant-project.org/help/workflow/forking_workflow.md>`_ or by
sending a message to kwant-devel@kwant-project.org.


Method 2: Sending patches to the development mailing list
.........................................................

Run the command ::

    git format-patch origin/master

This will create a “patch” file for each commit on your branch.  Now simply
send these patches as email attachments to kwant-devel@kwant-project.org,
together with an explanation of your idea.  You do not have to be subscribed
to the mailing list.

(Or, even better, use ``git send-email`` as shown in this `example of usage
<https://kernel.org/pub/software/scm/git/docs/git-send-email.html#_example>`_
and this `git send-email howto
<http://www.freedesktop.org/wiki/Software/PulseAudio/HowToUseGitSendEmail/>`_.)


Coding style
------------

* Please keep the code consistent by adhering to the prevailing naming and
  formatting conventions.  We generally respect the `"Style Guide for Python
  Code" <http://www.python.org/dev/peps/pep-0008/>`_.  For docstrings, we
  follow `NumPy's "Docstring Standard"
  <http://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_ and
  `Python's "Docstring Conventions"
  <http://www.python.org/dev/peps/pep-0257/>`_.

* Write tests for all the important functionality you add.  Be sure not to
  break existing tests.

* Create a logical sequence of commits with clear commit messages.