@wordpress/env
Version:
A zero-config, self contained local WordPress environment for development and testing.
77 lines (68 loc) • 2.17 kB
JavaScript
;
/**
* External dependencies
*/
const util = require( 'util' );
const fs = require( 'fs' );
const stream = require( 'stream' );
const path = require( 'path' );
/**
* Promisified dependencies
*/
const exists = util.promisify( fs.exists );
const readDir = util.promisify( fs.readdir );
const finished = util.promisify( stream.finished );
/**
* Detects whether the given directory is a WordPress installation, a plugin or a theme.
*
* @param {string} directoryPath The directory to detect.
* @return {Promise<string|null>} 'core' if the directory is a WordPress installation, 'plugin' if it is a plugin, 'theme' if it is a theme, or null if we can't tell.
*/
module.exports = async function detectDirectoryType( directoryPath ) {
// If we have a `wp-includes/version.php` file, then this is a Core install.
if (
await exists(
path.resolve( directoryPath, 'wp-includes', 'version.php' )
)
) {
return 'core';
}
let result = null;
// Use absolute paths to files so that we can properly read
// dependencies not in the current working directory.
const absolutePath = path.resolve( directoryPath );
// Race multiple file read streams against each other until
// a plugin or theme header is found.
const files = ( await readDir( absolutePath ) )
.filter(
( file ) =>
path.extname( file ) === '.php' ||
path.basename( file ) === 'style.css'
)
.map( ( fileName ) => path.join( absolutePath, fileName ) );
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 ) {
result = 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 result;
};