# Contributing to *MRtrix3*

There are many ways in which to contribute to the ongoing improvement of *MRtrix3*:

## Bug reporting

1. Please search on both the [*MRtrix3* community forum](http://community.mrtrix.org/search)
   and the [GitHub issue list](https://github.com/MRtrix3/mrtrix3/issues)
   to see if anybody else has lodged a similar observation.

1. How confident are you that the behaviour you have observed is in fact a
   genuine bug, and not a misunderstanding?

   -  *Confident*: Please [open a new GitHub issue](https://github.com/MRtrix3/mrtrix3/issues/new);
      select the "bug report" issue template to get started.

   -  *Not so confident*: That's fine! Consider instead creating a new topic
      on the [*MRtrix3* community forum](http://community.mrtrix.org/);
      others can then comment on your observation and determine the
      appropriate level of escalation.

## Requesting a new feature

Please search the [GitHub issue list](https://github.com/MRtrix3/mrtrix3/issues)
to see if anybody else has made a comparable request:

   -  If a corresponding issue already exists, please add a comment to that
      issue to escalate the request. Additionally, describe any
      aspect of that feature not yet described in the existing issue.

   -  If no such listing exists, then you are welcome to create a [new
      issue](https://github.com/MRtrix3/mrtrix3/issues/new) outlining the
      request. Be sure to select the "feature request" option to get started
      with writing the Issue.
      
## Asking questions

General questions regarding *MRtrix3* installation, usage, or any other
aspect that is not specific to the *MRtrix3* *code*, should be directed to
the [community forum](http://community.mrtrix.org/). Also consider perusing
the [online documentation](https://mrtrix.readthedocs.io/en/latest/) for
the software, in case your issue has already been described there.

## Contribution of content

Thanks for your interest in making direct contributions to *MRtrix3*!
We are excited to expand the breadth of researchers involved in improving
and expanding this software, and to ensure that all who make such
contributions receive appropriate acknowledgement through Git.

The instructions below give an overview of how to go about generating a
proposed change to *MRtrix3*. Making your first contribution to an
open-source project can certainly be daunting. The *MRtrix3* developers
are however more than willing to be engaged in the process for those
without experience in Git or GitHub.

#### Classification of contribution

We here classify three distinct types of contributions. For any particular
proposed contribution, the classification here will influence the advice
to be provided in subsequent sections of this document.

1. *Fixing a bug*

   If the current code behaviour is *unambiguously incorrect*.

   If there does not already exist a [GitHub Issue](https://github.com/MRtrix3/mrtrix3/issues)
   describing the bug, consider reporting the bug as a standalone Issue
   prior to progressing further; that way developers can confirm the issue,
   and possibly provide guidance if you intend to resolve the issue yourself.

2. *Adding or altering features*

   If any of the following are true:

   -  The current code behaviour is considered incorrect or non-ideal,
      and could be improved, but is nevertheless *functional* in its
      current state;

   -  The proposed change would *alter* the output data generated by
      a command;

   -  The proposed change improves the *performance* of a particular
      command or process, but does not change its output.

   -  The proposal involves a novel addition to the repository that
      is inconsequential for the operation of any existing command.

3. *Documentation*

   If you wish to make changes to the [*MRtrix3* documentation](https://mrtrix.readthedocs.io/en/latest/).

#### Generating content

1. If you have not already done so, you will need to create a *fork* of
   the [*MRtrix3* repository](https://github.com/MRtrix3/mrtrix3)
   into your GitHub account, where unlike the main *MRtrix3* repository,
   you will have full write access to make the requisite changes.

1. Create a Git branch that is named appropriately according to the
   modifications that are being made. The existing code branch on which
   this new derived branch should be based depends on the nature of the
   proposed change:

   -  If your changes involve *fixing a bug* in existing *MRtrix3*
      functionality, then your code should be based on the "`master`"
      branch.

      Once merged, these changes will become immediately available to any user
      building *MRtrix3* from source via the default `master` branch, whether
      from freshly cloning that source code or from updating their code. It
      will additionally be included in the next tag release of *MRtrix3*,
      including "*patch*" releases, i.e. "`3.0.x`" (see [this
      page](https://semver.org/) for a full description of release versioning)

      This can be done with the following commands:

      ```
      $ git checkout master
      $ git checkout -b fix_feature
      ```

      (name your new branch appropriately)

   -  If your changes involve *adding or altering features*, then your
      code should be based on the "`dev`" branch. 

      Once merged, such code will only be propagated to users who elect to
      explicitly check out the code on the "`dev`" branch when building *MRtrix3*
      from source, which will almost exclusively be the core development team.
      It will additionally be included in the next *minor* release of
      *MRtrix3*, i.e. "`3.x.0`" (*patch* releases, i.e. "`3.0.x`", do *not*
      include changes that have been merged onto the "`dev`" branch). (see
      [this page](https://semver.org/) for a full description of release
      versioning)

      This can be done with the following commands:

      ```
      $ git checkout dev
      $ git checkout -b add_feature
      ```

      (name your new branch appropriately)

   -  If only making changes to the *MRtrix3* *documentation*, then the
      appropriate base branch will depend upon the nature of the changes
      being proposed and the urgency of the update. For instance, if providing
      a minor correction to spelling / grammar, or fixing an erroneous
      hyperlink, then a direct merge to `master` is likely appropriate.
      Conversely, if the changes are non-trivial, and it makes more sense for
      the changes to be made as part of an *MRtrix3* update rather than
      immediately, then `dev` may be the more appropriate base branch. If
      the answer to this question in the context of your proposed changes is
      unclear to you, then please generate an [Issue](https://github.com/MRtrix3/mrtrix3/issues)
      to facilitate direct discussion with the *MRtrix3* core development
      team (ideally before commencing the implementation of changes, as
      incorrect selection can sometimes be laborious to resolve later).

1. Generate one or more Git commits that apply your proposed changes to
   the repository.

   Before commencing writing or modifying code, you may wish to read the
   [coding conventions](#coding-conventions) section at the bottom of this
   page.

   -  Individual commits should ideally have a clear singular purpose,
      and not incorporate multiple unrelated changes. If your proposed
      changes involve multiple disparate components, consider breaking
      those changes up into individual commits.

      Conversely, if multiple code changes are logically grouped with /
      linked to one another, these should ideally be integrated into a
      single commit.

   -  Commits should contain an appropriate message that adequately
      describes the change encapsulated within.

      If the change demands a longer description, then the commit message
      should be broken into a synopsis (less than 72 characters, ideally less
      than 50) and message body, separated by two newline characters (as this
      enables GitHub to parse them appropriately). Please follow the
      [suggestions on this page](https://chris.beams.io/posts/git-commit/) to
      make your git commit messages as useful as possible.

      For single-line commits, this can be achieved at the command-line using
      the `git commit -m` option:

      `$ git commit -m 'mrconvert: fix problem in datatype handling'`

   -  Where relevant, commit messages can also contain references to
      GitHub issues or pull requests (type the "`#`" character followed
      by the issue / PR number), and/or other individual commits (copy
      and paste the first 8-10 characters of the commit hash). This will
      result in GitHub automatically generating bi-directional hyperlinks
      between the various pages, which greatly assists in navigating
      around related discussions.

   -  If multiple persons have contributed to the proposed changes, it is
      possible to modify individual Git commits to have [multiple
      authors](https://help.github.com/en/articles/creating-a-commit-with-multiple-authors),
      to ensure that all contributors receive appropriate acknowledgement.

   As a general rule: Git commits and commit messages should be constructed
   in such a way that, at some time in the future, when one is navigating
   through the contribution history, the evolution of the code is as clear
   as possible.

1. Check that your modified code does not prevent *MRtrix3* from
   passing existing tests, or introduce any other issues (unless otherwise
   specified, all files referenced below are in the *MRtrix3* root directory):

   -  If adding or modifying C++ code, make sure that script "`./check_syntax`"
      executes successfully.

   -  If adding or modifying Python code, make sure that script
      "`./run_pylint`" executes successfully.

   -  If there is a chance of your modifications altering the observable
      behaviour of one or more existing commands, make sure that script
      "`./run_tests`" executes successfully. When running this script you
      must specify the test(s) to be run: you can either specify an
      individual command or unit test, or execute tests for all
      "`binaries`" or all "`scripts`" (especially important if modifying
      code that is not specific to an individual command, or modifying
      a command that is utilised by Python scripts).

   -  If your changes involve the addition of one or more novel commands,
      or the modification of help page information of an existing command,
      then you will need to run script "`./docs/generate_user_docs.sh`"
      and generate a commit that adds the resulting updates to the
      list of available commands and command documentation page(s).

   -  If making changes to the online documentation, then you should ideally
      generate the documentation on your local system, and manually inspect
      it for any formatting issues. Instructions for doing so can be found
      in "[`docs/README.md`](https://github.com/MRtrix3/mrtrix3/blob/master/docs/README.md)".

1. For code contributions, if possible, a unit test or reproducibility
   test should be added. This can be used to:

   -  Demonstrate appropriate behaviour of novel functionality;

   -  Prove that a demonstrable error with existing code is resolved
      with the revised code (i.e. *fixing a bug*);

   -  Preclude regression of the behaviour of that code in the future
      (which can in some instances occur with changes to seemingly
      unrelated code).

   For tests that require the addition of raw data to the
   [`test_data`](https://github.com/MRtrix3/test_data) or
   [`script_test_data`](https://github.com/MRtrix3/script_test_data)
   repositories, please coordinate with the *MRtrix3* core development
   team.

#### Creating a Pull Request

Once you are content with the additions / modifications that you have made
to the repository content, the next step is to propose that those changes be
merged into the main *MRtrix3* repository. This involves setting up a
"Pull Request", which proposes merging the changes that you have made in your
repository fork into the relevant branch of the main *MRtrix3* repository.
It additionally enables both discussion with the core development team
regarding those changes, and explicit code review.

The "*head*" branch of the Pull Request should be the Git branch on your
fork of the repository within which you have performed the relevant changes.
The "*base*" *repository* should be the main *MRtrix3* repository; however,
the base *branch* will depend on the nature of the contribution:

-  If *fixing a bug*, then the base branch should be "`master`"
   (just as was used when first constructing the branch in your fork).

-  If *adding or altering features*, then the base branch should be
   "`dev`" (just as was used when first constructing the branch in your
   fork).

-  If making changes to the *MRtrix3* *documentation*, then the base
   branch should be the same branch as was used when first constructing
   the working branch on your fork.

In the initial post of your Pull Request, you should include in your text
references to any other Issues or Pull Requests that you consider relevant
to the discussion, as this greatly facilitates reader comprehension (and
this may indeed include yourself in the future). Simply including the text
"`#xxxx`" (replacing "`xxxx`" with the number of the relevant Issue /
Pull Request) will result in GitHub automatically creating bi-directional
hyperinks between the relevant pages.

-----

## Coding conventions

While we do not have strict enforced coding conventions in *MRtrix3*, the
accepted conventions should be self-evident from the code itself. So while
some flexibility in coding style is permitted, substantial deviations
from such may result in a request during the Pull Request phase to make
corresponding revisions.

A few explicit notes on such:

-  For both C++ and Python, indentation is achieved using two space
   characters.

-  Newline characters are Unix-style ("`LF`" / '`\n`'); any changes that
   introduce Windows-style newline characters ("`CR LF`" / "`\r\n`")
   will need to be edited accordingly.

-  In Python, variable / class / module names are enforced through
   `pylint`. Script "`run_pylint`" in the *MRtrix3* root directory
   will test any code modifications against these expectations.

-  If the operation of your code is not trivially self-apparent,
   please endeavour to comment appropriately.

-  Do not leave excess newline characters at the end of a file.
