textlint
Version:
The pluggable linting tool for natural language.
140 lines • 4.75 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanFilePath = exports.searchFiles = void 0;
exports.pathsToGlobPatterns = pathsToGlobPatterns;
const promises_1 = __importDefault(require("node:fs/promises"));
const debug_1 = __importDefault(require("debug"));
const node_path_1 = __importDefault(require("node:path"));
const glob_1 = require("glob");
const path_to_glob_pattern_1 = require("path-to-glob-pattern");
const debug = (0, debug_1.default)("textlint:find-util");
const DEFAULT_IGNORE_PATTERNS = ["**/.git/**", "**/node_modules/**"];
/**
* Convert file paths to glob patterns
* @param patterns file paths or patterns
* @param options
*/
function pathsToGlobPatterns(patterns, options = {}) {
const processPatterns = (0, path_to_glob_pattern_1.pathToGlobPattern)({
extensions: options.extensions || [],
cwd: options.cwd || process.cwd()
});
return patterns.map(processPatterns);
}
const createIgnorePatterns = async (cwd, ignoreFilePath) => {
try {
const normalizeIgnoreFilePath = node_path_1.default.resolve(cwd, ignoreFilePath);
const ignoreFileContent = await promises_1.default.readFile(normalizeIgnoreFilePath, "utf-8");
return ignoreFileContent.split(/\r?\n/).filter((line) => !/^\s*$/.test(line) && !/^\s*#/.test(line));
}
catch (error) {
// If ignore file doesn't exist, return empty array (for default .textlintignore behavior)
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
debug("ignore file not found: %s", ignoreFilePath);
return [];
}
throw new Error(`Failed to read ignore file: ${ignoreFilePath}`, {
cause: error
});
}
};
/**
* globby wrapper that support ignore options
* @param patterns
* @param options
*/
const searchFiles = async (patterns, options) => {
var _a;
const cwd = (_a = options.cwd) !== null && _a !== void 0 ? _a : process.cwd();
const ignoredPatterns = [...DEFAULT_IGNORE_PATTERNS];
// Only add ignore patterns if ignoreFilePath is explicitly provided
if (options.ignoreFilePath) {
const ignorePatterns = await createIgnorePatterns(cwd, options.ignoreFilePath);
ignoredPatterns.push(...ignorePatterns);
}
debug("search patterns: %o", patterns);
debug("search ignore patterns: %o", ignoredPatterns);
// Glob support file path, we can pass file path directly
// https://github.com/azu/node-glob-example
// TODO: add pathsToGlobPatterns here
const files = await (0, glob_1.glob)(patterns, {
cwd,
absolute: true,
nodir: true,
dot: true,
ignore: ignoredPatterns
});
debug("found files: %o", files);
if (files.length > 0) {
return {
ok: true,
items: files
};
}
// If ignore file is matched and result is empty, it should be ignored
const filesWithoutIgnoreFiles = await (0, glob_1.glob)(patterns, {
cwd,
absolute: true,
nodir: true,
dot: true
// no ignore
});
const isEmptyResultByIgnoreFile = files.length === 0 && filesWithoutIgnoreFiles.length !== 0;
if (isEmptyResultByIgnoreFile) {
debug("all files are ignored by ignore files. ignored files: %o", filesWithoutIgnoreFiles);
return {
ok: true,
items: []
};
}
// Not found target file
debug("Not found target file");
return {
ok: false,
errors: [
{
type: "SearchFilesNoTargetFileError"
}
]
};
};
exports.searchFiles = searchFiles;
/**
* Scan file path and return the file is target or not
* @param filePath
* @param options
*/
const scanFilePath = async (filePath, options) => {
const exists = await promises_1.default.stat(filePath).catch(() => null);
if (!exists) {
return {
status: "error",
errors: [
{
type: "ScanFilePathNoExistFilePathError",
filePath
}
]
};
}
const searchResult = await (0, exports.searchFiles)([filePath], options);
if (!searchResult.ok) {
return {
status: "error",
errors: searchResult.errors
};
}
if (searchResult.items.length === 0) {
return {
status: "ignored"
};
}
return {
status: "ok"
};
};
exports.scanFilePath = scanFilePath;
//# sourceMappingURL=find-util.js.map
;