Friday, November 20, 2015

Static Analysis: Improving the quality and consistency of your cookbooks [feedly]

Static Analysis: Improving the quality and consistency of your cookbooks
https://www.chef.io/blog/2015/11/20/static-analysis-improving-the-quality-and-consistency-of-your-cookbooks/

-- via my feedly.com reader 

Every time we make changes to our cookbooks we are introducing risk. We can stop making changes to reduce the risk OR we can adopt new practices, like linting and testing, to help us manage that risk.

Linting tools provide automated ways to ensure that the code we write adheres to conventions that ensure code uniformity, portability, and uses best practices. This ensures everyone on the team writes similarly structured source code. It helps weave the expectations into the development of the code, and encourages collaboration over time. Ensuring the uniformity of source code helps set the expectations for fellow project contributors.

In this recorded webinar (presented on November 4, 2015) we focus on using Foodcritic and Rubocop (@ 21:45 in the recording) – two linting tools packaged in the Chef Development Kit (ChefDK) that you can immediately start using to reduce the risk in the cookbooks you develop. Q&A from the live webinar, including questions we didn't have time to answer live, can be viewed below.

  • Introduction to Foodcritic (@ 10:00 in the recording)
  • Introduction to Rubocop (@ 21:45 in the recording)
  • Demonstration of the Tools (@ 30:45 in the recording)

 

Is it easy to integrate these code analysis tools into Jenkins for pass/fail during the delivery pipeline?

It is definitely easy to integrate Foodcritic and Rubocop with Jenkins or any continuous integration (CI) tools within your organization. It is also strongly encouraged. In the past I would simply add a new build step, executed after the latest version of the code had been syncronized, to execute both Foodcritic and Rubocop from the command-line as I would run locally.

The benefit of running these tools on a central system is that it ensures that the code that everyone on the team writes adheres to the policy that all of you define. Without this central system it may not be executed by each individual team member or the results may vary on individual machines.

We currently use both Foodcritic and Rubocop lint cops as warnings and we plan to actually fail the build soon on some of them while excluding the legacy code we would probably not change. What do you think will be the best way to exclude them? A .rubocop.yml file and a .foodcritic inside the cookbook?

Yes. Each cookbook should have both of these files configured with the rules that you wanted enabled and the rules that you want disabled.

Should / Can you use Foodcritic / Rubocop to lint data bags?

Data Bags are stored as JSON on the local file system. When you attempt to use knife to upload those data bags to the Chef Server, the knife tool will perform some validation on that data for correctness.

However, you may not be immediately be using knife to upload the updated data bag content to the Chef Server. Your workflow may have you 1) make the changes to the JSON 2) commit those changes to a source code repository 3) push those changes to a central code repository 4) allow a Continuous Integration (CI) environment to read in those changes and upload them to the Chef Server. In this environment it would be incredibly useful to have a tool to validate the JSON on your local machine before submitting to a CI system. Here are a few tools that I quickly found that are able to validate JSON from the command-line:

  • https://github.com/zaach/jsonlint
  • https://stedolan.github.io/jq

Remember, it is also possible to use Ruby or any other programming language that has JSON support. Write a script that loads all the JSON files to ensure that they simply load correctly. Here is an example of doing that in Ruby.

Have you used the Atom Text Editor linter packages for Foodcritic and Rubocop? Do you find them useful?

I recently made the change over to using Atom as my full-time editor and these tools were one of the number one reasons. Atom supports plugins for both of these tools.

  • https://atom.io/packages/rubocop-auto-correct
  • https://atom.io/packages/linter-foodcritic

In the past, when doing some serious development, I would have both of these tools running in the background monitoring a file on every save with the a Ruby tool named Guard.

  • https://github.com/guard/guard-rubocop
  • https://github.com/guard/guard-shell

Similar to the Atom Text Editor lint packages questions, have you used RubyMine with chef and chef linting?

I am big fan of the JetBrains tools. In the past I have used ReSharper to accelerate my workflow when working with C#. RubyMine is the most sophisticated Integrated Development Environment (IDE) for Ruby with some incredible features.

Does Chef conduct training that's based on Test Kitchen and these linting tools?

In the new Chef Essentials training we demonstrate the use of Test Kitchen.

What is your process to get the .rubocop rules that everyone agrees on out to the multiple cookbooks?

My usual process involves defining that first .rubocop file with one cookbook. I try to target the biggest cookbook with the most recipes, helpers, tests, etc. I execute Rubocop against each file, fix the changes the team agrees with and then add the rules I want to disable to the configuration file.

How I distribute the completed file to each cookbook depends on if I am using a single chef repository for all my cookbooks or if I am using a repository per cookbook.

With the single all, encompassing repository you can actually store the .rubocop file in the root of the chef repository. Rubocop will look for a configuration file in the current directory and then move up directories until it finds one.

Now for the individual repositories per cookbook you could do the same. Store the file in a parent directory and distribute to each of the team members through a separate code repository. Though, I often times simply add this file to every cookbook that we maintain.

One way to get around having to copy this configuration file every single time you create a cookbook is to use the generator tools present in the Chef Development Kit (ChefDK). You can setup a template to automatically generate a cookbook for you that contains all the common configuration files you may desire.

Does Foodcritic support things like enforcing particular copyright text blurbs or other company specific conventions? Or is there a better tool to investigate for that kind of functionality?

Foodcritic does not by default. However, Foodcritic does provide the ability for you generate your own rules. A number of examples are present on the website.

Rubocop provides a Domain Specific Language (DSL) that allows you to define a rule, give it a code, a name, tags, what files it examines, and what it does when it examines each line of code. It does require some Ruby programming skills.

What was the terminal prompt used during the Webinar?

On my Mac I use iTerm2 with the Agnoster Theme with Powerline Patched Fonts.

  • https://www.iterm2.com
  • https://github.com/robbyrussell/oh-my-zsh
  • https://gist.github.com/agnoster/3712874
  • https://github.com/powerline/fonts