/** * @param InputInterface $input * @param OutputInterface $output * * @return bool */ protected function execute(InputInterface $input, OutputInterface $output) { /* @var $composer Composer */ $composer = $this->getContainer()->get('anime_db.composer'); $composer->setIO(new ConsoleIO($input, $output, $this->getHelperSet())); /* @var $github GitHub */ $github = $this->getContainer()->get('anime_db.client.github'); // search tag with new version of application $output->writeln('Search for a new version of the application'); $tag = $github->getLastRelease('anime-db/anime-db'); $tag['version'] = Composer::getVersionCompatible($tag['name']); $current_version = Composer::getVersionCompatible($composer->getRootPackage()->getPrettyVersion()); // update itself if ($tag && version_compare($tag['version'], $current_version) == 1) { $this->doUpdateItself($tag, $composer, $output); } else { $output->writeln('<info>Application has already been updated to the latest version</info>'); } unset($github, $tag, $current_version); // update from composer if ($composer->getInstaller()->run() === 0) { $output->writeln('<info>Update requirements has been completed</info>'); } else { $output->writeln('<error>During updating dependencies error occurred</error>'); } $output->writeln('<info>Updating the application has been completed<info>'); }
/** * @param string $repository * * @return array|false */ public function getLastRelease($repository) { $last_version = ''; $last_tag = []; foreach ($this->getTags($repository) as $tag) { if (($version = Composer::getVersionCompatible($tag['name'])) && (!$last_version || version_compare($version, $last_version, '>=')) && version_compare($version, '1.0.0', '<')) { $last_version = $version; $last_tag = $tag; } } return $last_tag ?: false; }
/** * @dataProvider getVersions * * @param string $actual * @param string $expected */ public function testGetVersionCompatible($actual, $expected) { $this->assertEquals($expected, Composer::getVersionCompatible($actual)); }
public function testExecuteUpdateItself() { $tag = ['name' => '1.1.0-alpha', 'zipball_url' => 'http://example.com/tags/1.0.1.zip']; $dispatcher = $this->getMock('\\Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); $local_dispatcher = $this->getMockBuilder('\\AnimeDb\\Bundle\\AnimeDbBundle\\Event\\Dispatcher')->disableOriginalConstructor()->getMock(); $package = $this->getMock('\\Composer\\Package\\RootPackageInterface'); // vars for closures $that = $this; $fs = $this->fs; $root_dir = $this->root_dir; $target = $this->target; $root_package = $this->package; // create files for Finder $this->fs->mkdir([$this->root_dir . 'app/cache', $this->root_dir . 'app/DoctrineMigrations/', $this->root_dir . 'app/Resources/views/', $this->root_dir . 'app/config/', $this->root_dir . 'src/Tests/', $this->root_dir . 'src/Console']); $this->fs->touch([$this->root_dir . 'app/bootstrap.php.cache', $this->root_dir . 'app/DoctrineMigrations/Version11111111111111_Demo.php', $this->root_dir . 'app/Resources/views/base.html.twig', $this->root_dir . 'app/config/config.yml', $this->root_dir . 'src/AnimeDbAnimeDbBundle.php', $this->root_dir . 'src/Tests/TestCaseWritable.php']); // init command $command = $this->getCommandToExecute($tag, '1.0.0', 0); $this->write(['Discovered a new version of the application: <info>' . $tag['name'] . '</info>', '<info>Update itself has been completed</info>', '<info>Update requirements has been completed</info>', '<info>Updating the application has been completed<info>']); $this->container->expects($this->at(2))->method('get')->will($this->returnValue($this->filesystem))->with('filesystem'); $this->container->expects($this->at(3))->method('get')->will($this->returnValue($dispatcher))->with('event_dispatcher'); $this->container->expects($this->at(4))->method('get')->will($this->returnValue($this->filesystem))->with('filesystem'); $this->container->expects($this->at(8))->method('get')->will($this->returnValue($local_dispatcher))->with('anime_db.event_dispatcher'); $this->container->expects($this->atLeastOnce())->method('getParameter')->will($this->returnValue($this->root_dir . 'app'))->with('kernel.root_dir'); $this->composer->expects($this->once())->method('download')->will($this->returnCallback(function ($package, $_target) use($that, $target, $tag) { $that->assertEquals($target, $_target); // check package /* @var $package Package */ $that->assertInstanceOf('\\Composer\\Package\\Package', $package); $that->assertEquals('anime-db/anime-db', $package->getName()); $that->assertEquals(Composer::getVersionCompatible($tag['name']), $package->getVersion()); $that->assertEquals($tag['name'], $package->getPrettyVersion()); $that->assertEquals('zip', $package->getDistType()); $that->assertEquals($tag['zipball_url'], $package->getDistUrl()); $that->assertEquals('dist', $package->getInstallationSource()); })); $this->composer->expects($this->once())->method('getPackageFromConfigFile')->with($this->target . '/composer.json')->will($this->returnValue($package)); $this->composer->expects($this->once())->method('reload'); $dispatcher->expects($this->once())->method('dispatch')->will($this->returnCallback(function ($name, $event) use($that, $target, $package, $root_package) { $that->assertEquals(StoreEvents::DOWNLOADED, $name); // check event /* @var $event Downloaded */ $that->assertInstanceOf('\\AnimeDb\\Bundle\\AnimeDbBundle\\Event\\UpdateItself\\Downloaded', $event); $that->assertEquals($target, $event->getPath()); $that->assertEquals($package, $event->getNewPackage()); $that->assertEquals($root_package, $event->getOldPackage()); })); $local_dispatcher->expects($this->once())->method('dispatch')->will($this->returnCallback(function ($name, $event) use($that, $package) { $that->assertEquals(StoreEvents::UPDATED, $name); /* @var $event Updated */ $that->assertInstanceOf('\\AnimeDb\\Bundle\\AnimeDbBundle\\Event\\UpdateItself\\Updated', $event); $that->assertEquals($package, $event->getPackage()); })); $this->filesystem->expects($this->at(0))->method('remove')->with($this->target); $this->filesystem->expects($this->at(1))->method('remove')->will($this->returnCallback(function ($finder) use($that, $fs, $root_dir) { $that->assertInstanceOf('\\Symfony\\Component\\Finder\\Finder', $finder); // test remove files from Finder $fs->remove($finder); $that->assertFileExists($root_dir . 'app/bootstrap.php.cache'); $that->assertFileExists($root_dir . 'app/DoctrineMigrations/Version11111111111111_Demo.php'); $that->assertFileExists($root_dir . 'app/Resources/views/base.html.twig'); $that->assertFileExists($root_dir . 'app/config'); $that->assertFileExists($root_dir . 'src/Console'); $that->assertFileNotExists($root_dir . 'app/config/config.yml'); $that->assertFileNotExists($root_dir . 'src/AnimeDbAnimeDbBundle.php'); $that->assertFileNotExists($root_dir . 'src/Tests/TestCaseWritable.php'); })); $this->filesystem->expects($this->at(3))->method('remove')->with($this->target); $this->filesystem->expects($this->once())->method('mirror')->with($this->target, $this->root_dir . 'app/../', null, ['override' => true, 'copy_on_windows' => true]); $command->run($this->input, $this->output); // test }