Merge #16584 - Improve the version handling
Signed-off-by: William Desportes <williamdes@wdes.fr>
This commit is contained in:
commit
0a55b43adc
102
libraries/classes/Command/SetVersionCommand.php
Normal file
102
libraries/classes/Command/SetVersionCommand.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Command;
|
||||
|
||||
use RangeException;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use function file_put_contents;
|
||||
use function preg_match;
|
||||
use function sprintf;
|
||||
|
||||
final class SetVersionCommand extends Command
|
||||
{
|
||||
/** @var string */
|
||||
protected static $defaultName = 'set-version';
|
||||
|
||||
/** @var string */
|
||||
private static $generatedClassTemplate = <<<'PHP'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin;
|
||||
|
||||
/**
|
||||
* This class is generated by scripts/console.
|
||||
*
|
||||
* @see \PhpMyAdmin\Command\SetVersionCommand
|
||||
*/
|
||||
final class Version
|
||||
{
|
||||
// The VERSION_SUFFIX constant is defined at libraries/vendor_config.php
|
||||
public const VERSION = '%1$u.%2$u.%3$u%4$s' . VERSION_SUFFIX;
|
||||
public const SERIES = '%1$u.%2$u';
|
||||
public const MAJOR = %1$u;
|
||||
public const MINOR = %2$u;
|
||||
public const PATCH = %3$u;
|
||||
public const ID = %1$u%2$02u%3$02u;
|
||||
public const PRE_RELEASE_NAME = '%5$s';
|
||||
public const IS_DEV = %6$s;
|
||||
}
|
||||
|
||||
PHP;
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->setDescription('Sets the version number');
|
||||
$this->setHelp('This command generates the PhpMyAdmin\Version class based on the version number provided.');
|
||||
$this->addArgument('version', InputArgument::REQUIRED, 'The version number');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
/** @var string $version */
|
||||
$version = $input->getArgument('version');
|
||||
|
||||
$generatedClass = $this->getGeneratedClass($version);
|
||||
|
||||
if (! $this->writeGeneratedClassFile($generatedClass)) {
|
||||
// failure
|
||||
return 1;
|
||||
}
|
||||
|
||||
$output->writeln('PhpMyAdmin\Version class successfully generated!');
|
||||
|
||||
// success
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function getGeneratedClass(string $version): string
|
||||
{
|
||||
// Do not allow any major below 5
|
||||
$return = preg_match('/^([5-9]+)\.(\d{1,2})\.(\d{1,2})(-([a-z0-9]+))?$/', $version, $matches);
|
||||
if ($return === false || $return === 0) {
|
||||
throw new RangeException('The version number is in the wrong format: ' . $version);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
self::$generatedClassTemplate,
|
||||
$matches[1],
|
||||
$matches[2],
|
||||
$matches[3],
|
||||
$matches[4] ?? '',
|
||||
$matches[5] ?? '',
|
||||
($matches[5] ?? '') === 'dev' ? 'true' : 'false'
|
||||
);
|
||||
}
|
||||
|
||||
private function writeGeneratedClassFile(string $generatedClass): bool
|
||||
{
|
||||
$result = file_put_contents(
|
||||
ROOT_PATH . 'libraries/classes/Version.php',
|
||||
$generatedClass
|
||||
);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
}
|
||||
@ -136,12 +136,9 @@ class Config
|
||||
*/
|
||||
public function checkSystem(): void
|
||||
{
|
||||
$this->set('PMA_VERSION', '5.1.0-rc2');
|
||||
/* Major version */
|
||||
$this->set(
|
||||
'PMA_MAJOR_VERSION',
|
||||
implode('.', array_slice(explode('.', $this->get('PMA_VERSION'), 3), 0, 2))
|
||||
);
|
||||
// All the version handling is now done in the Version class
|
||||
$this->set('PMA_VERSION', Version::VERSION);
|
||||
$this->set('PMA_MAJOR_VERSION', Version::SERIES);
|
||||
|
||||
$this->checkWebServerOs();
|
||||
$this->checkWebServer();
|
||||
|
||||
23
libraries/classes/Version.php
Normal file
23
libraries/classes/Version.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin;
|
||||
|
||||
/**
|
||||
* This class is generated by scripts/console.
|
||||
*
|
||||
* @see \PhpMyAdmin\Command\SetVersionCommand
|
||||
*/
|
||||
final class Version
|
||||
{
|
||||
// The VERSION_SUFFIX constant is defined at libraries/vendor_config.php
|
||||
public const VERSION = '5.1.0-dev' . VERSION_SUFFIX;
|
||||
public const SERIES = '5.1';
|
||||
public const MAJOR = 5;
|
||||
public const MINOR = 1;
|
||||
public const PATCH = 0;
|
||||
public const ID = 50100;
|
||||
public const PRE_RELEASE_NAME = 'dev';
|
||||
public const IS_DEV = true;
|
||||
}
|
||||
@ -79,3 +79,8 @@ define('LOCALE_PATH', ROOT_PATH . 'locale' . DIRECTORY_SEPARATOR);
|
||||
* Define the cache directory for routing cache an other cache files
|
||||
*/
|
||||
define('CACHE_DIR', ROOT_PATH . 'libraries' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR);
|
||||
|
||||
/**
|
||||
* Suffix to add to the phpMyAdmin version
|
||||
*/
|
||||
define('VERSION_SUFFIX', '');
|
||||
|
||||
@ -20,3 +20,5 @@ parameters:
|
||||
- tmp/*
|
||||
- twig-templates/*
|
||||
- vendor/*
|
||||
dynamicConstantNames:
|
||||
- VERSION_SUFFIX
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
<?php
|
||||
|
||||
use PhpMyAdmin\Command\CacheWarmupCommand;
|
||||
use PhpMyAdmin\Command\SetVersionCommand;
|
||||
use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\DatabaseInterface;
|
||||
use PhpMyAdmin\Tests\Stubs\DbiDummy;
|
||||
@ -65,5 +66,6 @@ $application = new Application('phpMyAdmin Console Tool');
|
||||
|
||||
$application->add(new CacheWarmupCommand());
|
||||
$application->add(new LintCommand($twig));
|
||||
$application->add(new SetVersionCommand());
|
||||
|
||||
$application->run();
|
||||
|
||||
@ -238,24 +238,24 @@ delete_phpunit_sandbox() {
|
||||
# Ensure we have tracking branch
|
||||
ensure_local_branch $branch
|
||||
|
||||
# Check if we're releasing older
|
||||
if git cat-file -e $branch:libraries/classes/Config.php 2> /dev/null ; then
|
||||
CONFIG_LIB=libraries/classes/Config.php
|
||||
elif git cat-file -e $branch:libraries/Config.php 2> /dev/null ; then
|
||||
CONFIG_LIB=libraries/Config.php
|
||||
else
|
||||
CONFIG_LIB=libraries/Config.class.php
|
||||
fi
|
||||
VERSION_FILE=libraries/classes/Version.php
|
||||
|
||||
fetchReleaseFromFile() {
|
||||
php -r "define('VERSION_SUFFIX', ''); require_once('libraries/classes/Version.php'); echo \PhpMyAdmin\Version::VERSION;"
|
||||
}
|
||||
|
||||
echo "The actual configured release is: $(fetchReleaseFromFile)"
|
||||
|
||||
if [ $do_ci -eq 0 -a -$do_daily -eq 0 ] ; then
|
||||
cat <<END
|
||||
|
||||
Please ensure you have incremented rc count or version in the repository :
|
||||
- in $CONFIG_LIB Config::__constructor() the line
|
||||
" \$this->set('PMA_VERSION', '$version'); "
|
||||
- run ./scripts/console set-version $version
|
||||
- in $VERSION_FILE Version class:
|
||||
- check that VERSION, MAJOR, MINOR and PATCH are correct.
|
||||
- in doc/conf.py the line
|
||||
" version = '$version' "
|
||||
- in README
|
||||
- in README the "Version" line
|
||||
- in package.json the line
|
||||
" "version": "$version", "
|
||||
- set release date in ChangeLog
|
||||
@ -269,6 +269,8 @@ END
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "The actual configured release is now: $(fetchReleaseFromFile)"
|
||||
|
||||
# Create working copy
|
||||
mkdir -p release
|
||||
git worktree prune
|
||||
@ -290,8 +292,8 @@ fi
|
||||
|
||||
# Check release version
|
||||
if [ $do_ci -eq 0 -a -$do_daily -eq 0 ] ; then
|
||||
if ! grep -q "'PMA_VERSION', '$version'" $CONFIG_LIB ; then
|
||||
echo "There seems to be wrong version in $CONFIG_LIB!"
|
||||
if ! grep -q "VERSION = '$version'" $VERSION_FILE ; then
|
||||
echo "There seems to be wrong version in $VERSION_FILE!"
|
||||
exit 2
|
||||
fi
|
||||
if ! grep -q "version = '$version'" doc/conf.py ; then
|
||||
@ -601,11 +603,13 @@ Todo now:
|
||||
based on documentation.
|
||||
|
||||
7. increment rc count or version in the repository :
|
||||
- in $CONFIG_LIB Config::__constructor() the line
|
||||
" \$this->set( 'PMA_VERSION', '2.7.1-dev' ); "
|
||||
- in Documentation.html (if it exists) the 2 lines
|
||||
" <title>phpMyAdmin 2.2.2-rc1 - Documentation</title> "
|
||||
" <h1>phpMyAdmin 2.2.2-rc1 Documentation</h1> "
|
||||
- run ./scripts/console set-version $version
|
||||
- in $VERSION_FILE Version class:
|
||||
- check that VERSION, MAJOR, MINOR and PATCH are correct.
|
||||
- in README the "Version" line
|
||||
" Version 2.7.1-dev "
|
||||
- in package.json the line
|
||||
" "version": " 2.7.1-dev", "
|
||||
- in doc/conf.py (if it exists) the line
|
||||
" version = '2.7.1-dev' "
|
||||
|
||||
@ -615,6 +619,6 @@ Todo now:
|
||||
|
||||
10. in case of a new major release ('y' in x.y.0), update the pmaweb/settings.py in website repository to include the new major releases
|
||||
|
||||
11. update the Dockerfile in the docker repository to reflect the new version and create a new annotated tag (such as with git tag -s -a 4.7.9-1 -m "Version 4.7.9-1"). Remember to push the tag with git push origin --tags
|
||||
11. update the Dockerfile in the docker repository to reflect the new version and create a new annotated tag (such as with git tag -s -a 4.7.9-1 -m "Version 4.7.9-1"). Remember to push the tag with git push origin {tagName}
|
||||
|
||||
END
|
||||
|
||||
208
test/classes/Command/SetVersionCommandTest.php
Normal file
208
test/classes/Command/SetVersionCommandTest.php
Normal file
@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Command;
|
||||
|
||||
use PhpMyAdmin\Command\SetVersionCommand;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use RangeException;
|
||||
use function sprintf;
|
||||
use function class_exists;
|
||||
|
||||
class SetVersionCommandTest extends AbstractTestCase
|
||||
{
|
||||
/** @var SetVersionCommand */
|
||||
private $command;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
if (! class_exists(Command::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->command = new SetVersionCommand();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function dataProviderBadVersions(): array
|
||||
{
|
||||
return [
|
||||
[''],
|
||||
['4.9.0.1'],
|
||||
['4.9'],
|
||||
['4-9-0-1'],
|
||||
['4-9-0'],
|
||||
['0-0-0'],
|
||||
['0.0.0'],
|
||||
['1.0.0'],
|
||||
['2.0.0'],
|
||||
['3.0.0'],
|
||||
['4.0.0'],
|
||||
['0.0.-1'],
|
||||
['5.000.0'],
|
||||
['5.0.000'],
|
||||
['5.0.0-'],
|
||||
['5.0.0-foo bar'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderBadVersions
|
||||
*/
|
||||
public function testGetGeneratedClassInvalidVersion(string $version): void
|
||||
{
|
||||
if (! class_exists(Command::class)) {
|
||||
$this->markTestSkipped('The Symfony Console is missing');
|
||||
}
|
||||
|
||||
$this->expectException(RangeException::class);
|
||||
$this->expectExceptionMessage('The version number is in the wrong format: ' . $version);
|
||||
$this->callFunction(
|
||||
$this->command,
|
||||
SetVersionCommand::class,
|
||||
'getGeneratedClass',
|
||||
[$version]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function dataProviderGoodVersions(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'5.0.0-rc1',
|
||||
' public const VERSION = \'5.0.0-rc1\' . VERSION_SUFFIX;' . "\n"
|
||||
. ' public const SERIES = \'5.0\';' . "\n"
|
||||
. ' public const MAJOR = 5;' . "\n"
|
||||
. ' public const MINOR = 0;' . "\n"
|
||||
. ' public const PATCH = 0;' . "\n"
|
||||
. ' public const ID = 50000;' . "\n"
|
||||
. ' public const PRE_RELEASE_NAME = \'rc1\';' . "\n"
|
||||
. ' public const IS_DEV = false;',
|
||||
],
|
||||
[
|
||||
'5.0.0-beta',
|
||||
' public const VERSION = \'5.0.0-beta\' . VERSION_SUFFIX;' . "\n"
|
||||
. ' public const SERIES = \'5.0\';' . "\n"
|
||||
. ' public const MAJOR = 5;' . "\n"
|
||||
. ' public const MINOR = 0;' . "\n"
|
||||
. ' public const PATCH = 0;' . "\n"
|
||||
. ' public const ID = 50000;' . "\n"
|
||||
. ' public const PRE_RELEASE_NAME = \'beta\';' . "\n"
|
||||
. ' public const IS_DEV = false;',
|
||||
],
|
||||
[
|
||||
'5.0.0-beta1',
|
||||
' public const VERSION = \'5.0.0-beta1\' . VERSION_SUFFIX;' . "\n"
|
||||
. ' public const SERIES = \'5.0\';' . "\n"
|
||||
. ' public const MAJOR = 5;' . "\n"
|
||||
. ' public const MINOR = 0;' . "\n"
|
||||
. ' public const PATCH = 0;' . "\n"
|
||||
. ' public const ID = 50000;' . "\n"
|
||||
. ' public const PRE_RELEASE_NAME = \'beta1\';' . "\n"
|
||||
. ' public const IS_DEV = false;',
|
||||
],
|
||||
[
|
||||
'5.0.0-alpha',
|
||||
' public const VERSION = \'5.0.0-alpha\' . VERSION_SUFFIX;' . "\n"
|
||||
. ' public const SERIES = \'5.0\';' . "\n"
|
||||
. ' public const MAJOR = 5;' . "\n"
|
||||
. ' public const MINOR = 0;' . "\n"
|
||||
. ' public const PATCH = 0;' . "\n"
|
||||
. ' public const ID = 50000;' . "\n"
|
||||
. ' public const PRE_RELEASE_NAME = \'alpha\';' . "\n"
|
||||
. ' public const IS_DEV = false;',
|
||||
],
|
||||
[
|
||||
'5.0.0-alpha1',
|
||||
' public const VERSION = \'5.0.0-alpha1\' . VERSION_SUFFIX;' . "\n"
|
||||
. ' public const SERIES = \'5.0\';' . "\n"
|
||||
. ' public const MAJOR = 5;' . "\n"
|
||||
. ' public const MINOR = 0;' . "\n"
|
||||
. ' public const PATCH = 0;' . "\n"
|
||||
. ' public const ID = 50000;' . "\n"
|
||||
. ' public const PRE_RELEASE_NAME = \'alpha1\';' . "\n"
|
||||
. ' public const IS_DEV = false;',
|
||||
],
|
||||
[
|
||||
'5.0.0-alpha1',
|
||||
' public const VERSION = \'5.0.0-alpha1\' . VERSION_SUFFIX;' . "\n"
|
||||
. ' public const SERIES = \'5.0\';' . "\n"
|
||||
. ' public const MAJOR = 5;' . "\n"
|
||||
. ' public const MINOR = 0;' . "\n"
|
||||
. ' public const PATCH = 0;' . "\n"
|
||||
. ' public const ID = 50000;' . "\n"
|
||||
. ' public const PRE_RELEASE_NAME = \'alpha1\';' . "\n"
|
||||
. ' public const IS_DEV = false;',
|
||||
],
|
||||
[
|
||||
'5.1.0-dev',
|
||||
' public const VERSION = \'5.1.0-dev\' . VERSION_SUFFIX;' . "\n"
|
||||
. ' public const SERIES = \'5.1\';' . "\n"
|
||||
. ' public const MAJOR = 5;' . "\n"
|
||||
. ' public const MINOR = 1;' . "\n"
|
||||
. ' public const PATCH = 0;' . "\n"
|
||||
. ' public const ID = 50100;' . "\n"
|
||||
. ' public const PRE_RELEASE_NAME = \'dev\';' . "\n"
|
||||
. ' public const IS_DEV = true;',
|
||||
],
|
||||
[
|
||||
'9.99.99-dev',
|
||||
' public const VERSION = \'9.99.99-dev\' . VERSION_SUFFIX;' . "\n"
|
||||
. ' public const SERIES = \'9.99\';' . "\n"
|
||||
. ' public const MAJOR = 9;' . "\n"
|
||||
. ' public const MINOR = 99;' . "\n"
|
||||
. ' public const PATCH = 99;' . "\n"
|
||||
. ' public const ID = 99999;' . "\n"
|
||||
. ' public const PRE_RELEASE_NAME = \'dev\';' . "\n"
|
||||
. ' public const IS_DEV = true;',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderGoodVersions
|
||||
*/
|
||||
public function testGetGeneratedClassValidVersion(string $version, string $content): void
|
||||
{
|
||||
if (! class_exists(Command::class)) {
|
||||
$this->markTestSkipped('The Symfony Console is missing');
|
||||
}
|
||||
|
||||
$output = $this->callFunction(
|
||||
$this->command,
|
||||
SetVersionCommand::class,
|
||||
'getGeneratedClass',
|
||||
[$version]
|
||||
);
|
||||
$template = <<<'PHP'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin;
|
||||
|
||||
/**
|
||||
* This class is generated by scripts/console.
|
||||
*
|
||||
* @see \PhpMyAdmin\Command\SetVersionCommand
|
||||
*/
|
||||
final class Version
|
||||
{
|
||||
// The VERSION_SUFFIX constant is defined at libraries/vendor_config.php
|
||||
%s
|
||||
}
|
||||
|
||||
PHP;
|
||||
$this->assertSame(
|
||||
sprintf($template, $content),
|
||||
$output
|
||||
);
|
||||
}
|
||||
}
|
||||
34
test/classes/VersionTest.php
Normal file
34
test/classes/VersionTest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests;
|
||||
|
||||
use PhpMyAdmin\Version;
|
||||
use function defined;
|
||||
|
||||
class VersionTest extends AbstractTestCase
|
||||
{
|
||||
/**
|
||||
* Validate the current version
|
||||
*/
|
||||
public function testValidateVersion(): void
|
||||
{
|
||||
$this->assertIsString(Version::VERSION);
|
||||
$this->assertNotEmpty(Version::VERSION);
|
||||
$this->assertStringContainsString(Version::SERIES, Version::VERSION, 'x.y must be found in x.y.z');
|
||||
$this->assertIsInt(Version::MAJOR);
|
||||
$this->assertIsInt(Version::MINOR);
|
||||
$this->assertIsInt(Version::PATCH);
|
||||
$this->assertTrue(Version::MAJOR >= 5);// @phpstan-ignore-line Just checking
|
||||
$this->assertTrue(Version::MINOR >= 0);// @phpstan-ignore-line Just checking
|
||||
$this->assertTrue(Version::PATCH >= 0);// @phpstan-ignore-line Just checking
|
||||
$this->assertTrue(Version::ID >= 50000);// @phpstan-ignore-line Just checking
|
||||
if (defined('VERSION_SUFFIX')) {
|
||||
$this->assertIsString(VERSION_SUFFIX);
|
||||
}
|
||||
$this->assertIsInt(Version::ID);
|
||||
$this->assertIsString(Version::PRE_RELEASE_NAME);
|
||||
$this->assertIsBool(Version::IS_DEV);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user