Add version.yaml processing for Symfony/Yaml v4 support (#65)

Fixes #13
Follows on from wintercms/storm#16

Moves the version.yaml processing into the System module and updates all version file parsing to use this new processor.
This commit is contained in:
Ben Thomson 2021-03-28 11:25:42 +08:00 committed by GitHub
parent 2ddfd28c65
commit 181f213079
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 114 additions and 20 deletions

View File

@ -279,7 +279,9 @@ class VersionManager
}
$versionFile = $this->getVersionFile($code);
$versionInfo = Yaml::parseFile($versionFile);
$versionInfo = Yaml::withProcessor(new VersionYamlProcessor, function ($yaml) use ($versionFile) {
return $yaml->parseFile($versionFile);
});
if (!is_array($versionInfo)) {
$versionInfo = [];

View File

@ -0,0 +1,57 @@
<?php namespace System\Classes;
use Winter\Storm\Parse\Processor\Contracts\YamlProcessor;
/**
* "version.yaml" pre-processor class.
*
* Post-v3.x versions of the Symonfy/Yaml package use more recent versions of YAML spec, which breaks common
* implementations of our version file format. To maintain compatibility, this class will pre-process YAML
* contents from these files to work with Symfony/Yaml 4.0+.
*
* @author Winter CMS
*/
class VersionYamlProcessor implements YamlProcessor
{
/**
* @inheritDoc
*/
public function preprocess($text)
{
$lines = preg_split('/[\n\r]+/', $text, -1, PREG_SPLIT_NO_EMPTY);
foreach ($lines as $num => &$line) {
// Surround array keys with quotes if not already
$line = preg_replace_callback('/^\s*([\'"]{0}[^\'"\n\r:]+[\'"]{0})\s*:/m', function ($matches) {
return '"' . trim($matches[1]) . '":';
}, rtrim($line));
// Add quotes around any unquoted text following an array key
// specifically to ensure usage of !!! in unquoted comments does not fail
$line = preg_replace('/^\s*([^\n\r\-:]+)\s*: +(?![\'"\s])(.*)/m', '$1: "$2"', $line);
// If this line is the continuance of a multi-line string, remove the quote from the previous line and
// continue the quote
if (
preg_match('/^(?!\s*(-|(.*?):\s*))([^\n\r]+)([^"]$)/m', $line)
&& substr($lines[$num - 1], -1) === '"'
) {
$lines[$num - 1] = substr($lines[$num - 1], 0, -1);
$line .= '"';
}
// Add quotes around any unquoted array items
$line = preg_replace('/^(\s*-\s*)(?![\'" ])(.*)/m', '$1"$2"', $line);
}
return implode("\n", $lines);
}
/**
* @inheritDoc
*/
public function process($parsed)
{
return $parsed;
}
}

View File

@ -17,6 +17,7 @@ use System\Models\PluginVersion;
use System\Classes\UpdateManager;
use System\Classes\PluginManager;
use System\Classes\SettingsManager;
use System\Classes\VersionYamlProcessor;
use ApplicationException;
use Exception;
@ -184,7 +185,9 @@ class Updates extends Controller
$contents = [];
try {
$updates = (array) Yaml::parseFile($path.'/'.$filename);
$updates = Yaml::withProcessor(new VersionYamlProcessor, function ($yaml) use ($path, $filename) {
return (array) $yaml->parseFile($path.'/'.$filename);
});
foreach ($updates as $version => $details) {
if (!is_array($details)) {
@ -192,9 +195,9 @@ class Updates extends Controller
}
//Filter out update scripts
$details = array_filter($details, function ($string) use ($path) {
$details = array_values(array_filter($details, function ($string) use ($path) {
return !preg_match('/^[a-z_\-0-9]*\.php$/i', $string) || !File::exists($path . '/updates/' . $string);
});
}));
$contents[$version] = $details;
}

View File

@ -1,19 +1,26 @@
1.3.2:
Added support for Translate plugin.
Added some new languages.
'1.3.1' :
- 'Minor bug fix
Please see changelog'
- 'fix_database.php'
"1.3.0" : !!! We've refactored major parts
of this plugin. Please see the
website for more information.
1.2.0:
- "!!! Security update - see: https://wintercms.com"
1.1.0:
1.1.0 :
- !!! Drop support for blog settings
- drop_blog_settings_table.php
1.0.5:
"1.0.5":
- Create blog settings table
- Another update message
- Yet one more update message
- create_blog_settings_table.php
1.0.4: Another fix
1.0.3: Bug fix update that uses no scripts
1.0.2:
- Create blog post comments table
- Multiple update messages are allowed
- create_comments_table.php
"1.0.4": "Another fix"
"1.0.3": Bug fix update that uses no scripts
1.0.2: Added some stuff
1.0.1:
- Added some upgrade file and some seeding
- some_upgrade_file.php

View File

@ -14,12 +14,20 @@ class UpdatesControllerTest extends TestCase
$controller = $this->getMockBuilder(Updates::class)->disableOriginalConstructor()->getMock();
$expectedVersions = [
'1.3.2' => [
'Added support for Translate plugin. Added some new languages.',
],
'1.3.1' => [
'Minor bug fix Please see changelog',
],
'1.3.0' => [
'!!! We\'ve refactored major parts of this plugin. Please see the website for more information.',
],
'1.2.0' => [
'!!! Security update - see: https://wintercms.com',
],
'1.1.0' => [
'!!! Drop support for blog settings',
'drop_blog_settings_table.php',
],
'1.0.5' => [
'Create blog settings table',
@ -33,12 +41,10 @@ class UpdatesControllerTest extends TestCase
'Bug fix update that uses no scripts'
],
'1.0.2' => [
'Create blog post comments table',
'Multiple update messages are allowed',
'Added some stuff',
],
'1.0.1' => [
'Added some upgrade file and some seeding',
'some_upgrade_file.php', //does not exist
'some_seeding_file.php' //does not exist
],
];

View File

@ -24,7 +24,7 @@ class VersionManagerTest extends TestCase
$result = self::callProtectedMethod($manager, 'getLatestFileVersion', ['\Winter\\Tester']);
$this->assertNotNull($result);
$this->assertEquals('1.2.0', $result);
$this->assertEquals('1.3.2', $result);
}
public function testGetFileVersions()
@ -32,7 +32,7 @@ class VersionManagerTest extends TestCase
$manager = VersionManager::instance();
$result = self::callProtectedMethod($manager, 'getFileVersions', ['\Winter\\Tester']);
$this->assertCount(7, $result);
$this->assertCount(10, $result);
$this->assertArrayHasKey('1.0.1', $result);
$this->assertArrayHasKey('1.0.2', $result);
$this->assertArrayHasKey('1.0.3', $result);
@ -40,6 +40,9 @@ class VersionManagerTest extends TestCase
$this->assertArrayHasKey('1.0.5', $result);
$this->assertArrayHasKey('1.1.0', $result);
$this->assertArrayHasKey('1.2.0', $result);
$this->assertArrayHasKey('1.3.0', $result);
$this->assertArrayHasKey('1.3.1', $result);
$this->assertArrayHasKey('1.3.2', $result);
$sample = $result['1.0.1'];
$this->assertEquals('Added some upgrade file and some seeding', $sample[0]);
@ -51,6 +54,16 @@ class VersionManagerTest extends TestCase
$sample = $result['1.2.0'];
$this->assertEquals('!!! Security update - see: https://wintercms.com', $sample[0]);
$sample = $result['1.3.0'];
$this->assertEquals('!!! We\'ve refactored major parts of this plugin. Please see the website for more information.', $sample);
$sample = $result['1.3.1'];
$this->assertEquals('Minor bug fix Please see changelog', $sample[0]);
$this->assertEquals('fix_database.php', $sample[1]);
$sample = $result['1.3.2'];
$this->assertEquals('Added support for Translate plugin. Added some new languages.', $sample);
/*
* Test junk file
*/
@ -78,11 +91,14 @@ class VersionManagerTest extends TestCase
$manager = VersionManager::instance();
$result = self::callProtectedMethod($manager, 'getNewFileVersions', ['\Winter\\Tester', '1.0.3']);
$this->assertCount(4, $result);
$this->assertCount(7, $result);
$this->assertArrayHasKey('1.0.4', $result);
$this->assertArrayHasKey('1.0.5', $result);
$this->assertArrayHasKey('1.1.0', $result);
$this->assertArrayHasKey('1.2.0', $result);
$this->assertArrayHasKey('1.3.0', $result);
$this->assertArrayHasKey('1.3.1', $result);
$this->assertArrayHasKey('1.3.2', $result);
/*
* When at version 0, should return everything
@ -90,7 +106,7 @@ class VersionManagerTest extends TestCase
$manager = VersionManager::instance();
$result = self::callProtectedMethod($manager, 'getNewFileVersions', ['\Winter\\Tester']);
$this->assertCount(7, $result);
$this->assertCount(10, $result);
$this->assertArrayHasKey('1.0.1', $result);
$this->assertArrayHasKey('1.0.2', $result);
$this->assertArrayHasKey('1.0.3', $result);
@ -98,6 +114,9 @@ class VersionManagerTest extends TestCase
$this->assertArrayHasKey('1.0.5', $result);
$this->assertArrayHasKey('1.1.0', $result);
$this->assertArrayHasKey('1.2.0', $result);
$this->assertArrayHasKey('1.3.0', $result);
$this->assertArrayHasKey('1.3.1', $result);
$this->assertArrayHasKey('1.3.2', $result);
}
/**