Repository: prettier/prettier (JavaScript)
Date: 2017-12-05 18:08:24+00:00
Task type: Bug Fix

Issue:
Prettier couldn't go through the directories recursively [error] EISDIR: illegal operation on a directory, read
Hi guys. 
I assume that it's not probably connected to the prettier. But I gave up already to fix that somehow, cause it's the only node based tool which doesn't work with GLOB pattern for now.

Mac OS High Sierra
Latest node and npm.
prettier: 1.9.0

```
prettier --write {scripts,config,bin}/**/*
```
throws lot's of errors in my face like:
```
bin/react-scripts.js 58ms
config/custom-react-scripts
[error] Unable to read file: config/custom-react-scripts
[error] EISDIR: illegal operation on a directory, read
config/env.js 26ms
config/jest
[error] Unable to read file: config/jest
[error] EISDIR: illegal operation on a directory, read
config/paths.js 31ms
config/polyfills.js 6ms
config/webpack.config.dev.js 34ms
config/webpack.config.prod.js 44ms
config/webpackDevServer.config.js 9ms
scripts/build.js 17ms
scripts/eject.js 33ms
scripts/init.js 26ms
scripts/start.js 8ms
scripts/test.js 6ms
scripts/utils
[error] Unable to read file: scripts/utils
[error] EISDIR: illegal operation on a directory, read
template/README.md 819ms
```

In the same, this script returns all required files in the deeply nested paths with no arguing.
```javascript
require('glob')('{scripts,config,bin}/**/*', (e, f) => console.log(f));
```

I have prettier of the same version (1.9.0) both installed globally as well as the prettier in the package.json.

I tried to call it with `sudo` and tried to reinstall it etc. not much of a result.
Running it through the npm scripts or directly result in the same output.

Node and npm are the latest and were installed using brew. I'm under administrator profile.


Issue discussion:
Can you try running with quotes around the glob? i.e.
```
prettier --write "{scripts,config,bin}/**/*"
```

Without quotes, your shell is actually passing the list of files already expanded. With quotes, you're passing to prettier the glob and prettier will take of care of expanding and will only select files.

See here for more information: https://prettier.io/docs/en/cli.html
@duailibe 
The result is following:
```
prettier --write "{scripts,config,bin}/**/*"
bin/react-scripts.js 67ms
config/custom-react-scripts
[error] Unable to read file: config/custom-react-scripts
[error] EISDIR: illegal operation on a directory, read
config/custom-react-scripts/config.js 7ms
config/custom-react-scripts/customizers
[error] Unable to read file: config/custom-react-scripts/customizers
[error] EISDIR: illegal operation on a directory, read
config/custom-react-scripts/customizers/babel-plugins.js 1ms
config/custom-react-scripts/customizers/loaders.js 7ms
config/custom-react-scripts/customizers/plugins.js 2ms
config/custom-react-scripts/options
[error] Unable to read file: config/custom-react-scripts/options
[error] EISDIR: illegal operation on a directory, read
config/custom-react-scripts/options/extract-text-plugin-options.js 3ms
config/custom-react-scripts/options/postcss-options.js 3ms
config/custom-react-scripts/utils
[error] Unable to read file: config/custom-react-scripts/utils
[error] EISDIR: illegal operation on a directory, read
config/custom-react-scripts/utils/map-object.js 4ms
config/custom-react-scripts/webpack-config
[error] Unable to read file: config/custom-react-scripts/webpack-config
[error] EISDIR: illegal operation on a directory, read
config/custom-react-scripts/webpack-config/style-loader.js 13ms
config/env.js 20ms
config/jest
[error] Unable to read file: config/jest
[error] EISDIR: illegal operation on a directory, read
config/jest/babelTransform.js 2ms
config/jest/cssTransform.js 2ms
config/jest/fileTransform.js 1ms
config/paths.js 27ms
config/polyfills.js 5ms
config/webpack.config.dev.js 32ms
config/webpack.config.prod.js 36ms
config/webpackDevServer.config.js 11ms
scripts/build.js 28ms
scripts/eject.js 45ms
scripts/init.js 34ms
scripts/start.js 15ms
scripts/test.js 6ms
scripts/utils
[error] Unable to read file: scripts/utils
[error] EISDIR: illegal operation on a directory, read
scripts/utils/createJestConfig.js 9ms
```
So it means that it's format all the stuff, but still error out on dirs.
Will use with `|| exit 0` for now in npm scripts, but it's still quite messy.
@RIP21 Can you tell the exact command you are running?
@duailibe exactly as you told me.
`prettier --write "{scripts,config,bin}/**/*"`
Please try using single quotes instead of double quotes (yes, really)
@suchipi same result.
@RIP21 Thanks, the reason I asked is because we've seen some problems when people ran prettier through a npm script and had the quotes problem (same reason @suchipi recommended single quotes)

