From f28fbe06e4aafcdd36d79e17d401f161ce2a83fc Mon Sep 17 00:00:00 2001 From: William Desportes Date: Sat, 6 Feb 2021 00:18:33 +0100 Subject: [PATCH 1/6] Improve the release script for versionning Signed-off-by: William Desportes Improve the version handling Signed-off-by: William Desportes Simplify the version handling Signed-off-by: William Desportes --- libraries/classes/Config.php | 9 ++--- libraries/classes/Version.php | 67 +++++++++++++++++++++++++++++++++++ libraries/vendor_config.php | 5 +++ phpstan.neon.dist | 2 ++ scripts/create-release.sh | 54 ++++++++++++++++++---------- 5 files changed, 112 insertions(+), 25 deletions(-) create mode 100644 libraries/classes/Version.php diff --git a/libraries/classes/Config.php b/libraries/classes/Config.php index 263474241e..ff7aefdb98 100644 --- a/libraries/classes/Config.php +++ b/libraries/classes/Config.php @@ -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::phpMyAdminVersion()); + $this->set('PMA_MAJOR_VERSION', Version::phpMyAdminSeriesVersion()); $this->checkWebServerOs(); $this->checkWebServer(); diff --git a/libraries/classes/Version.php b/libraries/classes/Version.php new file mode 100644 index 0000000000..e5761b6f50 --- /dev/null +++ b/libraries/classes/Version.php @@ -0,0 +1,67 @@ + /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 "require_once('libraries/classes/Version.php'); echo \PhpMyAdmin\Version::phpMyAdminVersion();" +} + +echo "The actual configured release is: $(fetchReleaseFromFile)" if [ $do_ci -eq 0 -a -$do_daily -eq 0 ] ; then cat <set('PMA_VERSION', '$version'); " + - in $VERSION_FILE Version class: + - check that VERSION_MAJOR, VERSION_MINOR and VERSION_PATCH are correct. + - for a normal release + - check that IS_DEV is false + - check that PRE_RELEASE_NAME is empty + - for a -rc release + - check that IS_DEV is false + - change PRE_RELEASE_NAME to "rc1" - 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 +274,8 @@ END fi fi +echo "The actual configured release is now: $(fetchReleaseFromFile)" + # Create working copy mkdir -p release git worktree prune @@ -290,8 +297,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 "'PMA_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 +608,20 @@ 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 - " phpMyAdmin 2.2.2-rc1 - Documentation " - "

phpMyAdmin 2.2.2-rc1 Documentation

