Skip to content

Implement prettier.getFileInfo() method and --file-info CLI option#4341

Merged
ikatyang merged 4 commits intoprettier:masterfrom
kachkaev:file-info
May 9, 2018
Merged

Implement prettier.getFileInfo() method and --file-info CLI option#4341
ikatyang merged 4 commits intoprettier:masterfrom
kachkaev:file-info

Conversation

@kachkaev
Copy link
Copy Markdown
Member

@kachkaev kachkaev commented Apr 18, 2018

Closes #4253


This PR adds the following prettier method:

const info = prettier.getFileInfo(filepath, opts);
// opts = {
//   ignorePath?: string,
//   withNodeModules?: boolean,
//   plugins: string[]
// }

and a corresponding CLI option:

prettier.js --help file-info
--file-info <path>

  Extract the following info (as JSON) for a given file path. Reported fields:
  * ignored (boolean) - true if file path is filtered by --ignore-path
  * inferredParser (string | null) - name of parser inferred from file path

The new API method is designed to help text editors decide whether a file needs to be formatted on save. A call to it is vital given the introduction of plugins and thus no fixed mapping between file extensions and parsers. A file with the given path does not have to exist for the method to be called.

Usage examples

prettier --file-info README.md

{ "ignored": false, "inferredParser": "markdown" }
  • Expecting to use a markdown parser, according to the file extension
  • No signs of README.md in .prettierignoreignored: false

prettier --file-info README

{ "ignored": false, "inferredParser": "markdown" }
  • Same as above despite the lack of extension, because README is a special case

prettier --file-info src/something.js

{ "ignored": false, "inferredParser": "babylon" }
  • Choosing babylon parser for a js file – usual thing

prettier --file-info src/something.elm

{ "ignored": false, "inferredParser": null }
  • Prettier does not know what to do with .elm files by default, so can't infer a parser

yarn add prettier-plugin-elm
prettier --file-info src/something.elm

{ "ignored": false, "inferredParser": "elm" }
  • Installing a corresponding plugin (prettier-plugin-elm in this case) helps --file-info pick the right parser

prettier --file-info src/something.js --ignore-path .ignoresrc

{ "ignored": true, "inferredParser": "babylon" }
  • Assuming that file .ignoresrc contains src, the result contains ignored: true

prettier --file-info node_modules/module/something.js

{ "ignored": true, "inferredParser": "babylon" }
  • Stuff in node_modules is ignored by default

prettier --file-info node_modules/module/something.js --with-node-modules

{ "ignored": false, "inferredParser": "babylon" }
  • An already existing CLI option --with-node-modules makes the file inside node_modules not ignored
outdated info (changed after further discussion)

prettier --file-info README.md

