#+TITLE: Contribution guidelines
#+HTML_HEAD_EXTRA: <link rel="stylesheet" type="text/css" href="../css/readtheorg.css" />

Spacemacs is a volunteer effort. We encourage you to pitch in. The community
makes Spacemacs what it is. We have a few guidelines, which we ask all
contributors to follow.

You can only consider reading the sections relevant to what you are going to do:
- [[#asking-for-help][Asking for help]] if you are about to open an issue to ask a question.
- [[#reporting-issues][Reporting issues]] if you are about to open a new issue.
- [[#contributing-code][Contributing code]] if you are about to send a Pull-Request.

Thanks! :heart: :heart: :heart:

* Content                                                    :TOC@2:noexport:
 - [[#asking-for-help][Asking for help]]
 - [[#reporting-issues][Reporting issues]]
 - [[#contributing-code][Contributing code]]
   - [[#general-contribution-guidelines][General contribution guidelines]]
   - [[#contributing-a-layer][Contributing a layer]]
   - [[#contributing-a-keybinding][Contributing a keybinding]]
   - [[#contributing-a-banner][Contributing a banner]]
 - [[#additional-information][Additional information]]
   - [[#testing][Testing]]
 - [[#credits][Credits]]

* Asking for help
If you want to ask an usage question, be sure to look first into some places as
it may hold the answer:

- [[doc/FAQ.org][The FAQ]]. Some of the most frequently asked questions are answered there.
- [[doc/DOCUMENTATION.org][The documentation]]. It's the general documentation of Spacemacs.
- You may also read the =README.org= of the [[layers/][relevant layer(s)]].

If your question is not answered there, then please come into our [[https://gitter.im/syl20bnr/spacemacs][gitter chat]] to
discuss it with us :relaxed:. We will direct you to a solution, or ask you to
open an issue if it is needed.

* Reporting issues
Issues have to be reported on our [[https://github.com/syl20bnr/spacemacs/issues][issues tracker]]. Please:

- Check that the issue has not already been reported.
  - This can be achieved by searching keywords on the [[https://github.com/syl20bnr/spacemacs/issues][issues tracker]].
- Check that the issue has not been fixed in the =develop= version of Spacemacs.
  - This can be achieved by running Spacemacs on the =develop= branch and trying
    to reproduce the bug here. You can also check at the [[https://github.com/syl20bnr/spacemacs/tree/develop][source code]] to see if
    it has been changed/corrected.
- Try to use a clear title, and describe your problem with complete sentences.
  See also [[https://github.com/syl20bnr/spacemacs/wiki/Debugging#how-to-make-a-great-bug-report][How to make a great bug report]] in the wiki.
- Include the following information in your issue:
  - The output of =SPC h d s= (=M-m h d s= in Emacs style), which gives the
    versions information about your installation.
  - If relevant, include the mode in which the problem arise (e.g. javascript
    files, =org-mode=, etc…).
  - If possible, try to include details on how to reproduce it, like a step by
    step guide.

* Contributing code
Code contributions are welcome. Please read the following sections carefully. In
any case, feel free to join us on the [[https://gitter.im/syl20bnr/spacemacs][gitter chat]] to ask questions about
contributing!

** General contribution guidelines

*** License
The license is =GPLv3= for all parts specific to Spacemacs, this includes:
- The initialization and core files
- All the layer files.

For files not belonging to Spacemacs like local packages and libraries, refer
to the header file. Those files should not have an empty header, we may not
accept code without a proper header file.

*** Conventions
Spacemacs is based on conventions, mainly for naming functions, keybindings
definition and writing documentation. Please read the [[file:doc/CONVENTIONS.org][CONVENTIONS.org]] file
before your first contribution to get to know them.

*** Pull-Request
Submit your contribution against the =develop= branch. You should not use
your =master= branch to modify Spacemacs, this branch is considered to be
read-only.

You may want to [[https://github.com/syl20bnr/spacemacs/wiki/Beginner%27s-Guide-to-Contributing-a-Pull-Request-to-Spacemacs][read our beginner’s guide for Pull Requests]].

/PR = Pull-Request/

**** Ideally for /simple/ PRs (most of them):
-  Branch from =develop=
-  One topic per PR
-  One commit per PR
-  If you have several commits on different topics, close the PR and
   create one PR per topic
-  If you still have several commits, squash them into only one commit
-  Rebase your PR branch on top of upstream =develop= before submitting
   the PR

Those PRs are usually /cherry-picked/.

**** For complex PRs (big refactoring, etc):
- Squash only the commits with uninteresting changes like typos, syntax fixes,
  etc... and keep the important and /isolated/ steps in different commits.

Those PRs are /merged/ and explicitly /not fast-forwarded/.

*** Commit messages
Write commit messages according to adapted [[http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html][Tim Pope's guidelines]]:

- Use present tense and write in the imperative: “Fix bug”, not “fixed bug” or
  “fixes bug”.
- Start with a capitalized, short (72 characters or less) summary, followed by a
  blank line.
- If necessary, add one or more paragraphs with details, wrapped at 72
  characters.
- Separate paragraphs by blank lines.

This is a model commit message:

#+begin_EXAMPLE
Capitalized, short (72 chars or less) summary

More detailed explanatory text, if necessary.  Wrap it to about 72
characters or so.  In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body.  The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.

Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
or "Fixes bug."  This convention matches up with commit messages generated
by commands like git merge and git revert.

Further paragraphs come after blank lines.

- Bullet points are okay, too

    - Typically a hyphen or asterisk is used for the bullet, followed by a
      single space, with blank lines in between, but conventions vary here

    - Use a hanging indent
#+end_EXAMPLE

[[https://github.com/magit/magit/][Git Commit]] and [[https://github.com/magit/magit/][Magit]] provide Emacs mode for Git commit messages, which helps you
to comply to these guidelines.

** Contributing a layer
Please read the [[file:doc/LAYERS.org][layers documentation]] first.

It is recommended to use the =configuration-layer/create-layer= command in order
to create a layer, as it will take care of using the files templates and will
also create the file headers correctly.

Contributed configuration layers are stored in the =layers/= folder. The
=layers/= folder also contains categories prefixed with =+= to put your layers
in. For example a layer for a language would go in the =layers/+lang/= folder.

Layer with no associated configuration will be rejected. For instance a layer
with just a package and a hook can be easily replaced by the usage of the
variable =dotspacemacs-additional-packages=.

*** File header
The file header for =elisp= files should look like the following template:

#+BEGIN_EXAMPLE
    ;;; FILENAME --- NAME Layer packages File for Spacemacs
    ;;
    ;; Copyright (c) 2012-2016 Sylvain Benner & Contributors
    ;;
    ;; Author: YOUR_NAME <YOUR_EMAIL>
    ;; URL: https://github.com/syl20bnr/spacemacs
    ;;
    ;; This file is not part of GNU Emacs.
    ;;
    ;;; License: GPLv3
#+END_EXAMPLE

You should replace =FILENAME= by the name of the file (e.g. =packages.el=)
and =NAME= by the name of the layer you are creating, don't forget to replace
=YOUR_NAME= and =YOUR_EMAIL= also. Some files already have a template inside
=core/templates/=, so look in there first.
Note that if you use =configuration-layer/create-layer=, spacemacs will prepare
files and headers for you, and for free :smile: !

*** Author of a new layer
In the files header, change the default author name (=Sylvain Benner=) to your
name.

*** Contributor to an existing layer
If you are contributing to an already existing layer, you should not modify any
header file.

** Contributing a keybinding
Keybindings are an important part of spacemacs.

First if you want to have some personal keybindings, you can freely bind them
inside the ~SPC o~ and ~SPC m o~ prefixes which are reserved for the user. This
can be done from the =dotspacemacs/user-config= function of your =.spacemacs=
file and don't require any contribution to Spacemacs.

If you think it worth contributing a new key bindings then be sure to read
the [[doc/CONVENTIONS.org][CONVENTIONS.org]] file to find the best key bindings, then create a
Pull-Request with your changes.

*ALWAYS* document your new keybindings or keybindings changes inside the
relevant documentation file. It should be the layer's =README.org= file for
layer's keybindings, or =DOCUMENTATION.org= for general Spacemacs key
bindings.

** Contributing a banner
The startup banner is by default the Spacemacs logo but there are also ASCII
banners available in the directory =core/banners/=.

If you have some ASCII skills you can submit your artwork!

You are free to choose a reasonable height size but the width size should be
around 75 characters.

* Additional information
** Testing
Tests live in the =tests/= folder, with a folder structure corresponding to the
rest of the repository.

To run tests locally, navigate to the relevant subfolder and run =make=.

Spacemacs uses Travis CI to perform more comprehensive testing, where each
testable layer is enabled in turn.

To add tests for a layer, do the following:

1. Create a subfolder of =tests/= corresponding to the layer you want to test.
2. Write a file called =dotspacemacs.el= in that folder. It should be a minimal
   dotfile that enables the layer in question (and other layers it may depend
   on).
3. Write a number of files with tests. Please try to separate unit and
   functional tests. Look at existing tests for clues.
4. Write a =Makefile= in that folder. It should define three variables.
   - =LOAD_FILES= :: a list of additional files to load before testing (relative
        to the root Spacemacs folder). This should typically be =init.el=.
   - =UNIT_TEST_FILES= :: a list of unit test files in the current folder.
   - =FUNC_TEST_FILES= :: a list of functional test files in the current folder.
   See existing tests for examples.
   #+begin_src makefile
     TEST_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

     LOAD_FILES = ...
     UNIT_TEST_FILES = ...
     FUNC_TEST_FILES = ...

     include ../../spacemacs.mk
   #+end_src
5. Add the new test to list of tests in =travis/run_build.sh=.

* Credits

This =CONTRIBUTING.org= file is partially based on the [[https://github.com/rails/rails/blob/master/CONTRIBUTING.md][Rails Contribution
guidelines]] and [[https://github.com/flycheck/flycheck/blob/master/CONTRIBUTING.md][Flycheck Contribution guidelines]].
