bash

Today I would like to share one of the simplest developer lifehacks I came up with, yet the one that saved me a ton of time since I started using it. In fact, it's been used without me having to do anything more than just set it up.

Automate all the things!

I'm a huge fan of automating stuff. I totally get how one can spend a whole weekend working on some magic solution that is able to do a 10-second task on its own. I mean, anytime I hear somebody is saving time using automation, I give thumbs up (BTW, if you have some, please share!). This one is super-tiny, doesn't require much knowledge, but is one I cannot see myself working on a daily basis anymore.

Problems with microservices

I don't want to talk about whether microservices are better than the monolith, as it generally depends on what your system wants to achieve, how big and skilled your team is, etc. Another story is that even with the former approach, you have to make a choice: one repo to rule them all, or multiple smaller (in-theory-independent) ones? If you go for the latter, and your team does not have any service-specific ownership (eg. one smaller team is responsible for given service/repository) you are going to face some code conflicts more time than not. Every time you want to commit something, you find out that your master is nowhere near there origin/master is. This becomes irritating pretty quickly, so I decided that I need to have the changes fetched automatically so that I don't need to remember if I have to fetch any changes from the remote server.

The solution

Fist of all, we need to have a script, that will fetch changes for all the repositories. At work, we are using GitHub and have all repositories in the same place, so that helps a lot. The script is nothing more than a bunch of bash commands:

# fetch-repos
#!/bin/bash
for repo in $(ls ~/go/src/github.com/ORGANIZATION); do 
    git -C ~/go/src/github.com/ORGANIZATION/${repo} fetch; 
done

Now we just need to set the script running periodically using crontab command. First, we need to type:

crontab -e

This opens up a text editor where we need to enter a full path to the script and information how often it should be run. In this case, we want to fetch repository changes every hour, so we type:

0 * * * *  /Users/slomek/scripts/fetch-repos

Now we just need to save and exit the editor. Next time we enter one of the repos within ORGANIZATION directory and check the branch status, we will immediately get information about the changes that have been made, even though we didn't need to fetch them manually. Lots of time saved, right?

Cron basics

In order to fully understand what has happened with crontab command, we need to understand what is cron and how it can be utilized. Shortly, it's a scheduler that is configured using a file named the same as the command used for editing it (yep, crontab) and it consists of the list of scripts that user wants to be executed at given time. Each like consists of two sections, time definition, and the path to the script. In our example used before, 0 * * * * is a time definition.

Time section consists of five values, representing minute, hour, the day of the month, month and day of the week, respectively. This gives us a chance to define pretty accurate times when a script should be executed. An asterisk * stands for every (as in every minute, every month, etc) and numbers stand for specific values of given part (eg. 5th minute of every hour). Let's first again take a look at the one definition we've used before:

0 * * * *  /Users/slomek/scripts/fetch-repos

We define only the first element, which means we want to execute fetch-repos script at the 0th minute of every hour, which basically means we run it every hour. We can also use any other number there, eg. 17 would still fetch all repos every 60 minutes, but it won't be done at an even hour.

We can also use more complex values in time definition like:

0,30 * * * *    /run/script/on-0ht-and-30th-minute
*/5 * * * *     /run/script/every-five-minutes
1-5 * * * *     /run/script/on-1st,2nd,3rd,4th,5th-minutes-only
0 0 * * *       /run/script/on-every-midnight
0 0 1 * *       /run/script/on-first-day-of-month
0 0 1 */2 *     /run/script/on-first-day-of-every-second-month
0 7 * * 1-5     /run/script/at-7am-every-weekday # regular day alarm clock
0 10 * * 0,6    /run/script/at-7am-on-weekends # weekend day alarm clock

For more information, I recommend an awesome site called crontab.guru, which allows you to play around with time definitions, also show you when would be a next time your script would be activated.