async function copyPackageWithDependenciesRecursive()

in desktop/scripts/copy-package-with-dependencies.tsx [43:120]


async function copyPackageWithDependenciesRecursive(
  packageDir: string,
  targetDir: string,
  rootTargetDir: string,
) {
  if (await fs.pathExists(targetDir)) {
    return;
  }
  await fs.mkdirp(targetDir);
  if ((await fs.stat(packageDir)).isSymbolicLink()) {
    packageDir = await fs.readlink(packageDir);
  }
  const ignores = await fs
    .readFile(path.join(packageDir, '.buildignore'), 'utf-8')
    .then((l) => l.split('\n'))
    .catch((_e) => [])
    .then((l: Array<string>) => ignore().add(DEFAULT_BUILD_IGNORES.concat(l)));
  await fs.copy(packageDir, targetDir, {
    dereference: true,
    recursive: true,
    filter: (src) => {
      const relativePath = path.relative(packageDir, src);
      return relativePath === '' || !ignores.ignores(relativePath);
    },
  });
  const pkg = await fs.readJson(path.join(packageDir, 'package.json'));
  const dependencies = (pkg.dependencies ?? {}) as {[key: string]: string};
  let unresolvedCount = Object.keys(dependencies).length;
  let curPackageDir = packageDir;
  let curTargetDir = targetDir;
  while (unresolvedCount > 0) {
    const curPackageModulesDir = path.join(curPackageDir, 'node_modules');
    if (await fs.pathExists(curPackageModulesDir)) {
      for (const moduleName of Object.keys(dependencies)) {
        const curModulePath = path.join(
          curPackageModulesDir,
          ...moduleName.split('/'),
        );
        const targetModulePath = path.join(
          curTargetDir,
          'node_modules',
          ...moduleName.split('/'),
        );
        if (await fs.pathExists(curModulePath)) {
          await copyPackageWithDependenciesRecursive(
            curModulePath,
            targetModulePath,
            rootTargetDir,
          );
          delete dependencies[moduleName];
          unresolvedCount--;
        }
      }
    }

    const parentPackageDir = getParentPackageDir(curPackageDir);
    if (
      !parentPackageDir ||
      parentPackageDir === '' ||
      parentPackageDir === curPackageDir
    ) {
      break;
    }
    curPackageDir = parentPackageDir;

    curTargetDir = getParentPackageDir(curTargetDir);
    if (!curTargetDir || curTargetDir.length < rootTargetDir.length) {
      curTargetDir = rootTargetDir;
    }
  }

  if (unresolvedCount > 0) {
    for (const unresolvedDependency of Object.keys(dependencies)) {
      console.error(`Cannot resolve ${unresolvedDependency} in ${packageDir}`);
    }
    process.exit(1);
  }
}