Skip to content

Commit

Permalink
Merge pull request #62 from moderntribe/fix/xdebug-host
Browse files Browse the repository at this point in the history
Fix XDebug remote host issues
  • Loading branch information
borkweb authored Dec 2, 2020
2 parents 0620769 + 50ce957 commit f86d68d
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 14 deletions.
9 changes: 9 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ 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.16] - 2020-11-26
### Changed

- Add support for the `TRIC_HOST` environment variable. This will override the default host machine IP address lookup `tric` would perform on Linux or the hard-wired `host.docker.internal` hostname `tric` would use on Windows and Mac host to set the default `xdebug.remote_host` value.
- Default to the host machin IP address to set `xdebug.remote_host` only if the host has not been set by means of a call to `tric xdebug host <host>` or by setting the `XDH` environment variable explicitly.
- Fix an issue that would reset run settings stored in the `.env.tric.run` file when using the `tric xdebug <key> <value>` command.
- Correctly handle Docker network removal in parallel tasks to avoid "error while removing network" errors.
- Add support for `tric run` to run all the avaiable Codeception test suites from the target one after another.

## [0.5.15] - 2020-11-24
### Changed

Expand Down
4 changes: 2 additions & 2 deletions containers/wordpress/Dockerfile.base
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ FROM wordpress:${WORDPRESS_IMAGE_VERSION}
# This will allow setting the `APACHE_RUN_USER`, and with it deal with filemode issues, correctly.
ARG DOCKER_RUN_UID=0
ARG DOCKER_RUN_GID=0
RUN if [ "${DOCKER_RUN_GID}" > 0 ]; then addgroup --gid ${DOCKER_RUN_GID} docker; fi; \
if [ "${DOCKER_RUN_UID}" > 0 ]; then adduser --uid ${DOCKER_RUN_UID} --gid ${DOCKER_RUN_GID} --home /home/docker \
RUN if [ "${DOCKER_RUN_GID}" != 0 ]; then addgroup --gid ${DOCKER_RUN_GID} docker; fi; \
if [ "${DOCKER_RUN_UID}" != 0 ]; then adduser --uid ${DOCKER_RUN_UID} --gid ${DOCKER_RUN_GID} --home /home/docker \
--shell /bin/sh --disabled-password --gecos "" docker; fi
4 changes: 2 additions & 2 deletions containers/wordpress/Dockerfile.debug
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ FROM wordpress:${WORDPRESS_IMAGE_VERSION}
# This will allow setting the `APACHE_RUN_USER`, and with it deal with filemode issues, correctly.
ARG DOCKER_RUN_UID=0
ARG DOCKER_RUN_GID=0
RUN if [ "${DOCKER_RUN_GID}" > 0 ]; then addgroup --gid ${DOCKER_RUN_GID} docker; fi; \
if [ "${DOCKER_RUN_UID}" > 0 ]; then adduser --uid ${DOCKER_RUN_UID} --gid ${DOCKER_RUN_GID} --home /home/docker \
RUN if [ "${DOCKER_RUN_GID}" != 0 ]; then addgroup --gid ${DOCKER_RUN_GID} docker; fi; \
if [ "${DOCKER_RUN_UID}" != 0 ]; then adduser --uid ${DOCKER_RUN_UID} --gid ${DOCKER_RUN_GID} --home /home/docker \
--shell /bin/sh --disabled-password --gecos "" docker; fi

# Pull in an helper library to install PHP extensions.
Expand Down
28 changes: 24 additions & 4 deletions src/commands/run.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@
* command.
* See the `init` command for more details.
*
* @var bool $is_help Whether we're handling an `help` request on this command or not.
* @var \Closure $args The argument map closure, as produced by the `args` function.
* @var string $cli_name The current name of the CLI tool, usually `tric`.
* @var bool $is_help Whether we're handling an `help` request on this command or not.
* @var \Closure $args The argument map closure, as produced by the `args` function.
*/

namespace Tribe\Test;

