Skip to content

Commit

Permalink
Merge pull request #30 from moderntribe/feat/composer-switch
Browse files Browse the repository at this point in the history
Add the target command.
  • Loading branch information
borkweb authored Jul 30, 2020
2 parents a0bb1aa + 0b5f0db commit 19ae1ed
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 13 deletions.
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.5.0] - 2020-07-30
### Added

- Added the `tric target` command to support running the same command against multiple targets.

## [0.4.9] - 2020-07-07
### Changed

Expand Down
60 changes: 60 additions & 0 deletions src/commands/target.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* Handles the execution of the `target` command.
*
* @packag Tribe\Test
*/

namespace Tribe\Test;

if ( $is_help ) {
echo "Runs a command on a set of targets.\n";
echo PHP_EOL;
echo colorize( "usage: <light_cyan>tric target</light_cyan>\n" );

return;
}

$targets = [];
do {
$last_target = ask( 'Target (return when done): ', null );
if ( $last_target && ensure_valid_target( $last_target, false ) ) {
$targets[] = $last_target;
} else {
continue;
}
} while ( $last_target );

$targets = array_unique( $targets );

echo yellow( "\nTargets: " ) . implode( ', ', $targets ) . "\n\n";

// Allow users to enter a command prefixing it with `tric` or not.
do {
$command_line = trim(
preg_replace( '/^\\s*tric/', '', ask( 'Command: ' )
)
);
} while ( ! $command_line );

echo "\n";

if ( preg_match( '/^n/i', ask(
colorize(
sprintf(
"<bold>Are you sure you want to run</bold> <light_cyan>%s</light_cyan> <bold>on</bold> <light_cyan>%s</light_cyan>?",
$command_line,
implode( ', ', $targets )
)
),
'yes'
) ) ) {
echo "\nDone!";

return;
}

$command = preg_split( '/\\s/', $command_line );
$base_command = array_shift( $command );

