Apply coding standards by using pre-commit

When working on a project in a team, it’s typical that engineers’ coding styles might be different. It’s fine in the first place; however, if the number of engineers increases, you may end up having multiple coding styles in the project.

For example, one may prefer a line length of 80, the other may like 120. One may use Windows OS in which the line endings are \r\n while one may use a UNIX-like OS like macOS in which \n is used. Furthermore, it is very difficult to catch these types of during the code-review. No one likes (or can) take care of these tiny things because we are humans and making mistakes is part of our day-to-day life.

Also, there might be some runtime issues that cannot be identified during the development and testing. For instance, in Python projects, you may have a function like this:

def sum(a, b):
    return a + b

But then by mistake, you may use the function like this:

result = sum("1", "2")

Theoretically, the function definition and usage is correct. But is that really what you want? This may seem very obvious and trivial but believe me, in real-world projects, these things happen!

Although some of these human and runtime errors can be identified by the reviewer(s), there will be cases in which they may forget to spot them. As a result, the optimal way is to automate these processes. There are several tools out there for this type of automation but the one that I like and use is pre-commit.

How it works

As the name implies, pre-commit can be triggered when the user attempts to “commit” a new change. This is done by defining a new git hook. After the attachment, each time the git commit is run, pre-commit start checking all changed files.

To install pre-commit you can use your OS package manager. I am using macOS and Homebrew so the command to install would be:

brew install pre-commit

After installation, you need to install the git hook scripts. This is done by running the following in the repo directory:

$ pre-commit install
pre-commit installed at .git/hooks/pre-commit

After this pre-commit starts automatically every time a new commit is going to be created.

You can also trigger pre-commit manually and on all files inside the project by running. This is very useful you can run the checks again in your CI/CD pipeline:

pre-commit run --all-files

After the installation process is finished it’s now time to start configuring the pre-commit

Configurations

Pre-commit works by running some hooks that is defined as configurations. You can configure pre-commit by adding the .pre-commit-config.yaml file to your project. Here’s an example:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v2.3.0
    hooks:
      - id: check-yaml
      - id: check-json
      - id: end-of-file-fixer
      - id: trailing-whitespace
  - repo: https://github.com/psf/black
    rev: 21.12b0
    hooks:
      - id: black

Each configuration starts with a list of repos in which the hooks exist. Each repo can have one or more hooks. In the above example, there are two repos defined. The first is the pre-commit’s default hooks repository which contains lots of useful hooks such as check-yaml, check-json, end-of-file-fixer, and trailing-whitespace that we have used. The second is the black hook which is a Python code formater. When a new commit is added, these hooks will be run automatically.

Note: When you change the pre-commit configuration file, it’s recommended to run pre-commit install again to fetch newly added hooks

For more information about pre-commit’s default hooks please check https://github.com/pre-commit/pre-commit-hooks

Using pre-commit for us is critical because it saves us a lot of time and energy, especially during code reviews.

In | 25 Mar 2022

It's now around 18 months that I have quit Twitter

I think I was one of the firsts among software engineers who started using Twitter in Iran back in 2007-2008; however, I am not proud of it at all. What makes me proud is that I was able to quit it 18 months ago! Also, I didn’t limit my self to just Twitter, and I also quit Facebook. Having said that, now the only social network that I am partially active in is Instagram which I have planned to get rid of soon.

No social media. Photo taken from:
https://aaasolutions.com/wp-content/uploads/2016/01/no-social-media.jpg

What I have experienced during the these 18 months is that, the advantages of Twitter and other social networks are radically less than their disadvantages. I think we are spending our most valuable thing, which is time, making money for social network companies while we don’t get too much of them. Even if you follow, NASA, MIT, or your favorite music band doesn’t mean that your time is spent meaningfully.

But one may ask, I use social networks to stay informed about topics I like! If I quit Twitter for example, how can I keep posted about my favorite soccer club? My approach is to be as specific as possible. For instance, I like astronomy. To be able to stay informed about the latest news and stories, I have signed up for a weekly newsletter called The Space Review. Every Tuesday, I get the top most important and trending stories about space directly in my inbox. Tech and programming are another examples, I check hackernews twice a week and also subscribed to ArchLinux mailing list.

This approach works for me but it may not work for you. But the good point here is that you have control over your time and that’s the important part.

Updates to my blog including shutting the comment section down

For almost 10 years, I have been using the Disqus comment management system to manage my posts’ comments. Last year, when I was moving to Germany, I have decided to hide the comment section by default. The main reason behind the idea was, since Disqus is considered a third-party and it is using cookies, and to prevent displaying the annoying pop-up informing visitors that “the website is using cookies”, I hide it until users really want to leave a comment (or viewing them). After near a year, I think that the comment section is not useful anymore; therefore, I decided to remove it completely this time.

People who blog these days are not looking for comments or impressions. They just write because they love to. I can vividly see that the amount of bloggers decreased significantly during the last 5-7 years and the main reason of that is social media. Most people prefer to just send their updates through series of tweets or Facebook posts. So, their social network get informed automatically. On the other hand, I think nearly all people who still blog are not doing it because they want to inform visitors or keep them up-to-date.

In addition to the comment section, I also removed the bootstrap CSS library. I have been using this to implement the theme. However, a few days back, I decided to implement the simplest grid system ever existed (as it was my main dependency to Bootstrap) and remove it completely.

