public function testSuccessfulWrite() { $jsonFile = new JsonFile(__DIR__ . '/test_write.json'); $data = array('test' => 'test'); $jsonFile->write($data); $this->assertEquals($data, $jsonFile->read()); unlink(__DIR__ . '/test_write.json'); }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { /* @var DialogHelper $dialog */ $dialog = $this->getHelperSet()->get('dialog'); $dependenciesOption = $input->getOption('dependencies'); $runCommandsOption = $input->getOption('run-commands'); $versionsPathArg = $input->getArgument('versions-path'); $versionJsonPath = getcwd() . '/modera-version.txt'; $output->writeln(''); if (!$dependenciesOption && !$runCommandsOption) { $msg = ['If you want to update dependencies then please use <info>--dependencies</info> option for the command, ', 'if you need to have commands executed when a version is upgraded then use <info>--run-commands</info> option instead.']; $output->writeln(implode('', $msg)); $output->writeln(''); return; } $output->writeln("Reading upgrade instructions from '<info>{$versionsPathArg}</info>'."); $basePath = dirname($this->getContainer()->get('kernel')->getRootdir()); $composerFile = new JsonFile($basePath . '/composer.json'); $versionsFile = new JsonFile($versionsPathArg); $composerFileContents = $composerFile->read(); $versionsFileContents = $versionsFile->read(); $currentVersion = @file_get_contents($versionJsonPath); if ($dependenciesOption) { $newVersion = null; $versions = array_keys($versionsFileContents); if ($currentVersion && $currentVersion == $versions[count($versions) - 1]) { $output->writeln("<info>You have the latest version {$currentVersion}</info>"); $output->writeln(''); return; } // backup composer.json file_put_contents($basePath . '/composer' . ($currentVersion ? '.v' . $currentVersion : '') . '.backup.json', file_get_contents($basePath . '/composer.json')); // manage dependencies $oldDependencies = $newDependencies = array(); if (!$currentVersion) { $newVersion = $versions[0]; $newDependencies = $this->getArrayValue($versionsFileContents[$newVersion], 'dependencies', array()); } else { foreach (array_keys($versions) as $k) { if ($versions[$k] == $currentVersion) { $key = $k; while ($key >= 0) { $oldDependencies = $this->getArrayValue($versionsFileContents[$versions[$key]], 'dependencies'); if (is_array($oldDependencies)) { break; } $oldDependencies = array(); --$key; } $newVersion = $versions[$k + 1]; $newDependencies = $this->getArrayValue($versionsFileContents[$newVersion], 'dependencies', $oldDependencies); break; } } } $dependenciesDiff = $this->diffDependencies($oldDependencies, $newDependencies); $output->writeln(sprintf('<info>Upgrading from %s to %s</info>', $currentVersion ?: '-', $newVersion)); $dependenciesOption = $composerFileContents['require']; foreach ($dependenciesDiff['added'] as $name => $ver) { if (!isset($dependenciesOption[$name])) { $dependenciesOption[$name] = $ver; } else { if ($ver !== $dependenciesOption[$name]) { $msg = sprintf(implode('', ['<question>', 'Dependency "%s:%s" already exists. ', 'Would you like to change it to "%s:%s"? (Y/n)', '</question>']), $name, $dependenciesOption[$name], $name, $ver); if ($dialog->askConfirmation($output, $msg)) { $dependenciesOption[$name] = $ver; } } } } foreach ($dependenciesDiff['changed'] as $name => $ver) { if (!isset($dependenciesOption[$name]) || $oldDependencies[$name] == $dependenciesOption[$name] || $ver == $dependenciesOption[$name]) { $dependenciesOption[$name] = $ver; } else { $msg = sprintf(implode('', ['<question>', 'Dependency "%s:%s" already changed. ', 'Would you like to change it to "%s:%s"? (Y/n)', '</question>']), $name, $dependenciesOption[$name], $name, $ver); if ($dialog->askConfirmation($output, $msg)) { $dependenciesOption[$name] = $ver; } } } foreach ($dependenciesDiff['removed'] as $name => $ver) { if (isset($dependenciesOption[$name])) { $msg = sprintf(implode('', ['<question>', 'Dependency "%s" has been removed. ', 'Would you like to remove it? (Y/n)', '</question>']), $name); if ($dialog->askConfirmation($output, $msg)) { unset($dependenciesOption[$name]); } } } foreach ($dependenciesDiff['same'] as $name => $ver) { if (!isset($dependenciesOption[$name])) { $dependenciesOption[$name] = $ver; } elseif ($ver !== $dependenciesOption[$name]) { $msg = sprintf(implode('', ['<question>', 'Dependency "%s:%s" has been manually changed. ', 'Would you like to restore it to "%s:%s"? (Y/n)', '</question>']), $name, $dependenciesOption[$name], $name, $ver); if ($dialog->askConfirmation($output, $msg)) { $dependenciesOption[$name] = $ver; } } } $composerFileContents['require'] = $dependenciesOption; // manage repositories $repositories = $this->getArrayValue($composerFileContents, 'repositories', array()); $addRepositories = $this->getArrayValue($versionsFileContents[$newVersion], 'add-repositories'); $rmRepositories = $this->getArrayValue($versionsFileContents[$newVersion], 'rm-repositories'); if ($addRepositories) { foreach ($addRepositories as $repo) { if (false === array_search($repo, $repositories)) { $repositories[] = $repo; } } } if ($rmRepositories) { foreach ($rmRepositories as $repo) { if (false !== ($key = array_search($repo, $repositories))) { unset($repositories[$key]); } } $repositories = array_values($repositories); } $composerFileContents['repositories'] = $repositories; // write modera-version.txt file_put_contents($versionJsonPath, $newVersion); // write composer.json $composerFile->write($composerFileContents); // interactions $output->writeln("<info>composer.json 'requires' section has been updated to version {$newVersion}</info>"); if (count($this->getArrayValue($versionsFileContents[$newVersion], 'add-bundles'))) { $output->writeln('<comment>Add bundle(s) to app/AppKernel.php</comment>'); foreach ($versionsFileContents[$newVersion]['add-bundles'] as $bundle) { $output->writeln(' ' . $bundle); } } if (count($this->getArrayValue($versionsFileContents[$newVersion], 'rm-bundles'))) { $output->writeln('<comment>Remove bundle(s) from app/AppKernel.php</comment>'); foreach ($versionsFileContents[$newVersion]['rm-bundles'] as $bundle) { $output->writeln(' ' . $bundle); } } if (count($this->getArrayValue($versionsFileContents[$newVersion], 'instructions'))) { foreach ($versionsFileContents[$newVersion]['instructions'] as $instruction) { $output->writeln(sprintf('<comment>%s</comment>', $instruction)); } } if (count($this->getArrayValue($versionsFileContents[$newVersion], 'commands'))) { $output->writeln('After composer update run:'); $output->writeln('<info>php app/console ' . $this->getName() . ' --run-commands</info>'); } } elseif ($runCommandsOption) { if ($currentVersion) { $versionData = $this->getArrayValue($versionsFileContents, $currentVersion, array()); $commands = $this->getArrayValue($versionData, 'commands', array()); if (count($commands) > 0) { $this->getApplication()->setAutoExit(false); foreach ($commands as $command) { $output->writeln(''); $output->writeln("<comment>{$command}</comment>"); $this->getApplication()->run(new StringInput($command), $output); } } else { $output->writeln('<comment>No commands need to be run! Aborting ...</comment>'); } } } $output->writeln(''); }
public function testUpgrade() { $output = new BufferedOutput(); // null version check $expectedData = array('name' => 'modera/upgrade-bundle-test', 'repositories' => array(array('type' => 'composer', 'url' => 'http://packages.org')), 'require' => array('test/dependency_1' => 'dev-master')); $this->assertEquals($expectedData, self::$composerFile->read()); // 0.1.0 version check $expectedData['require'] = array('test/dependency_1' => '0.1.0', 'test/dependency_2' => '0.1.0', 'test/dependency_3' => '0.1.0'); $expectedData['repositories'][] = array('type' => 'vcs', 'url' => 'ssh://git@dependency.git'); $this->runUpdateDependenciesCommand($output); $str = $output->fetch(); $this->assertEquals('0.1.0', $this->getCurrentVersion()); $this->assertEquals(1, substr_count($str, 'new Test\\AddBundle\\TestAddBundle()')); $this->assertEquals(0, substr_count($str, 'new Test\\RemoveBundle\\TestRemoveBundle()')); $this->assertEquals($expectedData, self::$composerFile->read()); $this->assertTrue(is_file(self::$basePath . '/composer.backup.json')); unlink(self::$basePath . '/composer.backup.json'); // 0.1.0 version run commands $this->runCommandsCommand($output); $str = $output->fetch(); $this->assertEquals(0, substr_count($str, 'help --format=json')); $this->assertEquals(0, substr_count($str, 'help --format=txt')); // emulate composer.json changes $tmp = self::$composerFile->read(); $tmp['require']['test/dependency_1'] = 'dev-master'; self::$composerFile->write($tmp); // 0.1.1 version check $expectedData['require'] = array('test/dependency_1' => '0.1.1', 'test/dependency_2' => '0.1.0'); unset($expectedData['repositories'][1]); $expectedData['repositories'] = array_values($expectedData['repositories']); $this->runUpdateDependenciesCommand($output); $str = $output->fetch(); $this->assertEquals('0.1.1', $this->getCurrentVersion()); $this->assertEquals(0, substr_count($str, 'new Test\\AddBundle\\TestAddBundle()')); $this->assertEquals(1, substr_count($str, 'new Test\\RemoveBundle\\TestRemoveBundle()')); $this->assertEquals($expectedData, self::$composerFile->read()); $this->assertTrue(is_file(self::$basePath . '/composer.v0.1.0.backup.json')); unlink(self::$basePath . '/composer.v0.1.0.backup.json'); // 0.1.1 version run commands $this->runCommandsCommand($output); $str = $output->fetch(); $this->assertEquals(1, substr_count($str, 'help --format=json')); $this->assertEquals(0, substr_count($str, 'help --format=txt')); // emulate composer.json changes $tmp = self::$composerFile->read(); $tmp['require']['test/dependency_2'] = 'dev-master'; self::$composerFile->write($tmp); // 0.1.2 version check $expectedData['require'] = array('test/dependency_1' => '0.1.1', 'test/dependency_2' => '0.1.0', 'test/dependency_4' => '0.1.0'); $this->runUpdateDependenciesCommand($output); $str = $output->fetch(); $this->assertEquals('0.1.2', $this->getCurrentVersion()); $this->assertEquals(0, substr_count($str, 'new Test\\AddBundle\\TestAddBundle()')); $this->assertEquals(0, substr_count($str, 'new Test\\RemoveBundle\\TestRemoveBundle()')); $this->assertEquals($expectedData, self::$composerFile->read()); $this->assertTrue(is_file(self::$basePath . '/composer.v0.1.1.backup.json')); unlink(self::$basePath . '/composer.v0.1.1.backup.json'); // 0.1.2 version run commands $this->runCommandsCommand($output); $str = $output->fetch(); $this->assertEquals(0, substr_count($str, 'help --format=json')); $this->assertEquals(1, substr_count($str, 'help --format=txt')); // 0.1.3 version check $this->runUpdateDependenciesCommand($output); $str = $output->fetch(); $this->assertEquals('0.1.3', $this->getCurrentVersion()); $this->assertEquals(1, substr_count($str, 'Some foo instruction')); $this->assertEquals(0, substr_count($str, 'Some bar instruction')); $this->assertEquals(0, substr_count($str, 'Some baz instruction')); $this->assertEquals($expectedData, self::$composerFile->read()); $this->assertTrue(is_file(self::$basePath . '/composer.v0.1.2.backup.json')); unlink(self::$basePath . '/composer.v0.1.2.backup.json'); // 0.1.4 version check $this->runUpdateDependenciesCommand($output); $str = $output->fetch(); $this->assertEquals('0.1.4', $this->getCurrentVersion()); $this->assertEquals(0, substr_count($str, 'Some foo instruction')); $this->assertEquals(1, substr_count($str, 'Some bar instruction')); $this->assertEquals(0, substr_count($str, 'Some baz instruction')); $this->assertEquals($expectedData, self::$composerFile->read()); $this->assertTrue(is_file(self::$basePath . '/composer.v0.1.3.backup.json')); unlink(self::$basePath . '/composer.v0.1.3.backup.json'); // 0.1.5 version check $expectedData['require'] = array('test/dependency_1' => '0.1.1', 'test/dependency_4' => '0.1.1'); $this->runUpdateDependenciesCommand($output); $str = $output->fetch(); $this->assertEquals('0.1.5', $this->getCurrentVersion()); $this->assertEquals(0, substr_count($str, 'Some foo instruction')); $this->assertEquals(0, substr_count($str, 'Some bar instruction')); $this->assertEquals(1, substr_count($str, 'Some baz instruction')); $this->assertEquals($expectedData, self::$composerFile->read()); $this->assertTrue(is_file(self::$basePath . '/composer.v0.1.4.backup.json')); unlink(self::$basePath . '/composer.v0.1.4.backup.json'); }