Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 73 additions & 99 deletions content/workstation/cookstyle.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ cookbooks by detecting and automatically correcting style, syntax, and
logic mistakes in your code.

Cookstyle is powered by the RuboCop linting engine. RuboCop ships with
over three-hundred rules, or cops, designed to detect common Ruby coding
over 300 rules, or cops, designed to detect common Ruby coding
mistakes and enforce a common coding style. We've customized Cookstyle
with a subset of those cops tailored for cookbook development.
We also ship Chef-specific cops that catch common
cookbook coding mistakes, cleanup portions of code that are no longer
cookbook coding mistakes, clean up portions of code that are no longer
necessary, and detect deprecations that prevent cookbooks from running
on the latest releases of Chef Infra Client.

Expand All @@ -40,56 +40,56 @@ Cookstyle increases code quality by:
- Detecting deprecated code that creates errors after upgrading to a newer Chef Infra Client release.
- Detecting common Chef Infra mistakes that cause code to fail or behave incorrectly.

## Cookstyle vs Rubocop
## Cookstyle vs RuboCop

Cookstyle is more stable than Rubocop and is customized for Chef
Cookbook code. This means that linting Cookbooks with Cookstyle will be
Cookstyle is more stable than RuboCop and is customized for Chef
cookbook code. This means that linting cookbooks with Cookstyle will be
more consistent and less likely to produce CI test failures.

### Tailored cops

Cookbook development differs from traditional Ruby software development,
so we maintain a tailored set of built-in cops from Rubocop. Cops that
aren't useful for cookbook development are disabled and occasionally we
so we maintain a tailored set of built-in cops from RuboCop. Cops that
aren't useful for cookbook development are disabled, and occasionally we
change the configuration of a rule to enforce a different behavior.
We've also extended the base RuboCop package with a set of our own Chef
Infra-specific cops. These cops are only found in Cookstyle and will
help you to write more reliable and future-proof cookbooks.
help you write more reliable and future-proof cookbooks.

### New cops

New cops are continuously added to Rubocop. New cops can make an existing
New cops are continuously added to RuboCop. New cops can make an existing
codebase fail CI tests and force authors to constantly update their
code.

With Cookstyle, we update the RuboCop engine for bug and performance
fixes, but we only change the set of cops that will fail tests once a
year during Chef Infra's major release in April. All new cops are
introduced at RuboCop's "refactor" alert level, meaning they will alert
introduced at RuboCop's `refactor` alert level, meaning they will alert
to the screen as you run Cookstyle, but they won't fail a build. This
stability means you are free to upgrade releases of Cookstyle without
being forced to update your infrastructure code.

## Run Cookstyle

Cookstyle is run from the command line, typically against a single
cookbook and the Ruby files contained within it:
Run Cookstyle from the command line, typically against a single
cookbook and the Ruby files within it:

``` bash
```bash
cookstyle /path/to/cookbook
```

Cookstyle may also be run from the root of an individual cookbook
You can also run Cookstyle from the root of an individual cookbook
directory:

``` bash
```bash
cookstyle .
```

Cookstyle returns a list, via standard output, that shows the results of
Cookstyle returns a list, through standard output, that shows the results of
the evaluation:

``` bash
```bash
Inspecting 8 files
CWCWCCCC

Expand Down Expand Up @@ -118,15 +118,15 @@ Cookstyle output:

A Cookstyle evaluation has the following syntax:

``` none
```plain
FILENAME:LINE_NUMBER:CHARACTER_NUMBER: TYPE_OF_ERROR: MESSAGE
SOURCE CODE
^^^^^^^^^^^
```

For example:

``` none
```plain
cookbooks/apache/attributes/default.rb:1:9: C: Prefer single-quoted strings when you don't
need string interpolation or special symbols.
default["apache"]["indexfile"] = "index1.html"
Expand All @@ -135,144 +135,118 @@ default["apache"]["indexfile"] = "index1.html"

#### Symbols

The following symbols appear in the standard output and are used to
indicate the result of an evaluation:

<table>
<colgroup>
<col style="width: 12%" />
<col style="width: 87%" />
</colgroup>
<thead>
<tr class="header">
<th>Symbol</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>.</code></td>
<td>The file does not have any issues.</td>
</tr>
<tr class="even">
<td><code>C</code></td>
<td>The file has an issue with convention.</td>
</tr>
<tr class="odd">
<td><code>E</code></td>
<td>The file contains an error.</td>
</tr>
<tr class="even">
<td><code>F</code></td>
<td>The file contains a fatal error.</td>
</tr>
<tr class="odd">
<td><code>W</code></td>
<td>The file contains a warning.</td>
</tr>
<tr class="even">
<td><code>R</code></td>
<td>The file contains code that should be refactored.</td>
</tr>
</tbody>
</table>

## Autocorrecting Cookstyle Warnings

Many of the Cookstyle Cops include the ability to autocorrect
violations. To autocorrect code run the following from the cookbook
directory:
The following symbols appear in the standard output to indicate the result of an evaluation:

`.`
: The file doesn't have any issues.

`C`
: The file has an issue with convention.

`E`
: The file contains an error.

`F`
: The file contains a fatal error.

`W`
: The file contains a warning.

`R`
: The file contains code that should be refactored.

## Autocorrecting Cookstyle warnings

Many Cookstyle cops can autocorrect violations. To autocorrect code, run the following command from the cookbook directory:

``` bash
```bash
cookstyle -a .
```

