2 Static Analysis Tools to Enhance Your Productivity
Published: 2021-11-06 03:01:57

If you are tired of maintaining your coding style, I have good news for you. Fortunately, there are developer tools that can automate and streamline mundane development tasks. In this blog, I'll show you how I integrated 2 [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis) tools and a package manager for pre-commit hooks into [Silke](https://github.com/oliver-pham/silkie), my work-in-progress static site generator.

## Black: The uncompromising Python code formatter

[Black](https://github.com/psf/black) can help you automatically format your Python code that follows (most of) the style conventions in [PEP 8](http://www.python.org/dev/peps/pep-0008/). You can install this tool with [Pip](https://pypi.org/project/pip/) and **Python 3.6.2+**: 

```
$ pip install black
```

After installation, Black should work without configuring anything else:

```
$ black .
```

Once Black is executed, it will tell you which files have been reformatted. When I ran it on Silkie, Black produced the following output:

```
reformatted silkie/silkie.py
All done! ✨ 🍰 ✨
1 file reformatted.
```

After testing Silkie, I was pleasantly amazed that Black didn't break my code. If you are still worried that Black may break your program by alternating your code, you can include the `--diff` flag when running it. That should allow Black to only suggest their changes. 

### VSCode Integration
If you use Visual Studio Code as your code editor, you can easily integrate Black into it. First, you need to create a `settings.json` file under `.vscode` folder if you haven't had it. Then, add these 2 lines to enable Black to reformat your Python code when you save your files:

```json
{
    "python.formatting.provider": "black",
    "editor.formatOnSave": true,
}
```

## Flake8: Python 3-in-one linter
A [code linter](https://en.wikipedia.org/wiki/Lint_(software)) should help developers identify potential errors and coding style violations in your code; and I think [Flake8](https://github.com/pycqa/flake8) can accomplish that. Flake8 combines `PyFlakes`, `pycodestyle`, and `Ned Batchelder's McCabe script` to enhance our Python code quality.

Setting it up is as easy as a one-line command:

```
pip install flake8
```

Once it's installed, you can run it on your project right away. However, you can save your time later by specifying which files and/or directories Flake8 should exclude from its scan. In order to do that: 

1. Create a `tox.ini` file in your root directory.
2. Specify the excluded files/folders separated by commas. Take my project as an example:

```ini
[flake8]
exclude =
    # Version control directory
    .git,
    # GitHub configuration directory
    .github
    # Python compiled bytecode 
    __pycache__,
    # Python third-party libraries & packages
    lib,
    # Python scripts & binary files
    bin,
    # Build directory
    dist,
```

Then, I ran Flake8 on my project: 

```
$ flake8 .
```

By default, Flake8's style rules may have some conflicts with Black's. For instance, although Black already formatted my code, Flake8 would still bug me for having too many characters per line:

```
./silkie/silkie.py:37:80: E501 line too long (83 > 79 characters)
./silkie/silkie.py:43:80: E501 line too long (84 > 79 characters)
./silkie/silkie.py:52:80: E501 line too long (80 > 79 characters)
./silkie/silkie.py:76:80: E501 line too long (86 > 79 characters)
./silkie/silkie.py:80:80: E501 line too long (80 > 79 characters)
./silkie/silkie.py:104:80: E501 line too long (80 > 79 characters)
./silkie/silkie.py:149:80: E501 line too long (80 > 79 characters)
./silkie/silkie.py:157:80: E501 line too long (80 > 79 characters)
./silkie/silkie.py:159:80: E501 line too long (83 > 79 characters)
./silkie/silkie.py:199:80: E501 line too long (85 > 79 characters)
./silkie/silkie.py:210:80: E501 line too long (88 > 79 characters)
```

Moreover, Flake8 found a [false positive error](https://github.com/PyCQA/pycodestyle/issues/373):

```
./silkie/silkie.py:159:56: E203 whitespace before ':'
```

Flake8 actually complained about the whitespace before a list slice:
![Whitespace before list slice](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8vr0fpkumvohc746e8k.jpg)
 
To resolve those issues, I configured Flake8 in `tox.ini` file, located in the root directory, to ignore those false positive stylistic errors:

```ini
[flake8]
max-line-length = 88
ignore =
    # False positive whitespace before ':' on list slice.
    # See https://github.com/PyCQA/pycodestyle/issues/373 for details
    E203
```

### VSCode Integration
Flake8 can integrated into Visual Studio Code by adding these lines to `settings.json` file under `.vscode` folder:

```json
{
    "python.linting.flake8Enabled": true,
    "python.linting.enabled": true,
    "python.linting.flake8Args": ["--max-line-length=88"],
    ...
}
```

## Pre-commit: Multi-language pre-commit hooks manager
If you don't want to manually run Black and Flake8 before committing your changes, you can automate it with [`pre-commit`](https://pre-commit.com/).

To install `pre-commit`, run this command:

```
$ pip install pre-commit
```

Once it's installed, you can set up pre-commit hooks by specifying them in the `.pre-commit-config.yaml` file. For example, this is how I added Black and Flake8 as pre-commit Git hook scripts to my project:

```yaml
repos:
  - repo: https://github.com/psf/black
    rev: 21.10b0
    hooks:
      - id: black
  - repo: https://github.com/pycqa/flake8
    rev: 4.0.1
    hooks:
      - id: flake8
```

To run these tools before every `git commit` commands, you need to install the scripts with this command:

```
$ pre-commit install
```

After installation, Black and Flake8 should be executed before any modification is committed.

## Conclusion
I initially thought integrating these tools into my project would take a lot of time, but it was actually really quick and straightforward. Thanks to the development teams behind Black & Flake8, my life as a developer has been much easier. I can't wait to try out other awesome tools!