How to update lint without lint the whole project

seeliang
3 min readJul 14, 2021

--

Since you are reading this, I think it is safe to say: we all love lint. We love the part it could reduce the time we spend on code review, and more importantly, when it catch the critical problems on the fly with your IDE.

The problem

The only problem is, commonly, lint rules are set to check the whole project. It means any lint rule update will easly lead to hundreds of line changes in the project.

This “we shall lint everything” concept is hardcore for developers, but not really agile for business. As my scrum master once told me: it is very likely this section will be refactor or removed before we really need to maintain it; we may end up waste time to correct the lint errors in this section for nothing. This is not align with business value.

In short, “It ain’t broken, don’t fix it”

“Once we set the lint rules, that is it” situation could not match my team’s development needs. For me, the lint rule update could be as essential as framework update.

It haunted me for a long time and I was always trying to find a breakthrough.

The rescue

One day I was debugging with my college lisheng yu , he was showing me all the files we have changed comparing to release branch with git, instead of PR page.

git diff --name-only release

It hit me like a ray of sun:

These are the files we are developing, so it makes all the sense to improve the quality of these.

All we need to do is grab the right type of files, and that part can be done with grep

git diff --name-only release | grep -E “(.js$|.ts$|.tsx$)”

Wait, what about those we removed ones? We will need a filter. Luckily it comes with git

git diff --name-only — diff-filter=ACMRTUXB release | grep -E “(.js$|.ts$|.tsx$)”

The samples

Here is how we can do it with eslint

eslint -c eslintrc.js $(git diff --name-only --diff-filter=ACMRTUXB release | grep -E \"(.js$|.ts$|.tsx$)\")

For CI, we will need to use remote branch

eslint -c eslintrc.js $(git diff --name-only --diff-filter=ACMRTUXB origin/release | grep -E \"(.js$|.ts$|.tsx$)\")

For style lint, fallback file is required when not file has found with diff. Based on https://github.com/stylelint/stylelint/issues/4649, we will need bash script

Script: lint:style

stylelint --config .stylelintrc.js $(git diff --name-only --diff-filter=ACMRTUXB origin/release | grep -E \"(.js$|.ts$|.tsx$)\")

Bash:

if [[ $(git diff --name-only --diff-filter=ACMRTUXB origin/release | grep -E "(.ts$|.tsx$)") == *".t"* ]];thenecho "has changes"yarn lint:styleelseecho 'nothing for stylelint'fi

And in some cases CI could not get remote, all we need to do is fetch all remote before lint:

git remote set-branches origin '*'        
git fetch

The ghost

Since the breakthrough, I have implemented this in multiple projects. There is one thing that we will need to do:

Sync with target branch (release), constantly

If we were behind the target branch, updated files in target branch would show up in our lint result. As we were not touch them, this feels like ghost for the developers who are not familiar with the setup.

In general, our development branches shall sync with release branch to make sure it pass updated UTs and e2e tests, so I have not got many complaints from the team after the explanation.

The chain reaction

In few cases, link checker requires dependencies fix in extra untouched files. When it was not complex, my team would do it. When it is complex, we would use inline lint disable and log a tech debt. The fixes will have to wait for that special day.

The end

Thank you for reading this. If you have any issues let me know, I will try to get back to you soon

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

seeliang
seeliang

Responses (1)

Write a response