if ( $is_help ) {
echo colorize( "Runs a Codeception test in the stack, the equivalent of <light_cyan>'codecept run ...'</light_cyan>.\n" );
echo colorize( "Runs a Codeception test in the stack, the equivalent of <light_cyan>'codecept run ...'</light_cyan>, or all the tests.\n" );
echo PHP_EOL;
echo colorize( "This command requires a use target set using the <light_cyan>use</light_cyan> command.\n" );
echo colorize( "usage: <light_cyan>{$cli_name} run</light_cyan>\n" );
echo colorize( "usage: <light_cyan>{$cli_name} run [...<commands>]</light_cyan>\n" );
echo colorize( "example: <light_cyan>{$cli_name} run wpunit</light_cyan>" );

Expand Down Expand Up @@ -86,7 +88,25 @@
// Add tric configuration file, if existing.
$run_configuration = array_merge( [ 'run', '--rm', 'codeception', 'run' ], $config_files );

$run_args = $args( '...' );
$run_suites = [];

if ( empty( $run_args ) ) {
$run_suites = collect_target_suites();
}

// Finally run the command.
$status = tric_realtime()( array_merge( $run_configuration, $args( '...' ) ) );
if ( empty( $run_suites ) ) {
// Run the command as per user input.
$status = tric_realtime()( array_merge( $run_configuration, $run_args ) );
} else {
// Run all the suites sequentially, stop at first error.
foreach ( $run_suites as $suite ) {
$status = tric_realtime()( array_merge( $run_configuration, [ $suite ] ) );
if ( $status !== 0 ) {
exit( $status );
}
}
}

exit( $status );
6 changes: 4 additions & 2 deletions src/docker.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ function docker_compose( array $options = [] ) {

if ( ! empty( $host_ip ) ) {
// Set the host IP address on Linux machines.
$command = 'XDH=' . host_ip() . ' ' . $command;
$xdebug_remote_host = (string) getenv( 'XDH' ) ?: host_ip();
$command = 'XDH=' . $xdebug_remote_host . ' ' . $command;
}

if ( ! empty( $is_ci ) ) {
Expand Down Expand Up @@ -188,7 +189,8 @@ function docker_compose_process( array $options = [], $is_realtime = true ) {

if ( ! empty( $host_ip ) ) {
// Set the host IP address on Linux machines.
$command = 'XDH=' . host_ip() . ' ' . $command;
$xdebug_remote_host = (string) getenv( 'XDH' ) ?: host_ip();
$command = 'XDH=' . $xdebug_remote_host . ' ' . $command;
}

if ( ! empty( $is_ci ) ) {
Expand Down
53 changes: 51 additions & 2 deletions src/tric.php
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ function tric_info() {
'TRIC_CURRENT_PROJECT',
'TRIC_CURRENT_PROJECT_RELATIVE_PATH',
'TRIC_CURRENT_PROJECT_SUBDIR',
'TRIC_HOST',
'TRIC_PLUGINS',
'TRIC_THEMES',
'TRIC_GIT_DOMAIN',
Expand Down Expand Up @@ -807,7 +808,7 @@ function tric_handle_xdebug( callable $args ) {
if ( array_key_exists( $toggle, $map ) ) {
$var = $args( 'value' );
echo colorize( "Setting <light_cyan>{$map[$toggle]}={$var}</light_cyan>" ) . PHP_EOL . PHP_EOL;
write_env_file( $run_settings_file, [ $map[ $toggle ] => $var ] );
write_env_file( $run_settings_file, [ $map[ $toggle ] => $var ], true );
echo PHP_EOL . PHP_EOL . colorize( "Tear down the stack with <light_cyan>down</light_cyan> and restar it to apply the new settings!\n" );

return;
Expand Down Expand Up @@ -981,7 +982,18 @@ function build_command_pool( $base_command, array $command, array $sub_directori
$network_name = "tric{$subnet}";
$status = tric_passive()( array_merge( [ '-p', $network_name, 'run', '--rm', $base_command ], $command ), $prefix );

shell_exec( "docker network rm {$network_name}_tric {$network_name}_default" );
if ( ! empty( $subnet ) ) {
do {
/*
* Some containers might take time to terminate after yielding control back to the Docker daemon (zombies).
* If we try to remote the network when zombie containers are attached to it, we'll get the following error:
* "error while removing network: network <network_name> id <id> has active endpoints".
* When this happens, the return status of the command will be a `1`.
* We iterate until the status is a `0`.
*/
$network_rm_status = (int) process( "docker network rm {$network_name}_tric {$network_name}_default" )( 'status' );
} while ( $network_rm_status !== 0 );
}

if ( 'target' !== $target ) {
tric_switch_target( $using );
Expand Down Expand Up @@ -1316,3 +1328,40 @@ function tric_target_or_fail( $reason = null ) {

return $target;
}

/**
* Returns the absolute path to the current target.
*
* @param null|string $append_path A relative path to append to the target absolute path.
*
* @return string The absolute path to the current target.
*/
function absolute_plugin_target_path( $append_path = null ) {
$full_target_path = rtrim( getenv( 'TRIC_HERE_DIR' ), '\\/' ) . '/' . trim( tric_target(), '\\/' );
if ( empty( $append_path ) ) {
return $full_target_path;
}

return $full_target_path . '/' . ltrim( $append_path, '\\/' );
}

/**
* Compiles a list of the current target Codeception suites. The available suites are inferred, as Codeception does,
* from the available suite configuration files.
*
* @return array<string> A list of the available target suites.
*/
function collect_target_suites() {
// If the command is just `run`, without arguments, then collect the available suites and run them separately.
$dir_iterator = new \DirectoryIterator( absolute_plugin_target_path( 'tests' ) );
$suitesFilter = new \CallbackFilterIterator( $dir_iterator, static function ( \SplFileInfo $file ) {
return $file->isFile() && preg_match( '/^.*\\.suite(\\.dist)?\\.yml$/', $file->getBasename() );
} );
$suites = [];
foreach ( $suitesFilter as $f ) {
$suites[] = preg_replace( '/^([\\w-]+)\\.suite(\\.dist)?\\.yml$/u', '$1', $f->getBasename() );
}

return $suites;
}

9 changes: 7 additions & 2 deletions src/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,18 @@ function the_fatality() {
* Returns the host machine IP address as reachable from the containers.
*
* The way the host machine IP address is fetched will vary depending on the Operating System the function runs on.
* If the `TRIC_HOST` environment variable is set, then that will be used without any further check.
*
* @param string $os The operating system to get the host machine IP address for.
*
* @return string The host machine IP address or host name (e.g. `host.docker.internal` on macOS or Windows), or
* an empty string to indicate the host machine IP address could not be obtained.
*/
function host_ip( $os = 'Linux' ) {
if ( $env_set_host = getenv( 'TRIC_HOST' ) ) {
return $env_set_host;
}

if ( $os === 'Linux' ) {
// Depending on the distribution being used either one, or both, these commands might yield a result.
$commands = [
Expand Down Expand Up @@ -406,7 +411,7 @@ function root( $path = '' ) {
function write_env_file( $file, array $lines = [], $update = false ) {
$existing_lines = [];

if ( $update && file_exists( $file ) ) {
if ( $update && is_file( $file ) ) {
$existing_lines = read_env_file( $file );
}

Expand All @@ -417,7 +422,7 @@ function write_env_file( $file, array $lines = [], $update = false ) {
}, array_keys( $new_lines ), $new_lines ) );

// If this is the first time creating the .env.tric.run file, assume this is the first run and place the CLI version in `.build-version`.
if ( false !== strpos( $file, '.env.tric.run' ) && ! file_exists( $file ) ) {
if ( false !== strpos( $file, '.env.tric.run' ) && ! is_file( $file ) ) {
write_build_version();
}

Expand Down

0 comments on commit f86d68d

Please sign in to comment.