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) {
try {
return createIgnorer(
return createIgnorer.sync(
context.argv["ignore-path"],
context.argv["with-node-modules"]
);

View File

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

View File

@ -3,20 +3,39 @@
const createIgnorer = require("./create-ignorer");
const options = require("../main/options");
/**
* @typedef {{ ignorePath?: string, withNodeModules?: boolean, plugins: object }} FileInfoOptions
* @typedef {{ ignored: boolean, inferredParser: string | null }} FileInfoResult
*/
/**
* @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,
* not an object. A transformation from this array to an object is automatically done
* internally by the method wrapper. See withPlugins() in index.js.
*/
function _getFileInfo(filePath, opts) {
let ignored = false;
const ignorer = createIgnorer(opts.ignorePath, opts.withNodeModules);
ignored = ignorer.ignores(filePath);
function getFileInfo(filePath, opts) {
return createIgnorer(opts.ignorePath, opts.withNodeModules).then(ignorer =>
_getFileInfo(ignorer, filePath, opts.plugins)
);
}
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 {
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;

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;