composer = $composer; $this->io = $io; $this->plugin = $plugin; $this->executor = new ProcessExecutor($io); } /** * Return the tool to run when applying patches (when applicable). * * @return string */ protected function patchTool(): string { if (isset($this->toolPathOverride) && !empty($this->toolPathOverride)) { return $this->toolPathOverride; } return $this->tool; } /** * Executes a shell command with escaping. * * @param string $cmd * @return bool */ protected function executeCommand($cmd) { // Shell-escape all arguments except the command. $args = func_get_args(); foreach ($args as $index => $arg) { if ($index !== 0 && !is_int($arg)) { $args[$index] = escapeshellarg($arg); } } // And replace the arguments. $command = call_user_func_array('sprintf', $args); $output = ''; if ($this->io->isVerbose()) { $this->io->write('' . $command . ''); $io = $this->io; $output = function ($type, $data) use ($io) { if ($type === Process::ERR) { $io->write('' . $data . ''); } else { $io->write('' . $data . ''); } }; } return ($this->executor->execute($command, $output) === 0); } /** * @inheritDoc */ abstract public function apply(Patch $patch, string $path): bool; /** * @inheritDoc */ abstract public function canUse(): bool; }