Description
This is not a critical bug but is little boring have to remove this extra rule always that I added a new rule to vercel.
Details
- CLI Version: 37.12.1
- OS: Microsoft Windows 11 Pro
Evidence
Steps to reproduce the issue
- Using an OS that has end-of-line
crlf
by default like Windows - Run
vercel env pull
Into a project that already has a the vercel rules into the.gitignore
What’s the expected result?
Only add the rule .env*.local
when the .gitignore
does not have it.
What’s the actual result?
Is adding the same rule multiple times.
🫚 Root cause
This is happeing because this condition in this file packages/cli/src/util/link/add-to-gitignore.ts
this is the code:
const EOL = gitIgnore.includes('\r\n') ? '\r\n' : os.EOL;
// ..
if (!gitIgnore.split(EOL).includes(ignore)) { /* add the rule */
In some cases this condition can be translated to:
const EOL = gitIgnore.includes('\r\n') ? '\r\n' : '\r\n';
For example in my case my file is using lf
= \n
but my os use crlf
= \r\n
by default that is this condition will never be true
.
Solution
I did a few changes in this code that I would like to check first here to avoid a forgotten PR!
Changes
-
Move this file
add-to-gitignore.ts
fromsrc/util/link
tosrc/util
since it is not only used in link command but also in env command. -
Change the code to check as an string. It is good for two reasons:
- The
.gitignore
can have multiples rules at the same line - Doesn’t matter what is the end-of-line
- The
if (gitIgnore.includes(ignore)) return isGitIgnoreUpdated;
- The last change that I would like to check if it is ok
or is too much. I created a function to get the dominant end-of-line and use it when add a new line. This is the code:
function getDominantEOL(text: string) {
const lines = (text.match(/\r\n|\n/g) ?? []) as Array<'\r\n' | '\n'>;
const {
'\n': LFCount,
'\r\n': CRLFCount,
} = lines.reduce(
(counter, lineEnding) => {
counter[lineEnding] += 1;
return counter;
},
{ '\n': 0, '\r\n': 0 },
);
const dominantEOL = LFCount > CRLFCount ? '\n' : '\r\n';
return LFCount === CRLFCount ? os.EOL : dominantEOL;
}
It can be simpler checking if there is any kind of end-of-line otherwise it uses the os end-of-line:
function getEOL(text: string) {
if (text.includes('\r\n')) return '\r\n';
if (text.includes('\n')) return '\n';
return os.EOL;
}
I will open the PR soon and leave the link to it here!
If you have any suggestions I will be happy to apply it