All files / src/utils recursive-execte.ts

26.32% Statements 10/38
23.08% Branches 3/13
33.33% Functions 3/9
24.24% Lines 8/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 7815x 15x 15x               15x                                                             15x         5x   5x 5x                                                        
import { join, isAbsolute } from 'path'
import glob from 'micromatch'
import { Effect } from '@/internal'
 
 
interface Err {
  readonly dir: string
  readonly message: string
}
 
const execteFuncInSubproject = async(func: Function, dir: string, options: any, errors: Err[]): Promise<void> => {
  const stats = await Effect.fs.stat(dir)
  if (!stats.isDirectory()) return
 
  if (await Effect.fs.pathExists(join(dir, '.milirc.yml'))) {
    Effect.logger.info(`check ${dir}`)
    try {
      const newOptions = { ...options, cwd: dir }
      await func(newOptions)
    } catch (e) {
      errors.push({ dir, message: e.message })
    } finally {
      console.log('\n')
    }
  }
 
  let folders = await Effect.fs.readdir(dir)
  folders = folders
    .map(filename => join(dir, filename))
    .filter(filepath => !glob.isMatch(filepath, options.ignore))
 
  /**
   * NOTE: There should upgrade one by one,
   *       because it's possible that two of these projects were used same template,
   *       resulting in template download conflict.
   */
  for (const folder of folders) {
    await execteFuncInSubproject(func, folder, options, errors)
  }
}
 
export default (func: Function) => async(options: any): Promise<void> => {
  const {
    cwd = process.cwd(),
    ignore = [],
    recursive = false,
  } = options
 
  Eif (!recursive) {
    await func(options)
  } else {
    const absolutePathIgnored = ignore.map((item: string) => {
      if (!isAbsolute(item)) return join(cwd, item)
      return item
    })
 
    const newOptions = {
      ...options,
      ignore: absolutePathIgnored,
    }
    const errors: Err[] = []
    await execteFuncInSubproject(func, cwd, newOptions, errors)
 
    if (errors.length) {
      errors.forEach(error => {
        Effect.logger.error([
          '',
          `Fail: ${error.dir}.`,
          `Because: ${error.message}`,
          '',
        ].join('\n'))
      })
 
      throw new Error('Please fix the error.')
    }
  }
}