From 2630249bc4599220170c006e9da5f9b880996530 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:54:40 +0100 Subject: [PATCH] chore(deps): update dependency globby to v16 (#1201) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: FabianLars --- README.md | 3 +- action.yml | 2 +- dist/index.js | 1059 ++++++++++++++++++++++++++++++++++++++---------- package.json | 2 +- pnpm-lock.yaml | 56 +-- src/utils.ts | 1 + 6 files changed, 875 insertions(+), 248 deletions(-) diff --git a/README.md b/README.md index 36c29ae..74e25a5 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ These inputs allow you to change how your Tauri project will be build. | Name | Description | Type | Default | | ----------------------- | ------------------------------------------------------------------------------------------------------------------ | ------ | ------------------------------------------------------------------------------ | -| `projectPath` | The path to the root of the tauri project relative to the current working directory | string | . | +| `projectPath` | The path to the root of the tauri project relative to the current working directory. It must NOT be gitignored. | string | . | | `includeUpdaterJson` | whether to upload a JSON file for the updater or not (only relevant if the updater is configured) | bool | true | | `updaterJsonPreferNsis` | whether the action will use the NSIS (setup.exe) or WiX (.msi) bundles for the updater JSON if both types exist | bool | `false`. May be changed to `true` for projects using `tauri@v2` in the future. | | `tauriScript` | the script to execute the Tauri CLI. It must not include any args or commands like `build` | string | `npm run\|pnpm\|yarn tauri` | @@ -133,6 +133,7 @@ These inputs allow you to modify the GitHub release. - When your Tauri app is not in the root of the repo, use the `projectPath` input. - Usually it will work without it, but the action will install and use a global `@tauri-apps/cli` installation instead of your project's CLI which can cause issues if you also configured `tauriScript` or if you have multiple `tauri.conf.json` files in your repo. - Additionally, relative paths provided via the `--config` flag will be resolved relative to the `projectPath` to match Tauri's behavior. + - The path must NOT be gitignored. Please open an issue if this causes you problems. - If `releaseId` is set, the action will use this release to upload assets to. If `tagName` is set the action will try to find an existing release for that tag. If there's none, the action requires `releaseName` to create a new release for the specified `tagName`. - If you create the release yourself and provide a `releaseId` but do not set `tagName`, the download url for updater bundles in `latest.json` will point to `releases/latest/download/` which can cause issues if your repo contains releases that do not include updater bundles. - If you provide a `tagName` to an existing release, `releaseDraft` must be set to `true` if the existing release is a draft. diff --git a/action.yml b/action.yml index 1b9285b..681fc46 100644 --- a/action.yml +++ b/action.yml @@ -22,7 +22,7 @@ inputs: releaseCommitish: description: 'Any branch or commit SHA the Git tag is created from, unused if the Git tag already exists. Default: SHA of current commit' projectPath: - description: 'Path to the root of the project that will be built' + description: 'Path to the root of the project that will be built. It must NOT be gitignored.' default: '.' includeUpdaterJson: description: 'Whether to upload a static JSON file for the updater using GitHub Releases as the CDN' diff --git a/dist/index.js b/dist/index.js index 4647058..f8bfcec 100644 --- a/dist/index.js +++ b/dist/index.js @@ -84638,8 +84638,8 @@ var external_node_fs_ = __nccwpck_require__(73024); var external_node_path_ = __nccwpck_require__(76760); // EXTERNAL MODULE: ./src/inputs.ts + 1 modules var inputs = __nccwpck_require__(53900); -// EXTERNAL MODULE: ./src/utils.ts + 144 modules -var utils = __nccwpck_require__(56958); +// EXTERNAL MODULE: ./src/utils.ts + 145 modules +var utils = __nccwpck_require__(25749); ;// CONCATENATED MODULE: ./src/runner.ts @@ -85116,7 +85116,7 @@ __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __we /* harmony import */ var _upload_release_assets__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(21103); /* harmony import */ var _upload_version_json__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(46715); /* harmony import */ var _upload_workflow_artifacts__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(34689); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(56958); +/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(25749); @@ -85371,7 +85371,7 @@ const updaterJsonPreferNsis = core.getBooleanInput('updaterJsonPreferNsis'); /* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(node_fs__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(84903); /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nccwpck_require__.n(_actions_github__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(56958); +/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(25749); /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(53900); @@ -85450,7 +85450,7 @@ async function uploadAssets(releaseId, assets, retryAttempts) { /* harmony import */ var _actions_github__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__nccwpck_require__.n(_actions_github__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(53900); /* harmony import */ var _upload_release_assets__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(21103); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(56958); +/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(25749); @@ -85698,9 +85698,9 @@ async function uploadVersionJSON(version, notes, tagName, releaseId, artifacts, /* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(node_path__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _actions_artifact__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(56037); /* harmony import */ var _actions_artifact__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nccwpck_require__.n(_actions_artifact__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var globby__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(71635); +/* harmony import */ var globby__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(26116); /* harmony import */ var _inputs__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(53900); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(56958); +/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(25749); @@ -85727,7 +85727,7 @@ async function uploadWorkflowArtifacts(artifacts) { /***/ }), -/***/ 56958: +/***/ 25749: /***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => { @@ -88109,8 +88109,57 @@ function pathKey(options = {}) { return Object.keys(env).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; } -// EXTERNAL MODULE: ./node_modules/.pnpm/unicorn-magic@0.3.0/node_modules/unicorn-magic/node.js -var node = __nccwpck_require__(51467); +;// CONCATENATED MODULE: ./node_modules/.pnpm/unicorn-magic@0.3.0/node_modules/unicorn-magic/node.js + + + + + +const execFileOriginal = (0,external_node_util_.promisify)(external_node_child_process_.execFile); + +function toPath(urlOrPath) { + return urlOrPath instanceof URL ? (0,external_node_url_.fileURLToPath)(urlOrPath) : urlOrPath; +} + +function rootDirectory(pathInput) { + return path.parse(toPath(pathInput)).root; +} + +function traversePathUp(startPath) { + return { + * [Symbol.iterator]() { + let currentPath = external_node_path_.resolve(toPath(startPath)); + let previousPath; + + while (previousPath !== currentPath) { + yield currentPath; + previousPath = currentPath; + currentPath = external_node_path_.resolve(currentPath, '..'); + } + }, + }; +} + +const TEN_MEGABYTES_IN_BYTES = (/* unused pure expression or super */ null && (10 * 1024 * 1024)); + +async function execFile(file, arguments_, options = {}) { + return execFileOriginal(file, arguments_, { + maxBuffer: TEN_MEGABYTES_IN_BYTES, + ...options, + }); +} + +function execFileSync(file, arguments_ = [], options = {}) { + return execFileSyncOriginal(file, arguments_, { + maxBuffer: TEN_MEGABYTES_IN_BYTES, + encoding: 'utf8', + stdio: 'pipe', + ...options, + }); +} + + + ;// CONCATENATED MODULE: ./node_modules/.pnpm/npm-run-path@6.0.0/node_modules/npm-run-path/index.js @@ -88124,7 +88173,7 @@ const npmRunPath = ({ execPath = external_node_process_.execPath, addExecPath = true, } = {}) => { - const cwdPath = external_node_path_.resolve((0,node/* toPath */.b0)(cwd)); + const cwdPath = external_node_path_.resolve(toPath(cwd)); const result = []; const pathParts = pathOption.split(external_node_path_.delimiter); @@ -88142,7 +88191,7 @@ const npmRunPath = ({ }; const applyPreferLocal = (result, pathParts, cwdPath) => { - for (const directory of (0,node/* traversePathUp */.n5)(cwdPath)) { + for (const directory of traversePathUp(cwdPath)) { const pathPart = external_node_path_.join(directory, 'node_modules/.bin'); if (!pathParts.includes(pathPart)) { result.push(pathPart); @@ -88152,7 +88201,7 @@ const applyPreferLocal = (result, pathParts, cwdPath) => { // Ensure the running `node` binary is used const applyExecPath = (result, pathParts, execPath, cwdPath) => { - const pathPart = external_node_path_.resolve(cwdPath, (0,node/* toPath */.b0)(execPath), '..'); + const pathPart = external_node_path_.resolve(cwdPath, toPath(execPath), '..'); if (!pathParts.includes(pathPart)) { result.push(pathPart); } @@ -95719,8 +95768,8 @@ const { } = getIpcExport(); -// EXTERNAL MODULE: ./node_modules/.pnpm/globby@15.0.0/node_modules/globby/index.js + 4 modules -var globby = __nccwpck_require__(71635); +// EXTERNAL MODULE: ./node_modules/.pnpm/globby@16.0.0/node_modules/globby/index.js + 5 modules +var globby = __nccwpck_require__(26116); // EXTERNAL MODULE: external "fs" var external_fs_ = __nccwpck_require__(79896); // EXTERNAL MODULE: external "path" @@ -95914,16 +95963,16 @@ var external_node_fs_promises_ = __nccwpck_require__(51455); -const toPath = urlOrPath => urlOrPath instanceof URL ? (0,external_node_url_.fileURLToPath)(urlOrPath) : urlOrPath; +const find_up_simple_toPath = urlOrPath => urlOrPath instanceof URL ? (0,external_node_url_.fileURLToPath)(urlOrPath) : urlOrPath; async function findUp(name, { cwd = process.cwd(), type = 'file', stopAt, } = {}) { - let directory = path.resolve(toPath(cwd) ?? ''); + let directory = path.resolve(find_up_simple_toPath(cwd) ?? ''); const {root} = path.parse(directory); - stopAt = path.resolve(directory, toPath(stopAt ?? root)); + stopAt = path.resolve(directory, find_up_simple_toPath(stopAt ?? root)); const isAbsoluteName = path.isAbsolute(name); while (directory) { @@ -95948,9 +95997,9 @@ function findUpSync(name, { type = 'file', stopAt, } = {}) { - let directory = external_node_path_.resolve(toPath(cwd) ?? ''); + let directory = external_node_path_.resolve(find_up_simple_toPath(cwd) ?? ''); const {root} = external_node_path_.parse(directory); - stopAt = external_node_path_.resolve(directory, toPath(stopAt) ?? root); + stopAt = external_node_path_.resolve(directory, find_up_simple_toPath(stopAt) ?? root); const isAbsoluteName = external_node_path_.isAbsolute(name); while (directory) { @@ -96106,6 +96155,7 @@ function getPackageJson(root) { } function getTauriDir() { const tauriConfPaths = (0,globby/* globbySync */.Hz)(['**/tauri.conf.json', '**/tauri.conf.json5', '**/Tauri.toml'], { + // globby v16 changes this to also look into parent dir. Monitor this closely and disable if needed. gitignore: true, cwd: inputs/* projectPath */.DZ, // Forcefully ignore target and node_modules dirs @@ -147549,7 +147599,7 @@ const PASSTHROUGH_LISTENERS_PER_STREAM = 1; /***/ }), -/***/ 71635: +/***/ 26116: /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => { @@ -147572,56 +147622,81 @@ var external_node_stream_ = __nccwpck_require__(57075); var merge_streams = __nccwpck_require__(85956); // EXTERNAL MODULE: ./node_modules/.pnpm/fast-glob@3.3.3/node_modules/fast-glob/out/index.js var out = __nccwpck_require__(80197); +// EXTERNAL MODULE: external "node:util" +var external_node_util_ = __nccwpck_require__(57975); +// EXTERNAL MODULE: external "node:child_process" +var external_node_child_process_ = __nccwpck_require__(31421); +// EXTERNAL MODULE: external "node:url" +var external_node_url_ = __nccwpck_require__(73136); +;// CONCATENATED MODULE: ./node_modules/.pnpm/unicorn-magic@0.4.0/node_modules/unicorn-magic/node.js + + + + + +const execFileOriginal = (0,external_node_util_.promisify)(external_node_child_process_.execFile); + +function toPath(urlOrPath) { + return urlOrPath instanceof URL ? (0,external_node_url_.fileURLToPath)(urlOrPath) : urlOrPath; +} + +function rootDirectory(pathInput) { + return path.parse(toPath(pathInput)).root; +} + +function traversePathUp(startPath) { + return { + * [Symbol.iterator]() { + let currentPath = path.resolve(toPath(startPath)); + let previousPath; + + while (previousPath !== currentPath) { + yield currentPath; + previousPath = currentPath; + currentPath = path.resolve(currentPath, '..'); + } + }, + }; +} + +const TEN_MEGABYTES_IN_BYTES = (/* unused pure expression or super */ null && (10 * 1024 * 1024)); + +async function execFile(file, arguments_, options = {}) { + return execFileOriginal(file, arguments_, { + maxBuffer: TEN_MEGABYTES_IN_BYTES, + ...options, + }); +} + +function execFileSync(file, arguments_ = [], options = {}) { + return execFileSyncOriginal(file, arguments_, { + maxBuffer: TEN_MEGABYTES_IN_BYTES, + encoding: 'utf8', + stdio: 'pipe', + ...options, + }); +} + + + // EXTERNAL MODULE: external "node:fs/promises" var promises_ = __nccwpck_require__(51455); -;// CONCATENATED MODULE: ./node_modules/.pnpm/path-type@6.0.0/node_modules/path-type/index.js - - - -async function isType(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); - } - - try { - const stats = await promises_[fsStatType](filePath); - return stats[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { - return false; - } - - throw error; - } -} - -function isTypeSync(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); - } - - try { - return external_node_fs_[fsStatType](filePath)[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { - return false; - } - - throw error; - } -} - -const isFile = isType.bind(undefined, 'stat', 'isFile'); -const isDirectory = isType.bind(undefined, 'stat', 'isDirectory'); -const isSymlink = isType.bind(undefined, 'lstat', 'isSymbolicLink'); -const isFileSync = isTypeSync.bind(undefined, 'statSync', 'isFile'); -const isDirectorySync = isTypeSync.bind(undefined, 'statSync', 'isDirectory'); -const isSymlinkSync = isTypeSync.bind(undefined, 'lstatSync', 'isSymbolicLink'); - -// EXTERNAL MODULE: ./node_modules/.pnpm/unicorn-magic@0.3.0/node_modules/unicorn-magic/node.js -var node = __nccwpck_require__(51467); // EXTERNAL MODULE: ./node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js var ignore = __nccwpck_require__(94877); +;// CONCATENATED MODULE: ./node_modules/.pnpm/is-path-inside@4.0.0/node_modules/is-path-inside/index.js + + +function isPathInside(childPath, parentPath) { + const relation = external_node_path_.relative(parentPath, childPath); + + return Boolean( + relation && + relation !== '..' && + !relation.startsWith(`..${external_node_path_.sep}`) && + relation !== external_node_path_.resolve(childPath) + ); +} + ;// CONCATENATED MODULE: ./node_modules/.pnpm/slash@5.1.0/node_modules/slash/index.js function slash(path) { const isExtendedLengthPath = path.startsWith('\\\\?\\'); @@ -147633,10 +147708,298 @@ function slash(path) { return path.replace(/\\/g, '/'); } -;// CONCATENATED MODULE: ./node_modules/.pnpm/globby@15.0.0/node_modules/globby/utilities.js +;// CONCATENATED MODULE: ./node_modules/.pnpm/globby@16.0.0/node_modules/globby/utilities.js + + + + + const isNegativePattern = pattern => pattern[0] === '!'; -;// CONCATENATED MODULE: ./node_modules/.pnpm/globby@15.0.0/node_modules/globby/ignore.js +const bindFsMethod = (object, methodName) => { + const method = object?.[methodName]; + return typeof method === 'function' ? method.bind(object) : undefined; +}; + +// Only used as a fallback for legacy fs implementations +const promisifyFsMethod = (object, methodName) => { + const method = object?.[methodName]; + if (typeof method !== 'function') { + return undefined; + } + + return (0,external_node_util_.promisify)(method.bind(object)); +}; + +const normalizeDirectoryPatternForFastGlob = pattern => { + if (!pattern.endsWith('/')) { + return pattern; + } + + const trimmedPattern = pattern.replace(/\/+$/u, ''); + if (!trimmedPattern) { + return '/**'; + } + + // Special case for '**/' to avoid producing '**/**/**' + if (trimmedPattern === '**') { + return '**/**'; + } + + const hasLeadingSlash = trimmedPattern.startsWith('/'); + const patternBody = hasLeadingSlash ? trimmedPattern.slice(1) : trimmedPattern; + const hasInnerSlash = patternBody.includes('/'); + const needsRecursivePrefix = !hasLeadingSlash && !hasInnerSlash && !trimmedPattern.startsWith('**/'); + const recursivePrefix = needsRecursivePrefix ? '**/' : ''; + + return `${recursivePrefix}${trimmedPattern}/**`; +}; + +/** +Extract the parent directory prefix from a pattern (e.g., '../' or '../../'). + +Note: Patterns should have trailing slash after '..' (e.g., '../foo' not '..foo'). The directoryToGlob function ensures this in the normal pipeline. + +@param {string} pattern - The pattern to analyze. +@returns {string} The parent directory prefix, or empty string if none. +*/ +const getParentDirectoryPrefix = pattern => { + const normalizedPattern = isNegativePattern(pattern) ? pattern.slice(1) : pattern; + const match = normalizedPattern.match(/^(\.\.\/)+/); + return match ? match[0] : ''; +}; + +/** +Adjust ignore patterns to match the relative base of the main patterns. + +When patterns reference parent directories, ignore patterns starting with globstars need to be adjusted to match from the same base directory. This ensures intuitive behavior where ignore patterns work correctly with parent directory patterns. + +This is analogous to how node-glob normalizes path prefixes (see node-glob issue #309) and how Rust ignore crate strips path prefixes before matching. + +@param {string[]} patterns - The main glob patterns. +@param {string[]} ignorePatterns - The ignore patterns to adjust. +@returns {string[]} Adjusted ignore patterns. +*/ +const adjustIgnorePatternsForParentDirectories = (patterns, ignorePatterns) => { + // Early exit for empty arrays + if (patterns.length === 0 || ignorePatterns.length === 0) { + return ignorePatterns; + } + + // Get parent directory prefixes for all patterns (empty string if no prefix) + const parentPrefixes = patterns.map(pattern => getParentDirectoryPrefix(pattern)); + + // Check if all patterns have the same parent prefix + const firstPrefix = parentPrefixes[0]; + if (!firstPrefix) { + return ignorePatterns; // No parent directories in any pattern + } + + const allSamePrefix = parentPrefixes.every(prefix => prefix === firstPrefix); + if (!allSamePrefix) { + return ignorePatterns; // Mixed bases - don't adjust + } + + // Adjust ignore patterns that start with **/ + return ignorePatterns.map(pattern => { + // Only adjust patterns starting with **/ that don't already have a parent reference + if (pattern.startsWith('**/') && !pattern.startsWith('../')) { + return firstPrefix + pattern; + } + + return pattern; + }); +}; + +/** +Find the git root directory by searching upward for a .git directory. + +@param {string} cwd - The directory to start searching from. +@param {Object} [fsImplementation] - Optional fs implementation. +@returns {string|undefined} The git root directory path, or undefined if not found. +*/ +const getAsyncStatMethod = fsImplementation => + bindFsMethod(fsImplementation?.promises, 'stat') + ?? bindFsMethod(external_node_fs_.promises, 'stat'); + +const getStatSyncMethod = fsImplementation => { + if (fsImplementation) { + return bindFsMethod(fsImplementation, 'statSync'); + } + + return bindFsMethod(external_node_fs_, 'statSync'); +}; + +const pathHasGitDirectory = stats => Boolean(stats?.isDirectory?.() || stats?.isFile?.()); + +const buildPathChain = (startPath, rootPath) => { + const chain = []; + let currentPath = startPath; + + chain.push(currentPath); + + while (currentPath !== rootPath) { + const parentPath = external_node_path_.dirname(currentPath); + if (parentPath === currentPath) { + break; + } + + currentPath = parentPath; + chain.push(currentPath); + } + + return chain; +}; + +const findGitRootInChain = async (paths, statMethod) => { + for (const directory of paths) { + const gitPath = external_node_path_.join(directory, '.git'); + + try { + const stats = await statMethod(gitPath); // eslint-disable-line no-await-in-loop + if (pathHasGitDirectory(stats)) { + return directory; + } + } catch { + // Ignore errors and continue searching + } + } + + return undefined; +}; + +const findGitRootSyncUncached = (cwd, fsImplementation) => { + const statSyncMethod = getStatSyncMethod(fsImplementation); + if (!statSyncMethod) { + return undefined; + } + + const currentPath = external_node_path_.resolve(cwd); + const {root} = external_node_path_.parse(currentPath); + const chain = buildPathChain(currentPath, root); + + for (const directory of chain) { + const gitPath = external_node_path_.join(directory, '.git'); + try { + const stats = statSyncMethod(gitPath); + if (pathHasGitDirectory(stats)) { + return directory; + } + } catch { + // Ignore errors and continue searching + } + } + + return undefined; +}; + +const findGitRootSync = (cwd, fsImplementation) => { + if (typeof cwd !== 'string') { + throw new TypeError('cwd must be a string'); + } + + return findGitRootSyncUncached(cwd, fsImplementation); +}; + +const findGitRootAsyncUncached = async (cwd, fsImplementation) => { + const statMethod = getAsyncStatMethod(fsImplementation); + if (!statMethod) { + return findGitRootSync(cwd, fsImplementation); + } + + const currentPath = external_node_path_.resolve(cwd); + const {root} = external_node_path_.parse(currentPath); + const chain = buildPathChain(currentPath, root); + + return findGitRootInChain(chain, statMethod); +}; + +const findGitRoot = async (cwd, fsImplementation) => { + if (typeof cwd !== 'string') { + throw new TypeError('cwd must be a string'); + } + + return findGitRootAsyncUncached(cwd, fsImplementation); +}; + +/** +Get paths to all .gitignore files from git root to cwd (inclusive). + +@param {string} gitRoot - The git root directory. +@param {string} cwd - The current working directory. +@returns {string[]} Array of .gitignore file paths to search for. +*/ +const isWithinGitRoot = (gitRoot, cwd) => { + const resolvedGitRoot = external_node_path_.resolve(gitRoot); + const resolvedCwd = external_node_path_.resolve(cwd); + return resolvedCwd === resolvedGitRoot || isPathInside(resolvedCwd, resolvedGitRoot); +}; + +const getParentGitignorePaths = (gitRoot, cwd) => { + if (gitRoot && typeof gitRoot !== 'string') { + throw new TypeError('gitRoot must be a string or undefined'); + } + + if (typeof cwd !== 'string') { + throw new TypeError('cwd must be a string'); + } + + // If no gitRoot provided, return empty array + if (!gitRoot) { + return []; + } + + if (!isWithinGitRoot(gitRoot, cwd)) { + return []; + } + + const chain = buildPathChain(external_node_path_.resolve(cwd), external_node_path_.resolve(gitRoot)); + + return [...chain] + .reverse() + .map(directory => external_node_path_.join(directory, '.gitignore')); +}; + +/** +Convert ignore patterns to fast-glob compatible format. +Returns empty array if patterns should be handled by predicate only. + +@param {string[]} patterns - Ignore patterns from .gitignore files +@param {boolean} usingGitRoot - Whether patterns are relative to git root +@param {Function} normalizeDirectoryPatternForFastGlob - Function to normalize directory patterns +@returns {string[]} Patterns safe to pass to fast-glob, or empty array +*/ +const convertPatternsForFastGlob = (patterns, usingGitRoot, normalizeDirectoryPatternForFastGlob) => { + // Determine which patterns are safe to pass to fast-glob + // If there are negation patterns, we can't pass file patterns to fast-glob + // because fast-glob doesn't understand negations and would filter out files + // that should be re-included by negation patterns. + // If we're using git root, patterns are relative to git root not cwd, + // so we can't pass them to fast-glob which expects cwd-relative patterns. + // We only pass patterns to fast-glob if there are NO negations AND we're not using git root. + + if (usingGitRoot) { + return []; // Patterns are relative to git root, not cwd + } + + const result = []; + let hasNegations = false; + + // Single pass to check for negations and collect positive patterns + for (const pattern of patterns) { + if (isNegativePattern(pattern)) { + hasNegations = true; + break; // Early exit on first negation + } + + result.push(normalizeDirectoryPatternForFastGlob(pattern)); + } + + return hasNegations ? [] : result; +}; + +;// CONCATENATED MODULE: ./node_modules/.pnpm/globby@16.0.0/node_modules/globby/ignore.js + @@ -147660,6 +148023,107 @@ const ignoreFilesGlobOptions = { const GITIGNORE_FILES_PATTERN = '**/.gitignore'; +const getReadFileMethod = fsImplementation => + bindFsMethod(fsImplementation?.promises, 'readFile') + ?? bindFsMethod(promises_, 'readFile') + ?? promisifyFsMethod(fsImplementation, 'readFile'); + +const getReadFileSyncMethod = fsImplementation => + bindFsMethod(fsImplementation, 'readFileSync') + ?? bindFsMethod(external_node_fs_, 'readFileSync'); + +const shouldSkipIgnoreFileError = (error, suppressErrors) => { + if (!error) { + return Boolean(suppressErrors); + } + + if (error.code === 'ENOENT' || error.code === 'ENOTDIR') { + return true; + } + + return Boolean(suppressErrors); +}; + +const createIgnoreFileReadError = (filePath, error) => { + if (error instanceof Error) { + error.message = `Failed to read ignore file at ${filePath}: ${error.message}`; + return error; + } + + return new Error(`Failed to read ignore file at ${filePath}: ${String(error)}`); +}; + +const processIgnoreFileCore = (filePath, readMethod, suppressErrors) => { + try { + const content = readMethod(filePath, 'utf8'); + return {filePath, content}; + } catch (error) { + if (shouldSkipIgnoreFileError(error, suppressErrors)) { + return undefined; + } + + throw createIgnoreFileReadError(filePath, error); + } +}; + +const readIgnoreFilesSafely = async (paths, readFileMethod, suppressErrors) => { + const fileResults = await Promise.all(paths.map(async filePath => { + try { + const content = await readFileMethod(filePath, 'utf8'); + return {filePath, content}; + } catch (error) { + if (shouldSkipIgnoreFileError(error, suppressErrors)) { + return undefined; + } + + throw createIgnoreFileReadError(filePath, error); + } + })); + + return fileResults.filter(Boolean); +}; + +const readIgnoreFilesSafelySync = (paths, readFileSyncMethod, suppressErrors) => paths + .map(filePath => processIgnoreFileCore(filePath, readFileSyncMethod, suppressErrors)) + .filter(Boolean); + +const dedupePaths = paths => { + const seen = new Set(); + return paths.filter(filePath => { + if (seen.has(filePath)) { + return false; + } + + seen.add(filePath); + return true; + }); +}; + +const globIgnoreFiles = (globFunction, patterns, normalizedOptions) => globFunction(patterns, { + ...normalizedOptions, + ...ignoreFilesGlobOptions, // Must be last to ensure absolute/dot flags stick +}); + +const getParentIgnorePaths = (gitRoot, normalizedOptions) => gitRoot + ? getParentGitignorePaths(gitRoot, normalizedOptions.cwd) + : []; + +const combineIgnoreFilePaths = (gitRoot, normalizedOptions, childPaths) => dedupePaths([ + ...getParentIgnorePaths(gitRoot, normalizedOptions), + ...childPaths, +]); + +const buildIgnoreResult = (files, normalizedOptions, gitRoot) => { + const baseDir = gitRoot || normalizedOptions.cwd; + const patterns = getPatternsFromIgnoreFiles(files, baseDir); + + return { + patterns, + predicate: createIgnorePredicate(patterns, normalizedOptions.cwd, baseDir), + usingGitRoot: Boolean(gitRoot && gitRoot !== normalizedOptions.cwd), + }; +}; + // Apply base path to gitignore patterns based on .gitignore spec 2.22.1 // https://git-scm.com/docs/gitignore#_pattern_format // See also https://github.com/sindresorhus/globby/issues/146 @@ -147706,13 +148170,17 @@ const parseIgnoreFile = (file, cwd) => { }; const toRelativePath = (fileOrDirectory, cwd) => { - cwd = slash(cwd); if (external_node_path_.isAbsolute(fileOrDirectory)) { - if (slash(fileOrDirectory).startsWith(cwd)) { - return external_node_path_.relative(cwd, fileOrDirectory); + // When paths are equal, path.relative returns empty string which is valid + // isPathInside returns false for equal paths, so check this case first + const relativePath = external_node_path_.relative(cwd, fileOrDirectory); + if (relativePath && !isPathInside(fileOrDirectory, cwd)) { + // Path is outside cwd - it cannot be ignored by patterns in cwd + // Return undefined to indicate this path is outside scope + return undefined; } - throw new Error(`Path ${fileOrDirectory} is not in cwd ${cwd}`); + return relativePath; } // Normalize relative paths: @@ -147732,72 +148200,137 @@ const toRelativePath = (fileOrDirectory, cwd) => { return fileOrDirectory; }; -const getIsIgnoredPredicate = (files, cwd) => { - const patterns = files.flatMap(file => parseIgnoreFile(file, cwd)); +const createIgnorePredicate = (patterns, cwd, baseDir) => { const ignores = ignore().add(patterns); + // Normalize to handle path separator and . / .. components consistently + const resolvedCwd = external_node_path_.normalize(external_node_path_.resolve(cwd)); + const resolvedBaseDir = external_node_path_.normalize(external_node_path_.resolve(baseDir)); return fileOrDirectory => { - fileOrDirectory = (0,node/* toPath */.b0)(fileOrDirectory); - fileOrDirectory = toRelativePath(fileOrDirectory, cwd); - // If path is outside cwd (undefined), it can't be ignored by patterns in cwd - if (fileOrDirectory === undefined) { + fileOrDirectory = toPath(fileOrDirectory); + + // Never ignore the cwd itself - use normalized comparison + const normalizedPath = external_node_path_.normalize(external_node_path_.resolve(fileOrDirectory)); + if (normalizedPath === resolvedCwd) { return false; } - return fileOrDirectory ? ignores.ignores(slash(fileOrDirectory)) : false; + // Convert to relative path from baseDir (use normalized baseDir) + const relativePath = toRelativePath(fileOrDirectory, resolvedBaseDir); + + // If path is outside baseDir (undefined), it can't be ignored by patterns + if (relativePath === undefined) { + return false; + } + + return relativePath ? ignores.ignores(slash(relativePath)) : false; }; }; -const normalizeOptions = (options = {}) => ({ - cwd: (0,node/* toPath */.b0)(options.cwd) ?? external_node_process_.cwd(), - suppressErrors: Boolean(options.suppressErrors), - deep: typeof options.deep === 'number' ? options.deep : Number.POSITIVE_INFINITY, - ignore: [...options.ignore ?? [], ...defaultIgnoredDirectories], -}); +const normalizeOptions = (options = {}) => { + const ignoreOption = options.ignore + ? (Array.isArray(options.ignore) ? options.ignore : [options.ignore]) + : []; + + const cwd = toPath(options.cwd) ?? external_node_process_.cwd(); + + // Adjust deep option for fast-glob: fast-glob's deep counts differently than expected + // User's deep: 0 = root only -> fast-glob needs: 1 + // User's deep: 1 = root + 1 level -> fast-glob needs: 2 + const deep = typeof options.deep === 'number' ? Math.max(0, options.deep) + 1 : Number.POSITIVE_INFINITY; + + // Only pass through specific fast-glob options that make sense for finding ignore files + return { + cwd, + suppressErrors: options.suppressErrors ?? false, + deep, + ignore: [...ignoreOption, ...defaultIgnoredDirectories], + followSymbolicLinks: options.followSymbolicLinks ?? true, + concurrency: options.concurrency, + throwErrorOnBrokenSymbolicLink: options.throwErrorOnBrokenSymbolicLink ?? false, + fs: options.fs, + }; +}; + +const collectIgnoreFileArtifactsAsync = async (patterns, options, includeParentIgnoreFiles) => { + const normalizedOptions = normalizeOptions(options); + const childPaths = await globIgnoreFiles(out, patterns, normalizedOptions); + const gitRoot = includeParentIgnoreFiles + ? await findGitRoot(normalizedOptions.cwd, normalizedOptions.fs) + : undefined; + const allPaths = combineIgnoreFilePaths(gitRoot, normalizedOptions, childPaths); + const readFileMethod = getReadFileMethod(normalizedOptions.fs); + const files = await readIgnoreFilesSafely(allPaths, readFileMethod, normalizedOptions.suppressErrors); + + return {files, normalizedOptions, gitRoot}; +}; + +const collectIgnoreFileArtifactsSync = (patterns, options, includeParentIgnoreFiles) => { + const normalizedOptions = normalizeOptions(options); + const childPaths = globIgnoreFiles(out.sync, patterns, normalizedOptions); + const gitRoot = includeParentIgnoreFiles + ? findGitRootSync(normalizedOptions.cwd, normalizedOptions.fs) + : undefined; + const allPaths = combineIgnoreFilePaths(gitRoot, normalizedOptions, childPaths); + const readFileSyncMethod = getReadFileSyncMethod(normalizedOptions.fs); + const files = readIgnoreFilesSafelySync(allPaths, readFileSyncMethod, normalizedOptions.suppressErrors); + + return {files, normalizedOptions, gitRoot}; +}; const isIgnoredByIgnoreFiles = async (patterns, options) => { - const {cwd, suppressErrors, deep, ignore} = normalizeOptions(options); - - const paths = await out(patterns, { - cwd, - suppressErrors, - deep, - ignore, - ...ignoreFilesGlobOptions, - }); - - const files = await Promise.all(paths.map(async filePath => ({ - filePath, - content: await promises_.readFile(filePath, 'utf8'), - }))); - - return getIsIgnoredPredicate(files, cwd); + const {files, normalizedOptions, gitRoot} = await collectIgnoreFileArtifactsAsync(patterns, options, false); + return buildIgnoreResult(files, normalizedOptions, gitRoot).predicate; }; const isIgnoredByIgnoreFilesSync = (patterns, options) => { - const {cwd, suppressErrors, deep, ignore} = normalizeOptions(options); + const {files, normalizedOptions, gitRoot} = collectIgnoreFileArtifactsSync(patterns, options, false); + return buildIgnoreResult(files, normalizedOptions, gitRoot).predicate; +}; - const paths = out.sync(patterns, { - cwd, - suppressErrors, - deep, - ignore, - ...ignoreFilesGlobOptions, - }); +const getPatternsFromIgnoreFiles = (files, baseDir) => files.flatMap(file => parseIgnoreFile(file, baseDir)); - const files = paths.map(filePath => ({ - filePath, - content: external_node_fs_.readFileSync(filePath, 'utf8'), - })); +/** +Read ignore files and return both patterns and predicate. +This avoids reading the same files twice (once for patterns, once for filtering). - return getIsIgnoredPredicate(files, cwd); +@param {string[]} patterns - Patterns to find ignore files +@param {Object} options - Options object +@param {boolean} [includeParentIgnoreFiles=false] - Whether to search for parent .gitignore files +@returns {Promise<{patterns: string[], predicate: Function, usingGitRoot: boolean}>} +*/ +const getIgnorePatternsAndPredicate = async (patterns, options, includeParentIgnoreFiles = false) => { + const {files, normalizedOptions, gitRoot} = await collectIgnoreFileArtifactsAsync( + patterns, + options, + includeParentIgnoreFiles, + ); + + return buildIgnoreResult(files, normalizedOptions, gitRoot); +}; + +/** +Read ignore files and return both patterns and predicate (sync version). + +@param {string[]} patterns - Patterns to find ignore files +@param {Object} options - Options object +@param {boolean} [includeParentIgnoreFiles=false] - Whether to search for parent .gitignore files +@returns {{patterns: string[], predicate: Function, usingGitRoot: boolean}} +*/ +const getIgnorePatternsAndPredicateSync = (patterns, options, includeParentIgnoreFiles = false) => { + const {files, normalizedOptions, gitRoot} = collectIgnoreFileArtifactsSync( + patterns, + options, + includeParentIgnoreFiles, + ); + + return buildIgnoreResult(files, normalizedOptions, gitRoot); }; const isGitIgnored = options => isIgnoredByIgnoreFiles(GITIGNORE_FILES_PATTERN, options); const isGitIgnoredSync = options => isIgnoredByIgnoreFilesSync(GITIGNORE_FILES_PATTERN, options); -;// CONCATENATED MODULE: ./node_modules/.pnpm/globby@15.0.0/node_modules/globby/index.js - +;// CONCATENATED MODULE: ./node_modules/.pnpm/globby@16.0.0/node_modules/globby/index.js @@ -147814,6 +148347,33 @@ const assertPatternsInput = patterns => { } }; +const getStatMethod = fsImplementation => + bindFsMethod(fsImplementation?.promises, 'stat') + ?? bindFsMethod(external_node_fs_.promises, 'stat') + ?? promisifyFsMethod(fsImplementation, 'stat'); + +const globby_getStatSyncMethod = fsImplementation => + bindFsMethod(fsImplementation, 'statSync') + ?? bindFsMethod(external_node_fs_, 'statSync'); + +const isDirectory = async (path, fsImplementation) => { + try { + const stats = await getStatMethod(fsImplementation)(path); + return stats.isDirectory(); + } catch { + return false; + } +}; + +const isDirectorySync = (path, fsImplementation) => { + try { + const stats = globby_getStatSyncMethod(fsImplementation)(path); + return stats.isDirectory(); + } catch { + return false; + } +}; + const normalizePathForDirectoryGlob = (filePath, cwd) => { const path = isNegativePattern(filePath) ? filePath.slice(1) : filePath; return external_node_path_.isAbsolute(path) ? path : external_node_path_.join(cwd, path); @@ -147843,6 +148403,7 @@ const directoryToGlob = async (directoryPaths, { cwd = external_node_process_.cwd(), files, extensions, + fs: fsImplementation, } = {}) => { const globs = await Promise.all(directoryPaths.map(async directoryPath => { // Check pattern without negative prefix @@ -147855,7 +148416,7 @@ const directoryToGlob = async (directoryPaths, { // Original logic for checking actual directories const pathToCheck = normalizePathForDirectoryGlob(directoryPath, cwd); - return (await isDirectory(pathToCheck)) ? getDirectoryGlob({directoryPath, files, extensions}) : directoryPath; + return (await isDirectory(pathToCheck, fsImplementation)) ? getDirectoryGlob({directoryPath, files, extensions}) : directoryPath; })); return globs.flat(); @@ -147865,6 +148426,7 @@ const directoryToGlobSync = (directoryPaths, { cwd = external_node_process_.cwd(), files, extensions, + fs: fsImplementation, } = {}) => directoryPaths.flatMap(directoryPath => { // Check pattern without negative prefix const checkPattern = isNegativePattern(directoryPath) ? directoryPath.slice(1) : directoryPath; @@ -147876,7 +148438,7 @@ const directoryToGlobSync = (directoryPaths, { // Original logic for checking actual directories const pathToCheck = normalizePathForDirectoryGlob(directoryPath, cwd); - return isDirectorySync(pathToCheck) ? getDirectoryGlob({directoryPath, files, extensions}) : directoryPath; + return isDirectorySync(pathToCheck, fsImplementation) ? getDirectoryGlob({directoryPath, files, extensions}) : directoryPath; }); const toPatternsArray = patterns => { @@ -147885,32 +148447,38 @@ const toPatternsArray = patterns => { return patterns; }; -const checkCwdOption = cwd => { - if (!cwd) { +const checkCwdOption = (cwd, fsImplementation = external_node_fs_) => { + if (!cwd || !fsImplementation.statSync) { return; } - let stat; + let stats; try { - stat = external_node_fs_.statSync(cwd); + stats = fsImplementation.statSync(cwd); } catch { + // If stat fails (e.g., path doesn't exist), let fast-glob handle it return; } - if (!stat.isDirectory()) { - throw new Error('The `cwd` option must be a path to a directory'); + if (!stats.isDirectory()) { + throw new Error(`The \`cwd\` option must be a path to a directory, got: ${cwd}`); } }; const globby_normalizeOptions = (options = {}) => { + // Normalize ignore to an array (fast-glob accepts string but we need array internally) + const ignore = options.ignore + ? (Array.isArray(options.ignore) ? options.ignore : [options.ignore]) + : []; + options = { ...options, - ignore: options.ignore ?? [], + ignore, expandDirectories: options.expandDirectories ?? true, - cwd: (0,node/* toPath */.b0)(options.cwd), + cwd: toPath(options.cwd), }; - checkCwdOption(options.cwd); + checkCwdOption(options.cwd, options.fs); return options; }; @@ -147929,28 +148497,113 @@ const getIgnoreFilesPatterns = options => { return patterns; }; -const getFilter = async options => { +/** +Apply gitignore patterns to options and return filter predicate. + +When negation patterns are present (e.g., '!important.log'), we cannot pass positive patterns to fast-glob because it would filter out files before our predicate can re-include them. In this case, we rely entirely on the predicate for filtering, which handles negations correctly. + +When there are no negations, we optimize by passing patterns to fast-glob's ignore option to skip directories during traversal (performance optimization). + +All patterns (including negated) are always used in the filter predicate to ensure correct Git-compatible behavior. + +@returns {Promise<{options: Object, filter: Function}>} +*/ +const applyIgnoreFilesAndGetFilter = async options => { const ignoreFilesPatterns = getIgnoreFilesPatterns(options); - return createFilterFunction(ignoreFilesPatterns.length > 0 && await isIgnoredByIgnoreFiles(ignoreFilesPatterns, options)); + + if (ignoreFilesPatterns.length === 0) { + return { + options, + filter: createFilterFunction(false, options.cwd), + }; + } + + // Read ignore files once and get both patterns and predicate + // Enable parent .gitignore search when using gitignore option + const includeParentIgnoreFiles = options.gitignore === true; + const {patterns, predicate, usingGitRoot} = await getIgnorePatternsAndPredicate(ignoreFilesPatterns, options, includeParentIgnoreFiles); + + // Convert patterns to fast-glob format (may return empty array if predicate should handle everything) + const patternsForFastGlob = convertPatternsForFastGlob(patterns, usingGitRoot, normalizeDirectoryPatternForFastGlob); + + const modifiedOptions = { + ...options, + ignore: [...options.ignore, ...patternsForFastGlob], + }; + + return { + options: modifiedOptions, + filter: createFilterFunction(predicate, options.cwd), + }; }; -const getFilterSync = options => { +/** +Apply gitignore patterns to options and return filter predicate (sync version). + +@returns {{options: Object, filter: Function}} +*/ +const applyIgnoreFilesAndGetFilterSync = options => { const ignoreFilesPatterns = getIgnoreFilesPatterns(options); - return createFilterFunction(ignoreFilesPatterns.length > 0 && isIgnoredByIgnoreFilesSync(ignoreFilesPatterns, options)); + + if (ignoreFilesPatterns.length === 0) { + return { + options, + filter: createFilterFunction(false, options.cwd), + }; + } + + // Read ignore files once and get both patterns and predicate + // Enable parent .gitignore search when using gitignore option + const includeParentIgnoreFiles = options.gitignore === true; + const {patterns, predicate, usingGitRoot} = getIgnorePatternsAndPredicateSync(ignoreFilesPatterns, options, includeParentIgnoreFiles); + + // Convert patterns to fast-glob format (may return empty array if predicate should handle everything) + const patternsForFastGlob = convertPatternsForFastGlob(patterns, usingGitRoot, normalizeDirectoryPatternForFastGlob); + + const modifiedOptions = { + ...options, + ignore: [...options.ignore, ...patternsForFastGlob], + }; + + return { + options: modifiedOptions, + filter: createFilterFunction(predicate, options.cwd), + }; }; -const createFilterFunction = isIgnored => { +const createFilterFunction = (isIgnored, cwd) => { const seen = new Set(); + const basePath = cwd || external_node_process_.cwd(); + const pathCache = new Map(); // Cache for resolved paths return fastGlobResult => { const pathKey = external_node_path_.normalize(fastGlobResult.path ?? fastGlobResult); - if (seen.has(pathKey) || (isIgnored && isIgnored(pathKey))) { + // Check seen set first (fast path) + if (seen.has(pathKey)) { return false; } - seen.add(pathKey); + // Only compute absolute path and check predicate if needed + if (isIgnored) { + let absolutePath = pathCache.get(pathKey); + if (absolutePath === undefined) { + absolutePath = external_node_path_.isAbsolute(pathKey) ? pathKey : external_node_path_.resolve(basePath, pathKey); + pathCache.set(pathKey, absolutePath); + // Only clear path cache if it gets too large + // Never clear 'seen' as it's needed for deduplication + if (pathCache.size > 10_000) { + pathCache.clear(); + } + } + + if (isIgnored(absolutePath)) { + return false; + } + } + + seen.add(pathKey); return true; }; }; @@ -147958,6 +148611,12 @@ const createFilterFunction = isIgnored => { const unionFastGlobResults = (results, filter) => results.flat().filter(fastGlobResult => filter(fastGlobResult)); const convertNegativePatterns = (patterns, options) => { + // If all patterns are negative, prepend a positive catch-all pattern + // This makes negation-only patterns work intuitively (e.g., '!*.json' matches all files except JSON) + if (patterns.length > 0 && patterns.every(pattern => isNegativePattern(pattern))) { + patterns = ['**/*', ...patterns]; + } + const tasks = []; while (patterns.length > 0) { @@ -147993,6 +148652,14 @@ const convertNegativePatterns = (patterns, options) => { return tasks; }; +const applyParentDirectoryIgnoreAdjustments = tasks => tasks.map(task => ({ + patterns: task.patterns, + options: { + ...task.options, + ignore: adjustIgnorePatternsForParentDirectories(task.patterns, task.options.ignore), + }, +})); + const normalizeExpandDirectoriesOption = (options, cwd) => ({ ...(cwd ? {cwd} : {}), ...(Array.isArray(options) ? {files: options} : options), @@ -148001,13 +148668,16 @@ const normalizeExpandDirectoriesOption = (options, cwd) => ({ const generateTasks = async (patterns, options) => { const globTasks = convertNegativePatterns(patterns, options); - const {cwd, expandDirectories} = options; + const {cwd, expandDirectories, fs: fsImplementation} = options; if (!expandDirectories) { - return globTasks; + return applyParentDirectoryIgnoreAdjustments(globTasks); } - const directoryToGlobOptions = normalizeExpandDirectoriesOption(expandDirectories, cwd); + const directoryToGlobOptions = { + ...normalizeExpandDirectoriesOption(expandDirectories, cwd), + fs: fsImplementation, + }; return Promise.all(globTasks.map(async task => { let {patterns, options} = task; @@ -148017,54 +148687,70 @@ const generateTasks = async (patterns, options) => { options.ignore, ] = await Promise.all([ directoryToGlob(patterns, directoryToGlobOptions), - directoryToGlob(options.ignore, {cwd}), + directoryToGlob(options.ignore, {cwd, fs: fsImplementation}), ]); + // Adjust ignore patterns for parent directory references + options.ignore = adjustIgnorePatternsForParentDirectories(patterns, options.ignore); + return {patterns, options}; })); }; const generateTasksSync = (patterns, options) => { const globTasks = convertNegativePatterns(patterns, options); - const {cwd, expandDirectories} = options; + const {cwd, expandDirectories, fs: fsImplementation} = options; if (!expandDirectories) { - return globTasks; + return applyParentDirectoryIgnoreAdjustments(globTasks); } - const directoryToGlobSyncOptions = normalizeExpandDirectoriesOption(expandDirectories, cwd); + const directoryToGlobSyncOptions = { + ...normalizeExpandDirectoriesOption(expandDirectories, cwd), + fs: fsImplementation, + }; return globTasks.map(task => { let {patterns, options} = task; patterns = directoryToGlobSync(patterns, directoryToGlobSyncOptions); - options.ignore = directoryToGlobSync(options.ignore, {cwd}); + options.ignore = directoryToGlobSync(options.ignore, {cwd, fs: fsImplementation}); + + // Adjust ignore patterns for parent directory references + options.ignore = adjustIgnorePatternsForParentDirectories(patterns, options.ignore); + return {patterns, options}; }); }; const globby = normalizeArguments(async (patterns, options) => { - const [ - tasks, - filter, - ] = await Promise.all([ - generateTasks(patterns, options), - getFilter(options), - ]); + // Apply ignore files and get filter (reads .gitignore files once) + const {options: modifiedOptions, filter} = await applyIgnoreFilesAndGetFilter(options); + + // Generate tasks with modified options (includes gitignore patterns in ignore option) + const tasks = await generateTasks(patterns, modifiedOptions); const results = await Promise.all(tasks.map(task => out(task.patterns, task.options))); return unionFastGlobResults(results, filter); }); const globbySync = normalizeArgumentsSync((patterns, options) => { - const tasks = generateTasksSync(patterns, options); - const filter = getFilterSync(options); + // Apply ignore files and get filter (reads .gitignore files once) + const {options: modifiedOptions, filter} = applyIgnoreFilesAndGetFilterSync(options); + + // Generate tasks with modified options (includes gitignore patterns in ignore option) + const tasks = generateTasksSync(patterns, modifiedOptions); + const results = tasks.map(task => out.sync(task.patterns, task.options)); return unionFastGlobResults(results, filter); }); const globbyStream = normalizeArgumentsSync((patterns, options) => { - const tasks = generateTasksSync(patterns, options); - const filter = getFilterSync(options); + // Apply ignore files and get filter (reads .gitignore files once) + const {options: modifiedOptions, filter} = applyIgnoreFilesAndGetFilterSync(options); + + // Generate tasks with modified options (includes gitignore patterns in ignore option) + const tasks = generateTasksSync(patterns, modifiedOptions); + const streams = tasks.map(task => out.stream(task.patterns, task.options)); if (streams.length === 0) { @@ -148089,71 +148775,6 @@ const generateGlobTasksSync = normalizeArgumentsSync(generateTasksSync); const {convertPathToPattern} = out; -/***/ }), - -/***/ 51467: -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => { - -/* harmony export */ __nccwpck_require__.d(__webpack_exports__, { -/* harmony export */ b0: () => (/* binding */ toPath), -/* harmony export */ n5: () => (/* binding */ traversePathUp) -/* harmony export */ }); -/* unused harmony exports rootDirectory, execFile, execFileSync */ -/* harmony import */ var node_util__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(57975); -/* harmony import */ var node_child_process__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(31421); -/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(76760); -/* harmony import */ var node_url__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(73136); - - - - - -const execFileOriginal = (0,node_util__WEBPACK_IMPORTED_MODULE_0__.promisify)(node_child_process__WEBPACK_IMPORTED_MODULE_1__.execFile); - -function toPath(urlOrPath) { - return urlOrPath instanceof URL ? (0,node_url__WEBPACK_IMPORTED_MODULE_3__.fileURLToPath)(urlOrPath) : urlOrPath; -} - -function rootDirectory(pathInput) { - return path.parse(toPath(pathInput)).root; -} - -function traversePathUp(startPath) { - return { - * [Symbol.iterator]() { - let currentPath = node_path__WEBPACK_IMPORTED_MODULE_2__.resolve(toPath(startPath)); - let previousPath; - - while (previousPath !== currentPath) { - yield currentPath; - previousPath = currentPath; - currentPath = node_path__WEBPACK_IMPORTED_MODULE_2__.resolve(currentPath, '..'); - } - }, - }; -} - -const TEN_MEGABYTES_IN_BYTES = (/* unused pure expression or super */ null && (10 * 1024 * 1024)); - -async function execFile(file, arguments_, options = {}) { - return execFileOriginal(file, arguments_, { - maxBuffer: TEN_MEGABYTES_IN_BYTES, - ...options, - }); -} - -function execFileSync(file, arguments_ = [], options = {}) { - return execFileSyncOriginal(file, arguments_, { - maxBuffer: TEN_MEGABYTES_IN_BYTES, - encoding: 'utf8', - stdio: 'pipe', - ...options, - }); -} - - - - /***/ }), /***/ 39586: diff --git a/package.json b/package.json index a545965..6bafd3e 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@actions/github": "6.0.1", "execa": "9.6.0", "find-up-simple": "1.0.1", - "globby": "15.0.0", + "globby": "16.0.0", "json5": "2.2.3", "smol-toml": "1.5.2", "string-argv": "0.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96192be..713c9f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: 1.0.1 version: 1.0.1 globby: - specifier: 15.0.0 - version: 15.0.0 + specifier: 16.0.0 + version: 16.0.0 json5: specifier: 2.2.3 version: 2.2.3 @@ -959,8 +959,8 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - globby@15.0.0: - resolution: {integrity: sha512-oB4vkQGqlMl682wL1IlWd02tXCbquGWM4voPEI85QmNKCaw8zGTm1f1rubFgkg3Eli2PtKlFgrnmUqasbQWlkw==} + globby@16.0.0: + resolution: {integrity: sha512-ejy4TJFga99yW6Q0uhM3pFawKWZmtZzZD/v/GwI5+9bCV5Ew+D2pSND6W7fUes5UykqSsJkUfxFVdRh7Q1+P3Q==} engines: {node: '>=20'} gopd@1.2.0: @@ -1067,6 +1067,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} @@ -1300,10 +1304,6 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - path-type@6.0.0: - resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} - engines: {node: '>=18'} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1595,6 +1595,10 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} + unified@9.2.2: resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} @@ -1935,9 +1939,9 @@ snapshots: - encoding - mocha - '@covector/assemble@0.12.0(mocha@10.4.0)': + '@covector/assemble@0.12.0': dependencies: - '@covector/command': 0.8.0(mocha@10.4.0) + '@covector/command': 0.8.0 '@covector/files': 0.8.0 effection: 2.0.8(mocha@10.4.0) js-yaml: 4.1.0 @@ -1948,10 +1952,9 @@ snapshots: unified: 9.2.2 transitivePeerDependencies: - encoding - - mocha - supports-color - '@covector/changelog@0.12.0(mocha@10.4.0)': + '@covector/changelog@0.12.0': dependencies: '@covector/files': 0.8.0 effection: 2.0.8(mocha@10.4.0) @@ -1961,16 +1964,14 @@ snapshots: unified: 9.2.2 transitivePeerDependencies: - encoding - - mocha - supports-color - '@covector/command@0.8.0(mocha@10.4.0)': + '@covector/command@0.8.0': dependencies: - '@effection/process': 2.1.4(mocha@10.4.0) + '@effection/process': 2.1.4 effection: 2.0.8(mocha@10.4.0) transitivePeerDependencies: - encoding - - mocha '@covector/files@0.8.0': dependencies: @@ -2017,8 +2018,10 @@ snapshots: dependencies: effection: 2.0.8(mocha@10.4.0) mocha: 10.4.0 + transitivePeerDependencies: + - encoding - '@effection/process@2.1.4(mocha@10.4.0)': + '@effection/process@2.1.4': dependencies: cross-spawn: 7.0.6 ctrlc-windows: 2.2.0 @@ -2026,7 +2029,6 @@ snapshots: shellwords: 0.1.1 transitivePeerDependencies: - encoding - - mocha '@effection/stream@2.0.6': dependencies: @@ -2539,9 +2541,9 @@ snapshots: dependencies: '@clack/prompts': 0.7.0 '@covector/apply': 0.10.0(mocha@10.4.0) - '@covector/assemble': 0.12.0(mocha@10.4.0) - '@covector/changelog': 0.12.0(mocha@10.4.0) - '@covector/command': 0.8.0(mocha@10.4.0) + '@covector/assemble': 0.12.0 + '@covector/changelog': 0.12.0 + '@covector/command': 0.8.0 '@covector/files': 0.8.0 effection: 2.0.8(mocha@10.4.0) globby: 11.1.0 @@ -2881,14 +2883,14 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - globby@15.0.0: + globby@16.0.0: dependencies: '@sindresorhus/merge-streams': 4.0.0 fast-glob: 3.3.3 ignore: 7.0.5 - path-type: 6.0.0 + is-path-inside: 4.0.0 slash: 5.1.0 - unicorn-magic: 0.3.0 + unicorn-magic: 0.4.0 gopd@1.2.0: {} @@ -2973,6 +2975,8 @@ snapshots: is-number@7.0.0: {} + is-path-inside@4.0.0: {} + is-plain-obj@2.1.0: {} is-plain-obj@4.1.0: {} @@ -3207,8 +3211,6 @@ snapshots: path-type@4.0.0: {} - path-type@6.0.0: {} - picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -3482,6 +3484,8 @@ snapshots: unicorn-magic@0.3.0: {} + unicorn-magic@0.4.0: {} + unified@9.2.2: dependencies: '@types/unist': 2.0.11 diff --git a/src/utils.ts b/src/utils.ts index f2f007b..c815ba2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -193,6 +193,7 @@ export function getTauriDir(): string | null { const tauriConfPaths = globbySync( ['**/tauri.conf.json', '**/tauri.conf.json5', '**/Tauri.toml'], { + // globby v16 changes this to also look into parent dir. Monitor this closely and disable if needed. gitignore: true, cwd: projectPath, // Forcefully ignore target and node_modules dirs