Skip to content

Commit b468ff1

Browse files
author
Marcus Pousette
committed
fix: use fast-glob for resolving projects
1 parent dc5c226 commit b468ff1

File tree

5 files changed

+61
-155
lines changed

5 files changed

+61
-155
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@
283283
"micromark-extension-gfm-strikethrough": "^2.0.0",
284284
"micromark-extension-gfm-table": "^2.0.0",
285285
"micromark-extension-gfm-task-list-item": "^2.0.1",
286-
"minimatch": "^9.0.0",
286+
"fast-glob": "^3.3.2",
287287
"mocha": "^10.0.0",
288288
"npm-package-json-lint": "^7.0.0",
289289
"nyc": "^15.1.0",

src/check-project/index.js

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import prompt from 'prompt'
1010
import semver from 'semver'
1111
import yargsParser from 'yargs-parser'
1212
import {
13+
getSubprojectDirectories,
1314
isMonorepoProject,
14-
glob,
1515
usesReleasePlease
1616
} from '../utils.js'
1717
import { checkBuildFiles } from './check-build-files.js'
@@ -114,32 +114,27 @@ async function processMonorepo (projectDir, manifest, branchName, repoUrl, ciFil
114114

115115
const projectDirs = []
116116

117-
for (const workspace of workspaces) {
118-
for await (const subProjectDir of glob('.', workspace, {
119-
cwd: projectDir,
120-
absolute: true
121-
})) {
122-
const stat = await fs.stat(subProjectDir)
117+
for (const subProjectDir of await getSubprojectDirectories(projectDir, workspaces)) {
118+
const stat = await fs.stat(subProjectDir)
123119

124-
if (!stat.isDirectory()) {
125-
continue
126-
}
120+
if (!stat.isDirectory()) {
121+
continue
122+
}
127123

128-
const manfest = path.join(subProjectDir, 'package.json')
124+
const manfest = path.join(subProjectDir, 'package.json')
129125

130-
if (!fs.existsSync(manfest)) {
131-
continue
132-
}
126+
if (!fs.existsSync(manfest)) {
127+
continue
128+
}
133129

134-
const pkg = fs.readJSONSync(manfest)
135-
const homePage = `${repoUrl}/tree/${branchName}${subProjectDir.substring(projectDir.length)}`
130+
const pkg = fs.readJSONSync(manfest)
131+
const homePage = `${repoUrl}/tree/${branchName}${subProjectDir.substring(projectDir.length)}`
136132

137-
console.info('Found monorepo project', pkg.name)
133+
console.info('Found monorepo project', pkg.name)
138134

139-
await processModule(subProjectDir, pkg, branchName, repoUrl, homePage, ciFile, manifest)
135+
await processModule(subProjectDir, pkg, branchName, repoUrl, homePage, ciFile, manifest)
140136

141-
projectDirs.push(subProjectDir)
142-
}
137+
projectDirs.push(subProjectDir)
143138
}
144139

145140
await alignMonorepoProjectDependencies(projectDirs)

src/release.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { execa } from 'execa'
55
import fs from 'fs-extra'
66
import Listr from 'listr'
77
import { calculateSiblingVersion } from './check-project/utils.js'
8-
import { isMonorepoProject, isMonorepoRoot, hasDocs, glob } from './utils.js'
8+
import { isMonorepoProject, isMonorepoRoot, hasDocs, getSubprojectDirectories } from './utils.js'
99

1010
/**
1111
* @typedef {import("./types").GlobalOptions} GlobalOptions
@@ -151,18 +151,13 @@ async function calculateSiblingVersions (rootDir, workspaces) {
151151
/** @type {Record<string, string>} */
152152
const siblingVersions = {}
153153

154-
for (const workspace of workspaces) {
155-
for await (const subProjectDir of glob(rootDir, workspace, {
156-
cwd: rootDir,
157-
absolute: true
158-
})) {
159-
const pkg = JSON.parse(fs.readFileSync(path.join(subProjectDir, 'package.json'), {
160-
encoding: 'utf-8'
161-
}))
162-
163-
siblingVersions[pkg.name] = calculateSiblingVersion(pkg.version)
164-
packageDirs.push(subProjectDir)
165-
}
154+
for (const subProjectDir of await getSubprojectDirectories(rootDir, workspaces)) {
155+
const pkg = JSON.parse(fs.readFileSync(path.join(subProjectDir, 'package.json'), {
156+
encoding: 'utf-8'
157+
}))
158+
159+
siblingVersions[pkg.name] = calculateSiblingVersion(pkg.version)
160+
packageDirs.push(subProjectDir)
166161
}
167162

168163
return {

src/test-dependant/index.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import os from 'os'
44
import path from 'path'
55
import fs from 'fs-extra'
66
import {
7-
exec,
8-
glob
7+
exec, getSubprojectDirectories
98
} from '../utils.js'
109

1110
/**
@@ -197,10 +196,8 @@ const testMonoRepo = async (targetDir, deps, scriptName) => {
197196
}
198197

199198
// test each package that depends on passed deps
200-
for (const pattern of config.workspaces) {
201-
for await (const match of glob(targetDir, pattern)) {
202-
await testModule(path.join(targetDir, match), deps, scriptName)
203-
}
199+
for (const match of await getSubprojectDirectories(targetDir, config.workspaces)) {
200+
await testModule(path.join(targetDir, match), deps, scriptName)
204201
}
205202
}
206203

src/utils.js

Lines changed: 34 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ import { download } from '@electron/get'
1414
import envPaths from 'env-paths'
1515
import { execa } from 'execa'
1616
import extract from 'extract-zip'
17+
import fg from 'fast-glob'
1718
import fs from 'fs-extra'
1819
import kleur from 'kleur'
1920
import Listr from 'listr'
20-
import { minimatch } from 'minimatch'
2121
import PQueue from 'p-queue'
2222
import lockfile from 'proper-lockfile'
2323
import { readPackageUpSync } from 'read-pkg-up'
@@ -355,7 +355,7 @@ export async function everyMonorepoProject (projectDir, fn, opts) {
355355
}
356356

357357
/** @type {Record<string, Project>} */
358-
const projects = parseProjects(projectDir, workspaces)
358+
const projects = await parseProjects(projectDir, workspaces)
359359

360360
checkForCircularDependencies(projects)
361361

@@ -402,40 +402,45 @@ export async function everyMonorepoProject (projectDir, fn, opts) {
402402
* @param {string} projectDir
403403
* @param {string[]} workspaces
404404
*/
405-
export function parseProjects (projectDir, workspaces) {
405+
export const getSubprojectDirectories = async (projectDir, workspaces) => fg.glob(workspaces, {
406+
cwd: projectDir,
407+
onlyFiles: false
408+
})
409+
410+
/**
411+
*
412+
* @param {string} projectDir
413+
* @param {string[]} workspaces
414+
*/
415+
export async function parseProjects (projectDir, workspaces) {
406416
/** @type {Record<string, Project>} */
407417
const projects = {}
408418

409-
for (const workspace of workspaces) {
410-
for (const subProjectDir of glob('.', workspace, {
411-
cwd: projectDir,
412-
absolute: true
413-
})) {
414-
const stat = fs.statSync(subProjectDir)
419+
for (const subProjectDir of await getSubprojectDirectories(projectDir, workspaces)) {
420+
const stat = fs.statSync(subProjectDir)
415421

416-
if (!stat.isDirectory()) {
417-
continue
418-
}
422+
if (!stat.isDirectory()) {
423+
continue
424+
}
419425

420-
const manfest = path.join(subProjectDir, 'package.json')
426+
const manfest = path.join(subProjectDir, 'package.json')
421427

422-
if (!fs.existsSync(manfest)) {
423-
continue
424-
}
428+
if (!fs.existsSync(manfest)) {
429+
continue
430+
}
425431

426-
const pkg = fs.readJSONSync(manfest)
427-
428-
projects[pkg.name] = {
429-
manifest: pkg,
430-
dir: subProjectDir,
431-
siblingDependencies: [],
432-
dependencies: [
433-
...Object.keys(pkg.dependencies ?? {}),
434-
...Object.keys(pkg.devDependencies ?? {}),
435-
...Object.keys(pkg.optionalDependencies ?? {}),
436-
...Object.keys(pkg.peerDependencies ?? {})
437-
]
438-
}
432+
const pkg = fs.readJSONSync(manfest)
433+
434+
projects[pkg.name] = {
435+
manifest: pkg,
436+
dir: subProjectDir,
437+
siblingDependencies: [],
438+
dependencies: [
439+
...Object.keys(pkg.dependencies ?? {}),
440+
...Object.keys(pkg.devDependencies ?? {}),
441+
...Object.keys(pkg.optionalDependencies ?? {}),
442+
...Object.keys(pkg.peerDependencies ?? {})
443+
]
439444
}
440445
}
441446

@@ -504,92 +509,6 @@ function checkForCircularDependencies (projects) {
504509
}
505510
}
506511

507-
/**
508-
* @typedef {object} GlobOptions
509-
* @property {string} [cwd] The current working directory
510-
* @property {boolean} [absolute] If true produces absolute paths (default: false)
511-
* @property {boolean} [nodir] If true yields file paths and skip directories (default: false)
512-
*
513-
* Iterable filename pattern matcher
514-
*
515-
* @param {string} dir
516-
* @param {string} pattern
517-
* @param {GlobOptions & import('minimatch').MinimatchOptions} [options]
518-
* @returns {Generator<string, void, undefined>}
519-
*/
520-
export function * glob (dir, pattern, options = {}) {
521-
const absoluteDir = path.resolve(dir)
522-
const relativeDir = path.relative(options.cwd ?? process.cwd(), dir)
523-
524-
const stats = fs.statSync(absoluteDir)
525-
526-
if (stats.isDirectory()) {
527-
for (const entry of _glob(absoluteDir, '', pattern, options)) {
528-
yield entry
529-
}
530-
531-
return
532-
}
533-
534-
if (minimatch(relativeDir, pattern, options)) {
535-
yield options.absolute === true ? absoluteDir : relativeDir
536-
}
537-
}
538-
539-
/**
540-
* @param {string} base
541-
* @param {string} dir
542-
* @param {string} pattern
543-
* @param {GlobOptions & import('minimatch').MinimatchOptions} options
544-
* @returns {Generator<string, void, undefined>}
545-
*/
546-
function * _glob (base, dir, pattern, options) {
547-
const p = path.join(base, dir)
548-
549-
if (!fs.existsSync(p)) {
550-
return
551-
}
552-
553-
const stats = fs.statSync(p)
554-
555-
if (!stats.isDirectory()) {
556-
return
557-
}
558-
559-
const d = fs.opendirSync(p)
560-
561-
try {
562-
while (true) {
563-
const entry = d.readSync()
564-
565-
if (entry == null) {
566-
break
567-
}
568-
569-
const relativeEntryPath = path.join(dir, entry.name)
570-
const absoluteEntryPath = path.join(base, dir, entry.name)
571-
572-
let match = minimatch(relativeEntryPath, pattern, options)
573-
574-
const isDirectory = entry.isDirectory()
575-
576-
if (isDirectory && options.nodir === true) {
577-
match = false
578-
}
579-
580-
if (match) {
581-
yield options.absolute === true ? absoluteEntryPath : relativeEntryPath
582-
}
583-
584-
if (isDirectory) {
585-
yield * _glob(base, relativeEntryPath, pattern, options)
586-
}
587-
}
588-
} finally {
589-
d.closeSync()
590-
}
591-
}
592-
593512
/**
594513
*
595514
* @param {Error} error

0 commit comments

Comments
 (0)