import path from 'path' ; import fs from 'fs-extra' ; import resolvePkg from 'resolve-pkg' ; import * as git from './git' ; export async function installModules ( cwd ) { 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 ) => { 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 , directory ? ) { const cwd = await git . bootstrap ( fixture , directory ) ; await installModules ( cwd ) ; return cwd ; } function findParentPath ( parentPath , dirname ) { 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 ; }