Take particular care after running this command to ensure the
autocorrection logic resulted in appropriate cookbook code.
After running this command, verify that the autocorrection logic results in appropriate cookbook code.

## .rubocop.yml
## `.rubocop.yml`

Use a .rubocop.yml file in a cookbook to override the default settings
Use a `.rubocop.yml` file in a cookbook to override the default settings
in Cookstyle for enabled and disabled rules. Only enabled rules---either
in the `enabled.yml` file in Cookstyle itself or rules that are
specifically enabled in a cookbook's .rubocop.yml file---will be used
specifically enabled in a cookbook's `.rubocop.yml` file---will be used
during the evaluation. Any rule that becomes unhelpful should be
disabled in the .rubocop.yml file.
disabled in the `.rubocop.yml` file.

Each cookbook has its own .rubocop.yml file, which means that each
Each cookbook has its own `.rubocop.yml` file, which means that each
cookbook may have its own set of enabled, disabled, and custom rules.
That said, it's more common for all cookbooks to have the same set of
enabled, disabled, and custom rules. When RuboCop is run against a
cookbook, the full set of enabled and disabled rules (as defined the
cookbook, the full set of enabled and disabled rules (as defined in the
`enabled.yml` and `disabled.yml` files in Cookstyle itself) are loaded
first, and are then compared against the settings in the cookbook's
.rubocop.yml file.
`.rubocop.yml` file.

Custom rules should be specified in the .rubocop.yml file. The state of
rules---enabled or disabled---in a .rubocop.yml file take precedence
Custom rules should be specified in the `.rubocop.yml` file. The state of
rules---enabled or disabled---in a `.rubocop.yml` file take precedence
over the state of rules defined in the `enabled.yml` and `disabled.yml`
files.

### Syntax

A .rubocop.yml file has the following syntax:
A `.rubocop.yml` file has the following syntax:

``` yaml
```yaml
NAME_OF_RULE:
Description: 'a description of a rule'
Enabled : (true or false)
Enabled: (true or false)
KEY: VALUE
```

where

- `NAME_OF_RULE` is the name of a rule
- `Description` is the string that prints as part of the standard output that describes the rule if it is triggered during the evaluation
- `Description` is the string that prints as part of the standard output that describes the rule if it's triggered during the evaluation
- `Enabled` enables a rule (`true`) or disables a rule (`false`); for non-custom rules, this value will override the settings in the `enabled.yml` and `disabled.yml` files in Cookstyle
- `KEY: VALUE` adds additional details for a rule, if necessary. For example, `Max: 200` sets the line length to 200 characters for the `LineLength` rule

### .rubocop_todo.yml
### `.rubocop_todo.yml`

Use a .rubocop_todo.yml file to capture the current state of all
evaluations, and then write them to a file. This allows evaluations to
reviewed one at a time. Disable any evaluations that are unhelpful, and
then address the ones that are.
Use a `.rubocop_todo.yml` file to capture the current state of all
evaluations. This allows evaluations to be reviewed one at a time.
Disable any unhelpful evaluations, then address the remaining ones.

To generate the .rubocop_todo.yml file, run the following command:
To generate the `.rubocop_todo.yml` file, run the following command:

``` bash
```bash
cookstyle --auto-gen-config
```

{{< note >}}

Rename this file to .rubocop.yml to adopt this evaluation state as the
standard. Include this file in the .rubocop.yml file by adding
`inherit_from: .rubocop_todo.yml` to the top of the .rubocop.yml file.
Rename this file to `.rubocop.yml` to adopt this evaluation state as the
standard. Include this file in the `.rubocop.yml` file by adding
`inherit_from: .rubocop_todo.yml` to the top of the `.rubocop.yml` file.

{{< /note >}}

## Disable Cookstyle cops in code

Use Cookstyle-specific comments in your cookbook code to enable or disable cops instead of the standard RuboCop comments.
If you prefer them, you can also use RuboCop comments to enable and disable cops.
Use Cookstyle-specific comments in your cookbook code to enable or disable cops.
You can also use standard RuboCop comments to enable and disable cops.

Disable a cop using a RuboCop comment:

```ruby
'node.normal[:foo] # rubocop: disable ChefCorrectness/Bar'
node.normal[:foo] # rubocop: disable ChefCorrectness/Bar
```

Disable a cop using a Cookstyle comment:

```ruby
'node.normal[:foo] # cookstyle: disable ChefCorrectness/Bar'
node.normal[:foo] # cookstyle: disable ChefCorrectness/Bar
```

Disable a cop in a section of a file using a Cookstyle comment:

```ruby
# cookstyle: disable ChefCorrectness/Bar'
'node.normal[:foo]
# cookstyle: enable ChefCorrectness/Bar'
# cookstyle: disable ChefCorrectness/Bar
node.normal[:foo]
# cookstyle: enable ChefCorrectness/Bar
```
Loading