<?php namespace Grav\Plugin\Console; use Grav\Console\ConsoleCommand; use Grav\Plugin\GitSync\GitSync; use Grav\Plugin\GitSync\Helper; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputOption; /** * Class LogCommand * * @package Grav\Plugin\Console */ class StatusCommand extends ConsoleCommand { protected function configure() { $this ->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 <info>%command.name%</info> command checks if the plugin is usable the way it has been configured. While doing this it prints the available information for your inspection. <comment>No files in the workspace are modified when running this test.</comment> The <info>--fetch</info> option can be used to see differences between the remote in the <info>git status</info> (last check) It also returns with an error code and a helpful message when something is not normal: <error>100</error> : <info>git</info> binary not working as expected <error>50</error> : <info>repositoryFolder</info> and git workspace root do not match <error>10</error> : <info>repository</info> is not configured <error>5</error> : state of workspace not clean <error>1</error> : Some checks can throw a <info>RuntimeException</info> 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 <info>sync</info> command without problems!' ); } else { $this->output->writeln('<yellow>You are not in sync!</yellow>'); $this->output->writeln('Take a look at the output of git status to see more details.'); $this->output->writeln('In most cases the <info>sync</info> command is able to fix this.'); } } else { $this->console_header('Looks good: use <info>--fetch</info> option to check for updates.'); } } private function console_header($readable, $cmd = '', $remote_action = false) { $this->output->writeln( "<yellow>$readable</yellow>" . ($cmd ? "(<info>$cmd</info>)" : ''). ($remote_action ? '...' : '') ); } private function console_log($lines, $password) { foreach ($lines as $line) { $this->output->writeln(' ' . Helper::preventReadablePassword($line, $password)); } } }