Browse Source

Add self-update command test

Julien Falque 7 years ago
parent
commit
e0ef84019f

+ 1 - 0
composer.json

@@ -36,6 +36,7 @@
     "require-dev": {
         "johnkary/phpunit-speedtrap": "^1.0.1",
         "justinrainbow/json-schema": "^5.0",
+        "mikey179/vfsStream": "^1.6",
         "php-coveralls/php-coveralls": "^1.0.2",
         "phpunit/phpunit": "^4.8.35 || ^5.4.3",
         "symfony/phpunit-bridge": "^3.2.2 || ^4.0"

+ 8 - 1
src/Console/Application.php

@@ -17,6 +17,9 @@ use PhpCsFixer\Console\Command\FixCommand;
 use PhpCsFixer\Console\Command\HelpCommand;
 use PhpCsFixer\Console\Command\ReadmeCommand;
 use PhpCsFixer\Console\Command\SelfUpdateCommand;
+use PhpCsFixer\Console\SelfUpdate\GithubClient;
+use PhpCsFixer\Console\SelfUpdate\NewVersionChecker;
+use PhpCsFixer\PharChecker;
 use PhpCsFixer\ToolInfo;
 use Symfony\Component\Console\Application as BaseApplication;
 use Symfony\Component\Console\Command\ListCommand;
@@ -50,7 +53,11 @@ final class Application extends BaseApplication
         $this->add(new DescribeCommand());
         $this->add(new FixCommand($this->toolInfo));
         $this->add(new ReadmeCommand());
-        $this->add(new SelfUpdateCommand($this->toolInfo));
+        $this->add(new SelfUpdateCommand(
+            new NewVersionChecker(new GithubClient()),
+            $this->toolInfo,
+            new PharChecker()
+        ));
     }
 
     /**

+ 38 - 33
src/Console/Command/SelfUpdateCommand.php

@@ -12,8 +12,8 @@
 
 namespace PhpCsFixer\Console\Command;
 
-use PhpCsFixer\Console\SelfUpdate\GithubClient;
-use PhpCsFixer\Console\SelfUpdate\NewVersionChecker;
+use PhpCsFixer\Console\SelfUpdate\NewVersionCheckerInterface;
+use PhpCsFixer\PharCheckerInterface;
 use PhpCsFixer\ToolInfoInterface;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
@@ -33,16 +33,31 @@ final class SelfUpdateCommand extends Command
 {
     const COMMAND_NAME = 'self-update';
 
+    /**
+     * @var NewVersionCheckerInterface
+     */
+    private $versionChecker;
+
     /**
      * @var ToolInfoInterface
      */
     private $toolInfo;
 
