import path from 'path'; import fs from 'fs-extra'; import resolvePkg from 'resolve-pkg'; import * as git from './git'; export async function installModules(cwd: string) { const manifestPath = path.join(cwd, 'package.json'); const targetModulesPath = path.join(cwd, 'node_modules'); if (await fs.pathExists(manifestPath)) { const {dependencies = {}, devDependencies = {}} = await fs.readJson( manifestPath ); const deps = Object.keys({...dependencies, ...devDependencies}); await Promise.all( deps.map(async (dependency: any) => { const sourcePath = resolvePkg(dependency); if (!sourcePath) { throw new Error(`Could not resolve dependency ${dependency}`); } const sourceModulesPath = findParentPath(sourcePath, 'node_modules'); if (!sourceModulesPath) { throw new Error(`Could not determine node_modules for ${sourcePath}`); } const relativePath = path.relative(sourceModulesPath, sourcePath); const targetPath = path.join(targetModulesPath, relativePath); await fs.mkdirp(path.join(targetPath, '..')); await fs.symlink(sourcePath, targetPath); }) ); } } export async function bootstrap(fixture: string, directory?: string) { const cwd = await git.bootstrap(fixture, directory); await installModules(cwd); return cwd; } function findParentPath( parentPath: string, dirname: string ): string | undefined { const rawFragments = parentPath.split(path.sep); const {matched, fragments} = rawFragments.reduceRight( ({fragments, matched}, item) => { if (item === dirname && !matched) { return {fragments, matched: true}; } if (!matched && fragments.length > 0) { fragments.pop(); } return {fragments, matched}; }, {fragments: rawFragments, matched: false} ); return matched ? fragments.join(path.sep) : undefined; }