/** * Run Composer dependency check for uninstall * * @param array $packages * @return array * @throws \RuntimeException */ public function runUninstallReadinessCheck(array $packages) { try { $packagesAndTypes = $this->composerInfo->getRootRequiredPackageTypesByName(); $dependencies = $this->packageDependencyChecker->checkDependencies($packages, true); $messages = []; $themes = []; foreach ($packages as $package) { if (!isset($packagesAndTypes[$package])) { throw new \RuntimeException('Package ' . $package . ' not found in the system.'); } switch ($packagesAndTypes[$package]) { case ComposerInformation::METAPACKAGE_PACKAGE_TYPE: unset($dependencies[$package]); break; case ComposerInformation::THEME_PACKAGE_TYPE: $themes[] = $package; break; } if (!empty($dependencies[$package])) { $messages[] = $package . " has the following dependent package(s): " . implode(', ', $dependencies[$package]); } } if (!empty($themes)) { $messages = array_merge($messages, $this->themeDependencyChecker->checkChildThemeByPackagesName($themes)); } if (!empty($messages)) { throw new \RuntimeException(implode(PHP_EOL, $messages)); } return ['success' => true]; } catch (\RuntimeException $e) { $message = str_replace(PHP_EOL, '<br/>', htmlspecialchars($e->getMessage())); return ['success' => false, 'error' => $message]; } }
public function testRunUninstallReadinessCheckWithError() { $packages = ['verndor/module' => 'magento2-module', 'verndor/theme' => 'magento2-theme', 'verndor/metapackage' => 'metapackage', 'verndor/language' => 'magento2-language']; $this->composerInfo->expects($this->once())->method('getRootRequiredPackageTypesByName')->willReturn($packages); $this->packageDependencyChecker->expects($this->once())->method('checkDependencies')->with(array_keys($packages))->willReturn([]); $this->themeDependencyChecker->expects($this->once())->method('checkChildThemeByPackagesName')->with(['verndor/theme'])->willReturn(['Error message']); $result = $this->uninstallDependencyCheck->runUninstallReadinessCheck(array_keys($packages)); $this->assertEquals(['success' => false, 'error' => 'Error message'], $result); }
public function setUpPassValidation() { $this->themePackageInfo->expects($this->any())->method('getPackageName')->willReturn('magento/theme-a'); $this->collection->expects($this->any())->method('getThemeByFullPath')->willReturn($this->getMockForAbstractClass('Magento\\Framework\\View\\Design\\ThemeInterface', [], '', false)); $this->themeDependencyChecker->expects($this->any())->method('checkChildTheme')->willReturn([]); $this->collection->expects($this->any())->method('hasTheme')->willReturn(true); }
/** * @dataProvider executeFailedChildThemeCheckDataProvider * @param bool $hasVirtual * @param bool $hasPhysical * @param array $input * @param string $expected * @return void */ public function testExecuteFailedChildThemeCheck($hasVirtual, $hasPhysical, array $input, $expected) { $theme = $this->getMock('Magento\\Theme\\Model\\Theme', [], [], '', false); $theme->expects($this->any())->method('hasChildThemes')->willReturn($hasVirtual); $parentThemeA = $this->getMock('Magento\\Theme\\Model\\Theme', [], [], '', false); $parentThemeA->expects($this->any())->method('getFullPath')->willReturn('frontend/Magento/a'); $parentThemeB = $this->getMock('Magento\\Theme\\Model\\Theme', [], [], '', false); $parentThemeB->expects($this->any())->method('getFullPath')->willReturn('frontend/Magento/b'); $childThemeC = $this->getMock('Magento\\Theme\\Model\\Theme', [], [], '', false); $childThemeC->expects($this->any())->method('getFullPath')->willReturn('frontend/Magento/c'); $childThemeD = $this->getMock('Magento\\Theme\\Model\\Theme', [], [], '', false); $childThemeD->expects($this->any())->method('getFullPath')->willReturn('frontend/Magento/d'); if ($hasPhysical) { $childThemeC->expects($this->any())->method('getParentTheme')->willReturn($parentThemeA); $childThemeD->expects($this->any())->method('getParentTheme')->willReturn($parentThemeB); } $this->themeProvider->expects($this->any())->method('getThemeByFullPath')->willReturn($theme); $this->themeCollection->expects($this->any())->method('getIterator')->willReturn(new \ArrayIterator([$childThemeC, $childThemeD])); $this->assertEquals($expected, $this->themeDependencyChecker->checkChildTheme($input)); }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $messages = []; $themePaths = $input->getArgument(self::INPUT_KEY_THEMES); $messages = array_merge($messages, $this->validate($themePaths)); if (!empty($messages)) { $output->writeln($messages); return; } $messages = array_merge($messages, $this->themeValidator->validateIsThemeInUse($themePaths), $this->themeDependencyChecker->checkChildTheme($themePaths), $this->checkDependencies($themePaths)); if (!empty($messages)) { $output->writeln('<error>Unable to uninstall. Please resolve the following issues:</error>' . PHP_EOL . implode(PHP_EOL, $messages)); return; } try { $output->writeln('<info>Enabling maintenance mode</info>'); $this->maintenanceMode->set(true); if ($input->getOption(self::INPUT_KEY_BACKUP_CODE)) { $time = time(); $codeBackup = $this->backupRollbackFactory->create($output); $codeBackup->codeBackup($time); } $this->themeUninstaller->uninstallRegistry($output, $themePaths); $this->themeUninstaller->uninstallCode($output, $themePaths); $this->cleanup($input, $output); $output->writeln('<info>Disabling maintenance mode</info>'); $this->maintenanceMode->set(false); } catch (\Exception $e) { $output->writeln('<error>' . $e->getMessage() . '</error>'); $output->writeln('<error>Please disable maintenance mode after you resolved above issues</error>'); } }