Inspecting changes locally before pushing

If you work on your branch you run into the situation that you would like to push your changes to the remote repository. CI will then pick up your changes and run the linting and code quality checks on it. Afterwards, you will see whether you improved the quality. But perhaps there are some new violations that crept into the code? Happens to all of us!

I usually like to see and check if any new issues might come up on CI. This lets me improve them before I push.

The checks I run locally depend on the kind of work that I do. Lately that's a lot of Ruby on Rails again — which is great. I love that framework and the language.

To grade my code, I use Rubocop, Reek and Flay. If you run their respective commands on your repository, they will check the whole code base. This might be ok, if you didn't have any issues before. Since I join teams, these days, that work on legacy projects it is rare that there are no problems with the code. If I run the commands just so, I will get a long list and couldn't possibly see the issues that I introduced through my changes. Lucikly, there is Git and some "command line foo" that can help us here:

git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs rubocop

This command will fetch the current state from the remote and diff your branch/changes to master branch. It then runs rubocop on these changes.

In my ~/.aliases.local file I added three lines for all three linters.

# Code Quality
alias rubocop-changes="git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs rubocop"
alias reek-changes="git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs reek"
alias flay-changes="git fetch && git diff-tree -r --no-commit-id --name-only master@\{u\} head | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs flay"

I am still working on a way to just call one command and have all thee commands run. That doesn't yet work. Probably because of exit-code reasons, when one linter finds issues.

These simple commands offer a convenient way to find local issues and correct them before pushing to CI.

External forces

I am occupied with learning these days. Learning on my own about visualizations of data among other topics. But also learning about learning. For that I read what other people think about learning. There are many things I have to learn about this whole topic. One thought I saw repeatedly, was about external forces, or limiting factors.

Let me elaborate what I mean by that: There are people that can motivate themselves more easily than others can. They reach their goals or at least try very hard. Others give up more easily when they face some resistance. As always, there are people in the middle between these extremes. You know best which group you belong to. 💪

What has this do with software quality? I am getting there… 😉

I am wondering how external forces could help improve quality. If you need to reach your goal and you don't belong to the group of highly self-motivated people there are options like hiring a coach. Athletes do that all the time. I pay for a "virtual" coach that guides my running efforts.

How could you hire a "virtual" coach for your coding efforts, for reaching your targets on your software quality metrics? You could hire me or other "real" coaches, of course. But that doesn't scale too well and might be too expensive.

Again, for some people it is easy enough to use static analysis or linting — a kind of coach in it's own right — and follow their guidelines. Yet, still there are people that ignore the warnings or guidelines imposed upon them by the tools. Reasons may be a hard deadline or too much workload. How could we offer external forces, limiting factors that help them, guide them, towards doing the right thing?

One solution I can think of is to have a robot not accept your code when it is below standard or ignores guidelines. A robot could be anything that measures and grades your code and reports back to your team. Some tools already offer this, for example GitLab. If you want to merge code that decreases the overal quality metrics, you are not allowed to do so. So that would be one.

Another idea: If you try to commit or merge such code, you need to consult with another developer about the code. Once you worked on it together, the other dev has to enter her secret key, to remove the lock on the merge. This forces you to pair on code more often.

When it comes to teaching there is this saying of the "glass has to be empty (enough)." You cannot pour water into it, when it's already filled. Said ideas 👆probably won't work for a team that isn't aiming for learning and improving.

I will continue to think.

Computer says “no”

[…] we do have formal rules that we should obey when writing code. A team has rules, and new team members need to learn them before trying to write any code.

That's what I wrote yesterday. It's my email so I can write whatever I think is correct. You'll let me know through your answers if I am wrong.

My friend Tino answered on Friday and asked whether a university degree or certificates might function as a driver's license. And that is true to a certain degree. I am getting a new certificate these days as well. I hope to complete the exam on Wednesday (ISTQB Advanced Level — Technical Test Analyst).

The obvious difference to a driver's license? I am not legally required to obtain one before I can start writing code. Tino also said that he'd find it interesting to be (self)tested in current web-standards and best practices. I do believe these tests are valuable. If I come around to create one, I'll let you know.

Back to the beginning of the email. Why do rules matter to a team? Developers have their style for writing code. Even if there are rules and certain regulations you have to follow, developers still find ways to write code in their unique style. And that's a good thing. It would be boring otherwise.

Still, this style has to obey the rules. Here's why:

  • The code won't be too complex. Because your static analysis tools tell you if your cyclomatic complexity metric is too high.
  • Classes and modules will have low coupling and high cohesion. This leads to code that's more easily testable and has higher reusability than other code.
  • If you have an error if explaining comments are missing, you could make sure that your developers take some extra time to make sure code can be easier to understand. Other rules, like variable and method/class/module naming conventions, have the same goal.

In short: Rules help your team to write code that is maintainable and has low technical debt. This reduces the total costs of ownership. If you only look at the cost of writing the code and delivering the software, the costs might be higher if you follow stricter rules. Over the complete lifecycle of a software (product), the total costs would be lower because of better maintainability and a lower number of defects.

This is already getting long. See you tomorrow with even more thoughts on this topic.

Driving on the left side of the road

We don't have rules of the road for software development. You don't have to stop at every red light or keep your speed below a specific limit.

Well, yes. We do have rules. If you write your whole program in only one file, someone will tell you that this is bad. At least I hope that's the case!

If you only use variable names like x or y, your coworkers will flag this during code review. Perhaps you already have static analysis tools that tell you before your coworkers do?

While we do not have a driver's license, we do have formal rules that we should obey when writing code. A team has rules, and new team members need to learn them before trying to write any code. Otherwise, it could feel like driving on the wrong side of the road: Driving on the right side of the road feels natural to you if you've never done it any differently. But it can have dramatic consequences if everyone else expects you to drive on the left side.