fast-glob
fast-glob copied to clipboard
Result paths are not normalized to platform
Environment
- OS Version: Windows 10
- Node.js Version: 14.20.0
Actual behavior
Results from fast-glob use POSIX path separators, even when on Windows.
SRC C:\Users\JohnDoe\src
DEST C:\Users\JohnDoe\dist
SRC files (relative) [ 'secret.txt', 'foo/test.txt', 'foo/bar/fizz.txt' ]
SRC files (absolute) [
'C:/Users/JohnDoe/src/secret.txt',
'C:/Users/JohnDoe/src/foo/test.txt',
'C:/Users/JohnDoe/src/foo/bar/fizz.txt'
]
DEST files (relative) [
'C:\\Users\\JohnDoe\\dist\\secret.txt',
'C:\\Users\\JohnDoe\\dist\\foo\\test.txt',
'C:\\Users\\JohnDoe\\dist\\foo\\bar\\fizz.txt'
]
DEST files (absolute) [
'C:\\Users\\JohnDoe\\src\\secret.txt',
'C:\\Users\\JohnDoe\\src\\foo\\test.txt',
'C:\\Users\\JohnDoe\\src\\foo\\bar\\fizz.txt'
]
NOTE: DEST files (absolute)
are all incorrect (still pointing to the SRC files), because string substitution failed to find C:\\Users\\JohnDoe\\src
in the paths returned from fast-glob.
Expected behavior
I'd expect resulting file paths to be normalized (adhering to the platform-defined path separator).
SRC C:\Users\JohnDoe\src
DEST C:\Users\JohnDoe\dist
SRC files (relative) [ 'secret.txt', 'foo/test.txt', 'foo/bar/fizz.txt' ]
SRC files (absolute) [
'C:\\Users\\JohnDoe\\src\\secret.txt',
'C:\\Users\\JohnDoe\\src\\foo\\test.txt',
'C:\\Users\\JohnDoe\\src\\foo\\bar\\fizz.txt'
]
DEST files (relative) [
'C:\\Users\\JohnDoe\\dist\\secret.txt',
'C:\\Users\\JohnDoe\\dist\\foo\\test.txt',
'C:\\Users\\JohnDoe\\dist\\foo\\bar\\fizz.txt'
]
DEST files (absolute) [
'C:\\Users\\JohnDoe\\dist\\secret.txt',
'C:\\Users\\JohnDoe\\dist\\foo\\test.txt',
'C:\\Users\\JohnDoe\\dist\\foo\\bar\\fizz.txt'
]
Steps to reproduce
-
cd C:\Users\JohnDoe
-
node copyFiles.mjs
Code sample
Given the following directory structure of C:\Users\JohnDoe
:
src/
secret.txt
foo/
test.txt
bar/
fizz.txt
C:\Users\JohnDoe\copyFiles.mjs
import fg from 'fast-glob'
import path from 'path'
const SRC = path.resolve('src')
const DEST = path.resolve('dist')
async function main() {
console.log('SRC', SRC)
console.log('DEST', DEST)
// fetch source paths
let relFiles = await fg([ '**/*.txt' ], { cwd: SRC })
let absFiles = await fg([ '**/*.txt' ], { cwd: SRC, absolute: true })
console.log('SRC files (relative)', relFiles)
console.log('SRC files (absolute)', absFiles)
// compute destination paths
let relFilesDest = relFiles.map(relFile => path.resolve(DEST, relFile))
let absFilesDest = absFiles.map(absFile => absFile.replace(SRC, DEST))
console.log('DEST files (relative)', relFilesDest)
console.log('DEST files (absolute)', absFilesDest)
// perform "copy" logic here...
}
main()
EDIT: 2022-08-23 - expanded example, expected results, and actual results to reflect { absolute: true }
config
Works as expected. Users write patterns in POSIX-style. The result of the work is also presented in this style.
The Node.js platform can work with POSIX-style paths even on Windows.
I am ready to consider this functionality only if there are strong arguments.
The problem is more obvious when you use { absolute: true }
in fast glob configs (updated issue contents, to reflect). The absolute path strings returned from fast-glob do not match the format returned by functions in the Node path
module.
To perform string substitution on an absolute path returned from fast-glob, I have to normalize the fast-glob result first (so that it matches the format returned by path
functions) and then proceed with the string substitution.
While path normalization is not a difficult task to accomplish, my expectation was that fast-glob would match the native path
format when constructing absolute paths using path separators that match path.sep
("\\"
on win32, "/"
on POSIX).
If changes in this issue were to be made:
- POSIX environments won't see any change in the output for paths (regardless if they're relative or absolute)
- win32 environments that consume the absolute paths as-is, shouldn't be affected, because the paths are still valid in that environment
- 3rd-party logic on win32 environments that normalize the results wouldn't be affected, because the paths would already be normalized
- 3rd-party logic expecting absolute paths using the current format would either need to update their code to use the normalized paths OR fast-glob could provide an option to revert to the old behavior (which could then potentially be removed in a future release of fast-glob).