feat(api): make `getFileInfo()` really async (#4640)

master
Ika 2018-06-07 00:34:02 +08:00 committed by GitHub
parent 8ec5432768
commit fb74dc54c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 92 additions and 29 deletions

View File

@ -330,7 +330,7 @@ function formatStdin(context) {
function createIgnorerFromContextOrDie(context) { function createIgnorerFromContextOrDie(context) {
try { try {
return createIgnorer( return createIgnorer.sync(
context.argv["ignore-path"], context.argv["ignore-path"],
context.argv["with-node-modules"] context.argv["with-node-modules"]
); );

View File

@ -1,26 +1,37 @@
"use strict"; "use strict";
const ignore = require("ignore"); const ignore = require("ignore");
const fs = require("fs");
const path = require("path"); const path = require("path");
const getFileContentOrNull = require("../utils/get-file-content-or-null");
/**
* @param {undefined | string} ignorePath
* @param {undefined | boolean} withNodeModules
*/
function createIgnorer(ignorePath, withNodeModules) { function createIgnorer(ignorePath, withNodeModules) {
let ignoreText = ""; return (!ignorePath
? Promise.resolve(null)
: getFileContentOrNull(path.resolve(ignorePath))
).then(ignoreContent => _createIgnorer(ignoreContent, withNodeModules));
}
if (ignorePath) { /**
const resolvedIgnorePath = path.resolve(ignorePath); * @param {undefined | string} ignorePath
try { * @param {undefined | boolean} withNodeModules
ignoreText = fs.readFileSync(resolvedIgnorePath, "utf8"); */
} catch (readError) { createIgnorer.sync = function(ignorePath, withNodeModules) {
if (readError.code !== "ENOENT") { const ignoreContent = !ignorePath
throw new Error( ? null
`Unable to read ${resolvedIgnorePath}: ${readError.message}` : getFileContentOrNull.sync(path.resolve(ignorePath));
); return _createIgnorer(ignoreContent, withNodeModules);
} };
}
}
const ignorer = ignore().add(ignoreText); /**
* @param {null | string} ignoreContent
* @param {undefined | boolean} withNodeModules
*/
function _createIgnorer(ignoreContent, withNodeModules) {
const ignorer = ignore().add(ignoreContent || "");
if (!withNodeModules) { if (!withNodeModules) {
ignorer.add("node_modules"); ignorer.add("node_modules");
} }

View File

@ -3,20 +3,39 @@
const createIgnorer = require("./create-ignorer"); const createIgnorer = require("./create-ignorer");
const options = require("../main/options"); const options = require("../main/options");
/**
* @typedef {{ ignorePath?: string, withNodeModules?: boolean, plugins: object }} FileInfoOptions
* @typedef {{ ignored: boolean, inferredParser: string | null }} FileInfoResult
*/
/** /**
* @param {string} filePath * @param {string} filePath
* @param {{ ignorePath?: string, withNodeModules?: boolean, plugins: object }} opts * @param {FileInfoOptions} opts
* @returns {Promise<FileInfoResult>}
* *
* Please note that prettier.getFileInfo() expects opts.plugins to be an array of paths, * Please note that prettier.getFileInfo() expects opts.plugins to be an array of paths,
* not an object. A transformation from this array to an object is automatically done * not an object. A transformation from this array to an object is automatically done
* internally by the method wrapper. See withPlugins() in index.js. * internally by the method wrapper. See withPlugins() in index.js.
*/ */
function _getFileInfo(filePath, opts) { function getFileInfo(filePath, opts) {
let ignored = false; return createIgnorer(opts.ignorePath, opts.withNodeModules).then(ignorer =>
const ignorer = createIgnorer(opts.ignorePath, opts.withNodeModules); _getFileInfo(ignorer, filePath, opts.plugins)
ignored = ignorer.ignores(filePath); );
}
const inferredParser = options.inferParser(filePath, opts.plugins) || null; /**
* @param {string} filePath
* @param {FileInfoOptions} opts
* @returns {FileInfoResult}
*/
getFileInfo.sync = function(filePath, opts) {
const ignorer = createIgnorer.sync(opts.ignorePath, opts.withNodeModules);
return _getFileInfo(ignorer, filePath, opts.plugins);
};
function _getFileInfo(ignorer, filePath, plugins) {
const ignored = ignorer.ignores(filePath);
const inferredParser = options.inferParser(filePath, plugins) || null;
return { return {
ignored, ignored,
@ -24,11 +43,4 @@ function _getFileInfo(filePath, opts) {
}; };
} }
// the method has been implemented as asynchronous to avoid possible breaking changes in future
function getFileInfo(filePath, opts) {
return Promise.resolve().then(() => _getFileInfo(filePath, opts));
}
getFileInfo.sync = _getFileInfo;
module.exports = getFileInfo; module.exports = getFileInfo;

View File

@ -0,0 +1,40 @@
"use strict";
const fs = require("fs");
/**
* @param {string} filename
* @returns {Promise<null | string>}
*/
function getFileContentOrNull(filename) {
return new Promise((resolve, reject) => {
fs.readFile(filename, "utf8", (error, data) => {
if (error && error.code !== "ENOENT") {
reject(createError(filename, error));
} else {
resolve(error ? null : data);
}
});
});
}
/**
* @param {string} filename
* @returns {null | string}
*/
getFileContentOrNull.sync = function(filename) {
try {
return fs.readFileSync(filename, "utf8");
} catch (error) {
if (error && error.code === "ENOENT") {
return null;
}
throw createError(filename, error);
}
};
function createError(filename, error) {
return new Error(`Unable to read ${filename}: ${error.message}`);
}
module.exports = getFileContentOrNull;