exit( execute_command_pool( build_targets_command_pool( $targets, $base_command, $command, [ 'common' ] ) ) );
92 changes: 80 additions & 12 deletions src/tric.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ function tric_here_is_site() {
* - If tric here was done on the site level, "site" is also a valid target.
*
* @param string $target The target to check in the valid list of targets.
* @param bool $exit Whether to exit if the target is invalid, or to return `false`.
*
* @return string|false $target The validated target or `false` to indicate the target is not valid if the `$exit`
* parameter is set to `false`.
*/
function ensure_valid_target( $target ) {
function ensure_valid_target( $target, $exit = true ) {
$targets_str = '';
$plugins = array_keys( dev_plugins() );
$themes = array_keys( dev_themes() );
Expand All @@ -50,13 +54,23 @@ function ensure_valid_target( $target ) {

if ( false === $target ) {
echo magenta( "This command needs a target argument; available targets are:\n${targets_str}\n" );
exit( 1 );
if ( $exit ) {
exit( 1 );
}

return false;
}

if ( ! in_array( $target, $targets, true ) ) {
echo magenta( "'{$target}' is not a valid target; available targets are:\n${targets_str}\n" );
exit( 1 );
if ( $exit ) {
exit( 1 );
}

return false;
}

return $target;
}

/**
Expand Down Expand Up @@ -783,36 +797,42 @@ function maybe_build_install_command_pool( $base_command, $target, array $sub_di
* If any subdirectories are provided and are available in the target, then the user will be prompted to run the same
* command on those subdirectories.
*
* @param string $base_command The base service command to run, e.g. `npm`, `composer`, etc.
* @param array<string> $command The command to run, e.g. `['install','--save-dev']` in array format.
* @param string $base_command The base service command to run, e.g. `npm`, `composer`, etc.
* @param array<string> $command The command to run, e.g. `['install','--save-dev']` in array format.
* @param array<string> $sub_directories Sub directories to prompt for additional execution.
* @param string $using An optional target to use in place of the specified one.
*
* @return int Result of command execution.
* @return array The built command pool.
*/
function build_command_pool( string $base_command, array $command, array $sub_directories = [] ) {
$using = tric_target();
function build_command_pool( $base_command, array $command, array $sub_directories = [], $using = null ) {
$using_alias = $using;
$using = $using ?: tric_target();
$targets = [ 'target' ];

// Prompt for execution within subdirectories if enabled.
if ( getenv( 'TRIC_BUILD_SUBDIR' ) ) {
foreach ( $sub_directories as $dir ) {
$dir_name = $using_alias ? "{$using_alias}/{$dir}" : $dir;
$question = "\nWould you also like to run that {$base_command} command against {$dir_name}?";
if (
file_exists( tric_plugins_dir( "{$using}/{$dir}" ) )
&& ask( "\nWould you also like to run that {$base_command} command against {$dir}?", 'yes' )
&& ask( $question, 'yes' )
) {
$targets[] = $dir;
}
}
}

// Build the command process.
$command_process = static function( $target, $subnet = '') use ( $using, $base_command, $command, $sub_directories ) {
$prefix = "{$base_command}:" . light_cyan( $target );
$command_process = static function( $target, $subnet = '' ) use ( $using, $using_alias, $base_command, $command, $sub_directories ) {
$target_name = $using_alias ?: $target;
$prefix = "{$base_command}:" . light_cyan( $target_name );

// Execute command as the parent.
if ( 'target' !== $target ) {
tric_switch_target( "{$using}/{$target}" );
$prefix = "{$base_command}:" . yellow( $target );
$sub_target_name = $using_alias ? "{$using_alias}/{$target}" : $target;
$prefix = "{$base_command}:" . yellow( $sub_target_name );
}

putenv( "TRIC_TEST_SUBNET={$subnet}" );
Expand Down Expand Up @@ -1137,3 +1157,51 @@ function build_subdir_status() {

echo 'Sub-directories build status is: ' . ( $enabled ? light_cyan( 'on' ) : magenta( 'off' ) ) . PHP_EOL;
}

/**
* Build a command pool, suitable to be run using the `execute_command_pool` function, for multiple targets.
*
* If any subdirectories are provided and are available in the target, then the user will be prompted to run the same
* command on those subdirectories.
*
* @param array<string> $targets An array of targets for the command pool; note the targets are NOT validated by
* this function and the validation should be done by the calling code.
* @param string $base_command The base service command to run, e.g. `npm`, `composer`, etc.
* @param array<string> $command The command to run, e.g. `['install','--save-dev']` in array format.
* @param array<string> $sub_directories Sub directories to prompt for additional execution.
*
* @return array The built command pool for all the targets.
*/
function build_targets_command_pool( array $targets, $base_command, array $command, array $sub_directories = [] ) {
$raw_command_pool = array_combine(
$targets,
array_map( static function ( $target ) use ( $base_command, $command, $sub_directories ) {
return build_command_pool( $base_command, $command, $sub_directories, $target );
}, $targets )
);

// Set the keys correctly to have the command prefixes correctly built.
$command_pool = [];
foreach ( $raw_command_pool as $target => $target_pool ) {
foreach ( $target_pool as $target_key => $process ) {
$key = preg_replace(
[
// Main target.
'/^target:/',
// Sub-directories.
'/^([\w\d]+):/'
],
[
// Replace with `<target>:`.
$target . ':',
// Replace with `<target>/<subdir>:`.
$target . '/$1:'
],
$target_key
);
$command_pool[ $key ] = $process;
}
}

return $command_pool;
}
4 changes: 3 additions & 1 deletion tric
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $args = args( [
] );

$cli_name = basename( $argv[0] );
const CLI_VERSION = '0.4.9';
const CLI_VERSION = '0.5.0';

$cli_header = implode( ' - ', [
light_cyan( $cli_name ) . ' version ' . light_cyan( CLI_VERSION ),
Expand Down Expand Up @@ -53,6 +53,7 @@ Available commands:
<light_cyan>init</light_cyan> Initializes a plugin for use in tric.
<light_cyan>composer</light_cyan> Runs a Composer command in the stack.
<light_cyan>npm</light_cyan> Runs an npm command in the stack.
<light_cyan>target</light_cyan> Runs a command on a set of targets.
<light_cyan>xdebug</light_cyan> Activates and deactivates XDebug in the stack, returns the current XDebug status or sets its values.
<light_cyan>airplane-mode</light_cyan> Activates or deactivates the airplane-mode plugin.
<light_cyan>cache</light_cyan> Activates and deactivates object cache support, returns the current object cache status.
Expand Down Expand Up @@ -133,6 +134,7 @@ switch ( $subcommand ) {
case 'run':
case 'serve':
case 'shell':
case 'target':
case 'up':
case 'update':
case 'upgrade':
Expand Down

0 comments on commit 19ae1ed

Please sign in to comment.