I managed to reproduce the error, not sure what the bug is yet
And BTW I'm using zsh if it can affect anything.

On Dec 5, 2017 18:33, "Lucas Duailibe" <notifications@github.com> wrote:

> @RIP21 <https://github.com/rip21> Thanks, the reason I asked is because
> we've seen some problems when people ran prettier through a npm script and
> had the quotes problem..
>
> I managed to reproduce the error, not sure what the bug is yet
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/prettier/prettier/issues/3409#issuecomment-349379484>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ADwe76J69s0wp9_PeHyd2WVDal0klKGpks5s9X5MgaJpZM4Q2ow6>
> .
>

To clarify: running without quotes *is* a problem because prettier receives the paths as arguments and not the glob:

```js
// console.log(process.argv)
[ 'node',
  'prettier.js',
  '--write',
  'src/a',
  'src/a/a.js',
  'src/b',
  'src/b/a.js' ]
```

But even with quotes I reproduced this bug (that happens when using the `**/*` pattern):
```js
// console.log(process.argv)
[ 'node',
  'prettier.js',
  '--write',
  'src/**/*' ]
We should be passing `nodir: true` here:

https://github.com/prettier/prettier/blob/e09359d2428bdac40c30cd6a82c92a627d1e1d05/src/cli-util.js#L284
Yay. Glad that it's actually an issue of the prettier and not mine :)
And that i didn't spend the time of the maintainers for nothing :)

On Dec 5, 2017 18:53, "Lucas Duailibe" <notifications@github.com> wrote:

> We should be passing nodir: true here:
>
> https://github.com/prettier/prettier/blob/e09359d2428bdac40c30cd6a82c92a
> 627d1e1d05/src/cli-util.js#L284
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/prettier/prettier/issues/3409#issuecomment-349385629>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ADwe79MG6h-MIvkAz0axA33Jcsqy0TdVks5s9YMDgaJpZM4Q2ow6>
> .
>


Solution patch:
diff --git a/src/cli-util.js b/src/cli-util.js
index 50e401b95c3a..27c0494d2e46 100644
--- a/src/cli-util.js
+++ b/src/cli-util.js
@@ -281,7 +281,7 @@ function eachFilename(argv, patterns, callback) {
 
   try {
     const filePaths = globby
-      .sync(patterns, { dot: true })
+      .sync(patterns, { dot: true, nodir: true })
       .map(filePath => path.relative(process.cwd(), filePath));
 
     if (filePaths.length === 0) {


Test patch:
diff --git a/tests_integration/__tests__/__snapshots__/skip-folders.js.snap b/tests_integration/__tests__/__snapshots__/skip-folders.js.snap
new file mode 100644
index 000000000000..26593103dff8
--- /dev/null
+++ b/tests_integration/__tests__/__snapshots__/skip-folders.js.snap
@@ -0,0 +1,17 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`skip folders passed specifically (stdout) 1`] = `
+"a/file.js
+b/file.js
+"
+`;
+
+exports[`skip folders passed specifically (write) 1`] = `Array []`;
+
+exports[`skips folders in glob (stdout) 1`] = `
+"a/file.js
+b/file.js
+"
+`;
+
+exports[`skips folders in glob (write) 1`] = `Array []`;
diff --git a/tests_integration/__tests__/skip-folders.js b/tests_integration/__tests__/skip-folders.js
new file mode 100644
index 000000000000..a2403bbf8c2b
--- /dev/null
+++ b/tests_integration/__tests__/skip-folders.js
@@ -0,0 +1,22 @@
+"use strict";
+
+const runPrettier = require("../runPrettier");
+
+expect.addSnapshotSerializer(require("../path-serializer"));
+
+describe("skips folders in glob", () => {
+  runPrettier("cli/skip-folders", ["**/*", "-l"]).test({
+    status: 1,
+    stderr: ""
+  });
+});
+
+describe("skip folders passed specifically", () => {
+  runPrettier("cli/skip-folders", [
+    "a",
+    "a/file.js",
+    "b",
+    "b/file.js",
+    "-l"
+  ]).test({ status: 1, stderr: "" });
+});
diff --git a/tests_integration/cli/skip-folders/a/file.js b/tests_integration/cli/skip-folders/a/file.js
new file mode 100644
index 000000000000..d785a6ad8f4f
--- /dev/null
+++ b/tests_integration/cli/skip-folders/a/file.js
@@ -0,0 +1,1 @@
+fooA(     )
diff --git a/tests_integration/cli/skip-folders/b/file.js b/tests_integration/cli/skip-folders/b/file.js
new file mode 100644
index 000000000000..2fc0b7efc7db
--- /dev/null
+++ b/tests_integration/cli/skip-folders/b/file.js
@@ -0,0 +1,1 @@
+fooB(   )