EACCESS: permission denied on ignored directory
nicolas-goudry opened this issue · 2 comments
I have the following issue trying to run xo on my project :
> xo-eaccess-permission-denied-on-ignored-dir@1.0.0 lint
> xo
Error: EACCES: permission denied, scandir '/fakepath/xo-eaccess-permission-denied-on-ignored-dir/.data/mysql/#innodb_redo'
I created a repository to reproduce this issue.
To better explain, I have a MySQL container running alongside my Node.js API, and I’m mounting its data directory in a .data
directory at my project root. I added the .data
to .gitignore
, expecting xo to actually ignore it, but it still tries to scan the subdirectories of .data
, as per the error message.
Also tried adding .data/**/*
to .gitignore
, as well as adding them to the ignores
xo config field, with same results.
EDIT: I know I can fix this by running something like this: sudo chgrp -R $(whoami) .data/mysql
but I still think this is a bug.
I took a look at the code, and the error seems to come from the call to globby
inside the globFiles
function, on line 29. I’ll keep digging.
EDIT: tracked down to the call to fastGlob
inside globby
’s isIgnoredByIgnoreFiles
function, on line 68. Still digging.
EDIT 2: got too deep, now I’m down to @nodelib/fs.walk
used by fast-glob
… I’m getting lost a bit rn. I don’t quite understand why the isIgnoredByIgnoreFiles
is only passing **/.gitignore
to fast-glob
.
Here’s my walkthrough:
- in
xo
’sglobFiles
function, I can see that the following is passed toglobby
’signore
option
[
'**/node_modules/**',
'**/bower_components/**',
'flow-typed/**',
'coverage/**',
'{tmp,temp}/**',
'**/*.min.js',
'vendor/**',
'dist/**',
'tap-snapshots/*.{cjs,js}',
'**/.data'
]
- in
globby
’sgetFilter
function, I can see that the followingoptions
are passed
{
ignore: [
'**/node_modules/**',
'**/bower_components/**',
'flow-typed/**',
'coverage/**',
'{tmp,temp}/**',
'**/*.min.js',
'vendor/**',
'dist/**',
'tap-snapshots/*.{cjs,js}',
'**/.data'
],
gitignore: true,
absolute: true,
cwd: '/home/nicolas/dev/kdaf-api',
expandDirectories: true
}
- in
globby
’sgetIgnoreFilesPatterns
function, I can see that the fieldignoreFiles
is destructured from theoptions
object although it doesn’t exist - therefore, the resulting
ignoreFilesPatterns
ofgetFilter
is the following:
[ '**/.gitignore' ]
I think this is a bug, but somehow, if I change the code of getIgnoreFilesPatterns
to destructure the right field from options
(ie. the ignore
field), I get the following for ignoreFilesPatterns
:
[
'**/node_modules/**',
'**/bower_components/**',
'flow-typed/**',
'coverage/**',
'{tmp,temp}/**',
'**/*.min.js',
'vendor/**',
'dist/**',
'tap-snapshots/*.{cjs,js}',
'**/.data',
'**/.gitignore'
]
But that doesn’t resolve the issue…
It’s getting late and I’m tired rn, I’ll try to continue tomorrow.
Looking back at this, I now think I understand what does the isIgnoredByIgnoreFiles
function: return a list of ignore files relative to the current working directory.
I think this is the issue, because it’s actually trying to search for an ignore file inside the .data
directory, to which it doesn’t have access permission.
If I update the code of isIgnoredByIgnoreFiles
to add the options.ignore
to the ignoreFilesGlobOptions.ignore
, the issue goes away.
Something like that (dirty):
export const isIgnoredByIgnoreFiles = async (patterns, options) => {
const {cwd, suppressErrors, deep} = normalizeOptions(options);
const paths = await fastGlob(patterns, {
cwd,
suppressErrors,
deep,
...ignoreFilesGlobOptions,
ignore: [...ignoreFilesGlobOptions.ignore, ...options.ignore],
});
const files = await Promise.all(
paths.map(async filePath => ({
filePath,
content: await fs.promises.readFile(filePath, 'utf8'),
})),
);
return getIsIgnoredPredicate(files, cwd);
};
Would you like me to open an issue in I opened a related issue in globby
’s repository instead ?globby
’s repository.