summaryrefslogtreecommitdiffstats
path: root/CONTRIBUTING.md
diff options
context:
space:
mode:
Diffstat (limited to 'CONTRIBUTING.md')
-rw-r--r--CONTRIBUTING.md191
1 files changed, 191 insertions, 0 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..9c8292c
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,191 @@
+# Contributing to bash-completion
+
+Contributions to the bash completion project are more than
+welcome. Fixes, clean-ups and improvements of existing code are much
+appreciated, as are completion functions for new commands.
+
+However, before submitting a completion to us, first consider submitting it to
+the project that ships the commands your completion is for. Having the
+completion shipped along with the command opens up some liberties we don't have
+if the completion is included with bash-completion. For example, we generally
+do not want to hardcode lists of available command options and their
+completions, because they quite probably vary between versions of the completed
+command, and therefore resort to scraping --help output and the like. While we
+do fairly well there, depending on the command, this can be fragile or
+expensive, or just not possible. If the completion is shipped alongside the
+command, they can be kept in sync and use more hardcoding etc. They are also
+more likely to be maintained and/or watched by people intimately familiar with
+the completed commands. See instructions in README.md how to install completion
+files from other projects so they are automatically enabled and dynamically
+loaded by bash-completion.
+
+On the other hand, we do have a pretty nice test suite and a bunch of helper
+functions that you may find useful. And a whole slew of completions in one
+package. Our functions can be used from "external" completions as well, just
+make sure you test for their existence and/or fail gracefully if you intend
+your completion to be usable without having bash-completion installed.
+
+It's nowhere near clear cut always what is the best place for the completion,
+upstream project or us. Even if it would seem to be upstream, not all upstreams
+are interested in shipping completions, or their install systems might not
+easily support installing completion files properly. But give it some thought,
+and ask if unsure.
+
+If you wish to contribute code to us, volunteering for long term maintainership
+of your code within bash-completion is welcome. When exactly you will be asked
+to do that depends on the case; don't be disappointed if it does or doesn't
+happen instantly.
+
+Also, please bare the following coding guidelines in mind:
+
+- Do not use Perl, Ruby, Python etc. to do text processing unless the
+ command for which you are writing the completion code implies the
+ presence of one of those languages.
+
+ For example, if you were writing completion code for perldoc(1), the
+ use of Perl to achieve your goal would be acceptable. irb(1)
+ completion would similarly make the use of Ruby acceptable.
+
+ Even so, please consider alternatives to these large and slow to
+ start interpreters. Use lightweight programs such as grep(1), awk(1)
+ and sed(1).
+
+- Use the full power of bash >= 4.2. We no longer support earlier bash
+ versions, so you may as well use all the features of that version of
+ bash to optimise your code. However, be careful when using features
+ added since bash 4.2, since not everyone will be able to use them.
+
+ For example, extended globs often enable you to avoid the use of
+ external programs, which are expensive to fork and execute, so do
+ make full use of those:
+
+ `?(pattern-list)` - match zero or one occurrences of patterns
+ `*(pattern-list)` - match zero or more occurrences of patterns
+ `+(pattern-list)` - match one or more occurrences of patterns
+ `@(pattern-list)` - match exactly one of the given patterns
+ `!(pattern-list)` - match anything except one of the given patterns
+
+- Following on from the last point, be sparing with the use of
+ external processes whenever you can. Completion functions need to be
+ fast, so sacrificing some code legibility for speed is acceptable.
+
+ For example, judicious use of sed(1) can save you from having to
+ call grep(1) and pipe the output to cut(1), which saves a fork(2)
+ and exec(3).
+
+ Sometimes you don't even need sed(1) or other external programs at
+ all, though. Use of constructs such as `${parameter#word}`,
+ `${parameter%word}` and `${parameter/pattern/string}` can provide
+ you a lot of power without having to leave the shell.
+
+ For example, if `$foo` contains the path to an executable,
+ `${foo##*/}` will give you the basename of the program, without
+ having to call basename(1). Similarly, `${foo%/*}` will give you the
+ dirname, without having to call dirname(1).
+
+ As another example,
+
+ ```shell
+ bar=$(echo $foo | command sed -e 's/bar/baz/g')
+ ```
+
+ can be replaced by:
+
+ ```shell
+ bar=${foo//bar/baz}
+ ```
+
+ These forms of parameter substitutions can also be used on arrays,
+ which makes them very powerful (if a little slow).
+
+- We want our completions to work in `posix` and `nounset` modes.
+
+ Unfortunately due to a bash < 5.1 bug, toggling POSIX mode interferes
+ with keybindings and should not be done. This rules out use of
+ process substitution which causes syntax errors in POSIX mode.
+
+ Instead of toggling `nounset` mode, make sure to test whether
+ variables are set (e.g. with `[[ -v varname ]]`) or use default
+ expansion (e.g. `${varname-}`).
+
+- Prefer `compgen -W '...' -- $cur` over embedding `$cur` in external
+ command arguments (often e.g. sed, grep etc) unless there's a good
+ reason to embed it. Embedding user input in command lines can result
+ in syntax errors and other undesired behavior, or messy quoting
+ requirements when the input contains unusual characters. Good
+ reasons for embedding include functionality (if the thing does not
+ sanely work otherwise) or performance (if it makes a big difference
+ in speed), but all embedding cases should be documented with
+ rationale in comments in the code.
+
+- When completing available options, offer only the most descriptive
+ ones as completion results if there are multiple options that do the
+ same thing. Usually this means that long options should be preferred
+ over the corresponding short ones. This way the user is more likely
+ to find what she's looking for and there's not too much noise to
+ choose from, and there are less situations where user choice would
+ be needed in the first place. Note that this concerns only display
+ of available completions; argument processing/completion for options
+ that take an argument should be made to work with all known variants
+ for the functionality at hand. For example if `-s`, `-S`, and
+ `--something` do the same thing and require an argument, offer only
+ `--something` as a completion when completing option names starting
+ with a dash, but do implement required argument processing for all
+ `-s`, `-S`, and `--something`. Note that GNU versions of various
+ standard commands tend to have long options while other userland
+ implementations of the same commands may not have them, and it would
+ be good to have the completions work for as many userlands as
+ possible so things aren't always that simple.
+
+- Do not write to the file-system under any circumstances. This can
+ create race conditions, is inefficient, violates the principle of
+ least surprise and lacks robustness.
+
+- Use printf(1) instead of echo(1) for portability reasons, and be
+ sure to invoke commands that are often found aliased (such as `ls`
+ or `grep` etc) using the `command` (or `builtin`) command as
+ appropriate.
+
+- Make small, incremental commits that do one thing. Don't cram
+ unrelated changes into a single commit.
+
+- If your code was written for a particular platform, try to make it
+ portable to other platforms, so that everyone may enjoy it. If your
+ code works only with the version of a binary on a particular
+ platform, ensure that it will not be loaded on other platforms that
+ have a command with the same name.
+
+ In particular, do not use GNU extensions to commands like sed and
+ awk if you can write your code another way. If you really, REALLY must
+ use them, do so if there's no other sane way to do what you're doing.
+ The "Shell and Utilities" volume of the POSIX specification is a good
+ starting reference for portable use of various utilities, see
+ <https://pubs.opengroup.org/onlinepubs/9699919799/>.
+
+- Use an editor that supports EditorConfig, see <https://editorconfig.org/>,
+ and format source code according to our settings.
+
+- Read the existing source code for examples of how to solve
+ particular problems. Read the bash man page for details of all the
+ programming tools available to you within the shell.
+
+- Please test your code thoroughly before sending it to us. We don't
+ have access to all the commands for which we are sent completion
+ functions, so we are unable to test them all personally. If your
+ code is accepted into the distribution, a lot of people will try it
+ out, so try to do a thorough job of eradicating all the bugs before
+ you send it to us. If at all practical, **add test cases** to our
+ test suite (in the test/ dir) that verify that the code does what it
+ is intended to do, fixes issues it intends to fix, etc.
+
+- In addition to running the test suite, there are a few scripts in the test/
+ dir that catch some common issues, see and use for example runLint.
+
+- File bugs, enhancement, and pull requests at GitHub,
+ <https://github.com/scop/bash-completion>.
+ Sending them to the developers might work too, but is really strongly
+ discouraged as bits are more likely to fall through the cracks that
+ way compared to the tracker. Just use GitHub. If that's not an
+ option for some reason and you want to use email to send patches,
+ send them as attachments formatted by `git format-patch` or directly
+ with `git send-email`.