{ "exists": true, "ignored": false, "inferredParser": "markdown" }
  • Expecting to use a markdown parser, according to the file extension
  • No signs of README.md in .prettierignoreignored: false
  • FIle exists (let's assume so)

prettier --file-info README

{ "exists": false, "ignored": false, "inferredParser": "markdown" }
  • Same as above despite the lack of extension, because README is a special case
  • File does not exist (again, let's assume so)

prettier --file-info src/something.js

{ "exists": true, "ignored": false, "inferredParser": "babylon" }
  • Choosing babylon parser for a js file – usual thing

prettier --file-info src/something.elm

{ "exists": true, "ignored": false, "inferredParser": null }
  • Prettier does not know what to do with .elm files by default, so can't infer a parser

yarn add prettier-plugin-elm
prettier --file-info src/something.elm

{ "exists": true, "ignored": false, "inferredParser": "elm" }
  • Installing a corresponding plugin (prettier-plugin-elm in this case) helps --file-info pick the right parser

prettier --file-info src/something.js --ignore-path .ignoresrc

{ "exists": true, "ignored": true, "inferredParser": "babylon" }
  • Assuming that file .ignoresrc contains src, the result contains ignored: true

prettier --file-info node_modules/module/something.js

{ "exists": false, "ignored": true, "inferredParser": "babylon" }
  • Stuff in node_modules is ignored by default

prettier --file-info node_modules/module/something.js --with-node-modules

{ "exists": false, "ignored": false, "inferredParser": "babylon" }
  • An already existing CLI option --with-node-modules makes the file inside node_modules not ignored
outdated info-2 (changed after further discussion)

prettier --file-info README.md

{ "exists": true, "ignored": false, "inferredParser": "markdown" }
  • Expecting to use a markdown parser, according to the file extension
  • No signs of README.md in .prettierignoreignored: false
  • FIle exists (let's assume so)

prettier --file-info README

{ "exists": false, "ignored": false, "inferredParser": "markdown" }
  • Same as above despite the lack of extension, because README is a special case
  • File does not exist (again, let's assume so)

prettier --file-info src/something.js

{ "exists": true, "ignored": false, "inferredParser": "babylon" }
  • Choosing babylon parser for a js file – usual thing

prettier --file-info src/something.elm

{ "exists": true, "ignored": false, "inferredParser": null }
  • Prettier does not know what to do with .elm files by default, so can't infer a parser

yarn add prettier-plugin-elm
prettier --file-info src/something.elm

{ "exists": true, "ignored": false, "inferredParser": "elm" }
  • Installing a corresponding plugin (prettier-plugin-elm in this case) helps --file-info pick the right parser

prettier --file-info src/something.js --ignore-path .ignoresrc

{ "exists": true, "ignored": true, "inferredParser": "babylon" }
  • Assuming that file .ignoresrc contains src, the result contains ignored: true

prettier --file-info node_modules/module/something.js

{ "exists": false, "ignored": true, "inferredParser": "babylon" }
  • Stuff in node_modules is ignored by default

prettier --file-info node_modules/module/something.js --with-node-modules

{ "exists": false, "ignored": false, "inferredParser": "babylon" }
  • An already existing CLI option --with-node-modules makes the file inside node_modules not ignored

In the simplest scenario, should be enough to just call if (prettier.getFileInfo(filePath).formattable) {...} as @robwise suggests. Additional fields in the output may be useful for ‘forced format on save’, status display in UI and other cases. JSON output also makes this method expandable in future.

Usage examples

prettier --file-info README.md

{
  "formattable": true,
  "ignored": false,
  "parser": "markdown",
  "parserIsFallback": false
}
  • Expecting to use a markdown parser, according to the file extension
  • No signs of README.md in .prettierignoreignored: false
  • Conclusion: the file is formattable

prettier --file-info README

{
  "formattable": false,
  "ignored": false,
  "parser": "markdown",
  "parserIsFallback": false
}
  • Same as above despite the lack of extension, because README is a special case

prettier --file-info src/something.js

{
  "formattable": true,
  "ignored": false,
  "parser": "babylon",
  "parserIsFallback": false
}
  • Choosing babylon parser for a js file – usual thing

prettier --file-info src/something.elm

{
  "formattable": false,
  "ignored": false,
  "parser": "babylon",
  "parserIsFallback": true
}
  • Prettier does not know what to do with .elm files by default, so picks babylon parser as a fallback one
  • When a fallback parser is used, the file is considered as non-formattable (editors should not attempt to format it on save as this will produce an error anyway)

yarn add prettier-plugin-elm
prettier --file-info src/something.elm

{
  "formattable": true,
  "ignored": false,
  "parser": "elm",
  "parserIsFallback": false
}
  • Installing a corresponding plugin (prettier-plugin-elm in this case) helps --file-info pick the right parser and mark the file as formattable

prettier --file-info src/something.js --ignore-path .ignoresrc

{
  "formattable": false,
  "ignored": true,
  "parser": "babylon",
  "parserIsFallback": false
}
  • Assuming that file .ignoresrc contains src, the result contains ignored: true
  • ignored: true implies formattable: false

prettier --file-info node_modules/module/something.js

{
  "formattable": false,
  "ignored": true,
  "parser": "babylon",
  "parserIsFallback": false
}
  • Stuff in node_modules is ignored by default and hence not formattable

prettier --file-info node_modules/module/something.js --with-node-modules

{
  "formattable": true,
  "ignored": false,
  "parser": "babylon",
  "parserIsFallback": false
}
  • An already existing CLI option --with-node-modules makes the file inside node_modules not ignored and thus formattable

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented Apr 18, 2018

🤔 should we also have exists flag in the output? It probably makes sense to claim that a file is formattable only if it exists. Also the logic behind formattable gets a bit too complicated, don't you think?

@j-f1 j-f1 added the status:wip Pull requests that are a work in progress and should not be merged label Apr 18, 2018
@robwise
Copy link
Copy Markdown

robwise commented Apr 19, 2018

should we also have exists flag in the output?

I don't have an opinion on this one way or the other.

Also the logic behind formattable gets a bit too complicated, don't you think?

Well, this logic needs to exist somewhere, right? It's better to do it once in the main repo than reproduced in all of the editor implementations. Or maybe I'm misunderstanding you?

I've looked over each of the scenarios you've documented, everything looks good to me!

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented Apr 19, 2018

Re formattable:

It's better to do it once in the main repo than reproduced in all of the editor implementations. Or maybe I'm misunderstanding you?

After a bit of thinking, I guess that moving this logic to the editor implementation is a better thing. The main reason is that there are two ways of formatting a file:

  • from stdin / text argument + file name as option to determine parser
  • from CLI for a real file with --write

In the first approach, it's OK to set formattable to true when a file does not exist – no harm at all. However, in the second scenario, just checking formattable for a path and then calling prettier --write could throw ENOENT (file does not exist). Now if we add exists flag and only trigger formattable if it's true, the first scenario breaks. So depending on what approach a tool like the Atom Package chooses, formattable will either work or not – it cannot be tuned so that it fits everyone.

What is also a bit confusing is that this flag may look over-promising. Someone may reasonably think that formattable: true may mean that prettier has already looked and the file syntax, successfully parsed it and has some changes to suggest. At least there is a chance that someone might interpret the name of the flag that way and come back with an issue.

I understand that implementing the logic of formattable within prettier-atom makes the if a lot bigger, but on the other hand, it removes some questions and does not lock everyone into a certain opinionated flavour of this flag. With formattable removed and exists: true/false added, the consumers of --file-info will be free to use whatever formatting approach they find best. Both stdin and prettier --write methods will be first-class choices.

New proposal:

{
  "exists": true,
  "ignored": false,
  "parser": "markdown", // can be null after 2.0
  "parserIsFallback": false // to be removed in 2.0
}

Or even (to simplify if today):

{
  "exists": true,
  "ignored": false,
  "inferredParser": "markdown", // can be null even in v1.x
  "parser": "markdown" // or babylon if inferredParser is null
   // parser can be removed in 2.0 as it will be the same as "inferredParser"
}

There is an internal function called inferParser, which already returns null when a fallback parser needs to be used.

Or actually we can even remove parser. 😅 It's inferredParser || "babylon" at all times anyway!

{
  "exists": true,
  "ignored": false,
  "inferredParser": "markdown", // or null, even in v1.x
}

WDYT? Will this make your if simple enough without formattable? Anything I forgot to take into account?

@kachkaev
Copy link
Copy Markdown
Member Author

@robwise I can provide a prebuilt copy of prettier that you can test in prettier/prettier-atom#404. The reason why a prebuilt version is better is because it does not have eval() in plugin-related code, which Atom does not like (details).

Would you like me to change the result of getFileInfo() to the following before that?

{
  "exists": true,
  "ignored": false,
  "inferredParser": "markdown", // or null, even in v1.x
}

@robwise
Copy link
Copy Markdown

robwise commented Apr 23, 2018

@kachkaev What happened to isFormattable? That's the really important part.

As far as eval, I'm already having to use atom/loophole for prettier-eslint so it's not the end of the world if we also start needing to use that for regular prettier.

@robwise
Copy link
Copy Markdown

robwise commented Apr 23, 2018

Oh just saw the previous comment.

In the first approach, it's OK to set formattable to true when a file does not exist – no harm at all. However, in the second scenario, just checking formattable for a path and then calling prettier --write could throw ENOENT (file does not exist). Now if we add exists flag and only trigger formattable if it's true, the first scenario breaks. So depending on what approach a tool like the Atom Package chooses, formattable will either work or not – it cannot be tuned so that it fits everyone.

I'm not sure I understand this one, why would we return formattable: true if the file doesn't exist?

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented Apr 23, 2018

why would we return formattable: true if the file doesn't exist?

@robwise on first ‘format on save’. That is when the file name has already been given, there is some content to prettify, but the file has never been put on disk yet.

I'm still sceptical about adding formattable, details in #4341 (comment).

Apart from formattable existing or not, are you OK with these three options instead of the original ones? I'll update the implementation of so.

{
  "exists": true,
  "ignored": false,
  "inferredParser": "markdown", // or null, even in v1.x
}

The lack of parserIsFallback and the fact that inferredParser can be null, makes calculating formattable on your side less bulky:

if (fileInfo.exists && !fileInfo.ignored && fileInfo.inferredParser) {
  // format
}

or even like this to allow format on save for a file that has not been saved on disk yet:

if (!fileInfo.ignored && fileInfo.inferredParser) {
  // format 
}

IMO that's the way to go – prettier should not decide too much for the editor plugin.

@robwise
Copy link
Copy Markdown

robwise commented Apr 24, 2018

@robwise on first ‘format on save’. That is when the file name has already been given, there is some content to prettify, but the file has never been put on disk yet.

I'm still confused about this point: if the file does not even exist on disk, why would we have Prettier claim it's formattable at that point? How would it know anything about the file at all—at this point, it doesn't exist except as a string of text inside of my editor's text buffer, and Prettier knows nothing about my editor's text buffer?

IMO that's the way to go – prettier should not decide too much for the editor plugin.

Well, agree to disagree, but I can definitely get the job done with what you've shown in your examples (where you demonstrate combining some of the flags), so 👍from me.

Apart from formattable existing or not, are you OK with these three options instead of the original ones? I'll update the implementation of so.

Yeah, the main differences being no formattable and no isFallbackParser? I'm fine with that IIUC.

@kachkaev
Copy link
Copy Markdown
Member Author

@robwise done! I also rebased on top of the latest master and updated the first comment in this PR.

If you'd like to try out getFileInfo() in prettier/prettier-atom#404, feel free to npm install github:kachkaev/prettier#file-info-dist (with -dist in the end). It's a built version of my branch, which matches how prettier looks like on npm.

Waiting to hear your feedback and will proceed to writing tests after that.

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented Apr 24, 2018

if the file does not even exist on disk, why would we have Prettier claim it's formattable at that point?

In atom you would not be able to infer a parser while you don't know the file extension, i.e. until you save for the first time – that's true. But what about other editors? Imagine a hypothetical editor that always has a file path input field on top of a text area and you fill in both before you save for the first time. In this scenario, exists won't matter to derive formattable.

What I really like about having only exists, ignored and inferredParaser is that all these fields are orthogonal (i.e. they cannot be derived from each other). This means that there is no redundancy in the output.

If you're still worried about the size of an if statement in format on save, there's space for a new npm module that would shorten that for you 🙂

const { isFormattable } = require('prettier-file-info');

if (isFormattable(prettier.getFileInfo(filePath))) {
  // format on save
}

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented Apr 24, 2018

@suchipi could you please have a look at this PR? If you're happy with its design and implementation, I'll tick the first checkbox and proceed to writing tests. It'd be also great if we could go through #4192 before 1.13 because that PR is also important for text editors in a context of prettier plugins.

@robwise
Copy link
Copy Markdown

robwise commented Apr 25, 2018

@kachkaev I'm getting an error:

path.js:28
    throw new TypeError('Path must be a string. Received ' + inspect(path));
    ^

TypeError: Path must be a string. Received undefined
    at assertPath (path.js:28:11)
    at Object.resolve (path.js:1188:7)
    at createIgnorer (/Users/rob/github/prettier-atom/node_modules/prettier/index.js:1743:39)
    at Object.getFileInfo (/Users/rob/github/prettier-atom/node_modules/prettier/index.js:24170:19)
    at Object.<anonymous> (/Users/rob/github/prettier-atom/test.js:8:27)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)
// test.js
const prettier = require('prettier')
const path = require('path')

const filePath = path.join(__dirname, 'test.js')
const fileInfo = prettier.getFileInfo(filePath)

console.log('file info:', JSON.stringify(fileInfo, null, 2))

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented Apr 26, 2018

@robwise – sorry for not mentioning what arguments prettier.getFileInfo() expects and so causing this exception on your side. The function has this API:

getFileInfo(
  filePath: string,
  opts: Options,
  ignorePath: string,
  doNotIgnoreNodeModules: boolean
): FileInfo

The reason why you were getting an exception was because you did not pass ignorePath, so an instance of ignorer could not be created.

This worked for me:

const filePath = path.join(__dirname, "test.js");
const ignorePath = path.join(__dirname, ".prettierignore");
const fileInfo = prettier.getFileInfo(filePath, {}, ignorePath);

or just

const fileInfo = prettier.getFileInfo("test.js", {}, '.prettierignore');

(paths are resolved based on cwd)

I'll make all arguments but the first one optional in the next few days, but you are free to test the method even before the changes. Apologies for not sharing this caveat with you – I was only testing the new functionality as the --file-info CLI option and did not think about it. My example two comments above is definitely wrong until I make all arguments but the first one optional.

@robwise
Copy link
Copy Markdown

robwise commented Apr 27, 2018

No worries.

I was curious about the Options (which I'm presuming are the Prettier parsing options) as I assumed that they are irrelevant to just checking file info (no actual formatting is done here)?

I was thinking it might be more something like this, that way you aren't forced to provide an ignorePath in order to specify doNotIgnoreNodeModules:

type getFileInfo = (
  filePath: string, 
  opts?: { configPath?: string, ignorePath?: string, doNotIgnoreNodeModules?: boolean }
) => FileInfo;

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented Apr 27, 2018

Fair point, I’ll check that. I was not sure that mixing the options with two additional parameters is a good thing, but if the same is done in other methods, I’m happy to go for the trick.

Apart from this, do things work for you in general? I’m keen to cover the new feature with tests and remove the PR’s WIP status.

@robwise
Copy link
Copy Markdown

robwise commented Apr 30, 2018

@kachkaev All seems to work so far, now we're able to get rid of that scopes thing entirely :)

@duailibe
Copy link
Copy Markdown
Collaborator

@kachkaev index.js has been significantly changed in master. Can you get the latest from master and update the PR? Thanks!

@kachkaev
Copy link
Copy Markdown
Member Author

@duailibe sure, just give me a few days ;–)

@duailibe
Copy link
Copy Markdown
Collaborator

No hurry!

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 2, 2018

@duailibe the changes have been rebased on top of the latest master.

@robwise thanks to your suggestion and the new internal withPlugins() function, I was able to simplify the API of getFileInfo() It looks like this now:

const fileInfo = getFileInfo({
  filepath: 'path/to/file.js',
  ignorePath: 'path/to/.prettierignore', // optional, '.prettierignore' by default, can be set to false for disabling
  withNodeModules: true,  // optional, assumed false by default
  ...otherPrettierOptions, // optional
});

When getFileInfo() is called from CLI via --file-info, ignorePath is set to .prettierignore by default. I've decided to give this option the same default value in method call for consistency. If the file does not exist in cwd, nothing dramatic happens – an instance of ignorer is still created and this withNodeModules still works. As far as I understand, an exception is only thrown when a file at ignorePath cannot be read due to permission issues.

It's unfortunate that filepath is not camelCase while ignorePath is. This is because Prettier uses filepath everywhere else inside options and it's probably not a good idea to change this. I'm not naming ignorePath ignorepath for consistency with --ignore-path and other variable names throughout the code (filepath is the only exception here).

If everyone is happy with the new design, I'm happy to proceed to tests to remove WIP status from this PR.

@suchipi
Copy link
Copy Markdown
Member

suchipi commented May 2, 2018

@kachkaev sorry it took me so long to look at this, the API looks good to me. I'm not super familiar with the stuff in src/cli/util.js so I defer to you and the other maintainers on that part.

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 2, 2018

@suchipi great to hear that you're OK with the API (hope you looked at the version in my last commit as I forgot to update the first one and only did this now). Could you please cc someone who could look at src/cli/util.js?

@suchipi
Copy link
Copy Markdown
Member

suchipi commented May 2, 2018

Yeah, I looked at your most recent commit.

@ikatyang @azz @duailibe @lydell @j-f1 could one of you take a look at this?

@duailibe duailibe self-assigned this May 2, 2018
@robwise
Copy link
Copy Markdown

robwise commented May 3, 2018

@kachkaev if I don't pass an ignorePath, it's going to look for .prettierignore in the project's root directory, not in the directory of the filepath, right?

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 3, 2018

@robwise I guess it will be $(cwd)/.prettierignore – anything else would require too much changes throughout Prettier. Does it sound good to you?

While running Prettier in the context of a text editor, it’s probably worth setting this to project-dir/.prettierignore, because you know more about the env. Ideally, this file would be mentioned in prettier config, but Prettier does not support this yet.

Copy link
Copy Markdown
Collaborator

@duailibe duailibe left a comment

Choose a reason for hiding this comment

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

Looks good to me.

Last suggestion: isFormattable that returns true if path is not ignored and a parser can be inferred.

ignored,
inferredParser
};
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

My opinions:

  • getFileInfo(filepath, {ignorePath, withNodeModules, plugins})
  • returns {ignored, inferredParser}

Copy link
Copy Markdown
Member Author

@kachkaev kachkaev May 3, 2018

Choose a reason for hiding this comment

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

getFileInfo(filepath, {ignorePath, withNodeModules, plugins})

Looks a bit simpler to use and does not expose different naming styles for filepath and ignorePath – I like this! Will change the API again as you suggest. We can also avoid setting ignorePath when a method is called directly (not via CLI) – that may work a bit more predictably for Prettier API users. The only problem that remains is with plugins – they will not be found automatically unless cwd matches project path (which will be the case for editor plugins). We need #4192 to solve that.

Last suggestion: isFormattable that returns true if path is not ignored and a parser can be inferred

This will bloat the output without adding any new information and may also cause confusion; see #4341 (comment), #4341 (comment) and #4341 (comment)

Copy link
Copy Markdown
Collaborator

@duailibe duailibe May 3, 2018

Choose a reason for hiding this comment

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

Sorry I wasn't clear. I'm suggesting an alternative API to getFileInfo not an additional return value.

What I mean is: most integrations will use this function and use something like:

if (fileinfo.ignored || !fileinfo.parser) return;
// proceed to format

So maybe we could do instead:

if (!prettier.isFileSupported(filepath, someOptions)) return;
// proceed to format

WDYT?

Copy link
Copy Markdown
Member Author

@kachkaev kachkaev May 3, 2018

Choose a reason for hiding this comment

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

What you’re suggesting will work when using format on save. But when a person calls format manually, I can imagine a scenario when .prettierifnore is ignored. I’d let editors decide what to do in this case.

Copy link
Copy Markdown
Member Author

@kachkaev kachkaev May 3, 2018

Choose a reason for hiding this comment

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

Hmm in the second scenario we can just avoid passing .prettierignore as an option and this will do the job. Guess you’re right and I should open a competing PR with your suggestion (isFileSupported()). What would be an appropriate CLI option name in this case? 🤔

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't know if we need separate PRs, they'll probably be very similar, we just need to figure out the API but it's your call!

What would be an appropriate CLI option name in this case?

Now you got me 😂

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 9, 2018

@lipis
Copy link
Copy Markdown
Member

lipis commented May 9, 2018

There was button indeed, to restart only that job. Let's see :) 🕥

@lipis
Copy link
Copy Markdown
Member

lipis commented May 9, 2018

All green!

@lipis lipis removed the status:wip Pull requests that are a work in progress and should not be merged label May 9, 2018
@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 9, 2018

Squashed and rebased on top of the latest master that contains #4192 (had to squash because placing intermediate commits on top of master was creating conflicts). Old commits are still available in branch file-info-before-rebase-03 of my fork (for history).

I'll sortly add a test case for --plugin-search-dir as suggested previously.

@lipis
Copy link
Copy Markdown
Member

lipis commented May 9, 2018

Everything will be squashed anyways.. so no worries about the history! It's mostly for you

Comment thread index.js
@@ -22,6 +23,13 @@ function withPlugins(fn) {
return fn.apply(null, args);
};
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: Empty line between functions :P

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

👍 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Like in the good old days! :)

@kachkaev
Copy link
Copy Markdown
Member Author

kachkaev commented May 9, 2018

All done 🎉 I guess the PR is ready to be merged after someone checks out my last two commits.

@lipis
Copy link
Copy Markdown
Member

lipis commented May 9, 2018

the second to last is OK :P

Comment thread src/common/get-file-info.js Outdated
@@ -0,0 +1,40 @@
"use strict";

const createIgnorer = require("../common/create-ignorer");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

const createIgnorer = require("./create-ignorer");

Comment thread src/cli/constant.js Outdated
},
"file-info": {
type: "path",
category: coreOptions.CATEGORY_CONFIG,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It should be same as support-info, i.e. using default category.

}

