@@ -20,7 +20,7 @@ import envPaths from 'env-paths'
2020import lockfile from 'proper-lockfile'
2121import { fileURLToPath } from 'url'
2222import Listr from 'listr'
23- import glob from 'it-glob '
23+ import minimatch from 'minimatch '
2424
2525const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) )
2626const EnvPaths = envPaths ( 'aegir' , { suffix : '' } )
@@ -451,3 +451,65 @@ function checkForCircularDependencies (projects) {
451451 }
452452 }
453453}
454+
455+ /**
456+ * @typedef {object } GlobOptions
457+ * @property {string } [cwd] The current working directory
458+ * @property {boolean } [absolute] If true produces absolute paths (default: false)
459+ * @property {boolean } [nodir] If true yields file paths and skip directories (default: false)
460+ *
461+ * Async iterable filename pattern matcher
462+ *
463+ * @param {string } dir
464+ * @param {string } pattern
465+ * @param {GlobOptions & import('minimatch').IOptions } [options]
466+ * @returns {AsyncGenerator<string, void, undefined> }
467+ */
468+ export async function * glob ( dir , pattern , options = { } ) {
469+ const absoluteDir = path . resolve ( dir )
470+ const relativeDir = path . relative ( options . cwd ?? process . cwd ( ) , dir )
471+
472+ const stats = await fs . stat ( absoluteDir )
473+
474+ if ( stats . isDirectory ( ) ) {
475+ for await ( const entry of _glob ( absoluteDir , '' , pattern , options ) ) {
476+ yield entry
477+ }
478+
479+ return
480+ }
481+
482+ if ( minimatch ( relativeDir , pattern , options ) ) {
483+ yield options . absolute === true ? absoluteDir : relativeDir
484+ }
485+ }
486+
487+ /**
488+ * @param {string } base
489+ * @param {string } dir
490+ * @param {string } pattern
491+ * @param {GlobOptions & import('minimatch').IOptions } options
492+ * @returns {AsyncGenerator<string, void, undefined> }
493+ */
494+ async function * _glob ( base , dir , pattern , options ) {
495+ for await ( const entry of await fs . opendir ( path . join ( base , dir ) ) ) {
496+ const relativeEntryPath = path . join ( dir , entry . name )
497+ const absoluteEntryPath = path . join ( base , dir , entry . name )
498+
499+ let match = minimatch ( relativeEntryPath , pattern , options )
500+
501+ const isDirectory = entry . isDirectory ( )
502+
503+ if ( isDirectory && options . nodir === true ) {
504+ match = false
505+ }
506+
507+ if ( match ) {
508+ yield options . absolute === true ? absoluteEntryPath : relativeEntryPath
509+ }
510+
511+ if ( isDirectory ) {
512+ yield * _glob ( base , relativeEntryPath , pattern , options )
513+ }
514+ }
515+ }
0 commit comments