summaryrefslogtreecommitdiff
path: root/CONTRIBUTING.rst
diff options
context:
space:
mode:
authorMo Zhou <lumin@debian.org>2021-05-08 12:59:41 +0800
committerMo Zhou <lumin@debian.org>2021-05-08 12:59:41 +0800
commitb4a43ecbaff7889649f05d3275753dcce39b7440 (patch)
tree4c72d4e5dd0c085bc33d83617b1774a8889659f4 /CONTRIBUTING.rst
parenta9261f41003dffdb7eedca608339c1e4e0737095 (diff)
New upstream version 3.2.2
Diffstat (limited to 'CONTRIBUTING.rst')
-rw-r--r--CONTRIBUTING.rst475
1 files changed, 475 insertions, 0 deletions
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
new file mode 100644
index 0000000..2df7809
--- /dev/null
+++ b/CONTRIBUTING.rst
@@ -0,0 +1,475 @@
+Guidelines For Developers
+=========================
+
+This document provides guidelines for making changes to the fish-shell
+project. This includes rules for how to format the code, naming
+conventions, et cetera.
+
+In short:
+
+- Be conservative in what you need (``C++11``, few dependencies)
+- Use automated tools to help you (including ``make test``, ``build_tools/style.fish`` and ``make lint``)
+
+General
+-------
+
+Fish uses C++11. Newer C++ features should not be used to make it possible to use on older systems.
+
+It does not use exceptions, they are disabled at build time with ``-fno-exceptions``.
+
+Don't introduce new dependencies unless absolutely necessary, and if you do,
+please make it optional with graceful failure if possible.
+Add any new dependencies to the README.rst under the *Running* and/or *Building* sections.
+
+This also goes for completion scripts and functions - if at all possible, they should only use
+POSIX-compatible invocations of any tools, and no superfluous dependencies.
+
+E.g. some completions deal with JSON data. In those it's preferable to use python to handle it,
+as opposed to ``jq``, because fish already optionally uses python elsewhere. (It also happens to be quite a bit *faster*)
+
+Lint Free Code
+--------------
+
+Automated analysis tools like cppcheck and oclint can point out
+potential bugs or code that is extremely hard to understand. They also
+help ensure the code has a consistent style and that it avoids patterns
+that tend to confuse people.
+
+To make linting the code easy there are two make targets: ``lint`` and
+``lint-all``. The latter does exactly what the name implies. The former
+will lint any modified but not committed ``*.cpp`` files. If there is no
+uncommitted work it will lint the files in the most recent commit.
+
+Fish has custom cppcheck rules in the file ``.cppcheck.rule``. These
+help catch mistakes such as using ``wcwidth()`` rather than
+``fish_wcwidth()``. Please add a new rule if you find similar mistakes
+being made.
+
+Dealing With Lint Warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You are strongly encouraged to address a lint warning by refactoring the
+code, changing variable names, or whatever action is implied by the
+warning.
+
+Suppressing Lint Warnings
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once in a while the lint tools emit a false positive warning. For
+example, cppcheck might suggest a memory leak is present when that is
+not the case. To suppress that cppcheck warning you should insert a line
+like the following immediately prior to the line cppcheck warned about:
+
+::
+
+ // cppcheck-suppress memleak // addr not really leaked
+
+The explanatory portion of the suppression comment is optional. For
+other types of warnings replace “memleak” with the value inside the
+parenthesis (e.g., “nullPointerRedundantCheck”) from a warning like the
+following:
+
+::
+
+ [src/complete.cpp:1727]: warning (nullPointerRedundantCheck): Either the condition 'cmd_node' is redundant or there is possible null pointer dereference: cmd_node.
+
+Suppressing oclint warnings is more complicated to describe so I’ll
+refer you to the `OCLint
+HowTo <http://docs.oclint.org/en/latest/howto/suppress.html#annotations>`__
+on the topic.
+
+Ensuring Your Changes Conform to the Style Guides
+-------------------------------------------------
+
+The following sections discuss the specific rules for the style that
+should be used when writing fish code. To ensure your changes conform to
+the style rules you simply need to run
+
+::
+
+ build_tools/style.fish
+
+before committing your change. That will run ``git-clang-format`` to
+rewrite only the lines you’re modifying.
+
+If you’ve already committed your changes that’s okay since it will then
+check the files in the most recent commit. This can be useful after
+you’ve merged another person’s change and want to check that it’s style
+is acceptable. However, in that case it will run ``clang-format`` to
+ensure the entire file, not just the lines modified by the commit,
+conform to the style.
+
+If you want to check the style of the entire code base run
+
+::
+
+ build_tools/style.fish --all
+
+That command will refuse to restyle any files if you have uncommitted
+changes.
+
+Configuring Your Editor for Fish C++ Code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Vim
+^^^
+
+As of Vim 7.4 it does not recognize triple-slash comments as used by
+Doxygen and the OS X Xcode IDE to flag comments that explain the
+following C symbol. This means the ``gq`` key binding to reformat such
+comments doesn’t behave as expected. You can fix that by adding the
+following to your vimrc:
+
+::
+
+ autocmd Filetype c,cpp setlocal comments^=:///
+
+If you use Vim I recommend the `vim-clang-format
+plugin <https://github.com/rhysd/vim-clang-format>`__ by
+[@rhysd](https://github.com/rhysd).
+
+Emacs
+^^^^^
+
+If you use Emacs: TBD
+
+Configuring Your Editor for Fish Scripts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you use Vim: Install `vim-fish <https://github.com/dag/vim-fish>`__,
+make sure you have syntax and filetype functionality in ``~/.vimrc``:
+
+::
+
+ syntax enable
+ filetype plugin indent on
+
+Then turn on some options for nicer display of fish scripts in
+``~/.vim/ftplugin/fish.vim``:
+
+::
+
+ " Set up :make to use fish for syntax checking.
+ compiler fish
+
+ " Set this to have long lines wrap inside comments.
+ setlocal textwidth=79
+
+ " Enable folding of block structures in fish.
+ setlocal foldmethod=expr
+
+If you use Emacs: Install
+`fish-mode <https://github.com/wwwjfy/emacs-fish>`__ (also available in
+melpa and melpa-stable) and ``(setq-default indent-tabs-mode nil)`` for
+it (via a hook or in ``use-package``\ s “:init” block). It can also be
+made to run fish_indent via e.g.
+
+.. code:: elisp
+
+ (add-hook 'fish-mode-hook (lambda ()
+ (add-hook 'before-save-hook 'fish_indent-before-save)))
+
+Suppressing Reformatting of C++ Code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can tell ``clang-format`` to not reformat a block by enclosing it in
+comments like this:
+
+::
+
+ // clang-format off
+ code to ignore
+ // clang-format on
+
+Fish Script Style Guide
+-----------------------
+
+1. All fish scripts, such as those in the *share/functions* and *tests*
+ directories, should be formatted using the ``fish_indent`` command.
+
+2. Function names should be in all lowercase with words separated by
+ underscores. Private functions should begin with an underscore. The
+ first word should be ``fish`` if the function is unique to fish.
+
+3. The first word of global variable names should generally be ``fish``
+ for public vars or ``_fish`` for private vars to minimize the
+ possibility of name clashes with user defined vars.
+
+C++ Style Guide
+---------------
+
+1. The `Google C++ Style
+ Guide <https://google.github.io/styleguide/cppguide.html>`__ forms
+ the basis of the fish C++ style guide. There are two major deviations
+ for the fish project. First, a four, rather than two, space indent.
+ Second, line lengths up to 100, rather than 80, characters.
+
+2. The ``clang-format`` command is authoritative with respect to
+ indentation, whitespace around operators, etc.
+
+3. All names in code should be ``small_snake_case``. No Hungarian
+ notation is used. The names for classes and structs should be
+ followed by ``_t``.
+
+4. Always attach braces to the surrounding context.
+
+5. Indent with spaces, not tabs and use four spaces per indent.
+
+6. Document the purpose of a function or class with doxygen-style
+ comment blocks. e.g.:
+
+::
+
+ /**
+ * Sum numbers in a vector.
+ *
+ * @param values Container whose values are summed.
+ * @return sum of `values`, or 0.0 if `values` is empty.
+ */
+ double sum(std::vector<double> & const values) {
+ ...
+ }
+ */
+
+or
+
+::
+
+ /// brief description of somefunction()
+ void somefunction() {
+
+Testing
+-------
+
+The source code for fish includes a large collection of tests. If you
+are making any changes to fish, running these tests is a good way to make
+sure the behaviour remains consistent and regressions are not
+introduced. Even if you don’t run the tests on your machine, they will
+still be run via Github Actions.
+
+You are strongly encouraged to add tests when changing the functionality
+of fish, especially if you are fixing a bug to help ensure there are no
+regressions in the future (i.e., we don’t reintroduce the bug).
+
+The tests can be found in three places:
+
+- src/fish_tests.cpp for tests to the core C++ code
+- tests/checks for script tests, run by `littlecheck <https://github.com/ridiculousfish/littlecheck>`__
+- tests/pexpects for interactive tests using `pexpect <https://pexpect.readthedocs.io/en/stable/>`__
+
+When in doubt, the bulk of the tests should be added as a littlecheck test in tests/checks, as they are the easiest to modify and run, and much faster and more dependable than pexpect tests. The syntax is fairly self-explanatory. It's a fish script with the expected output in ``# CHECK:`` or ``# CHECKERR:`` (for stderr) comments.
+
+fish_tests.cpp is mostly useful for unit tests - if you wish to test that a function does the correct thing for given input, use it.
+
+The pexpects are written in python and can simulate input and output to/from a terminal, so they are needed for anything that needs actual interactivity. The runner is in build_tools/pexpect_helper.py, in case you need to modify something there.
+
+Local testing
+~~~~~~~~~~~~~
+
+The tests can be run on your local computer on all operating systems.
+
+::
+
+ cmake path/to/fish-shell
+ make test
+
+Git hooks
+~~~~~~~~~
+
+Since developers sometimes forget to run the tests, it can be helpful to
+use git hooks (see githooks(5)) to automate it.
+
+One possibility is a pre-push hook script like this one:
+
+.. code:: sh
+
+ #!/bin/sh
+ #### A pre-push hook for the fish-shell project
+ # This will run the tests when a push to master is detected, and will stop that if the tests fail
+ # Save this as .git/hooks/pre-push and make it executable
+
+ protected_branch='master'
+
+ # Git gives us lines like "refs/heads/frombranch SOMESHA1 refs/heads/tobranch SOMESHA1"
+ # We're only interested in the branches
+ while read from _ to _; do
+ if [ "x$to" = "xrefs/heads/$protected_branch" ]; then
+ isprotected=1
+ fi
+ done
+ if [ "x$isprotected" = x1 ]; then
+ echo "Running tests before push to master"
+ make test
+ RESULT=$?
+ if [ $RESULT -ne 0 ]; then
+ echo "Tests failed for a push to master, we can't let you do that" >&2
+ exit 1
+ fi
+ fi
+ exit 0
+
+This will check if the push is to the master branch and, if it is, only
+allow the push if running ``make test`` succeeds. In some circumstances
+it may be advisable to circumvent this check with
+``git push --no-verify``, but usually that isn’t necessary.
+
+To install the hook, place the code in a new file
+``.git/hooks/pre-push`` and make it executable.
+
+Coverity Scan
+~~~~~~~~~~~~~
+
+We use Coverity’s static analysis tool which offers free access to open
+source projects. While access to the tool itself is restricted,
+fish-shell organization members should know that they can login
+`here <https://scan.coverity.com/projects/fish-shell-fish-shell?tab=overview>`__
+with their GitHub account. Currently, tests are triggered upon merging
+the ``master`` branch into ``coverity_scan_master``. Even if you are not
+a fish developer, you can keep an eye on our statistics there.
+
+Installing the Required Tools
+-----------------------------
+
+Installing the Linting Tools
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To install the lint checkers on Mac OS X using Homebrew:
+
+::
+
+ brew tap oclint/formulae
+ brew install oclint
+ brew install cppcheck
+
+To install the lint checkers on Debian-based Linux distributions:
+
+::
+
+ sudo apt-get install clang
+ sudo apt-get install oclint
+ sudo apt-get install cppcheck
+
+Installing the Formatting Tools
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Mac OS X:
+
+::
+
+ brew install clang-format
+
+Debian-based:
+
+::
+
+ sudo apt-get install clang-format
+
+Message Translations
+--------------------
+
+Fish uses the GNU gettext library to translate messages from English to
+other languages.
+
+All non-debug messages output for user consumption should be marked for
+translation. In C++, this requires the use of the ``_`` (underscore)
+macro:
+
+::
+
+ streams.out.append_format(_(L"%ls: There are no jobs\n"), argv[0]);
+
+All messages in fish script must be enclosed in single or double quote
+characters. They must also be translated via a subcommand. This means
+that the following are **not** valid:
+
+::
+
+ echo (_ hello)
+ _ "goodbye"
+
+Above should be written like this instead:
+
+::
+
+ echo (_ "hello")
+ echo (_ "goodbye")
+
+Note that you can use either single or double quotes to enclose the
+message to be translated. You can also optionally include spaces after
+the opening parentheses and once again before the closing parentheses.
+
+Creating and updating translations requires the Gettext tools, including
+``xgettext``, ``msgfmt`` and ``msgmerge``. Translation sources are
+stored in the ``po`` directory, named ``LANG.po``, where ``LANG`` is the
+two letter ISO 639-1 language code of the target language (eg ``de`` for
+German).
+
+To create a new translation, for example for German:
+
+* generate a ``messages.pot`` file by running ``build_tools/fish_xgettext.fish`` from
+ the source tree
+* copy ``messages.pot`` to ``po/LANG.po``
+
+To update a translation:
+
+* generate a ``messages.pot`` file by running
+ ``build_tools/fish_xgettext.fish`` from the source tree
+
+* update the existing translation by running
+ ``msgmerge --update --no-fuzzy-matching po/LANG.po messages.pot``
+
+Many tools are available for editing translation files, including
+command-line and graphical user interface programs.
+
+Be cautious about blindly updating an existing translation file. Trivial
+changes to an existing message (eg changing the punctuation) will cause
+existing translations to be removed, since the tools do literal string
+matching. Therefore, in general, you need to carefully review any
+recommended deletions.
+
+Read the `translations
+wiki <https://github.com/fish-shell/fish-shell/wiki/Translations>`__ for
+more information.
+
+Versioning
+----------
+
+The fish version is constructed by the *build_tools/git_version_gen.sh*
+script. For developers the version is the branch name plus the output of
+``git describe --always --dirty``. Normally the main part of the version
+will be the closest annotated tag. Which itself is usually the most
+recent release number (e.g., ``2.6.0``).
+
+Include What You Use
+--------------------
+
+You should not depend on symbols being visible to a ``*.cpp`` module
+from ``#include`` statements inside another header file. In other words
+if your module does ``#include "common.h"`` and that header does
+``#include "signal.h"`` your module should not assume the sub-include is
+present. It should instead directly ``#include "signal.h"`` if it needs
+any symbol from that header. That makes the actual dependencies much
+clearer. It also makes it easy to modify the headers included by a
+specific header file without having to worry that will break any module
+(or header) that includes a particular header.
+
+To help enforce this rule the ``make lint`` (and ``make lint-all``)
+command will run the
+`include-what-you-use <https://include-what-you-use.org/>`__ tool. You
+can find the IWYU project on
+`github <https://github.com/include-what-you-use/include-what-you-use>`__.
+
+To install the tool on OS X you’ll need to add a
+`formula <https://github.com/jasonmp85/homebrew-iwyu>`__ then install
+it:
+
+::
+
+ brew tap jasonmp85/iwyu
+ brew install iwyu
+
+On Ubuntu you can install it via ``apt-get``:
+
+::
+
+ sudo apt-get install iwyu