// the method has been implemented as asynchronous to avoid possible breaking changes in future
function getFileInfo(filePath, opts) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This async method looks just like

(...args) => Promise.resolve(_getFileInfo(...args))

We need to use createIgnorer/createIgnorer.sync if we'd like to make it really async.

Copy link
Copy Markdown
Member Author

@kachkaev kachkaev May 9, 2018

Choose a reason for hiding this comment

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

Would not ...args fail in Node 4? I'm not sure it supports args spreading.

I agree that having createIgnorer./createIgnorer.sync would be useful, but does this have to be done now? The async interface for getFileInfo is mainly a placeholder for keeping things future-proof 🤔

I'll address other issues now. Well spotted! 👀

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's just a quick demo, not meant to be used in node 4. 😂

does this have to be done now?

Yeah, it can be another PR, just a reminder.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Changing the function to the following does not work:

function getFileInfo(filePath, opts) {
  return Promise.resolve(_getFileInfo(filePath, opts));
}

It throws rather than rejects, because _getFileInfo() is sync.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Opened #4452 to track this issue.

@ikatyang ikatyang merged commit cc73475 into prettier:master May 9, 2018
} catch (e) {
reject(e);
}
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This could just be Promise.resolve().then(() => _getFileInfo(filePath, options)).

Copy link
Copy Markdown
Member Author

