- Editor/IDE styling standardization
- Pre-push static analysis with Lefthook
- Ruby, Rails, RSpec
- Database migrations
- Shell commands (Ruby)
- Shell scripting
We use EditorConfig to automatically apply certain styling
standards before files are saved locally. Most editors/IDEs will honor the
settings automatically by default. If your editor/IDE does not automatically support
we suggest investigating to see if a plugin exists. For instance here is the
plugin for vim.
Lefthook is a Git hooks manager that allows
custom logic to be executed prior to Git committing or pushing. GitLab comes with
Lefthook configuration (
lefthook.yml), but it must be installed.
We have a
lefthook.yml checked in but it is ignored until Lefthook is installed.
We were using Overcommit prior to Lefthook, so you may want to uninstall it first with
Install Lefthook managed Git hooks:
bundle exec lefthook install
Test Lefthook is working by running the Lefthook
bundle exec lefthook run prepare-commit-msg
This should return a fully qualified path command with no other output.
The current Lefthook configuration can be found in
Before you push your changes, Lefthook automatically runs the following checks:
- Danger: Runs a subset of checks that
danger-reviewruns on your merge requests.
- ES lint: Run
yarn run lint:eslintchecks (with the
.eslintrc.ymlconfiguration) on the modified
- HAML lint: Run
bundle exec haml-lintchecks (with the
.haml-lint.ymlconfiguration) on the modified
- Markdown lint: Run
yarn markdownlintchecks on the modified
- SCSS lint: Run
yarn lint:stylelintchecks (with the
.stylelintrcconfiguration) on the modified
- RuboCop: Run
bundle exec rubocopchecks (with the
.rubocop.ymlconfiguration) on the modified
- Vale: Run
valechecks (with the
.vale.iniconfiguration) on the modified
- Documentation metadata: Run checks for the absence of documentation metadata.
In addition to the default configuration, you can define a local configuration.
To disable Lefthook temporarily, you can set the
LEFTHOOK environment variable to
0. For instance:
LEFTHOOK=0 git push ...
To run the
pre-push Git hook, run:
bundle exec lefthook run pre-push
For more information, check out Lefthook documentation.
To skip some checks based on tags when pushing, you can set the
LEFTHOOK_EXCLUDE environment variable. For instance:
LEFTHOOK_EXCLUDE=frontend,documentation git push ...
As an alternative, you can create
lefthook-local.yml with this structure:
pre-push: exclude_tags: - frontend - documentation
For more information, check out Lefthook documentation.
To skip or enable a check based on its name when pushing, you can add
skip: false to the
lefthook-local.yml section for that hook. For instance,
you might want to enable the gettext check to detect issues with
pre-push: commands: gettext: skip: false
For more information, check out Lefthook documentation Skipping commands section.
Our codebase style is defined and enforced by RuboCop.
You can check for any offenses locally with
bundle exec rubocop --parallel.
On the CI, this is automatically checked by the
For RuboCop rules that we have not taken a decision on yet, we follow the Ruby Style Guide, Rails Style Guide, and RSpec Style Guide as general guidelines to write idiomatic Ruby/Rails/RSpec, but reviewers/maintainers should be tolerant and not too pedantic about style.
Similarly, some RuboCop rules are currently disabled, and for those, reviewers/maintainers must not ask authors to use one style or the other, as both are accepted. This isn’t an ideal situation since this leaves space for bike-shedding, and ideally we should enable all RuboCop rules to avoid style-related discussions/nitpicking/back-and-forth in reviews. There are some styles that commonly come up in reviews that are not enforced, the GitLab Ruby style guide includes a non-exhaustive list of these topics.
Typically it is better for the linting rules to be enforced programmatically as it reduces the aforementioned bike-shedding.
To that end, we encourage creation of new RuboCop rules in the codebase.
We currently maintain Cops across several Ruby code bases, and not all of them are specific to the GitLab application. When creating a new cop that could be applied to multiple applications, we encourage you to add it to our GitLab Styles gem. If the Cop targets rules that only apply to the main GitLab application, it should be added to GitLab instead.
When the number of RuboCop exceptions exceed the default
exclude-limit of 15,
we may want to resolve exceptions over multiple commits. To minimize confusion,
we should track our progress through the exception list.
When auto-generating the
.rubocop_todo.yml exception list for a particular Cop,
and more than 15 files are affected, we should add the exception list to
a different file,
This ensures that our list isn’t mistakenly removed by another auto generation of
.rubocop_todo.yml. This also allows us greater visibility into the exceptions
which are currently being resolved.
One way to generate the initial list is to run the
todo auto generation,
exclude limit set to a high number.
bundle exec rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit=100000
You can then move the list from the freshly generated
.rubocop_todo.yml for the Cop being actively
resolved and place it in the
.rubocop_manual_todo.yml. In this scenario, do not commit auto generated
changes to the
.rubocop_todo.yml as an
exclude limit that is higher than 15 will make the
.rubocop_todo.yml hard to parse.
To reveal existing RuboCop exceptions in the code that have been excluded via
.rubocop_manual_todo.yml, set the environment variable
This allows you to reveal existing RuboCop exceptions during your daily work cycle and fix them along the way.
Excludes should be defined in
See the dedicated Database Migrations Style Guide.
See the dedicated JS Style Guide.
See the dedicated SCSS Style Guide.
See the dedicated Go standards and style guidelines.
See the dedicated Guidelines for shell commands in the GitLab codebase.
See the dedicated Shell scripting standards and style guidelines.
We’re following Ciro Santilli’s Markdown Style Guide.
See the dedicated Documentation Style Guide.
See the dedicated Python Development Guidelines.
Code should be written in US English.