diff --git a/src/commands/composer.php b/src/commands/composer.php index 848a29b..a628b61 100644 --- a/src/commands/composer.php +++ b/src/commands/composer.php @@ -14,40 +14,9 @@ $using = tric_target(); echo light_cyan( "Using {$using}\n" ); -setup_id(); -$composer_command = $args( '...' ); -$targets = [ 'target' ]; +$command = $args( '...' ); +$pool = build_command_pool( 'composer', $command, [ 'common' ] ); +$status = execute_command_pool( $pool ); -if ( - file_exists( tric_plugins_dir( "{$using}/common" ) ) - && ask( "\nWould you also like to run that composer command against common?", 'yes' ) -) { - $targets[] = 'common'; -} - -$command_process = static function( $target ) use ( $using, $composer_command ) { - $prefix = light_cyan( $target ); - - // Execute composer as the parent. - if ( 'common' === $target ) { - tric_switch_target( "{$using}/common" ); - $prefix = yellow( $target ); - } - - $status = tric_realtime()( array_merge( [ 'run', '--rm', 'composer' ], $composer_command ), $prefix ); - - if ( 'common' === $target ) { - tric_switch_target( $using ); - } - - return pcntl_exit( $status ); -}; - -if ( count( $targets ) > 1 ) { - $status = parallel_process( $targets, $command_process ); - tric_switch_target( $using ); - exit( $status ); -} - -exit( $command_process( reset( $targets ) ) ); +exit( $status ); diff --git a/src/commands/init.php b/src/commands/init.php index 4523c48..23eb2cc 100644 --- a/src/commands/init.php +++ b/src/commands/init.php @@ -38,8 +38,19 @@ setup_plugin_tests( $plugin ); if ( getenv( 'TRIC_BUILD_PROMPT' ) ) { - tric_maybe_run_composer_install( $plugin ); - tric_maybe_run_npm_install( $plugin ); + $current_target = tric_target(); + + if ( $current_target !== $plugin ) { + tric_switch_target( $plugin ); + } + + $command_pool = maybe_build_install_command_pool( 'composer', $plugin, [ 'common' ] ); + $command_pool = array_merge( $command_pool, maybe_build_install_command_pool( 'npm', $plugin, [ 'common' ] ) ); + execute_command_pool( $command_pool ); + + if ( $current_target !== $plugin ) { + tric_switch_target( $current_target ); + } } echo light_cyan( "Finished initializing {$plugin}\n" ); diff --git a/src/commands/npm.php b/src/commands/npm.php index e66a887..6c6bc70 100644 --- a/src/commands/npm.php +++ b/src/commands/npm.php @@ -14,29 +14,10 @@ $using = tric_target(); echo light_cyan( "Using {$using}\n" ); -setup_id(); -$npm_command = $args( '...' ); -$status = tric_realtime()( array_merge( [ 'run', '--rm', 'npm' ], $npm_command ) ); +$command = $args( '...' ); +$pool = build_command_pool( 'npm', $command, [ 'common' ] ); +$status = execute_command_pool( $pool ); -// If there is a status other than 0, we have an error. Bail. -if ( $status ) { - exit( $status ); -} - -if ( ! file_exists( tric_plugins_dir( "{$using}/common" ) ) ) { - return; -} - -if ( ask( "\nWould you like to run that npm command against common?", 'yes' ) ) { - tric_switch_target( "{$using}/common" ); - - echo light_cyan( "Temporarily using " . tric_target() . "\n" ); - - $status = tric_realtime()( array_merge( [ 'run', '--rm', 'npm' ], $npm_command ) ); +exit( $status ); - tric_switch_target( $using ); - echo light_cyan( "Using " . tric_target() ." once again\n" ); -} - -exit( $status ); diff --git a/src/process.php b/src/process.php index 30a0ac9..2b719e0 100644 --- a/src/process.php +++ b/src/process.php @@ -207,12 +207,12 @@ function check_status_or( callable $process, callable $else = null ) { * * @return int The combined process status value of all child processes. */ -function parallel_process( $items, $command_process ) { +function parallel_process( $pool ) { $process_children = []; if ( function_exists( 'pcntl_fork' ) ) { // If we're on a OS that does support process control, then fork. - foreach ( $items as $item ) { + foreach ( $pool as $item ) { $pid = pcntl_fork(); if ( $pid === - 1 ) { echo magenta( "Unable to fork processes.\n" ); @@ -220,7 +220,7 @@ function parallel_process( $items, $command_process ) { } if ( 0 === $pid ) { - $command_process( $item ); + $item['process']( $item['target'] ); } else { $process_children[] = $pid; } @@ -233,8 +233,8 @@ function parallel_process( $items, $command_process ) { * If Process Control functions are not available or are disabled, then we execute the commands serially. * Nothing "parallel" here. */ - foreach ( $items as $item ) { - $status = $command_process( $item ); + foreach ( $pool as $item ) { + $status = $item['process']( $item['target'] ); if ( $status !== 0 ) { // At the first failure, bail. return $status; diff --git a/src/tric.php b/src/tric.php index 8b1bfc3..f622d76 100644 --- a/src/tric.php +++ b/src/tric.php @@ -710,122 +710,115 @@ function update_stack_images() { /** * Maybe runs composer install on a given target * + * @param array $base_command Base command to run. * @param string $target Target to potentially run composer install against. + * @param array $sub_directories Sub directories to prompt for additional execution. + * + * @return null|int Result of command execution. */ -function tric_maybe_run_build_install( $command, $target ) { +function maybe_build_install_command_pool( $base_command, $target, array $sub_directories = [] ) { $run = ask( - "\nWould you like to run the {$command} build processes for this plugin?", + "\nWould you like to run the {$base_command} build processes for this plugin?", 'yes' ); if ( empty( $run ) ) { - return; - } - - $current_target = tric_target(); - - if ( $current_target !== $target ) { - tric_switch_target( $target ); + return []; } - $function = "\Tribe\Test\\tric_run_{$command}_command"; - $function( [ 'install' ] ); - - if ( $current_target !== $target ) { - tric_switch_target( $current_target ); - } + return build_command_pool( $base_command, [ 'install' ], $sub_directories ); } /** - * Maybe runs composer install on a given target + * Run a command using the appropriate service. * - * @param string $target Target to potentially run composer install against. - */ -function tric_maybe_run_composer_install( $target ) { - return tric_maybe_run_build_install( 'composer', $target ); -} - -/** - * Maybe runs npm install on a given target - * - * @param string $target Target to potentially run npm install against. - */ -function tric_maybe_run_npm_install( $target ) { - return tric_maybe_run_build_install( 'npm', $target ); -} - -/** - * Run a command using the `npm` service. + * 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. * - * If `common` is available in the target and the command dos not fail, then the user will be prompted to run the same - * command on `common`. + * @param string $base_command The base service command to run, e.g. `npm`, `composer`, etc. + * @param array $command The command to run, e.g. `['install','--save-dev']` in array format. + * @param array $sub_directories Sub directories to prompt for additional execution. * - * @param array $command The `npm` command to run, e.g. `['install','--save-dev']` in array format. + * @return int Result of command execution. */ -function tric_run_npm_command( array $command ) { - $using = tric_target(); - echo light_cyan( "Using {$using}\n" ); - - setup_id(); - $status = tric_realtime()( array_merge( [ 'run', '--rm', 'npm' ], $command ) ); +function build_command_pool( string $base_command, array $command, array $sub_directories = [] ) { + $using = tric_target(); + $targets = [ 'target' ]; - if ( 0 !== $status ) { - // If the composer command failed there's no point in trying the same on `common` - return; + // Prompt for execution within subdirectories. + foreach ( $sub_directories as $dir ) { + if ( + file_exists( tric_plugins_dir( "{$using}/{$dir}" ) ) + && ask( "\nWould you also like to run that {$base_command} command against {$dir}?", 'yes' ) + ) { + $targets[] = $dir; + } } - if ( ! file_exists( tric_plugins_dir( "{$using}/common" ) ) ) { - return; - } + // Build the command process. + $command_process = static function( $target ) use ( $using, $base_command, $command, $sub_directories ) { + $prefix = "{$base_command}:" . light_cyan( $target ); - if ( ask( "\nWould you like to run that npm command against common?", 'yes' ) ) { - tric_switch_target( "{$using}/common" ); + // Execute command as the parent. + if ( 'target' !== $target ) { + tric_switch_target( "{$using}/{$target}" ); + $prefix = "{$base_command}:" . yellow( $target ); + } - echo light_cyan( "Temporarily using " . tric_target() . "\n" ); + $status = tric_realtime()( array_merge( [ 'run', '--rm', $base_command ], $command ), $prefix ); - tric_realtime()( array_merge( [ 'run', '--rm', 'npm' ], $command ) ); + if ( 'target' !== $target ) { + tric_switch_target( $using ); + } - tric_switch_target( $using ); + return pcntl_exit( $status ); + }; - echo light_cyan( "Using " . tric_target() . " once again\n" ); + $pool = []; + + // Build the pool with a target/container/command-specific key. + foreach ( $targets as $target ) { + $clean_command = implode( ' ', $command ); + + $pool[ "{$target}:{$base_command}:{$clean_command}" ] = [ + 'target' => $target, + 'container' => $base_command, + 'command' => $command, + 'process' => $command_process, + ]; } + + return $pool; } /** - * Run a command using the `composer` service. + * Executes a pool of commands in parallel. * - * If `common` is available in the target and the command dos not fail, then the user will be prompted to run the same - * command on `common`. - * - * @param array $command The `composer` command to run, e.g. `['install','--no-dev']` in array format. + * @param array $pool Pool of processes to execute in parallel. + * $pool[] = [ + * 'target' => (string) Tric target. + * 'container' => (string) Container on which to execute the command. + * 'command' => (array) The command to run, e.g. `['install', '--save-dev']` in array format. + * 'process' => (closure) The function to execute for each Tric target. + * ] + * @return int Result of combined command execution. */ -function tric_run_composer_command( array $command ) { - $using = tric_target(); - echo light_cyan( "Using {$using}\n" ); - - setup_id(); - $status = tric_realtime()( array_merge( [ 'run', '--rm', 'composer' ], $command ) ); - - if ( 0 !== $status ) { - // If the composer command failed there's no point in trying the same on `common` - return; - } - - if ( ! file_exists( tric_plugins_dir( "{$using}/common" ) ) ) { - return; +function execute_command_pool( $pool ) { + if ( ! $pool ) { + return 0; } - if ( ask( "\nWould you like to run that composer command against common?", 'yes' ) ) { - tric_switch_target( "{$using}/common" ); - - echo light_cyan( "Temporarily using " . tric_target() . "\n" ); - - tric_realtime()( array_merge( [ 'run', '--rm', 'composer' ], $command ) ); + $using = tric_target(); + if ( count( $pool ) > 1 ) { + $status = parallel_process( $pool ); tric_switch_target( $using ); - - echo light_cyan( "Using " . tric_target() . " once again\n" ); + return $status; } + + $pool_item = reset( $pool ); + + return $pool_item['process']( $pool_item['target'] ); } /**