@kachkaev kachkaev May 9, 2018

Choose a reason for hiding this comment

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

I'm happy to include this to #4451, which has a couple of other minor enhancements. See commit log.

@duailibe duailibe mentioned this pull request May 9, 2018
@kachkaev kachkaev mentioned this pull request May 9, 2018
azz pushed a commit that referenced this pull request May 10, 2018
* Fix plugin resolution when path does not start with ./

* Minor consistency fix: use "if (resolvedPluginSearchDir) {...}" in load-plugins

* Use more appropriate quotes in plugin-resolution.js

* Try both local paths and node modules when resolving plugins manually

* Test bespoke plugin loading by node module name

* Simplify getFileInfo() as suggested by @j-f1

#4341 (comment)
@robwise
Copy link
Copy Markdown

robwise commented Jun 6, 2018

@kachkaev Why was this made async?

@duailibe
Copy link
Copy Markdown
Collaborator

duailibe commented Jun 6, 2018

@robwise There's a sync and an async method.

@robwise
Copy link
Copy Markdown

robwise commented Jun 11, 2018

@duailibe ah excellent, that makes things much easier!

@lock lock Bot added the locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting. label Sep 9, 2018
@lock lock Bot locked as resolved and limited conversation to collaborators Sep 9, 2018
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.

Feature request: prettier.getFileInfo(path) API and CLI option

7 participants