PageRenderTime 66ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/doc/development/shell_scripting_guide/index.md

https://gitlab.com/wolfgang42/gitlab-ce
Markdown | 118 lines | 85 code | 33 blank | 0 comment | 0 complexity | ca68736ce0f036259191b4e3d9461fa7 MD5 | raw file
  1. # Shell scripting standards and style guidelines
  2. ## Overview
  3. GitLab consists of many various services and sub-projects. The majority of
  4. their backend code is written in [Ruby](https://www.ruby-lang.org) and
  5. [Go](https://golang.org). However, some of them use shell scripts for
  6. automation of routine system administration tasks like deployment,
  7. installation, etc. It's being done either for historical reasons or as an effort
  8. to minimize the dependencies, for instance, for Docker images.
  9. This page aims to define and organize our shell scripting guidelines,
  10. based on our various experiences. All shell scripts across GitLab project
  11. should be eventually harmonized with this guide. If there are any per-project
  12. deviations from this guide, they should be described in the
  13. `README.md` or `PROCESS.md` file for such a project.
  14. ### Avoid using shell scripts
  15. CAUTION: **Caution:**
  16. This is a must-read section.
  17. Having said all of the above, we recommend staying away from shell scripts
  18. as much as possible. A language like Ruby or Python (if required for
  19. consistency with codebases that we leverage) is almost always a better choice.
  20. The high-level interpreted languages have more readable syntax, offer much more
  21. mature capabilities for unit-testing, linting, and error reporting.
  22. Use shell scripts only if there's a strong restriction on project's
  23. dependencies size or any other requirements that are more important
  24. in a particular case.
  25. ## Scope of this guide
  26. According to the [GitLab installation requirements](../../install/requirements.md),
  27. this guide covers only those shells that are used by
  28. [supported Linux distributions](../../install/requirements.md#supported-linux-distributions),
  29. that is:
  30. - [POSIX Shell](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html)
  31. - [Bash](https://www.gnu.org/software/bash/)
  32. ## Shell language choice
  33. - When you need to reduce the dependencies list, use what's provided by the environment. For example, for Docker images it's `sh` from `alpine` which is the base image for most of our tool images.
  34. - Everywhere else, use `bash` if possible. It's more powerful than `sh` but still a widespread shell.
  35. ## Code style and format
  36. This section describes the tools that should be made a mandatory part of
  37. a project's CI pipeline if it contains shell scripts. These tools
  38. automate shell code formatting, checking for errors or vulnerabilities, etc.
  39. ### Linting
  40. We're using the [ShellCheck](https://www.shellcheck.net/) utility in its default configuration to lint our
  41. shell scripts.
  42. All projects with shell scripts should use this GitLab CI/CD job:
  43. ```yaml
  44. shell check:
  45. image: koalaman/shellcheck-alpine
  46. stage: test
  47. before_script:
  48. - shellcheck --version
  49. script:
  50. - shellcheck scripts/**/*.sh # path to your shell scripts
  51. ```
  52. TIP: **Tip:**
  53. By default, ShellCheck will use the [shell detection](https://github.com/koalaman/shellcheck/wiki/SC2148#rationale)
  54. to determine the shell dialect in use. If the shell file is out of your control and ShellCheck cannot
  55. detect the dialect, use `-s` flag to specify it: `-s sh` or `-s bash`.
  56. ### Formatting
  57. It's recommended to use the [shfmt](https://github.com/mvdan/sh#shfmt) tool to maintain consistent formatting.
  58. We format shell scripts according to the [Google Shell Style Guide](https://google.github.io/styleguide/shell.xml),
  59. so the following `shfmt` invocation should be applied to the project's script files:
  60. ```bash
  61. shfmt -i 2 -ci scripts/**/*.sh
  62. ```
  63. TIP: **Tip:**
  64. By default, shfmt will use the [shell detection](https://github.com/mvdan/sh#shfmt) similar to one of ShellCheck
  65. and ignore files starting with a period. To override this, use `-ln` flag to specify the shell dialect:
  66. `-ln posix` or `-ln bash`.
  67. NOTE: **Note:**
  68. Currently, the `shfmt` tool [is not shipped](https://github.com/mvdan/sh/issues/68) as a Docker image containing
  69. a Linux shell. This makes it impossible to use the [official Docker image](https://hub.docker.com/r/mvdan/shfmt)
  70. in GitLab Runner. This [may change](https://github.com/mvdan/sh/issues/68#issuecomment-507721371) in future.
  71. ## Testing
  72. NOTE: **Note:**
  73. This is a work in progress.
  74. It is an [ongoing effort](https://gitlab.com/gitlab-org/gitlab-foss/issues/64016) to evaluate different tools for the
  75. automated testing of shell scripts (like [BATS](https://github.com/sstephenson/bats)).
  76. ## Code Review
  77. The code review should be performed according to:
  78. - [ShellCheck Checks list](https://github.com/koalaman/shellcheck/wiki/Checks)
  79. - [Google Shell Style Guide](https://google.github.io/styleguide/shell.xml)
  80. - [Shfmt formatting caveats](https://github.com/mvdan/sh#caveats)
  81. However, the recommended course of action is to use the aforementioned
  82. tools and address reported offenses. This should eliminate the need
  83. for code review.
  84. ---
  85. [Return to Development documentation](../README.md).