After removing the Bootstrap, I can finally say that this blog is just pure HTML and around 200 lines of CSS. And, due to the fact that I don’t use any analytics or trackers (I removed Google Analytics about a year ago), there’s no Javascript is used as well!

Why?

As you may know, I am a big fan of science especially when it comes to physics and more specifically astrophysics. A few weeks back I was watching a video about science on YouTube and suddenly a video in the side column got my attention.

It was a video from Richard Feynman, the famous physicist, in which the interviewer asks him a very simple yet valid question about magnets. The question is about why something happens and Feynman answer is very interesting. I don’t want to spoil it so please take a moment and watch this ~7 minutes video:

My ultimate Neovim configuration for Python development

It’s about 5 years that I’m using Neovim as my daily text editor especially when it comes to software development. On the other hand, I do lots of Python programming during the last 4 years and so to develop more comfortably, I had to configure my text editor as well. In this post, I’m going to explain my daily setup for Python software development.

Tools

There are a few tools I use besides Neovim that help me a lot during my everyday development.

Terminal Emulator

Since I’m developing on macOS these days, my primary terminal of choice is iTerm2. I had also tried the macOS built-in terminal but I found that iTerm2 has better integration with Tmux so that I moved to it.

Shell

In term of shell, I moved to zsh (mainly through oh-my-zsh) about 5 years ago because I found it much better in compare to bash. OMZ community offer lots of useful plugins to choose from; but, for me these are my favorites:

plugins=(
    git
    docker
    docker-compose
    kubectl
    colored-man-pages
    git-flow
)

Tmux

Tmux plays a very important role in my daily development environment. I was using the neovim built-in terminal however I realized that nothing replaces Tmux. I usually split my main development window into two horizontal panes. The pane in the above for Neovim and the second pane which is located below that is for running tests and Git operations. I sometimes use the vim-fugitive plugin but in some cases, I believe it’s move convenient to use git in another window. Tmux panes

Neovim

If you’re a vim user, you are probably familiar with plugin managers. Vundle, Pathogen and Plugged are the three most popular ones. I was using Vundle for a long time, but recently I have moved to Plugged because I find it more customization about more easy to use. The plugins I use these days are:

" A fuzzy file finder
Plug 'kien/ctrlp.vim'
" Comment/Uncomment tool
Plug 'scrooloose/nerdcommenter'
" Switch to the begining and the end of a block by pressing %
Plug 'tmhedberg/matchit'
" A Tree-like side bar for better navigation
Plug 'scrooloose/nerdtree'
" A cool status bar
Plug 'vim-airline/vim-airline'
" Airline themes
Plug 'vim-airline/vim-airline-themes'
" Nord
Plug 'arcticicestudio/nord-vim'
" Better syntax-highlighting for filetypes in vim
Plug 'sheerun/vim-polyglot'
" Intellisense engine
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" Git integration
Plug 'tpope/vim-fugitive'
" Auto-close braces and scopes
Plug 'jiangmiao/auto-pairs'

For python development, I was previously using jedi-vim alongside YouCompleteMe but after the presentation of Coc I completely hooked! Coc is a Nodejs extension host for Neovim which allows you to install npm based plugins (which is currently used in other text-editors such as VSCode) easily.

After installing Coc, I was able to install all the plugins I want to for my development environment very easily and just by using the CocInstall <package-name> command. Here is a list of all plugins I use:

  • coc-spell-checker: The general spell checker for neovim
  • coc-prettier: A very popular code formatter
  • coc-git: A git plugin to show which line is added/deleted and not committed
  • coc-pyright: The main Python plugin I use
  • coc-json: JSON file formatting plugin
  • coc-docker: Dockerfile and docker-compose formatters
  • coc-yaml: Yaml plugin for Kubernetes and terraform files

After installing your desired plugins it’s also a good idea to do a CocUpdate once in a while to keep your plugins up-to-date.

Then I set the following the shortcuts for the Coc for more ease of use:

" Code action on <leader>a
vmap <leader>a <Plug>(coc-codeaction-selected)<CR>
nmap <leader>a <Plug>(coc-codeaction-selected)<CR>

" Format action on <leader>f
vmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)
" Goto definition
nmap <silent> gd <Plug>(coc-definition)
" Open definition in a split window
nmap <silent> gv :vsp<CR><Plug>(coc-definition)<C-W>L

Like VSCode, Coc also has a setting JSON file. For example, to formatOnSave or set a code formatter and linter, you can use that file. To open the setting file CocConfig command can be used. These are settings I use for Python development:

{
  "coc.preferences.formatOnSaveFiletypes": ["py", "yaml", "json"],
  "python.linting.flake8Enabled": true,
  "python.formatting.provider": "black"
}

Please also note that black and flake8 are external tools and need to be installed separately:

python3 -m pip install black flake8

There some other shortcuts which can be set to make your life easier as well. For example, I have set one to trigger NerdTree and showing hidden files:

map <C-n> :NERDTreeToggle<CR>
let NERDTreeShowHidden=1 " Show hidden files in NerdTree buffer.

Or for better split-view navigation:

" Split windows
map <C-j> <C-W>j
map <C-k> <C-W>k
map <C-h> <C-W>h
map <C-l> <C-W>l

Nord

Last but not least I use Nord theme almost everywhere. Nord has ports for almost everything. For example, for neovim you may add the following plugin:

Plug 'arcticicestudio/nord-vim'

And then add:

filetype plugin indent on
syntax on
colorscheme nord

I hope this post helped you setup your CLI based development environment as well :)