diff --git a/packages/env/README.md b/packages/env/README.md index 9be3fe8e36709c..1f06dabf9ce710 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -7,7 +7,7 @@ ```sh $ npm -g i @wordpress/env -$ cd path/to/gutenberg # WordPress install will be in path/to/gutenberg-wordpress. +$ cd path/to/plugin-or-theme # WordPress install will be in path/to/plugin-or-theme-wordpress. $ wp-env --help diff --git a/packages/env/lib/create-docker-compose-config.js b/packages/env/lib/create-docker-compose-config.js index 6cc4b8ddfabf1d..f5971723148b57 100644 --- a/packages/env/lib/create-docker-compose-config.js +++ b/packages/env/lib/create-docker-compose-config.js @@ -1,14 +1,15 @@ module.exports = function createDockerComposeConfig( - pluginPath, - pluginName, - pluginTestsPath + cwd, + cwdName, + cwdTestsPath, + context ) { const commonVolumes = ` - - ${ pluginPath }/:/var/www/html/wp-content/plugins/${ pluginName }/ - - ${ pluginPath }${ pluginTestsPath }/e2e-tests/mu-plugins/:/var/www/html/wp-content/mu-plugins/ - - ${ pluginPath }${ pluginTestsPath }/e2e-tests/plugins/:/var/www/html/wp-content/plugins/${ pluginName }-test-plugins/`; + - ${ cwd }/:/var/www/html/wp-content/${ context.type }s/${ cwdName }/ + - ${ cwd }${ cwdTestsPath }/e2e-tests/mu-plugins/:/var/www/html/wp-content/mu-plugins/ + - ${ cwd }${ cwdTestsPath }/e2e-tests/plugins/:/var/www/html/wp-content/plugins/${ cwdName }-test-plugins/`; const volumes = ` - - ${ pluginPath }/../${ pluginName }-wordpress/:/var/www/html/${ commonVolumes }`; + - ${ cwd }/../${ cwdName }-wordpress/:/var/www/html/${ commonVolumes }`; const testsVolumes = ` - tests-wordpress:/var/www/html/${ commonVolumes }`; return `version: '2.1' diff --git a/packages/env/lib/detect-context.js b/packages/env/lib/detect-context.js new file mode 100644 index 00000000000000..afc23f6dd5f6f3 --- /dev/null +++ b/packages/env/lib/detect-context.js @@ -0,0 +1,45 @@ +'use strict'; +/** + * External dependencies + */ +const util = require( 'util' ); +const fs = require( 'fs' ); +const stream = require( 'stream' ); +const path = require( 'path' ); + +/** + * Promisified dependencies + */ +const readDir = util.promisify( fs.readdir ); +const finished = util.promisify( stream.finished ); + +module.exports = async function detectContext() { + const context = {}; + + // Race multiple file read streams against each other until + // a plugin or theme header is found. + const files = ( await readDir( './' ) ).filter( + ( file ) => path.extname( file ) === '.php' || path.basename( file ) === 'style.css' + ); + const streams = []; + for ( const file of files ) { + const fileStream = fs.createReadStream( file, 'utf8' ); + fileStream.on( 'data', ( text ) => { + const [ , type ] = text.match( /(Plugin|Theme) Name: .*[\r\n]/ ) || []; + if ( type ) { + context.type = type.toLowerCase(); + + // Stop the creation of new streams by mutating the iterated array. We can't `break`, because we are inside a function. + files.splice( 0 ); + fileStream.destroy(); + streams.forEach( ( otherFileStream ) => otherFileStream.destroy() ); + } + } ); + streams.push( fileStream ); + } + await Promise.all( + streams.map( ( fileStream ) => finished( fileStream ).catch( () => {} ) ) + ); + + return context; +}; diff --git a/packages/env/lib/env.js b/packages/env/lib/env.js index 3b982c0e143f56..c2ba83ac24c221 100644 --- a/packages/env/lib/env.js +++ b/packages/env/lib/env.js @@ -11,12 +11,13 @@ const wait = require( 'util' ).promisify( setTimeout ); /** * Internal dependencies */ +const detectContext = require( './detect-context' ); const createDockerComposeConfig = require( './create-docker-compose-config' ); // Config Variables -const pluginPath = process.cwd(); -const pluginName = path.basename( pluginPath ); -const pluginTestsPath = fs.existsSync( './packages' ) ? '/packages' : ''; +const cwd = process.cwd(); +const cwdName = path.basename( cwd ); +const cwdTestsPath = fs.existsSync( './packages' ) ? '/packages' : ''; const dockerComposeOptions = { config: path.join( __dirname, 'docker-compose.yml' ), }; @@ -34,16 +35,18 @@ const setupSite = ( isTests = false ) => isTests ? process.env.WP_ENV_TESTS_PORT || 8889 : process.env.WP_ENV_PORT || 8888 - } --title=${ pluginName } --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, + } --title=${ cwdName } --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, isTests ); -const activatePlugin = ( isTests = false ) => - wpCliRun( `wp plugin activate ${ pluginName }`, isTests ); +const activateContext = ( context, isTests = false ) => + wpCliRun( `wp ${ context.type } activate ${ cwdName }`, isTests ); const resetDatabase = ( isTests = false ) => wpCliRun( 'wp db reset --yes', isTests ); module.exports = { async start( { ref, spinner = {} } ) { + const context = await detectContext(); + spinner.text = `Downloading WordPress@${ ref } 0/100%.`; const gitFetchOptions = { fetchOpts: { @@ -64,7 +67,7 @@ module.exports = { }; // Clone or get the repo. - const repoPath = `../${ pluginName }-wordpress/`; + const repoPath = `../${ cwdName }-wordpress/`; const repo = await NodeGit.Clone( 'https://github.com/WordPress/WordPress.git', repoPath, @@ -94,10 +97,10 @@ module.exports = { } spinner.text = `Downloading WordPress@${ ref } 100/100%.`; - spinner.text = `Installing WordPress@${ ref }.`; + spinner.text = `Starting WordPress@${ ref }.`; fs.writeFileSync( dockerComposeOptions.config, - createDockerComposeConfig( pluginPath, pluginName, pluginTestsPath ) + createDockerComposeConfig( cwd, cwdName, cwdTestsPath, context ) ); // These will bring up the database container, @@ -121,11 +124,14 @@ module.exports = { .catch( retryableSiteSetup ) .catch( retryableSiteSetup ); - await Promise.all( [ activatePlugin(), activatePlugin( true ) ] ); + await Promise.all( [ + activateContext( context ), + activateContext( context, true ), + ] ); // Remove dangling containers and finish. await dockerCompose.rm( dockerComposeOptions ); - spinner.text = `Installed WordPress@${ ref }.`; + spinner.text = `Started WordPress@${ ref }.`; }, async stop( { spinner = {} } ) { @@ -135,6 +141,8 @@ module.exports = { }, async clean( { environment, spinner } ) { + const context = await detectContext(); + const description = `${ environment } environment${ environment === 'all' ? 's' : '' }`; @@ -146,7 +154,7 @@ module.exports = { tasks.push( resetDatabase() .then( setupSite ) - .then( activatePlugin ) + .then( activateContext.bind( null, context ) ) .catch( () => {} ) ); } @@ -154,7 +162,7 @@ module.exports = { tasks.push( resetDatabase( true ) .then( setupSite.bind( null, true ) ) - .then( activatePlugin.bind( null, true ) ) + .then( activateContext.bind( null, context, true ) ) .catch( () => {} ) ); } diff --git a/packages/env/tests/cli.test.js b/packages/env/test/cli.js similarity index 100% rename from packages/env/tests/cli.test.js rename to packages/env/test/cli.js