10000 CLI: Support .ignore files by alexander-akait · Pull Request #2412 · prettier/prettier · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
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

Merged
merged 1 commit into from
8000 Jul 11, 2017
Merged

CLI: Support .ignore files #2412

merged 1 commit into from
Jul 11, 2017

Conversation

alexander-akait
Copy link
Member

Add --ignore-path argument and support .prettierignore

Issue: #2294

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" +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stylelint → Prettier

Copy link
Member Author

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 😄

@vjeux
Copy link
Contributor
vjeux commented Jul 6, 2017

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:

  • Options
  • Files to run it on
  • Files to ignore

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!

@vjeux
Copy link
Contributor
vjeux commented Jul 6, 2017

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?

@alexander-akait
Copy link
Member Author

@vjeux

Options

Be good implement .prettierrc (and other formats, using cosmiconfig), but we can implement this late.

Files to run it on

I did not quite understand what your mean. If your mean which files we can handle, multiple patterns are enough for most use case.

Files to ignore

Do this as eslint and stylelint, support multiple patterns (already done) and --ignore-path.
Option --ignore-path only for file, like .eslintignore and .stylelintignore (.gitignore stylistics), no JavaScript or JSON, only plain text.

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 support this in the CommonJS version of the API, move some CLI logic to prettier (config, glob, ignore) inside run function (maybe best name).

But we can do this in other PR. We already support multiple pattern, here we can add --ignore-path and then support configuration using .prettierrc, then move this logic into prettier api.

@CiGit
Copy link
Member
CiGit commented Jul 6, 2017

As an API consumer (prettier-vscode), I would be grateful if the CommonJS would be on par with the cli.
It would allow a more uniform integration between those editor plugins and the cli.

If it isn't resolved through the API for whatever reason, it would be great to have API calls like
prettier.getConfig(filePath): PrettierOption
prettier.isIgnored(filePath): boolean
I won't have to duplicate prettier's code :-) And certainly other API consumers.

@alexander-akait
Copy link
Member Author
alexander-akait commented Jul 7, 2017

/cc @vjeux what do your think about this:

  1. Merge this PR.
  2. Implement configuration support .prettierignore for CLI.
  3. Move logic from CLI to prettier.run?

Seems step by step allow implement this without big difficult PR and easy review?

@vjeux
Copy link
Contributor
vjeux commented Jul 7, 2017

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.

@alexander-akait
Copy link
Member Author

@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 😄

@vjeux
Copy link
Contributor
vjeux commented Jul 7, 2017

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!

@azz azz changed the title feat(cli): allow to specify ignored files using ignore file CLI: Support .ignore files Jul 10, 2017
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" +
Copy link
Member

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)
Copy link
Member

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"
Copy link
Member

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";
Copy link
Member

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 => {
Copy link
Member

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;
Copy link
Member
@azz azz Jul 10, 2017

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);

Copy link
Contributor

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/));
Copy link
Member

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);
Copy link
Contributor

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);

@alexander-akait alexander-akait force-pushed the issue-2294 branch 3 times, most recently from 5f74f3b to 17ff3a5 Compare July 11, 2017 11:33
@alexander-akait
Copy link
Member Author

/cc @azz @levithomason friendly ping

@azz
Copy link
Member
azz commented Jul 11, 2017

Configuration file (.prettierrc) format was recently merged (#2434).

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 .prettierignore? Maybe we can even re-use the configuration file for ignoring files, too:

// .prettierrc
{
  "ignore": [
    "*.min.js"
  ]
}

I know eslint has two files (.eslintrc and .eslintignore), but eslint config files can be much more complex than a .prettierrc.

Thoughts?

@alexander-akait
Copy link
Member Author

@azz we should support .prettierignore (and allow customize this value). Why? In many project i have .gitignore where put all files which i want to ignore, i use --ignore-path .gitignore for eslint, stylelint and other linters. If we don't support customize --ignore-path, I will have to duplicate all ignored files in the .prettierrc and .gitignore. It will be extremely inconvenient (sometimes it is many many files).

bin/prettier.js Outdated
],
default: {
color: true
color: true,
"ignore-path": null
Copy link
Member

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.

@azz
Copy link
Member
azz commented Jul 11, 2017

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" +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why <path|string>?

Copy link
Member Author

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>

@alexander-akait
Copy link
Member Author

@azz done

@vjeux
Copy link
Contributor
vjeux commented Jul 11, 2017

@azz: @evilebottnawi doesn't have commit access (yet?) so you need to merge it yourself :)

@azz
Copy link
Member
azz commented Jul 11, 2017

@CiGit To support this in prettier-vscode (for format-on-save), would you end up just reading the .prettierignore file yourself, or does it make sense to expose an API function for this (I doubt it)?

@azz azz merged commit 469059d into prettier:master Jul 11, 2017
@azz
Copy link
Member
azz commented Jul 11, 2017

Thanks @evilebottnawi 🎉

@alexander-akait alexander-akait deleted the issue-2294 branch July 11, 2017 13:36
@CiGit
Copy link
Member
CiGit commented Jul 11, 2017

@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)

  • Avoid copy-paste for all tooling based on prettier.
  • If the resolution algorithm changes, no need to copy-paste again.

Drawback :

  • An other exposed API.
  • Other ?

@azz
Copy link
Member
azz commented Jul 11, 2017

It isn't 100% copy-paste, you want to use the .ignores() function instead of .filter().

ignore()
  .add(fs.readFileSync(".prettierignore", "utf8"))
  .ignores(currentFilePath);


const ignorer = ignore();

if (ignoreText.trim()) {
Copy link
Member

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?

Copy link
Member Author

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author
@alexander-akait alexander-akait Jul 11, 2017

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);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah.

CEB7

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@azz done in #2455

@CiGit
Copy link
Member
CiGit commented Jul 11, 2017

@azz good point.
I still don't get why most people emphasis on ignoring for formatOnSave. Why not always?

@azz
Copy link
Member
azz commented Jul 11, 2017

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.

@CiGit
Copy link
Member
CiGit commented Jul 11, 2017

I agree with that. However, why would you ignore a file?

  • Don't use prettier on it. In which case preventing it's formatting is ok to me, preventing mistakes.
  • Don't waste time with the cli on files I don't care. IMO can be formatted on save in this case.

I don't see a use case for prettierignore which would prevent only onSave.
Disclaimer: I'm NOT an UX engineer.

@lock lock bot added the locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting. label Jan 19, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jan 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants
0