From 3270c3f775974d2665e089158f85dd3e09a1571d Mon Sep 17 00:00:00 2001 From: Pierre Goiffon Date: Thu, 8 Dec 2022 16:32:34 +0100 Subject: [PATCH] =?UTF-8?q?:hammer:=20N=C2=B05779=20update-xml=20:=20if=20?= =?UTF-8?q?XML=20files=20already=20at=20current=20version,=20tries=20to=20?= =?UTF-8?q?convert=20from=20previous=20one?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .make/release/update.classes.inc.php | 19 ++++++ setup/itopdesignformat.class.inc.php | 60 ++++++++++++++++--- test/.make/release/DatamodelsXmlFilesTest.php | 31 ++++++++++ .../iTopDesignFormat/iTopDesignFormatTest.php | 10 ++++ 4 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 test/.make/release/DatamodelsXmlFilesTest.php diff --git a/.make/release/update.classes.inc.php b/.make/release/update.classes.inc.php index cb6798730..8f1499439 100644 --- a/.make/release/update.classes.inc.php +++ b/.make/release/update.classes.inc.php @@ -202,6 +202,13 @@ class DatamodelsXmlFiles extends AbstractGlobFileVersionUpdater $oFileXml->loadXML($sFileContent); $oFileItopFormat = new iTopDesignFormat($oFileXml); + + $sDesignVersionToSet = static::GetDesignVersionToSet($oFileItopFormat->GetVersion()); + if (false === is_null($sDesignVersionToSet)) { + // N°5779 if same as target version, we will try to convert from version below + $oFileItopFormat->GetITopDesignNode()->setAttribute('version', $sDesignVersionToSet); + } + $bConversionResult = $oFileItopFormat->Convert($sVersionLabel); if (false === $bConversionResult) { @@ -210,4 +217,16 @@ class DatamodelsXmlFiles extends AbstractGlobFileVersionUpdater return $oFileItopFormat->GetXmlAsString(); } + + /** + * @return ?string version to use : if file version is same as current version then return previous version, else return null + * @since 3.1.0 N°5779 + */ + protected static function GetDesignVersionToSet($sFileDesignVersion):?string { + if ($sFileDesignVersion !== ITOP_DESIGN_LATEST_VERSION) { + return null; + } + + return iTopDesignFormat::GetPreviousDesignVersion(ITOP_DESIGN_LATEST_VERSION); + } } diff --git a/setup/itopdesignformat.class.inc.php b/setup/itopdesignformat.class.inc.php index 4e8517e56..5f6a4efb0 100644 --- a/setup/itopdesignformat.class.inc.php +++ b/setup/itopdesignformat.class.inc.php @@ -40,6 +40,17 @@ */ class iTopDesignFormat { + /** + * @var array{ + * string, + * array{ + * previous: string, + * go_to_previous: string, + * next: string, + * go_to_next: string + * } + * } + */ public static $aVersions = array( '1.0' => array( 'previous' => null, @@ -162,6 +173,29 @@ class iTopDesignFormat ); } + /** + * @param string $sCurrentDesignVersion A design version like 3.0 + * + * @return ?string the previous design version from the one passed, null if passed version unknown or 1.0 + * @since 3.1.0 N°5779 + */ + public static function GetPreviousDesignVersion(string $sCurrentDesignVersion): ?string + { + $aDesignVersions = array_keys(self::$aVersions); + + $iCurrentDesignVersionIndex = array_search($sCurrentDesignVersion, $aDesignVersions, true); + if (false === $iCurrentDesignVersionIndex) { + return null; + } + + $iPreviousDesignVersionIndex = $iCurrentDesignVersionIndex - 1; + if ($iPreviousDesignVersionIndex < 0) { + return null; + } + + return $aDesignVersions[$iPreviousDesignVersionIndex]; + } + /** * Get all the errors in one single array */ @@ -1013,7 +1047,7 @@ class iTopDesignFormat // N°5563 AttributeLinkedSet // - move edit_mode attribute to legacy_edit_mode attribute - // - fill relation_type & read_only + // - fill relation_type & read_only if non-existing $oLinkedSetNodes = $oXPath->query("/itop_design/classes/class/fields/field[@xsi:type='AttributeLinkedSet']"); /** @var \DOMElement $oNode */ foreach ($oLinkedSetNodes as $oNode) { @@ -1047,19 +1081,29 @@ class iTopDesignFormat break; } - $oRelationTypeNode = $oNode->ownerDocument->createElement('relation_type', $sRelationType); - $oNode->appendChild($oRelationTypeNode); - $oReadOnlyNode = $oNode->ownerDocument->createElement('read_only', $sReadOnly); - $oNode->appendChild($oReadOnlyNode); + $bHasRelationType = ($oNode->getElementsByTagName('relation_type')->count() > 0); + if (false === $bHasRelationType) { + $oRelationTypeNode = $oNode->ownerDocument->createElement('relation_type', $sRelationType); + $oNode->appendChild($oRelationTypeNode); + } + + $bHasReadOnly = ($oNode->getElementsByTagName('read_only')->count() > 0); + if (false === $bHasReadOnly) { + $oReadOnlyNode = $oNode->ownerDocument->createElement('read_only', $sReadOnly); + $oNode->appendChild($oReadOnlyNode); + } } } // N°5563 AttributeLinkedSetIndirect - // - fill read_only attribute + // - fill read_only attribute if non-existing $oLinkedSetIndirectNodes = $oXPath->query("/itop_design/classes/class/fields/field[@xsi:type='AttributeLinkedSetIndirect']"); foreach ($oLinkedSetIndirectNodes as $oNode) { - $oReadOnlyNode = $oNode->ownerDocument->createElement('read_only', 'false'); - $oNode->appendChild($oReadOnlyNode); + $bHasReadOnly = ($oNode->getElementsByTagName('read_only')->count() > 0); + if (false === $bHasReadOnly) { + $oReadOnlyNode = $oNode->ownerDocument->createElement('read_only', 'false'); + $oNode->appendChild($oReadOnlyNode); + } } } /** diff --git a/test/.make/release/DatamodelsXmlFilesTest.php b/test/.make/release/DatamodelsXmlFilesTest.php new file mode 100644 index 000000000..8f5b836d7 --- /dev/null +++ b/test/.make/release/DatamodelsXmlFilesTest.php @@ -0,0 +1,31 @@ +InvokeNonPublicStaticMethod(DatamodelsXmlFiles::class, 'GetDesignVersionToSet', ['1.0']); + $this->assertNull($sVersionFor10); + $sVersionFor26 = $this->InvokeNonPublicStaticMethod(DatamodelsXmlFiles::class, 'GetDesignVersionToSet', ['2.6']); + $this->assertNull($sVersionFor26); + $sVersionFor27 = $this->InvokeNonPublicStaticMethod(DatamodelsXmlFiles::class, 'GetDesignVersionToSet', ['2.7']); + $this->assertNull($sVersionFor27); + + $sPreviousDesignVersion = iTopDesignFormat::GetPreviousDesignVersion(ITOP_DESIGN_LATEST_VERSION); + $sVersionForLatest = $this->InvokeNonPublicStaticMethod(DatamodelsXmlFiles::class, 'GetDesignVersionToSet', [ITOP_DESIGN_LATEST_VERSION]); + $this->assertNotNull($sVersionForLatest); + $this->assertSame($sPreviousDesignVersion, $sVersionForLatest); + } +} diff --git a/test/setup/iTopDesignFormat/iTopDesignFormatTest.php b/test/setup/iTopDesignFormat/iTopDesignFormatTest.php index 8337723e0..6aab1a8ff 100644 --- a/test/setup/iTopDesignFormat/iTopDesignFormatTest.php +++ b/test/setup/iTopDesignFormat/iTopDesignFormatTest.php @@ -24,6 +24,16 @@ class iTopDesignFormatTest extends ItopTestCase require_once APPROOT.'setup/itopdesignformat.class.inc.php'; } + public function testGetPreviousDesignVersion() { + $this->assertSame('3.0', iTopDesignFormat::GetPreviousDesignVersion('3.1')); + $this->assertSame('1.7', iTopDesignFormat::GetPreviousDesignVersion('3.0')); + $this->assertSame('1.6', iTopDesignFormat::GetPreviousDesignVersion('1.7')); + $this->assertSame('1.5', iTopDesignFormat::GetPreviousDesignVersion('1.6')); + $this->assertNull(iTopDesignFormat::GetPreviousDesignVersion('1.0')); + $this->assertNull(iTopDesignFormat::GetPreviousDesignVersion('')); + $this->assertNull(iTopDesignFormat::GetPreviousDesignVersion('NonExistingVersion')); + } + /** * @covers iTopDesignFormat::Convert * @dataProvider ConvertProvider