WP_CLI

Runner::generate_ssh_commandprivateWP-CLI 1.0

Generate a shell command from the parsed connection string.

Метод класса: Runner{}

Хуков нет.

Возвращает

Строку.

Использование

// private - только в коде основоного (родительского) класса
$result = $this->generate_ssh_command( $bits, $wp_command );
$bits(массив) (обязательный)
Parsed connection string.
$wp_command(строка) (обязательный)
WP-CLI command to run.

Код Runner::generate_ssh_command() WP-CLI 2.13.0-alpha

private function generate_ssh_command( $bits, $wp_command ) {
	$escaped_command = '';

	// Set default values.
	foreach ( [ 'scheme', 'user', 'host', 'port', 'path', 'key', 'proxyjump' ] as $bit ) {
		if ( ! isset( $bits[ $bit ] ) ) {
			$bits[ $bit ] = null;
		}

		WP_CLI::debug( 'SSH ' . $bit . ': ' . $bits[ $bit ], 'bootstrap' );
	}

	/*
	 * posix_isatty(STDIN) is generally true unless something was passed on stdin
	 * If autodetection leads to false (fd on stdin), then `-i` is passed to `docker` cmd
	 * (unless WP_CLI_DOCKER_NO_INTERACTIVE is set)
	 */
	$is_stdout_tty = function_exists( 'posix_isatty' ) && posix_isatty( STDOUT );
	$is_stdin_tty  = function_exists( 'posix_isatty' ) ? posix_isatty( STDIN ) : true;

	if ( in_array( $bits['scheme'], [ 'docker', 'docker-compose', 'docker-compose-run' ], true ) ) {
			$docker_compose_v2_version_cmd = Utils\esc_cmd( Utils\force_env_on_nix_systems( 'docker' ) . ' compose %s', 'version' );
			$docker_compose_cmd            = ! empty( Process::create( $docker_compose_v2_version_cmd )->run()->stdout )
					? 'docker compose'
					: 'docker-compose';
	}

	if ( 'docker' === $bits['scheme'] ) {
		$command = 'docker exec %s%s%s%s%s sh -c %s';

		$escaped_command = sprintf(
			$command,
			$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
			$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
			$is_stdout_tty && ! getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '-t  ' : '',
			$is_stdin_tty || getenv( 'WP_CLI_DOCKER_NO_INTERACTIVE' ) ? '' : '-i ',
			escapeshellarg( $bits['host'] ),
			escapeshellarg( $wp_command )
		);
	}

	if ( 'docker-compose' === $bits['scheme'] ) {
		$command = '%s exec %s%s%s%s sh -c %s';

		$escaped_command = sprintf(
			$command,
			$docker_compose_cmd,
			$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
			$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
			$is_stdout_tty || getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '' : '-T ',
			escapeshellarg( $bits['host'] ),
			escapeshellarg( $wp_command )
		);
	}

	if ( 'docker-compose-run' === $bits['scheme'] ) {
		$command = '%s run %s%s%s%s%s %s';

		$escaped_command = sprintf(
			$command,
			$docker_compose_cmd,
			$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
			$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
			$is_stdout_tty || getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '' : '-T ',
			$is_stdin_tty || getenv( 'WP_CLI_DOCKER_NO_INTERACTIVE' ) ? '' : '-i ',
			escapeshellarg( $bits['host'] ),
			$wp_command
		);
	}

	// For "vagrant" & "ssh" schemes which don't provide a working-directory option, use `cd`
	if ( $bits['path'] ) {
		$wp_command = 'cd ' . escapeshellarg( $bits['path'] ) . '; ' . $wp_command;
	}

	// Vagrant ssh-config.
	if ( 'vagrant' === $bits['scheme'] ) {
		$cache     = WP_CLI::get_cache();
		$cache_key = 'vagrant:' . $this->project_config_path;
		if ( $cache->has( $cache_key ) ) {
			$cached = $cache->read( $cache_key );
			$values = json_decode( $cached, true );
		} else {
			$ssh_config = shell_exec( 'vagrant ssh-config 2>/dev/null' );
			if ( preg_match_all( '#\s*(?<NAME>[a-zA-Z]+)\s(?<VALUE>.+)\s*#', $ssh_config, $matches ) ) {
				$values = array_combine( $matches['NAME'], $matches['VALUE'] );
				$cache->write( $cache_key, json_encode( $values ) );
			}
		}

		if ( empty( $bits['host'] ) || ( isset( $values['Host'] ) && $bits['host'] === $values['Host'] ) ) {
			$bits['scheme'] = 'ssh';
			$bits['host']   = isset( $values['HostName'] ) ? $values['HostName'] : '';
			$bits['port']   = isset( $values['Port'] ) ? $values['Port'] : '';
			$bits['user']   = isset( $values['User'] ) ? $values['User'] : '';
			$bits['key']    = isset( $values['IdentityFile'] ) ? $values['IdentityFile'] : '';
		}

		// If we could not resolve the bits still, fallback to just `vagrant ssh`
		if ( 'vagrant' === $bits['scheme'] ) {
			$command = 'vagrant ssh -c %s %s';

			$escaped_command = sprintf(
				$command,
				escapeshellarg( $wp_command ),
				escapeshellarg( $bits['host'] )
			);
		}
	}

	// Default scheme is SSH.
	if ( 'ssh' === $bits['scheme'] || null === $bits['scheme'] ) {
		$command = 'ssh %s %s %s';

		if ( $bits['user'] ) {
			$bits['host'] = $bits['user'] . '@' . $bits['host'];
		}

		if ( ! empty( $this->alias ) ) {
			$alias_config = isset( $this->aliases[ $this->alias ] ) ? $this->aliases[ $this->alias ] : false;

			if ( is_array( $alias_config ) ) {
				$bits['proxyjump'] = isset( $alias_config['proxyjump'] ) ? $alias_config['proxyjump'] : '';
				$bits['key']       = isset( $alias_config['key'] ) ? $alias_config['key'] : '';
			}
		}

		$command_args = [
			$bits['proxyjump'] ? sprintf( '-J %s', escapeshellarg( $bits['proxyjump'] ) ) : '',
			$bits['port'] ? sprintf( '-p %d', (int) $bits['port'] ) : '',
			$bits['key'] ? sprintf( '-i %s', escapeshellarg( $bits['key'] ) ) : '',
			$is_stdout_tty ? '-t' : '-T',
			WP_CLI::get_config( 'debug' ) ? '-vvv' : '-q',
		];

		$escaped_command = sprintf(
			$command,
			implode( ' ', array_filter( $command_args ) ),
			escapeshellarg( $bits['host'] ),
			escapeshellarg( $wp_command )
		);
	}

	WP_CLI::debug( 'Running SSH command: ' . $escaped_command, 'bootstrap' );

	return $escaped_command;
}