Use search-closest to search Prettier config and Project root (#17412)
This commit is contained in:
1 parent
3640a4e70f
commit
eaeb1e7c04
9 files changed
+61
-150
No files matched your search
@@ -53,6 +53,10 @@
|
||||
groupName: "Regex related dependencies",
|
||||
matchPackageNames: ["regexp-util", "unicode-regex", "cjk-regex"],
|
||||
},
|
||||
{
|
||||
groupName: "Config search related dependencies",
|
||||
matchPackageNames: ["url-or-path", "search-closest"],
|
||||
},
|
||||
{
|
||||
branchPrefix: "renovate/website/",
|
||||
matchFileNames: ["website/package.json"],
|
||||
|
||||
+2
-2
@@ -69,7 +69,6 @@
|
||||
"ignore": "7.0.3",
|
||||
"import-meta-resolve": "4.1.0",
|
||||
"is-es5-identifier-name": "1.0.0",
|
||||
"iterate-directory-up": "1.1.1",
|
||||
"jest-docblock": "30.0.0-alpha.7",
|
||||
"js-yaml": "4.1.0",
|
||||
"json5": "2.2.3",
|
||||
@@ -94,6 +93,7 @@
|
||||
"remark-math": "3.0.1",
|
||||
"remark-parse": "8.0.3",
|
||||
"sdbm": "2.0.0",
|
||||
"search-closest": "0.1.1",
|
||||
"smol-toml": "1.3.4",
|
||||
"strip-ansi": "7.1.0",
|
||||
"to-fast-properties": "4.0.0",
|
||||
@@ -101,7 +101,7 @@
|
||||
"typescript": "5.8.3",
|
||||
"unicode-regex": "4.1.2",
|
||||
"unified": "9.2.2",
|
||||
"url-or-path": "2.3.2",
|
||||
"url-or-path": "2.6.1",
|
||||
"vnopts": "2.0.2",
|
||||
"wcwidth.js": "2.0.0",
|
||||
"yaml-unist-parser": "2.0.5"
|
||||
|
||||
@@ -2,16 +2,12 @@
|
||||
// https://github.com/kirstein/find-project-root/blob/master/index.js
|
||||
|
||||
import * as path from "node:path";
|
||||
import isDirectory from "../utils/is-directory.js";
|
||||
import Searcher from "./searcher.js";
|
||||
import { DirectorySearcher } from "search-closest";
|
||||
|
||||
const MARKERS = [".git", ".hg"];
|
||||
const DIRECTORIES = [".git", ".hg"];
|
||||
|
||||
/** @type {DirectorySearcher} */
|
||||
let searcher;
|
||||
const searchOptions = {
|
||||
names: MARKERS,
|
||||
filter: ({ path: directory }) =>
|
||||
isDirectory(directory, { allowSymlinks: false }),
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the directory contains a version control system directory
|
||||
@@ -20,10 +16,12 @@ const searchOptions = {
|
||||
* @returns {Promise<string | undefined>}
|
||||
*/
|
||||
async function findProjectRoot(startDirectory, options) {
|
||||
searcher ??= new Searcher(searchOptions);
|
||||
const mark = await searcher.search(startDirectory, options);
|
||||
searcher ??= new DirectorySearcher(DIRECTORIES, { allowSymlinks: false });
|
||||
const directory = await searcher.search(startDirectory, {
|
||||
cache: options.shouldCache,
|
||||
});
|
||||
|
||||
return mark ? path.dirname(mark) : undefined;
|
||||
return directory ? path.dirname(directory) : undefined;
|
||||
}
|
||||
|
||||
function clearFindProjectRootCache() {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import isFile from "../../utils/is-file.js";
|
||||
import Searcher from "../searcher.js";
|
||||
import { FileSearcher } from "search-closest";
|
||||
import {
|
||||
loadConfigFromPackageJson,
|
||||
loadConfigFromPackageYaml,
|
||||
} from "./loaders.js";
|
||||
|
||||
/**
|
||||
@import {SearcherOptions} from 'search-closest'
|
||||
*/
|
||||
|
||||
const CONFIG_FILE_NAMES = [
|
||||
"package.json",
|
||||
"package.yaml",
|
||||
@@ -28,11 +31,8 @@ const CONFIG_FILE_NAMES = [
|
||||
".prettierrc.toml",
|
||||
];
|
||||
|
||||
/** @type {SearcherOptions["filter"]} */
|
||||
async function filter({ name, path: file }) {
|
||||
if (!(await isFile(file))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name === "package.json") {
|
||||
try {
|
||||
return Boolean(await loadConfigFromPackageJson(file));
|
||||
@@ -53,7 +53,7 @@ async function filter({ name, path: file }) {
|
||||
}
|
||||
|
||||
function getSearcher(stopDirectory) {
|
||||
return new Searcher({ names: CONFIG_FILE_NAMES, filter, stopDirectory });
|
||||
return new FileSearcher(CONFIG_FILE_NAMES, { filter, stopDirectory });
|
||||
}
|
||||
|
||||
export default getSearcher;
|
||||
@@ -3,6 +3,10 @@ import mockable from "../../common/mockable.js";
|
||||
import getConfigSearcher from "./config-searcher.js";
|
||||
import loadConfig from "./load-config.js";
|
||||
|
||||
/**
|
||||
@import {FileSearcher} from 'search-closest'
|
||||
*/
|
||||
|
||||
const loadCache = new Map();
|
||||
const searchCache = new Map();
|
||||
function clearPrettierConfigCache() {
|
||||
@@ -27,8 +31,9 @@ function loadPrettierConfig(configFile, { shouldCache }) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} stopDirectory
|
||||
*/
|
||||
@param {string} stopDirectory
|
||||
@returns {FileSearcher["search"]}
|
||||
*/
|
||||
function getSearchFunction(stopDirectory) {
|
||||
stopDirectory = stopDirectory ? path.resolve(stopDirectory) : undefined;
|
||||
|
||||
@@ -44,7 +49,7 @@ function getSearchFunction(stopDirectory) {
|
||||
/**
|
||||
* @param {string} startDirectory
|
||||
* @param {{shouldCache?: boolean}} options
|
||||
* @returns {Promise<string>}
|
||||
* @returns {Promise<string | void>}
|
||||
*/
|
||||
function searchPrettierConfig(startDirectory, options = {}) {
|
||||
startDirectory = startDirectory
|
||||
@@ -55,7 +60,7 @@ function searchPrettierConfig(startDirectory, options = {}) {
|
||||
|
||||
const search = getSearchFunction(stopDirectory);
|
||||
|
||||
return search(startDirectory, { shouldCache: options.shouldCache });
|
||||
return search(startDirectory, { cache: options.shouldCache });
|
||||
}
|
||||
|
||||
export { clearPrettierConfigCache, loadPrettierConfig, searchPrettierConfig };
|
||||
@@ -1,71 +0,0 @@
|
||||
import path from "node:path";
|
||||
import iterateDirectoryUp from "iterate-directory-up";
|
||||
|
||||
class Searcher {
|
||||
#names;
|
||||
#filter;
|
||||
#stopDirectory;
|
||||
#cache = new Map();
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* names: string[],
|
||||
* filter: (fileOrDirectory: {name: string, path: string}) => Promise<boolean>,
|
||||
* stopDirectory?: string,
|
||||
* }} param0
|
||||
*/
|
||||
constructor({ names, filter, stopDirectory }) {
|
||||
this.#names = names;
|
||||
this.#filter = filter;
|
||||
this.#stopDirectory = stopDirectory;
|
||||
}
|
||||
|
||||
async #searchInDirectory(directory, shouldCache) {
|
||||
const cache = this.#cache;
|
||||
if (shouldCache && cache.has(directory)) {
|
||||
return cache.get(directory);
|
||||
}
|
||||
|
||||
for (const name of this.#names) {
|
||||
const fileOrDirectory = path.join(directory, name);
|
||||
|
||||
if (await this.#filter({ name, path: fileOrDirectory })) {
|
||||
return fileOrDirectory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async search(startDirectory, { shouldCache }) {
|
||||
const cache = this.#cache;
|
||||
if (shouldCache && cache.has(startDirectory)) {
|
||||
return cache.get(startDirectory);
|
||||
}
|
||||
|
||||
const searchedDirectories = [];
|
||||
let result;
|
||||
for (const directory of iterateDirectoryUp(
|
||||
startDirectory,
|
||||
this.#stopDirectory,
|
||||
)) {
|
||||
searchedDirectories.push(directory);
|
||||
result = await this.#searchInDirectory(directory, shouldCache);
|
||||
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Always cache the result, so we can use it when `useCache` is set to true
|
||||
for (const directory of searchedDirectories) {
|
||||
cache.set(directory, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
this.#cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export default Searcher;
|
||||
@@ -1,22 +0,0 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { toPath } from "url-or-path";
|
||||
|
||||
/**
|
||||
* @param {string | URL} directory
|
||||
* @param {{allowSymlinks: boolean}} [options]
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function isDirectory(directory, options) {
|
||||
const allowSymlinks = options?.allowSymlinks ?? true;
|
||||
|
||||
let stats;
|
||||
try {
|
||||
stats = await (allowSymlinks ? fs.stat : fs.lstat)(toPath(directory));
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
return stats.isDirectory();
|
||||
}
|
||||
|
||||
export default isDirectory;
|
||||
@@ -1,22 +0,0 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { toPath } from "url-or-path";
|
||||
|
||||
/**
|
||||
* @param {string | URL} file
|
||||
* @param {{allowSymlinks: boolean}} [options]
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function isFile(file, options) {
|
||||
const allowSymlinks = options?.allowSymlinks ?? true;
|
||||
|
||||
let stats;
|
||||
try {
|
||||
stats = await (allowSymlinks ? fs.stat : fs.lstat)(toPath(file));
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
return stats.isFile();
|
||||
}
|
||||
|
||||
export default isFile;
|
||||
@@ -4365,6 +4365,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"find-in-directory@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "find-in-directory@npm:2.0.1"
|
||||
dependencies:
|
||||
url-or-path: "npm:2.6.1"
|
||||
checksum: 10/1a02fdec539ff4c4d63d0e296d853bf88a633a882bc82fba8addc24fb08de799eaa2f05c4721e3954a23dddeb8301cc994dd509b58b5cac34d90a95a43e6a5ea
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"find-up-json@npm:^2.0.4, find-up-json@npm:^2.0.5":
|
||||
version: 2.0.5
|
||||
resolution: "find-up-json@npm:2.0.5"
|
||||
@@ -5213,12 +5222,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"iterate-directory-up@npm:1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "iterate-directory-up@npm:1.1.1"
|
||||
"iterate-directory-up@npm:^1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "iterate-directory-up@npm:1.2.1"
|
||||
dependencies:
|
||||
url-or-path: "npm:^2.3.0"
|
||||
checksum: 10/b724f63d1035a453b974d15dd9f809a0862131aa38cfe2960b0f388ee8100e42404f8fb8b52c46c82dc2c263c3ca9b30ba8716216ab9ae78cb9142d85110d706
|
||||
url-or-path: "npm:^2.6.1"
|
||||
checksum: 10/35846f8df1d31b6e37eef19cd7c4a7b3c4cbacbbdf80e1b7b1eb2f75ec7a611039da895592328a55885ace3f06def73015402d55409d0aec9e959fd4cb0d6b7e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7035,7 +7044,6 @@ __metadata:
|
||||
import-meta-resolve: "npm:4.1.0"
|
||||
index-to-position: "npm:1.1.0"
|
||||
is-es5-identifier-name: "npm:1.0.0"
|
||||
iterate-directory-up: "npm:1.1.1"
|
||||
jest: "npm:30.0.0-alpha.7"
|
||||
jest-docblock: "npm:30.0.0-alpha.7"
|
||||
jest-light-runner: "npm:0.7.8"
|
||||
@@ -7073,6 +7081,7 @@ __metadata:
|
||||
remark-parse: "npm:8.0.3"
|
||||
rollup-plugin-license: "npm:3.6.0"
|
||||
sdbm: "npm:2.0.0"
|
||||
search-closest: "npm:0.1.1"
|
||||
semver: "npm:7.7.1"
|
||||
serialize-javascript: "npm:6.0.2"
|
||||
smol-toml: "npm:1.3.4"
|
||||
@@ -7086,7 +7095,7 @@ __metadata:
|
||||
typescript: "npm:5.8.3"
|
||||
unicode-regex: "npm:4.1.2"
|
||||
unified: "npm:9.2.2"
|
||||
url-or-path: "npm:2.3.2"
|
||||
url-or-path: "npm:2.6.1"
|
||||
vnopts: "npm:2.0.2"
|
||||
wcwidth.js: "npm:2.0.0"
|
||||
yaml-unist-parser: "npm:2.0.5"
|
||||
@@ -7475,6 +7484,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"search-closest@npm:0.1.1":
|
||||
version: 0.1.1
|
||||
resolution: "search-closest@npm:0.1.1"
|
||||
dependencies:
|
||||
find-in-directory: "npm:^2.0.1"
|
||||
iterate-directory-up: "npm:^1.2.1"
|
||||
checksum: 10/5285c2d5e7e5d7ffbb2aa0bf2fd37acd19dff58c3975889125f2a92e9a0c17adea10484c43f1ae67ccf03896f891e7721b54211fea777164ac90b26dde7c93ff
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver-compare@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "semver-compare@npm:1.0.0"
|
||||
@@ -8468,10 +8487,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"url-or-path@npm:2.3.2, url-or-path@npm:^2.3.0":
|
||||
version: 2.3.2
|
||||
resolution: "url-or-path@npm:2.3.2"
|
||||
checksum: 10/9078f06d5754293464332da3f98eddd9878dc6a2b4ece5303f72e6a5fa72c3d25a3c33f01bd097bf54cccd29e61283fec38432c928894c032630a04867ceaf81
|
||||
"url-or-path@npm:2.6.1, url-or-path@npm:^2.3.0, url-or-path@npm:^2.6.1":
|
||||
version: 2.6.1
|
||||
resolution: "url-or-path@npm:2.6.1"
|
||||
checksum: 10/707d340bc72dbaccfaa0a371f8e70816518141ecbfdebddc4d6faf8e5e5afa6f33cb01e4e5701c0e76dc661bd699e00041c3b00f1a3e2fb7a0c4e144c9dd6ace
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in new issue
Block a user