Write revision info from a CLI
Signed-off-by: William Desportes <williamdes@wdes.fr>
This commit is contained in:
parent
84ede575e3
commit
7c2ebb163c
125
libraries/classes/Command/WriteGitRevisionCommand.php
Normal file
125
libraries/classes/Command/WriteGitRevisionCommand.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use function file_put_contents;
|
||||
use function shell_exec;
|
||||
use function trim;
|
||||
use function str_replace;
|
||||
use function sprintf;
|
||||
|
||||
class WriteGitRevisionCommand extends Command
|
||||
{
|
||||
/** @var string */
|
||||
protected static $defaultName = 'write-revision-info';
|
||||
|
||||
/** @var string */
|
||||
private static $generatedClassTemplate = <<<'PHP'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is generated by scripts/console.
|
||||
*
|
||||
* @see \PhpMyAdmin\Command\WriteGitRevisionCommand
|
||||
*/
|
||||
return [
|
||||
'revision' => '%s',
|
||||
'revisionUrl' => '%s',
|
||||
'branch' => '%s',
|
||||
'branchUrl' => '%s',
|
||||
];
|
||||
|
||||
PHP;
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->setDescription('Write Git revision');
|
||||
$this->addOption(
|
||||
'remote-commit-url',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'The remote URL to a commit',
|
||||
'https://github.com/phpmyadmin/phpmyadmin/commit/%s'
|
||||
);
|
||||
$this->addOption(
|
||||
'remote-branch-url',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'The remote URL to a branch',
|
||||
'https://github.com/phpmyadmin/phpmyadmin/tree/%s'
|
||||
);
|
||||
$this->setHelp('This command generates the revision-info.php file from Git data.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
/** @var string $commitUrlFormat */
|
||||
$commitUrlFormat = $input->getOption('remote-commit-url');
|
||||
/** @var string $branchUrlFormat */
|
||||
$branchUrlFormat = $input->getOption('remote-branch-url');
|
||||
|
||||
$generatedClass = $this->getRevisionInfo($commitUrlFormat, $branchUrlFormat);
|
||||
if ($generatedClass === null) {
|
||||
$output->writeln('No revision information detected.');
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
if (! $this->writeGeneratedFile($generatedClass)) {
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$output->writeln('revision-info.php successfully generated!');
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
private function getRevisionInfo(string $commitUrlFormat, string $branchUrlFormat): ?string
|
||||
{
|
||||
$revisionText = $this->gitCli('describe --always');
|
||||
if ($revisionText === null) {
|
||||
return null;
|
||||
}
|
||||
$commitHash = $this->gitCli('log -1 --format="%H"');
|
||||
if ($commitHash === null) {
|
||||
return null;
|
||||
}
|
||||
$branchName = $this->gitCli('symbolic-ref -q HEAD') ?? $this->gitCli('name-rev --name-only HEAD 2>/dev/null');
|
||||
if ($branchName === null) {
|
||||
return null;
|
||||
}
|
||||
$branchName = trim(str_replace('refs/heads/', '', $branchName));
|
||||
|
||||
return sprintf(
|
||||
self::$generatedClassTemplate,
|
||||
trim($revisionText),
|
||||
sprintf($commitUrlFormat, trim($commitHash)),
|
||||
trim($branchName),
|
||||
sprintf($branchUrlFormat, $branchName)
|
||||
);
|
||||
}
|
||||
|
||||
protected function gitCli(string $command): ?string
|
||||
{
|
||||
return shell_exec('git ' . $command);
|
||||
}
|
||||
|
||||
private function writeGeneratedFile(string $generatedClass): bool
|
||||
{
|
||||
$result = file_put_contents(
|
||||
ROOT_PATH . 'revision-info.php',
|
||||
$generatedClass
|
||||
);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
}
|
||||
@ -82,26 +82,23 @@ class Footer
|
||||
{
|
||||
$message = '<a href="/">' . __('phpMyAdmin Demo Server') . '</a>: ';
|
||||
if (@file_exists(ROOT_PATH . 'revision-info.php')) {
|
||||
$revision = '';
|
||||
$fullrevision = '';
|
||||
$repobase = '';
|
||||
$repobranchbase = '';
|
||||
$branch = '';
|
||||
include ROOT_PATH . 'revision-info.php';
|
||||
$message .= sprintf(
|
||||
__('Currently running Git revision %1$s from the %2$s branch.'),
|
||||
'<a target="_blank" rel="noopener noreferrer" href="'
|
||||
. htmlspecialchars($repobase . $fullrevision) . '">'
|
||||
. htmlspecialchars($revision) . '</a>',
|
||||
'<a target="_blank" rel="noopener noreferrer" href="'
|
||||
. htmlspecialchars($repobranchbase . $branch) . '">'
|
||||
. htmlspecialchars($branch) . '</a>'
|
||||
);
|
||||
} else {
|
||||
$message .= __('Git information missing!');
|
||||
$info = include ROOT_PATH . 'revision-info.php';
|
||||
if (is_array($info)) {
|
||||
return Message::notice(
|
||||
$message . sprintf(
|
||||
__('Currently running Git revision %1$s from the %2$s branch.'),
|
||||
'<a target="_blank" rel="noopener noreferrer" href="'
|
||||
. htmlspecialchars($info['revisionUrl'] ?? '') . '">'
|
||||
. htmlspecialchars($info['revision'] ?? '') . '</a>',
|
||||
'<a target="_blank" rel="noopener noreferrer" href="'
|
||||
. htmlspecialchars($info['branchUrl'] ?? '') . '">'
|
||||
. htmlspecialchars($info['branch'] ?? '') . '</a>'
|
||||
)
|
||||
)->getDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
return Message::notice($message)->getDisplay();
|
||||
return Message::notice($message . __('Git information missing!'))->getDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -35,6 +35,10 @@ use const CURLOPT_SSL_VERIFYHOST;
|
||||
use const CURLOPT_SSL_VERIFYPEER;
|
||||
use const CURLOPT_TIMEOUT;
|
||||
use const CURLOPT_USERAGENT;
|
||||
use function getenv;
|
||||
use function parse_url;
|
||||
use const PHP_SAPI;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* Handles HTTP requests
|
||||
@ -59,6 +63,26 @@ class HttpRequest
|
||||
$this->proxyPass = $cfg['ProxyPass'];
|
||||
}
|
||||
|
||||
public static function setProxySettingsFromEnv(): void
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
$httpProxy = getenv('http_proxy');
|
||||
$urlInfo = parse_url((string) $httpProxy);
|
||||
if (PHP_SAPI !== 'cli' || ! is_array($urlInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$proxyUrl = ($urlInfo['host'] ?? '')
|
||||
. (isset($urlInfo['port']) ? ':' . $urlInfo['port'] : '');
|
||||
$proxyUser = $urlInfo['user'] ?? '';
|
||||
$proxyPass = $urlInfo['pass'] ?? '';
|
||||
|
||||
$cfg['ProxyUrl'] = $proxyUrl;
|
||||
$cfg['ProxyUser'] = $proxyUser;
|
||||
$cfg['ProxyPass'] = $proxyPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information with regards to handling the http request
|
||||
*
|
||||
|
||||
@ -112,6 +112,14 @@
|
||||
<code>$defaultName</code>
|
||||
</NonInvariantDocblockPropertyType>
|
||||
</file>
|
||||
<file src="libraries/classes/Command/WriteGitRevisionCommand.php">
|
||||
<ForbiddenCode occurrences="1">
|
||||
<code>shell_exec('git ' . $command)</code>
|
||||
</ForbiddenCode>
|
||||
<NonInvariantDocblockPropertyType occurrences="1">
|
||||
<code>$defaultName</code>
|
||||
</NonInvariantDocblockPropertyType>
|
||||
</file>
|
||||
<file src="libraries/classes/Config.php">
|
||||
<NullableReturnStatement occurrences="1">
|
||||
<code>$this->get('is_https')</code>
|
||||
@ -305,7 +313,9 @@
|
||||
<MissingFile occurrences="1">
|
||||
<code>include ROOT_PATH . 'libraries/language_stats.inc.php'</code>
|
||||
</MissingFile>
|
||||
<PossiblyNullArgument occurrences="1">
|
||||
<PossiblyNullArgument occurrences="3">
|
||||
<code>$this->config->get('ShowGitRevision')</code>
|
||||
<code>$this->config->get('ShowGitRevision')</code>
|
||||
<code>$this->config->get('TempDir')</code>
|
||||
</PossiblyNullArgument>
|
||||
</file>
|
||||
@ -948,9 +958,6 @@
|
||||
<InvalidReturnType occurrences="1">
|
||||
<code>object</code>
|
||||
</InvalidReturnType>
|
||||
<MissingFile occurrences="1">
|
||||
<code>include ROOT_PATH . 'revision-info.php'</code>
|
||||
</MissingFile>
|
||||
<ReferenceConstraintViolation occurrences="2">
|
||||
<code>$object</code>
|
||||
<code>return $object;</code>
|
||||
@ -2625,9 +2632,6 @@
|
||||
<InvalidReturnType occurrences="1">
|
||||
<code>int</code>
|
||||
</InvalidReturnType>
|
||||
<NullableReturnStatement occurrences="1">
|
||||
<code>$wktval</code>
|
||||
</NullableReturnStatement>
|
||||
<PossiblyFalseOperand occurrences="2">
|
||||
<code>mb_strpos($value, '.')</code>
|
||||
<code>mb_strrpos($columnSpecification, ')')</code>
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
use PhpMyAdmin\Command\CacheWarmupCommand;
|
||||
use PhpMyAdmin\Command\SetVersionCommand;
|
||||
use PhpMyAdmin\Command\WriteGitRevisionCommand;
|
||||
use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Core;
|
||||
use PhpMyAdmin\DatabaseInterface;
|
||||
@ -37,5 +38,6 @@ $application = new Application('phpMyAdmin Console Tool');
|
||||
$application->add(new CacheWarmupCommand());
|
||||
$application->add(new LintCommand($twig));
|
||||
$application->add(new SetVersionCommand());
|
||||
$application->add(new WriteGitRevisionCommand());
|
||||
|
||||
$application->run();
|
||||
|
||||
@ -13,15 +13,11 @@ use PhpMyAdmin\SqlParser\Translator;
|
||||
use PhpMyAdmin\Tests\Stubs\DbiDummy;
|
||||
use PhpMyAdmin\Tests\Stubs\Response;
|
||||
use PhpMyAdmin\Theme;
|
||||
use PhpMyAdmin\Utils\HttpRequest;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionClass;
|
||||
|
||||
use function getenv;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function parse_url;
|
||||
|
||||
use const PHP_SAPI;
|
||||
|
||||
/**
|
||||
* Abstract class to hold some usefull methods used in tests
|
||||
@ -149,20 +145,7 @@ abstract class AbstractTestCase extends TestCase
|
||||
|
||||
protected function setProxySettings(): void
|
||||
{
|
||||
$httpProxy = getenv('http_proxy');
|
||||
$urlInfo = parse_url((string) $httpProxy);
|
||||
if (PHP_SAPI !== 'cli' || ! is_array($urlInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$proxyUrl = ($urlInfo['host'] ?? '')
|
||||
. (isset($urlInfo['port']) ? ':' . $urlInfo['port'] : '');
|
||||
$proxyUser = $urlInfo['user'] ?? '';
|
||||
$proxyPass = $urlInfo['pass'] ?? '';
|
||||
|
||||
$GLOBALS['cfg']['ProxyUrl'] = $proxyUrl;
|
||||
$GLOBALS['cfg']['ProxyUser'] = $proxyUser;
|
||||
$GLOBALS['cfg']['ProxyPass'] = $proxyPass;
|
||||
HttpRequest::setProxySettingsFromEnv();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
80
test/classes/Command/WriteGitRevisionCommandTest.php
Normal file
80
test/classes/Command/WriteGitRevisionCommandTest.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Command;
|
||||
|
||||
use PhpMyAdmin\Command\WriteGitRevisionCommand;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
use function class_exists;
|
||||
use function sprintf;
|
||||
|
||||
class WriteGitRevisionCommandTest extends AbstractTestCase
|
||||
{
|
||||
/** @var WriteGitRevisionCommand */
|
||||
private $command;
|
||||
|
||||
public function testGetGeneratedClassValidVersion(): void
|
||||
{
|
||||
if (! class_exists(Command::class)) {
|
||||
$this->markTestSkipped('The Symfony Console is missing');
|
||||
}
|
||||
|
||||
$this->command = $this->getMockBuilder(WriteGitRevisionCommand::class)
|
||||
->onlyMethods(['gitCli'])
|
||||
->getMock();
|
||||
|
||||
$this->command->expects($this->exactly(3))
|
||||
->method('gitCli')
|
||||
->withConsecutive(
|
||||
['describe --always'],
|
||||
['log -1 --format="%H"'],
|
||||
['symbolic-ref -q HEAD']
|
||||
)
|
||||
->willReturnOnConsecutiveCalls(
|
||||
'RELEASE_5_1_0-638-g1c018e2a6c',
|
||||
'1c018e2a6c6d518c4a2dde059e49f33af67c4636',
|
||||
'refs/heads/cli-rev-info'
|
||||
);
|
||||
|
||||
$output = $this->callFunction(
|
||||
$this->command,
|
||||
WriteGitRevisionCommand::class,
|
||||
'getRevisionInfo',
|
||||
[
|
||||
'https://github.com/phpmyadmin/phpmyadmin/commit/%s',
|
||||
'https://github.com/phpmyadmin/phpmyadmin/tree/%s',
|
||||
]
|
||||
);
|
||||
$template = <<<'PHP'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is generated by scripts/console.
|
||||
*
|
||||
* @see \PhpMyAdmin\Command\WriteGitRevisionCommand
|
||||
*/
|
||||
return [
|
||||
'revision' => '%s',
|
||||
'revisionUrl' => '%s',
|
||||
'branch' => '%s',
|
||||
'branchUrl' => '%s',
|
||||
];
|
||||
|
||||
PHP;
|
||||
$this->assertSame(
|
||||
sprintf(
|
||||
$template,
|
||||
'RELEASE_5_1_0-638-g1c018e2a6c',
|
||||
'https://github.com/phpmyadmin/phpmyadmin/commit/1c018e2a6c6d518c4a2dde059e49f33af67c4636',
|
||||
'cli-rev-info',
|
||||
'https://github.com/phpmyadmin/phpmyadmin/tree/cli-rev-info'
|
||||
),
|
||||
$output
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user