-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLI: Support .ignore files #2412
Conversation
bin/prettier.js
Outdated
@@ -243,6 +249,10 @@ if (argv["help"] || (!filepatterns.length && !stdin)) { | |||
" This option cannot be used with --cursor-offset.\n" + | |||
" Defaults to Infinity.\n" + | |||
" --no-color Do not colorize error messages.\n" + | |||
" --ignore-path <path|string> \n" + | |||
" Path to a file containing patterns that describe files to ignore. The\n" + | |||
" path can be absolute or relative to process.cwd(). By default, stylelint\n" + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stylelint → Prettier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lydell sorry for stupid error 😄
Thanks for the PR. I'm now convinced that we do need to address this problem inside of prettier. I'd like to take a step back and figure out what the end state will look like, then once we agree with it, we can start with PRs. I see three big things:
Do we want three files for those? Do we want a single file? Should those files be JavaScript, JSON, plain text? Different for all those or all the same? If you could tell me what you have in mind, that would be awesome! |
Also, what's the relationship between the CLI and the CommonJS version of the API. Should only the CLI part read from those files, or both? |
Be good implement
I did not quite understand what your mean. If your mean which files we can handle, multiple patterns are enough for most use case.
Do this as
Be good support this in the CommonJS version of the API, move some CLI logic to But we can do this in other PR. We already support multiple pattern, here we can add |
cc2b802
to
567a03b
Compare
As an API consumer (prettier-vscode), I would be grateful if the CommonJS would be on par with the cli. If it isn't resolved through the API for whatever reason, it would be great to have API calls like |
/cc @vjeux what do your think about this:
Seems step by step allow implement this without big difficult PR and easy review? |
I'm sorry I'm currently in vacation with no access to a computer, I'll be able to do a proper review only next week. Some other thoughts I have: For the docs website, we transform index.js, if we move this fs logic there we need to make sure it still works. I'm very concerned about performance if we put this inside of index.js, the naive version would be to do all the fs.stat/fs.read for every single call, but I fear that it's inefficient. This means that we'd need to introduce a watcher for all those paths which comes with their own sets of issues. I'm not sure what's the right solution is yet. I really want prettier to stay in the dozens of ms range for use in the editor. Otherwise it makes it a much worse experience for the developer. |
@vjeux So I think step by step implement will allow found good solution for this, without problems with perf 👍 But this pr only for cli 😄 |
I'm more interested in figuring out what the end result will look like. Once we know what it is, i'll just merge all the pull requests quickly, the implementation is not really the problem. Sorry for the delay! |
bin/prettier.js
Outdated
@@ -243,6 +248,10 @@ if (argv["help"] || (!filepatterns.length && !stdin)) { | |||
" This option cannot be used with --cursor-offset.\n" + | |||
" Defaults to Infinity.\n" + | |||
" --no-color Do not colorize error messages.\n" + | |||
" --ignore-path <path|string> \n" + | |||
" Path to a file containing patterns that describe files to ignore. The\n" + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we simplify this a bit?
Path to a file containing patterns that describe files to ignore. Defaults to ./.prettierignore.
bin/prettier.js
Outdated
// The ignorer will be used to filter file paths after the glob is checked, | ||
// before any files are actually read | ||
const ignoreFilePath = options.ignorePath || DEFAULT_IGNORE_FILENAME; | ||
const absoluteIgnoreFilePath = path.isAbsolute(ignoreFilePath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can just be:
const ignoreFilePath = path.resolve(options.ignorePath);
You don't need to explicitly pass process.cwd()
.
bin/prettier.js
Outdated
@@ -42,7 +44,8 @@ const argv = minimist(process.argv.slice(2), { | |||
"cursor-offset", | |||
"range-start", | |||
"range-end", | |||
"stdin-filepath" | |||
"stdin-filepath", | |||
"ignore-path" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add add a default value in the minimist options.
bin/prettier.js
Outdated
@@ -72,6 +75,8 @@ const ignoreNodeModulesGlobs = ["!**/node_modules/**", "!./node_modules/**"]; | |||
const globOptions = { | |||
dot: true | |||
}; | |||
const DEFAULT_IGNORE_FILENAME = ".prettierignore"; | |||
const FILE_NOT_FOUND_ERROR_CODE = "ENOENT"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need a constant for this, just inline the string.
bin/prettier.js
Outdated
@@ -382,6 +409,8 @@ function eachFilename(patterns, callback) { | |||
return; | |||
} | |||
|
|||
filePaths = ignorer.filter(filePaths); | |||
|
|||
filePaths.forEach(filePath => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignorer.filter(filePaths).forEach(filePath => {
...
bin/prettier.js
Outdated
ignoreText = fs.readFileSync(absoluteIgnoreFilePath, "utf8"); | ||
} catch (readError) { | ||
if (readError.code !== FILE_NOT_FOUND_ERROR_CODE) { | ||
throw readError; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably do something like this rather than throwing:
console.error(`Unable to read ${ignoreFilePath}: ${readError.toString()}`);
process.exit(2);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we log the full error so that we get the stack as well? It is often helpful for debugging.
console.error(`Unable to read ${ignoreFilePath}:`, readError);
process.exit(2);
bin/prettier.js
Outdated
} | ||
} | ||
|
||
const ignorer = ignore().add(ignoreText.split(/\r?\n/)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That .split
will create an array [ "" ]
if ignoreText
is ""
.
Might need to do this:
const ignorer = ignore();
if (ignoreText) {
ignorer.add(ignoreText.split(/\r?\n/));
}
bin/prettier.js
Outdated
@@ -382,6 +409,8 @@ function eachFilename(patterns, callback) { | |||
return; | |||
} | |||
|
|||
filePaths = ignorer.filter(filePaths); | |||
|
|||
filePaths.forEach(filePath => { | |||
return callback(filePath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're at cleanup here, return
does nothing in a forEach
loop. This can just be:
ignorer.filter(filePaths).forEach(callback);
5f74f3b
to
17ff3a5
Compare
/cc @azz @levithomason friendly ping |
Configuration file ( Prettier will look for configuration files starting at the file being formatted, and looking up the tree. Should we be doing the same thing for // .prettierrc
{
"ignore": [
"*.min.js"
]
} I know eslint has two files ( Thoughts? |
@azz we should support |
bin/prettier.js
Outdated
], | ||
default: { | ||
color: true | ||
color: true, | ||
"ignore-path": null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, might not have been clear before. This should be "ignore-path": ".prettierignore"
, then you don't need DEFAULT_IGNORE_PATH
.
Ok sounds good. Just one more small change and we can merge this. |
bin/prettier.js
Outdated
@@ -283,6 +288,9 @@ if ( | |||
" --list-different or -l Print filenames of files that are different from Prettier formatting.\n" + | |||
" --config Path to a prettier configuration file (.prettierrc, package.json, prettier.config.js).\n" + | |||
" --resolve-config <path> Resolve the path to a configuration file for a given input file.\n" + | |||
" --ignore-path <path|string> \n" + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why <path|string>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@azz your can use /path/to/.ignored
(path) or .ignored
(string), but we can simplify just use <path>
17ff3a5
to
602d4c3
Compare
@azz done |
@azz: @evilebottnawi doesn't have commit access (yet?) so you need to merge it yourself :) |
@CiGit To support this in |
Thanks @evilebottnawi 🎉 |
@azz I may implement that logic, certainly copy-paste that one. Reading quickly through the code, it seems, unlike gitignore, to only read first encountered file, won't be that tough. I still see some advantage to provide an API (code duplication)
Drawback :
|
It isn't 100% copy-paste, you want to use the ignore()
.add(fs.readFileSync(".prettierignore", "utf8"))
.ignores(currentFilePath); |
|
||
const ignorer = ignore(); | ||
|
||
if (ignoreText.trim()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out we don't need to split the string, you can just ignorer.add(ignoreText)
, @evilebottnawi do you want to open another quick PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@azz according docs we should pass array https://github.com/kaelzhang/node-ignore#usage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to support both: https://github.com/kaelzhang/node-ignore#addignorefilepath
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@azz i.e. just (without check on empty?):
const ignorer = ignore().add(ignoreText);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@azz good point. |
Its bad UX to format something on save that should be formatted. When it is an explicit action (like alt-shift-f) the UX is ok. |
I agree with that. However, why would you ignore a file?
I don't see a use case for prettierignore which would prevent only onSave. |
Add
--ignore-path
argument and support.prettierignore
Issue: #2294