-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(gatsby-cli): normalize case of windows drive letter (#20437)
This PR ensures that the current working directory on Windows always has an uppercase drive letter (i.e., C: vs. c:).
- Loading branch information
Showing
2 changed files
with
66 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
packages/gatsby-cli/src/util/ensure-windows-drive-letter-is-uppercase.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
const { tmpdir } = require(`os`) | ||
const report = require(`../reporter`) | ||
|
||
/** | ||
* This function ensures that the current working directory on Windows | ||
* always has an uppercase drive letter (i.e., C: vs. c:). | ||
* | ||
* Why? | ||
* 1. Different utils like "true-case-path", "normalize-path", "slash" treat Windows | ||
* drive letter differently. "true-case-path" will uppercase, others usually don't care. | ||
* As a result path normalization produces different results depending on current cwd (c: vs. C:) | ||
* which manifests in weird bugs that are very hard to debug. | ||
* | ||
* We can't control community plugins or site code, so everything should be working | ||
* even with a different set of libraries. | ||
* | ||
* Related: https://github.com/Profiscience/true-case-path/issues/3 | ||
* | ||
* 2. Builds save some paths in a cache. If you run the first build from "c:" shell | ||
* and then the next one from "C:" shell, you may get a bunch of webpack warnings | ||
* because it expects module paths to be case-sensitive. | ||
*/ | ||
module.exports = function ensureWindowsDriveLetterIsUppercase() { | ||
const cwd = process.cwd() | ||
const normalizedCwd = driveLetterToUpperCase(cwd) | ||
|
||
if (cwd !== normalizedCwd) { | ||
try { | ||
// When cwd is "c:\dir" then command "cd C:\dir" won't do anything | ||
// You have to change the dir twice to actually change the casing of the path | ||
process.chdir(tmpdir()) | ||
process.chdir(normalizedCwd) | ||
} catch { | ||
// rollback | ||
process.chdir(cwd) | ||
} | ||
|
||
if (normalizedCwd !== process.cwd()) { | ||
report.warn( | ||
report.stripIndent(` | ||
Your working directory has a lower case drive letter: | ||
"${cwd}". | ||
---^ | ||
For solid development experience, we recommend switching it to upper case: | ||
cd "C:\\" | ||
cd "${normalizedCwd}" | ||
(Windows requires two directory switches to change the case of the drive letter) | ||
`) | ||
) | ||
} | ||
} | ||
} | ||
|
||
function driveLetterToUpperCase(path) { | ||
const segments = path.split(`:\\`) | ||
return segments.length > 1 | ||
? segments.shift().toUpperCase() + `:\\` + segments.join(`:\\`) | ||
: path | ||
} |