" + - in $VERSION_FILE Version class: + - for a dev cycle + - set IS_DEV to true + - check that PRE_RELEASE_NAME is empty + - for a normal release + - check that IS_DEV is false + - check that PRE_RELEASE_NAME is empty + - for a -rc release + - check that IS_DEV is false + - change PRE_RELEASE_NAME to "rc1" + - 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 +631,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 From 92965c69451f18b07348232f38d28d3df6ec2ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Sat, 6 Feb 2021 14:34:51 -0300 Subject: [PATCH 2/6] Add the PhpMyAdmin\Version class generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creates the PhpMyAdmin\Command\SetVersionCommand class. Usage: ./scripts/console set-version 5.1.0-dev Signed-off-by: MaurĂ­cio Meneghini Fauth --- .../classes/Command/SetVersionCommand.php | 101 ++++++++++++++++++ libraries/classes/Config.php | 4 +- libraries/classes/Version.php | 66 ++---------- scripts/console | 2 + 4 files changed, 116 insertions(+), 57 deletions(-) create mode 100644 libraries/classes/Command/SetVersionCommand.php diff --git a/libraries/classes/Command/SetVersionCommand.php b/libraries/classes/Command/SetVersionCommand.php new file mode 100644 index 0000000000..437905a1c8 --- /dev/null +++ b/libraries/classes/Command/SetVersionCommand.php @@ -0,0 +1,101 @@ +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 + { + $return = preg_match('/^(\d+)\.(\d{1,2})\.(\d{1,2})(-(\w+))?$/', $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; + } +} diff --git a/libraries/classes/Config.php b/libraries/classes/Config.php index ff7aefdb98..e442a8cf0e 100644 --- a/libraries/classes/Config.php +++ b/libraries/classes/Config.php @@ -137,8 +137,8 @@ class Config public function checkSystem(): void { // All the version handling is now done in the Version class - $this->set('PMA_VERSION', Version::phpMyAdminVersion()); - $this->set('PMA_MAJOR_VERSION', Version::phpMyAdminSeriesVersion()); + $this->set('PMA_VERSION', Version::VERSION); + $this->set('PMA_MAJOR_VERSION', Version::SERIES); $this->checkWebServerOs(); $this->checkWebServer(); diff --git a/libraries/classes/Version.php b/libraries/classes/Version.php index e5761b6f50..76c2b3c007 100644 --- a/libraries/classes/Version.php +++ b/libraries/classes/Version.php @@ -4,64 +4,20 @@ declare(strict_types=1); namespace PhpMyAdmin; -use function defined; - /** - * Class to handle the phpMyAdmin version + * This class is generated by scripts/console. + * + * @see \PhpMyAdmin\Command\SetVersionCommand */ final class Version { - /* - * Packaging people can add a version suffix using the VERSION_SUFFIX constant at vendor_config.php - */ - - public const VERSION_MAJOR = 5; - public const VERSION_MINOR = 1; - public const VERSION_PATCH = 0; - - // The version will be {major}.{minor}.{patch}-dev + // 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; - - // The version will be {major}.{minor}.{patch}-{PRE_RELEASE_NAME} if not empty - public const PRE_RELEASE_NAME = ''; - - /** - * Get the current phpMyAdmin series version - * - * @example 5.1 - */ - public static function phpMyAdminSeriesVersion(): string - { - return self::VERSION_MAJOR . '.' . self::VERSION_MINOR; - } - - /** - * Get the current phpMyAdmin version - */ - public static function phpMyAdminVersion(): string - { - $versionRaw = self::VERSION_MAJOR . '.' . self::VERSION_MINOR . '.' . self::VERSION_PATCH; - - if (self::IS_DEV) { - return $versionRaw . '-dev'; - } - - if (self::PRE_RELEASE_NAME !== '') { - return $versionRaw . '-' . self::PRE_RELEASE_NAME; - } - - if (defined('VERSION_SUFFIX')) { - return $versionRaw . VERSION_SUFFIX; - } - - return $versionRaw; - } - - /** - * If the current version is a dev version - */ - public static function isDev(): bool - { - return self::IS_DEV; - } } diff --git a/scripts/console b/scripts/console index 65c8082ec7..36e24d8415 100755 --- a/scripts/console +++ b/scripts/console @@ -2,6 +2,7 @@ add(new CacheWarmupCommand()); $application->add(new LintCommand($twig)); +$application->add(new SetVersionCommand()); $application->run(); From 6e2459f57ac4ceb3a7fff1a962489676924b3d59 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Sat, 13 Feb 2021 18:36:06 +0100 Subject: [PATCH 3/6] Add tests to generate the version file Signed-off-by: William Desportes --- .../classes/Command/SetVersionCommand.php | 3 +- .../classes/Command/SetVersionCommandTest.php | 194 ++++++++++++++++++ 2 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 test/classes/Command/SetVersionCommandTest.php diff --git a/libraries/classes/Command/SetVersionCommand.php b/libraries/classes/Command/SetVersionCommand.php index 437905a1c8..780bd1b498 100644 --- a/libraries/classes/Command/SetVersionCommand.php +++ b/libraries/classes/Command/SetVersionCommand.php @@ -73,7 +73,8 @@ PHP; private function getGeneratedClass(string $version): string { - $return = preg_match('/^(\d+)\.(\d{1,2})\.(\d{1,2})(-(\w+))?$/', $version, $matches); + // 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); } diff --git a/test/classes/Command/SetVersionCommandTest.php b/test/classes/Command/SetVersionCommandTest.php new file mode 100644 index 0000000000..5934afc11c --- /dev/null +++ b/test/classes/Command/SetVersionCommandTest.php @@ -0,0 +1,194 @@ +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 + { + $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 + { + $output = $this->callFunction( + $this->command, + SetVersionCommand::class, + 'getGeneratedClass', + [$version] + ); + $template = <<<'PHP' +assertSame( + sprintf($template, $content), + $output + ); + } +} From cde808888ce0d2e957a4c50e0fcc1c14a3d7d520 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Sat, 13 Feb 2021 18:46:51 +0100 Subject: [PATCH 4/6] Add tests for the Version class Signed-off-by: William Desportes --- test/classes/VersionTest.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/classes/VersionTest.php diff --git a/test/classes/VersionTest.php b/test/classes/VersionTest.php new file mode 100644 index 0000000000..607c26541b --- /dev/null +++ b/test/classes/VersionTest.php @@ -0,0 +1,34 @@ +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); + } +} From 70b93789413489efbd7b2af99e86ef077ac81cd1 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Sat, 13 Feb 2021 19:29:40 +0100 Subject: [PATCH 5/6] Update the release script to match recent versionning changes Signed-off-by: William Desportes --- scripts/create-release.sh | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/scripts/create-release.sh b/scripts/create-release.sh index 63ded94518..58cc1c5858 100755 --- a/scripts/create-release.sh +++ b/scripts/create-release.sh @@ -241,7 +241,7 @@ ensure_local_branch $branch VERSION_FILE=libraries/classes/Version.php fetchReleaseFromFile() { - php -r "require_once('libraries/classes/Version.php'); echo \PhpMyAdmin\Version::phpMyAdminVersion();" + php -r "define('VERSION_SUFFIX', ''); require_once('libraries/classes/Version.php'); echo \PhpMyAdmin\Version::VERSION;" } echo "The actual configured release is: $(fetchReleaseFromFile)" @@ -250,14 +250,9 @@ if [ $do_ci -eq 0 -a -$do_daily -eq 0 ] ; then cat < Date: Mon, 22 Feb 2021 00:09:23 +0100 Subject: [PATCH 6/6] Skip Console test for releases and packaging people Signed-off-by: William Desportes --- test/classes/Command/SetVersionCommandTest.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/classes/Command/SetVersionCommandTest.php b/test/classes/Command/SetVersionCommandTest.php index 5934afc11c..42ffcc17d0 100644 --- a/test/classes/Command/SetVersionCommandTest.php +++ b/test/classes/Command/SetVersionCommandTest.php @@ -6,8 +6,10 @@ 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 { @@ -16,7 +18,9 @@ class SetVersionCommandTest extends AbstractTestCase public function setUp(): void { - $this->command = new SetVersionCommand(); + if (class_exists(Command::class)) { + $this->command = new SetVersionCommand(); + } } /** @@ -49,6 +53,10 @@ class SetVersionCommandTest extends AbstractTestCase */ 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( @@ -161,6 +169,10 @@ class SetVersionCommandTest extends AbstractTestCase */ 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,