From 9f3d7d2c36220622caa16421368598300ae5e718 Mon Sep 17 00:00:00 2001 From: odain Date: Thu, 4 Dec 2025 16:51:02 +0100 Subject: [PATCH] =?UTF-8?q?N=C2=B08760:=20revert=20dry=20removal=20audit?= =?UTF-8?q?=20and=20use=20real=20file=20deletion=20again?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit code formatting --- core/metamodel.class.php | 1 - lib/composer/InstalledVersions.php | 38 +------------- lib/composer/installed.php | 4 +- .../DryRemovalRuntimeEnvironment.php | 49 +++++++++++++++---- .../ModelReflectionSerializer.php | 4 +- setup/feature_removal/SetupAudit.php | 4 +- .../feature_removal/get_model_reflection.php | 11 ++--- setup/setuputils.class.inc.php | 2 +- setup/wizardcontroller.class.inc.php | 2 +- setup/wizardsteps.class.inc.php | 6 +-- .../ItopCustomDatamodelTestCase.php | 7 +-- .../Service/UnitTestRunTimeEnvironment.php | 5 -- .../ModelSerializationTest.php | 2 +- .../setup/feature_removal/SetupAuditTest.php | 4 +- .../model.finalclass_ext1_module1.php | 3 +- .../module.finalclass_ext1_module1.php | 33 +++++++------ .../model.finalclass_ext2_module1.php | 3 +- .../module.finalclass_ext2_module1.php | 33 +++++++------ .../model.nominal_ext1_module1.php | 3 +- .../module.nominal_ext1_module1.php | 33 +++++++------ 20 files changed, 121 insertions(+), 126 deletions(-) diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 426e9de14..4953299f1 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -462,7 +462,6 @@ abstract class MetaModel return call_user_func([$sClass, 'GetClassDescription'], $sClass); } - /** * @param string $sClass * diff --git a/lib/composer/InstalledVersions.php b/lib/composer/InstalledVersions.php index 2052022fd..07b32ed6e 100644 --- a/lib/composer/InstalledVersions.php +++ b/lib/composer/InstalledVersions.php @@ -26,23 +26,12 @@ use Composer\Semver\VersionParser; */ class InstalledVersions { - /** - * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to - * @internal - */ - private static $selfDir = null; - /** * @var mixed[]|null * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null */ private static $installed; - /** - * @var bool - */ - private static $installedIsLocalDir; - /** * @var bool|null */ @@ -320,24 +309,6 @@ class InstalledVersions { self::$installed = $data; self::$installedByVendor = array(); - - // when using reload, we disable the duplicate protection to ensure that self::$installed data is - // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, - // so we have to assume it does not, and that may result in duplicate data being returned when listing - // all installed packages for example - self::$installedIsLocalDir = false; - } - - /** - * @return string - */ - private static function getSelfDir() - { - if (self::$selfDir === null) { - self::$selfDir = strtr(__DIR__, '\\', '/'); - } - - return self::$selfDir; } /** @@ -354,9 +325,7 @@ class InstalledVersions $copiedLocalDir = false; if (self::$canGetVendors) { - $selfDir = self::getSelfDir(); foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { - $vendorDir = strtr($vendorDir, '\\', '/'); if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { @@ -364,14 +333,11 @@ class InstalledVersions $required = require $vendorDir.'/composer/installed.php'; self::$installedByVendor[$vendorDir] = $required; $installed[] = $required; - if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { self::$installed = $required; - self::$installedIsLocalDir = true; + $copiedLocalDir = true; } } - if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { - $copiedLocalDir = true; - } } } diff --git a/lib/composer/installed.php b/lib/composer/installed.php index 33b2f7d8a..0e696448c 100644 --- a/lib/composer/installed.php +++ b/lib/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'combodo/itop', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => '19d062aa830b6d6c7d17ac4046fc9ee2c5e3fab1', + 'reference' => '469afdb2f9aea1b6e078a2a5bb12f09a969d60e0', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -22,7 +22,7 @@ 'combodo/itop' => array( 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => '19d062aa830b6d6c7d17ac4046fc9ee2c5e3fab1', + 'reference' => '469afdb2f9aea1b6e078a2a5bb12f09a969d60e0', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/setup/feature_removal/DryRemovalRuntimeEnvironment.php b/setup/feature_removal/DryRemovalRuntimeEnvironment.php index 1b3bda65d..494598d73 100644 --- a/setup/feature_removal/DryRemovalRuntimeEnvironment.php +++ b/setup/feature_removal/DryRemovalRuntimeEnvironment.php @@ -2,13 +2,13 @@ namespace Combodo\iTop\Setup\FeatureRemoval; -use iTopExtensionsMap; +use MetaModel; use RunTimeEnvironment; use SetupUtils; class DryRemovalRuntimeEnvironment extends RunTimeEnvironment { - const DRY_REMOVAL_AUDIT_ENV = "extension-removal"; + public const DRY_REMOVAL_AUDIT_ENV = "extension-removal"; protected array $aExtensionsByCode; private bool $bExtensionMapModified = false; @@ -37,18 +37,49 @@ class DryRemovalRuntimeEnvironment extends RunTimeEnvironment $sEnv = $this->sFinalEnv; $this->aExtensionsByCode = $aExtensionCodesToRemove; - SetupUtils::rrmdir(APPROOT."/data/$sEnv-modules"); - SetupUtils::copydir(APPROOT."/data/$sSourceEnv-modules", APPROOT."/data/".$this->sFinalEnv."-modules"); + //SetupUtils::rrmdir(APPROOT."/data/$sEnv-modules"); + $this->Cleanup(); + SetupUtils::copydir(APPROOT."/data/$sSourceEnv-modules", APPROOT."/data/$sEnv-modules"); - /*$oDryRemovalConfig = clone(MetaModel::GetConfig()); + if (count($aExtensionCodesToRemove) > 0) { + $this->RemoveExtensionsLocally($aExtensionCodesToRemove); + } + $oDryRemovalConfig = clone(MetaModel::GetConfig()); $oDryRemovalConfig->ChangeModulesPath($sSourceEnv, $this->sFinalEnv); - $this->WriteConfigFileSafe($oDryRemovalConfig);*/ + $this->WriteConfigFileSafe($oDryRemovalConfig); + } + + private function RemoveExtensionsLocally(array $aExtensionCodes): void + { + $oExtensionsMap = new \iTopExtensionsMap($this->sFinalEnv); + + foreach ($aExtensionCodes as $sCode) { + /** @var \iTopExtension $oExtension */ + $oExtension = $oExtensionsMap->Get($sCode); + if (!is_null($oExtension)) { + $sDir = $oExtension->sSourceDir; + \IssueLog::Info(__METHOD__.": remove extension locally", null, [$oExtension->sCode => $sDir]); + SetupUtils::rrmdir($sDir); + } else { + \IssueLog::Warning(__METHOD__." cannot find extensions", null, ['env' => $this->sFinalEnv, 'code' => $sCode]); + } + } + } + + public function Cleanup() + { + $sEnv = $this->sFinalEnv; + SetupUtils::rrmdir(APPROOT."/data/$sEnv-modules"); + SetupUtils::rrmdir(APPROOT."/data/cache-$sEnv"); + SetupUtils::rrmdir(APPROOT."/env-$sEnv"); + SetupUtils::rrmdir(APPROOT."/conf/$sEnv"); + @unlink(APPROOT."/data/datamodel-$sEnv.xml"); } /** * @return \iTopExtensionsMap|null */ - protected function GetExtensionMap(): ?iTopExtensionsMap + /*protected function GetExtensionMap(): ?iTopExtensionsMap { if (is_null(parent::GetExtensionMap())) { return null; @@ -62,5 +93,5 @@ class DryRemovalRuntimeEnvironment extends RunTimeEnvironment } return parent::GetExtensionMap(); - } -} \ No newline at end of file + }*/ +} diff --git a/setup/feature_removal/ModelReflectionSerializer.php b/setup/feature_removal/ModelReflectionSerializer.php index 422b3acc4..5aff4dcdd 100644 --- a/setup/feature_removal/ModelReflectionSerializer.php +++ b/setup/feature_removal/ModelReflectionSerializer.php @@ -35,7 +35,7 @@ class ModelReflectionSerializer $iRes = 0; exec(sprintf("$sPHPExec %s/get_model_reflection.php --env='%s'", __DIR__, $sEnv), $sOutput, $iRes); if ($iRes != 0) { - \IssueLog::Error("Cannot get classes", null, ['code' => $iRes, "output" => $sOutput]); + \IssueLog::Error("Cannot get classes", null, ['env' => $sEnv, 'code' => $iRes, "output" => $sOutput]); throw new CoreException("Cannot get classes"); } @@ -52,4 +52,4 @@ class ModelReflectionSerializer return $aClasses; } -} \ No newline at end of file +} diff --git a/setup/feature_removal/SetupAudit.php b/setup/feature_removal/SetupAudit.php index 10734313b..76831a663 100644 --- a/setup/feature_removal/SetupAudit.php +++ b/setup/feature_removal/SetupAudit.php @@ -11,7 +11,7 @@ require_once APPROOT.'setup/feature_removal/ModelReflectionSerializer.php'; class SetupAudit { //file used when present to trigger audit exception when testing specific setups - const GETISSUE_ERROR_MSG_FILE_FORTESTONLY = '.setup_audit_error_msg.txt'; + public const GETISSUE_ERROR_MSG_FILE_FORTESTONLY = '.setup_audit_error_msg.txt'; private string $sEnvBeforeExtensionRemoval; private string $sEnvAfterExtensionRemoval; @@ -123,4 +123,4 @@ class SetupAudit return $oSet->Count(); } -} \ No newline at end of file +} diff --git a/setup/feature_removal/get_model_reflection.php b/setup/feature_removal/get_model_reflection.php index 073553519..29f0faae9 100644 --- a/setup/feature_removal/get_model_reflection.php +++ b/setup/feature_removal/get_model_reflection.php @@ -2,9 +2,7 @@ require_once(dirname(__DIR__, 2).'/approot.inc.php'); require_once(APPROOT.'application/application.inc.php'); - $sEnv = null; - if (isset($argv)) { foreach ($argv as $iArg => $sArg) { if (preg_match('/^--env=(.*)$/', $sArg, $aMatches)) { @@ -22,11 +20,12 @@ $sConfFile = utils::GetConfigFilePath($sEnv); try { MetaModel::Startup($sConfFile, false /* $bModelOnly */, true /* $bAllowCache */, false /* $bTraceSourceFiles */, $sEnv); -} -catch (\Throwable $e) { +} catch (\Throwable $e) { echo $e->getMessage(); echo $e->getTraceAsString(); - \SetupLog::Error("Cannot read model from provided environment", null, + \SetupLog::Error( + "Cannot read model from provided environment", + null, [ 'env' => $sEnv, 'error' => $e->getMessage(), @@ -39,4 +38,4 @@ catch (\Throwable $e) { $aClasses = MetaModel::GetClasses(); -echo json_encode($aClasses); \ No newline at end of file +echo json_encode($aClasses); diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index a55195b44..95ae569eb 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -2173,4 +2173,4 @@ class SetupInfo { return (array_key_exists($sModuleId, self::$aSelectedModules)); } -} \ No newline at end of file +} diff --git a/setup/wizardcontroller.class.inc.php b/setup/wizardcontroller.class.inc.php index 19d39979f..589c5c8a3 100644 --- a/setup/wizardcontroller.class.inc.php +++ b/setup/wizardcontroller.class.inc.php @@ -681,4 +681,4 @@ class Step3 extends WizardStep } } -End of the example */ \ No newline at end of file +End of the example */ diff --git a/setup/wizardsteps.class.inc.php b/setup/wizardsteps.class.inc.php index 021953811..d80f2d146 100644 --- a/setup/wizardsteps.class.inc.php +++ b/setup/wizardsteps.class.inc.php @@ -2127,9 +2127,7 @@ class WizStepSummary extends WizardStep //$oSetupAudit->AuditExtensionsCleanupRules(true); //} */ - } - catch(MissingDependencyException $e) - { + } catch (MissingDependencyException $e) { $this->bDependencyCheck = false; $this->sDependencyIssue = $e->getHtmlDesc(); } @@ -2596,4 +2594,4 @@ class WizStepDone extends WizardStep $oPage->add(file_get_contents($sBackupFile)); } } -} \ No newline at end of file +} diff --git a/tests/php-unit-tests/src/BaseTestCase/ItopCustomDatamodelTestCase.php b/tests/php-unit-tests/src/BaseTestCase/ItopCustomDatamodelTestCase.php index 299a80239..d35190ffa 100644 --- a/tests/php-unit-tests/src/BaseTestCase/ItopCustomDatamodelTestCase.php +++ b/tests/php-unit-tests/src/BaseTestCase/ItopCustomDatamodelTestCase.php @@ -64,7 +64,7 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase protected function setUp(): void { - static::LoadRequiredItopFiles(); + static::LoadRequiredItopFiles(); if (is_null($this->oEnvironment)) { $this->oEnvironment = new UnitTestRunTimeEnvironment($this->GetTestEnvironment()); } @@ -133,7 +133,6 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase // Note: To improve performances, we compile all XML deltas from test cases derived from this class and make a single environment where everything will be ran at once. // This requires XML deltas to be compatible, but it is a known and accepted trade-off. See PR #457 if (false === $this->IsEnvironmentReady()) { - $this->debug("Preparing custom environment '$sTestEnv' with the following datamodel files:"); foreach ($this->oEnvironment->GetCustomDatamodelFiles() as $sCustomDatamodelFile) { $this->debug(" - $sCustomDatamodelFile"); @@ -190,8 +189,10 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase CMDBSource::Query("CREATE TABLE $sNewDB.priv_module_install SELECT * FROM $sPreviousDB.priv_module_install"); $this->debug("Custom environment '$sTestEnv' is ready!"); + } else { + $this->debug("Custom environment '$sTestEnv' READY BUILT:"); } parent::PrepareEnvironment(); } -} \ No newline at end of file +} diff --git a/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php b/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php index 2daffa11c..d486b582e 100644 --- a/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php +++ b/tests/php-unit-tests/src/Service/UnitTestRunTimeEnvironment.php @@ -46,11 +46,6 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment */ protected $aAdditionExtensionFoldersByCode = null; - public function GetEnvironment(): string - { - return $this->sFinalEnv; - } - public function CompileFrom($sSourceEnv, $bUseSymLinks = null) { $sDestModulesDir = APPROOT.'data/'.$this->sTargetEnv.'-modules/'; diff --git a/tests/php-unit-tests/unitary-tests/setup/feature_removal/ModelSerializationTest.php b/tests/php-unit-tests/unitary-tests/setup/feature_removal/ModelSerializationTest.php index a9926fea6..b671ac984 100644 --- a/tests/php-unit-tests/unitary-tests/setup/feature_removal/ModelSerializationTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/feature_removal/ModelSerializationTest.php @@ -26,4 +26,4 @@ class ModelSerializationTest extends ItopDataTestCase $this->expectExceptionMessage("Cannot get classes"); ModelReflectionSerializer::GetInstance()->GetModelFromEnvironment('gabuzomeu'); } -} \ No newline at end of file +} diff --git a/tests/php-unit-tests/unitary-tests/setup/feature_removal/SetupAuditTest.php b/tests/php-unit-tests/unitary-tests/setup/feature_removal/SetupAuditTest.php index 4e77eafbb..841c5ff3c 100644 --- a/tests/php-unit-tests/unitary-tests/setup/feature_removal/SetupAuditTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/feature_removal/SetupAuditTest.php @@ -10,7 +10,7 @@ use Exception; class SetupAuditTest extends ItopCustomDatamodelTestCase { - const ENVT = 'php-unit-extensionremoval-tests'; + public const ENVT = 'php-unit-extensionremoval-tests'; public function GetDatamodelDeltaAbsPath(): string { @@ -115,4 +115,4 @@ class SetupAuditTest extends ItopCustomDatamodelTestCase $this->expectExceptionMessage('FinalClassFeature1Module1MyFinalClassFromLocation'); $oSetupAudit->GetIssues(true); } -} \ No newline at end of file +} diff --git a/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/finalclass_ext1/finalclass_ext1_module1/model.finalclass_ext1_module1.php b/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/finalclass_ext1/finalclass_ext1_module1/model.finalclass_ext1_module1.php index 43179ef20..acf219fa1 100644 --- a/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/finalclass_ext1/finalclass_ext1_module1/model.finalclass_ext1_module1.php +++ b/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/finalclass_ext1/finalclass_ext1_module1/model.finalclass_ext1_module1.php @@ -1,4 +1,5 @@ 'Ext For Test', @@ -19,32 +20,32 @@ SetupWebPage::AddModule( // Setup // - 'dependencies' => array( - 'itop-structure/3.2.0', - ), + 'dependencies' => [ + 'itop-structure/3.2.0', + ], 'mandatory' => false, 'visible' => true, 'installer' => '', // Components // - 'datamodel' => array( + 'datamodel' => [ 'model.finalclass_ext1_module1.php', - ), - 'webservice' => array(), - 'data.struct' => array(// add your 'structure' definition XML files here, - ), - 'data.sample' => array(// add your sample data XML files here, - ), + ], + 'webservice' => [], + 'data.struct' => [// add your 'structure' definition XML files here, + ], + 'data.sample' => [// add your sample data XML files here, + ], // Documentation // 'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any - 'doc.more_information' => '', // hyperlink to more information, if any + 'doc.more_information' => '', // hyperlink to more information, if any // Default settings // - 'settings' => array(// Module specific settings go here, if any - ), - ) -); \ No newline at end of file + 'settings' => [// Module specific settings go here, if any + ], + ] +); diff --git a/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/finalclass_ext2/finalclass_ext2_module1/model.finalclass_ext2_module1.php b/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/finalclass_ext2/finalclass_ext2_module1/model.finalclass_ext2_module1.php index 43179ef20..acf219fa1 100644 --- a/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/finalclass_ext2/finalclass_ext2_module1/model.finalclass_ext2_module1.php +++ b/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/finalclass_ext2/finalclass_ext2_module1/model.finalclass_ext2_module1.php @@ -1,4 +1,5 @@ 'Ext For Test', @@ -19,32 +20,32 @@ SetupWebPage::AddModule( // Setup // - 'dependencies' => array( - 'itop-structure/3.2.0', - ), + 'dependencies' => [ + 'itop-structure/3.2.0', + ], 'mandatory' => false, 'visible' => true, 'installer' => '', // Components // - 'datamodel' => array( + 'datamodel' => [ 'model.finalclass_ext2_module1.php', - ), - 'webservice' => array(), - 'data.struct' => array(// add your 'structure' definition XML files here, - ), - 'data.sample' => array(// add your sample data XML files here, - ), + ], + 'webservice' => [], + 'data.struct' => [// add your 'structure' definition XML files here, + ], + 'data.sample' => [// add your sample data XML files here, + ], // Documentation // 'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any - 'doc.more_information' => '', // hyperlink to more information, if any + 'doc.more_information' => '', // hyperlink to more information, if any // Default settings // - 'settings' => array(// Module specific settings go here, if any - ), - ) -); \ No newline at end of file + 'settings' => [// Module specific settings go here, if any + ], + ] +); diff --git a/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/nominal_ext1/nominal_ext1_module1/model.nominal_ext1_module1.php b/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/nominal_ext1/nominal_ext1_module1/model.nominal_ext1_module1.php index 43179ef20..acf219fa1 100644 --- a/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/nominal_ext1/nominal_ext1_module1/model.nominal_ext1_module1.php +++ b/tests/php-unit-tests/unitary-tests/setup/feature_removal/additional_features/nominal_ext1/nominal_ext1_module1/model.nominal_ext1_module1.php @@ -1,4 +1,5 @@ 'Ext For Test', @@ -19,32 +20,32 @@ SetupWebPage::AddModule( // Setup // - 'dependencies' => array( - 'itop-structure/3.2.0', - ), + 'dependencies' => [ + 'itop-structure/3.2.0', + ], 'mandatory' => false, 'visible' => true, 'installer' => '', // Components // - 'datamodel' => array( + 'datamodel' => [ 'model.nominal_ext1_module1.php', - ), - 'webservice' => array(), - 'data.struct' => array(// add your 'structure' definition XML files here, - ), - 'data.sample' => array(// add your sample data XML files here, - ), + ], + 'webservice' => [], + 'data.struct' => [// add your 'structure' definition XML files here, + ], + 'data.sample' => [// add your sample data XML files here, + ], // Documentation // 'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any - 'doc.more_information' => '', // hyperlink to more information, if any + 'doc.more_information' => '', // hyperlink to more information, if any // Default settings // - 'settings' => array(// Module specific settings go here, if any - ), - ) -); \ No newline at end of file + 'settings' => [// Module specific settings go here, if any + ], + ] +);