setName('status') ->setDescription('Checks the status of plugin config, git and git workspace. No files get modified!') ->addOption( 'fetch', 'f', InputOption::VALUE_NONE, 'additionally do a git fetch to look updates (changes not files in workspace)' ) ->setHelp(<<<'EOF' The %command.name% command checks if the plugin is usable the way it has been configured. While doing this it prints the available information for your inspection. No files in the workspace are modified when running this test. The --fetch option can be used to see differences between the remote in the git status (last check) It also returns with an error code and a helpful message when something is not normal: 100 : git binary not working as expected 50 : repositoryFolder and git workspace root do not match 10 : repository is not configured 5 : state of workspace not clean 1 : Some checks can throw a RuntimeException which is not caught, read the message for details EOF ) ; } protected function serve() { require_once __DIR__ . '/../vendor/autoload.php'; $plugin = new GitSync(); $this->output->writeln(''); $this->console_header('plugin runtime information:'); $info = $plugin->getRuntimeInformation(); $info['isGitInitialized'] = Helper::isGitInitialized(); $info['gitVersion'] = Helper::isGitInstalled(true); ksort($info); dump($info); if (!Helper::isGitInstalled()) { throw new RuntimeException('git binary not found', 100); } $this->console_header('detect git workspace root:'); $git_root = $plugin->execute('rev-parse --show-toplevel'); $this->console_log($git_root, ''); if (rtrim($info['repositoryPath'], '/') !== rtrim($git_root[0], '/')) { throw new RuntimeException('git root and repositoryPath do not match', 50); } // needed to prevent output in logs: $password = Helper::decrypt($plugin->getPassword() ?? ''); $this->console_header('local git config:'); $this->console_log( $plugin->execute('config --local -l'), $password ); $this->console_header( 'Testing connection to repository', 'git ls-remote', true ); $repository = $plugin->getConfig('repository', false); if (!$repository) { throw new RuntimeException('No repository has been configured', 10); } $testRepository = $plugin->testRepository( Helper::prepareRepository( $plugin->getUser() ?? '', $password, $repository), $plugin->getRemote('branch', null), ); $this->console_log($testRepository, $password); $fetched = false; if ($this->input->getOption('fetch')) { $remote = $plugin->getRemote('name', ''); $this->console_header( 'Looking for updates', "git fetch $remote", true ); $this->console_log($plugin->fetch($remote), $password); $fetched = true; } $this->console_header( 'Checking workspace status', 'git status', true ); $git_status = $plugin->execute('status'); $this->console_log($git_status, $password); if (!$plugin->isWorkingCopyClean()) { throw new RuntimeException('Working state is not clean.', 5); } if ($fetched) { $uptodate = strpos($git_status[1], 'branch is up-to-date with') > 0; if ($uptodate) { $this->console_header( 'Congrats: You should be able to run the sync command without problems!' ); } else { $this->output->writeln('You are not in sync!'); $this->output->writeln('Take a look at the output of git status to see more details.'); $this->output->writeln('In most cases the sync command is able to fix this.'); } } else { $this->console_header('Looks good: use --fetch option to check for updates.'); } } private function console_header($readable, $cmd = '', $remote_action = false) { $this->output->writeln( "$readable" . ($cmd ? "($cmd)" : ''). ($remote_action ? '...' : '') ); } private function console_log($lines, $password) { foreach ($lines as $line) { $this->output->writeln(' ' . Helper::preventReadablePassword($line, $password)); } } }