1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
# Contributing Guidelines
## Welcome!
Thank you for considering contributing to this project's
development and/or documentation. Just a reminder: if you're new to this project
or to OSS and want to find issues to work on, please check the following labels
on issues:
- [help wanted][helpwantedlabel]
- [docs][docslabel]
- [good first issue][goodfirstissuelabel]
[docslabel]: https://github.com/bats-core/bats-core/labels/docs
[helpwantedlabel]: https://github.com/bats-core/bats-core/labels/help%20wanted
[goodfirstissuelabel]: https://github.com/bats-core/bats-core/labels/good%20first%20issue
To see all labels and their meanings, [check this wiki page][labelswiki].
[labelswiki]: https://github.com/bats-core/bats-core/wiki/GitHub-Issue-Labels
## Table of contents
* [Contributing Guidelines](#contributing-guidelines)
* [Welcome!](#welcome)
* [Table of contents](#table-of-contents)
* [Quick links](#quick-links)
* [Code of conduct](#code-of-conduct)
* [Asking questions](#asking-questions)
* [Updating documentation](#updating-documentation)
* [Testing](#testing)
* [Coding conventions](#coding-conventions)
* [Function declarations](#function-declarations)
* [Variable and parameter declarations](#variable-and-parameter-declarations)
* [Command substitution](#command-substitution)
* [Process substitution](#process-substitution)
* [Conditionals and loops](#conditionals-and-loops)
* [Generating output](#generating-output)
* [Signal names](#signal-names)
* [Gotchas](#gotchas)
* [Open Source License](#open-source-license)
* [Credits](#credits)
## Quick links
- [Gitter channel →][gitterurl]: Feel free to come chat with us on Gitter
- [README →][README]
- [Code of conduct →][CODE_OF_CONDUCT]
- [License information →][LICENSE]
- [Original repository →][repohome]
- [Issues →][repoissues]
- [Pull requests →][repoprs]
- [Milestones →][repomilestones]
- [Projects →][repoprojects]
[README]: https://github.com/bats-core/bats-core/blob/master/README.md
[CODE_OF_CONDUCT]: https://github.com/bats-core/bats-core/blob/master/docs/CODE_OF_CONDUCT.md
[LICENSE]: https://github.com/bats-core/bats-core/blob/master/LICENSE.md
## Code of conduct
Harassment or rudeness of any kind will not be tolerated, period. For
specifics, see the [CODE_OF_CONDUCT][] file.
## Asking questions
Please check the [documentation][documentation] or existing [discussions][] and [issues][repoissues] first.
If you cannot find an answer to your question, please feel free to hop on our
[Gitter][gitterurl]. [](https://gitter.im/bats-core/bats-core)
## Updating documentation
We love documentation and people who love documentation!
If you love writing clear, accessible docs, please don't be shy about pull
requests. Remember: docs are just as important as code.
Also: _no typo is too small to fix!_ Really. Of course, batches of fixes are
preferred, but even one nit is one nit too many.
## Testing
- Continuous integration status: [](https://github.com/bats-core/bats-core/actions?query=workflow%3ATests)
To run all tests:
```sh
bin/bats test
```
To run a single test file:
```sh
bin/bats test/file.bats
```
When running from a terminal, Bats uses the *pretty* formatter by default.
However, to debug Bats you might need to see the raw test output.
The **cat** formatter is intended as an internal debugging tool because
it does not process test outputs.
To use it, run Bats with the `--formatter cat` option.
## Coding conventions
Use [`shfmt`](https://github.com/mvdan/sh#shfmt) and [ShellCheck](https://www.shellcheck.net/). The CI will enforce this.
Use `snake_case` for all identifiers.
### Function declarations
- Declare functions without the `function` keyword.
- Strive to always use `return`, never `exit`, unless an error condition is
severe enough to warrant it.
- Calling `exit` makes it difficult for the caller to recover from an error,
or to compose new commands from existing ones.
### Variable and parameter declarations
- Declare all variables inside functions using `local`.
- Declare temporary file-level variables using `declare`. Use `unset` to remove
them when finished.
- Don't use `local -r`, as a readonly local variable in one scope can cause a
conflict when it calls a function that declares a `local` variable of the same
name.
- Don't use type flags with `declare` or `local`. Assignments to integer
variables in particular may behave differently, and it has no effect on array
variables.
- For most functions, the first lines should use `local` declarations to
assign the original positional parameters to more meaningful names, e.g.:
```bash
format_summary() {
local cmd_name="$1"
local summary="$2"
local longest_name_len="$3"
```
For very short functions, this _may not_ be necessary, e.g.:
```bash
has_spaces() {
[[ "$1" != "${1//[[:space:]]/}" ]]
}
```
### Command substitution
- If possible, don't. While this capability is one of Bash's core strengths,
every new process created by Bats makes the framework slower, and speed is
critical to encouraging the practice of automated testing. (This is especially
true on Windows, [where process creation is one or two orders of magnitude
slower][win-slow]. See [bats-core/bats-core#8][pr-8] for an illustration of
the difference avoiding subshells makes.) Bash is quite powerful; see if you
can do what you need in pure Bash first.
- If you need to capture the output from a function, store the output using
`printf -v` instead if possible. `-v` specifies the name of the variable into
which to write the result; the caller can supply this name as a parameter.
- If you must use command substitution, use `$()` instead of backticks, as it's
more robust, more searchable, and can be nested.
[win-slow]: https://rufflewind.com/2014-08-23/windows-bash-slow
[pr-8]: https://github.com/bats-core/bats-core/pull/8
### Process substitution
- If possible, don't use it. See the advice on avoiding subprocesses and using
`printf -v` in the **Command substitution** section above.
- Use wherever necessary and possible, such as when piping input into a `while`
loop (which avoids having the loop body execute in a subshell) or running a
command taking multiple filename arguments based on output from a function or
pipeline (e.g. `diff`).
- *Warning*: It is impossible to directly determine the exit status of a process
substitution; emitting an exit status as the last line of output is a possible
workaround.
### Conditionals and loops
- Always use `[[` and `]]` for evaluating variables. Per the guideline under
**Formatting**, quote variables and strings within the brackets, but not
regular expressions (or variables containing regular expressions) appearing
on the right side of the `=~` operator.
### Generating output
- Use `printf` instead of `echo`. Both are Bash builtins, and there's no
perceptible performance difference when running Bats under the `time` builtin.
However, `printf` provides a more consistent experience in general, as `echo`
has limitations to the arguments it accepts, and even the same version of Bash
may produce different results for `echo` based on how the binary was compiled.
See [Stack Overflow: Why is printf better than echo?][printf-vs-echo] for
excruciating details.
[printf-vs-echo]: https://unix.stackexchange.com/a/65819
### Signal names
Always use upper case signal names (e.g. `trap - INT EXIT`) to avoid locale
dependent errors. In some locales (for example Turkish, see
[Turkish dotless i](https://en.wikipedia.org/wiki/Dotted_and_dotless_I)) lower
case signal names cause Bash to error. An example of the problem:
```bash
$ echo "tr_TR.UTF-8 UTF-8" >> /etc/locale.gen && locale-gen tr_TR.UTF-8 # Ubuntu derivatives
$ LC_CTYPE=tr_TR.UTF-8 LC_MESSAGES=C bash -c 'trap - int && echo success'
bash: line 0: trap: int: invalid signal specification
$ LC_CTYPE=tr_TR.UTF-8 LC_MESSAGES=C bash -c 'trap - INT && echo success'
success
```
## Credits
The [official bash logo](https://github.com/odb/official-bash-logo) is copyrighted
by the [Free Software Foundation](https://www.fsf.org/), 2016 under the [Free Art License](http://artlibre.org/licence/lal/en/)
This guide borrows **heavily** from [@mbland's go-script-bash][gsb] (with some
sections directly quoted), which in turn was
drafted with tips from [Wrangling Web Contributions: How to Build
a CONTRIBUTING.md][moz] and with some inspiration from [the Atom project's
CONTRIBUTING.md file][atom].
[gsb]: https://github.com/mbland/go-script-bash/blob/master/CONTRIBUTING.md
[moz]: https://mozillascience.github.io/working-open-workshop/contributing/
[atom]: https://github.com/atom/atom/blob/master/CONTRIBUTING.md
[discussions]: https://github.com/bats-core/bats-core/discussions
[documentation]: https://bats-core.readthedocs.io/
[repoprojects]: https://github.com/bats-core/bats-core/projects
[repomilestones]: https://github.com/bats-core/bats-core/milestones
[repoprs]: https://github.com/bats-core/bats-core/pulls
[repoissues]: https://github.com/bats-core/bats-core/issues
[repohome]: https://github.com/bats-core/bats-core
[osmit]: https://opensource.org/licenses/MIT
[gitterurl]: https://gitter.im/bats-core/bats-core
|