-    public function __construct(ToolInfoInterface $toolInfo)
-    {
+    /**
+     * @var PharCheckerInterface
+     */
+    private $pharChecker;
+
+    public function __construct(
+        NewVersionCheckerInterface $versionChecker,
+        ToolInfoInterface $toolInfo,
+        PharCheckerInterface $pharChecker
+    ) {
         parent::__construct();
 
+        $this->versionChecker = $versionChecker;
         $this->toolInfo = $toolInfo;
+        $this->pharChecker = $pharChecker;
     }
 
     /**
@@ -87,11 +102,9 @@ EOT
         preg_match('/^v?(?<major>\d+)\./', $currentVersion, $matches);
         $currentMajor = (int) $matches['major'];
 
-        $checker = new NewVersionChecker(new GithubClient());
-
         try {
-            $latestVersion = $checker->getLatestVersion();
-            $latestVersionOfCurrentMajor = $checker->getLatestVersionOfMajor($currentMajor);
+            $latestVersion = $this->versionChecker->getLatestVersion();
+            $latestVersionOfCurrentMajor = $this->versionChecker->getLatestVersionOfMajor($currentMajor);
         } catch (\Exception $exception) {
             $output->writeln(sprintf(
                 '<error>Unable to determine newest version: %s</error>',
@@ -101,7 +114,7 @@ EOT
             return 1;
         }
 
-        if (1 !== $checker->compareVersions($latestVersion, $currentVersion)) {
+        if (1 !== $this->versionChecker->compareVersions($latestVersion, $currentVersion)) {
             $output->writeln('<info>php-cs-fixer is already up to date.</info>');
 
             return 0;
@@ -110,7 +123,7 @@ EOT
         $remoteTag = $latestVersion;
 
         if (
-            0 !== $checker->compareVersions($latestVersionOfCurrentMajor, $latestVersion)
+            0 !== $this->versionChecker->compareVersions($latestVersionOfCurrentMajor, $latestVersion)
             && true !== $input->getOption('force')
         ) {
             $output->writeln(sprintf('<info>A new major version of php-cs-fixer is available</info> (<comment>%s</comment>)', $latestVersion));
@@ -118,7 +131,7 @@ EOT
             $output->writeln('<info>If you are ready to upgrade run this command with</info> <comment>-f</comment>');
             $output->writeln('<info>Checking for new minor/patch version...</info>');
 
-            if (1 !== $checker->compareVersions($latestVersionOfCurrentMajor, $currentVersion)) {
+            if (1 !== $this->versionChecker->compareVersions($latestVersionOfCurrentMajor, $currentVersion)) {
                 $output->writeln('<info>No minor update for php-cs-fixer.</info>');
 
                 return 0;
@@ -135,36 +148,28 @@ EOT
             return 1;
         }
 
-        $tempFilename = basename($localFilename, '.phar').'-tmp.phar';
-        $remoteFilename = sprintf('https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/%s/php-cs-fixer.phar', $remoteTag);
+        $tempFilename = dirname($localFilename).'/'.basename($localFilename, '.phar').'-tmp.phar';
+        $remoteFilename = $this->toolInfo->getPharDownloadUri($remoteTag);
 
-        try {
-            $copyResult = @copy($remoteFilename, $tempFilename);
-            if (false === $copyResult) {
-                $output->writeln(sprintf('<error>Unable to download new version %s from the server.</error>', $remoteTag));
+        if (false === @copy($remoteFilename, $tempFilename)) {
+            $output->writeln(sprintf('<error>Unable to download new version %s from the server.</error>', $remoteTag));
 
-                return 1;
-            }
-
-            chmod($tempFilename, 0777 & ~umask());
-
-            // test the phar validity
-            $phar = new \Phar($tempFilename);
-            // free the variable to unlock the file
-            unset($phar);
-            rename($tempFilename, $localFilename);
+            return 1;
+        }
 
-            $output->writeln(sprintf('<info>php-cs-fixer updated</info> (<comment>%s</comment>)', $remoteTag));
-        } catch (\Exception $e) {
-            if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
-                throw $e;
-            }
+        chmod($tempFilename, 0777 & ~umask());
 
+        $pharInvalidityReason = $this->pharChecker->checkFileValidity($tempFilename);
+        if (null !== $pharInvalidityReason) {
             unlink($tempFilename);
-            $output->writeln(sprintf('<error>The download of %s is corrupt (%s).</error>', $remoteTag, $e->getMessage()));
+            $output->writeln(sprintf('<error>The download of %s is corrupt (%s).</error>', $remoteTag, $pharInvalidityReason));
             $output->writeln('<error>Please re-run the self-update command to try again.</error>');
 
             return 1;
         }
+
+        rename($tempFilename, $localFilename);
+
+        $output->writeln(sprintf('<info>php-cs-fixer updated</info> (<comment>%s</comment>)', $remoteTag));
     }
 }

+ 5 - 17
src/Console/SelfUpdate/NewVersionChecker.php

@@ -19,7 +19,7 @@ use Composer\Semver\VersionParser;
 /**
  * @internal
  */
-final class NewVersionChecker
+final class NewVersionChecker implements NewVersionCheckerInterface
 {
     /**
      * @var GithubClientInterface
@@ -46,9 +46,7 @@ final class NewVersionChecker
     }
 
     /**
-     * Returns the tag of the latest version.
-     *
-     * @return string
+     * {@inheritdoc}
      */
     public function getLatestVersion()
     {
@@ -58,11 +56,7 @@ final class NewVersionChecker
     }
 
     /**
-     * Returns the tag of the latest minor/patch version of the given major version.
-     *
-     * @param int $majorVersion
-     *
-     * @return null|string
+     * {@inheritdoc}
      */
     public function getLatestVersionOfMajor($majorVersion)
     {
@@ -80,13 +74,7 @@ final class NewVersionChecker
     }
 
     /**
-     * Returns -1, 0, or 1 if the first version is respectively less than,
-     * equal to, or greater than the second.
-     *
-     * @param string $versionA
-     * @param string $versionB
-     *
-     * @return int
+     * {@inheritdoc}
      */
     public function compareVersions($versionA, $versionB)
     {
@@ -116,7 +104,7 @@ final class NewVersionChecker
             try {
                 $this->versionParser->normalize($version);
 
-                if ('stable' === Versionparser::parseStability($version)) {
+                if ('stable' === VersionParser::parseStability($version)) {
                     $this->availableVersions[] = $version;
                 }
             } catch (\UnexpectedValueException $exception) {

+ 46 - 0
src/Console/SelfUpdate/NewVersionCheckerInterface.php

@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Console\SelfUpdate;
+
+/**
+ * @internal
+ */
+interface NewVersionCheckerInterface
+{
+    /**
+     * Returns the tag of the latest version.
+     *
+     * @return string
+     */
+    public function getLatestVersion();
+
+    /**
+     * Returns the tag of the latest minor/patch version of the given major version.
+     *
+     * @param int $majorVersion
+     *
+     * @return null|string
+     */
+    public function getLatestVersionOfMajor($majorVersion);
+
+    /**
+     * Returns -1, 0, or 1 if the first version is respectively less than,
+     * equal to, or greater than the second.
+     *
+     * @param string $versionA
+     * @param string $versionB
+     *
+     * @return int
+     */
+    public function compareVersions($versionA, $versionB);
+}

+ 39 - 0
src/PharChecker.php

@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer;
+
+/**
+ * @internal
+ */
+final class PharChecker implements PharCheckerInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function checkFileValidity($filename)
+    {
+        try {
+            $phar = new \Phar($filename);
+            // free the variable to unlock the file
+            unset($phar);
+        } catch (\Exception $e) {
+            if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
+                throw $e;
+            }
+
+            return $e->getMessage();
+        }
+
+        return null;
+    }
+}

+ 26 - 0
src/PharCheckerInterface.php

@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer;
+
+/**
+ * @internal
+ */
+interface PharCheckerInterface
+{
+    /**
+     * @param string $filename
+     *
+     * @return string|null the invalidity reason if any, null otherwise
+     */
+    public function checkFileValidity($filename);
+}

+ 8 - 0
src/ToolInfo.php

@@ -94,6 +94,14 @@ final class ToolInfo implements ToolInfoInterface
         return $this->isInstalledByComposer;
     }
 
+    public function getPharDownloadUri($version)
+    {
+        return sprintf(
+            'https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/%s/php-cs-fixer.phar',
+            $version
+        );
+    }
+
     private function getComposerInstalledFile()
     {
         return __DIR__.'/../../../composer/installed.json';

+ 2 - 0
src/ToolInfoInterface.php

@@ -26,4 +26,6 @@ interface ToolInfoInterface
     public function isInstalledAsPhar();
 
     public function isInstalledByComposer();
+
+    public function getPharDownloadUri($version);
 }

+ 1 - 1
tests/AutoReview/ProjectCodeTest.php

@@ -37,7 +37,6 @@ final class ProjectCodeTest extends TestCase
      */
     private static $classesWithoutTests = array(
         'PhpCsFixer\ConfigurationException\InvalidForEnvFixerConfigurationException',
-        'PhpCsFixer\Console\Command\SelfUpdateCommand',
         'PhpCsFixer\Console\Output\NullOutput',
         'PhpCsFixer\Console\SelfUpdate\GithubClient',
         'PhpCsFixer\Console\WarningsDetector',
@@ -52,6 +51,7 @@ final class ProjectCodeTest extends TestCase
         'PhpCsFixer\FixerFileProcessedEvent',
         'PhpCsFixer\Linter\ProcessLintingResult',
         'PhpCsFixer\Linter\TokenizerLintingResult',
+        'PhpCsFixer\PharChecker',
         'PhpCsFixer\Report\ReportSummary',
         'PhpCsFixer\Runner\FileCachingLintingIterator',
         'PhpCsFixer\Runner\FileFilterIterator',

Some files were not shown because too many files changed in this diff