Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / consolidation / robo / src / SelfUpdateCommand.php
1 <?php
2
3 namespace Robo;
4
5 use Symfony\Component\Console\Command\Command;
6 use Symfony\Component\Console\Input\InputInterface;
7 use Symfony\Component\Console\Output\OutputInterface;
8 use Symfony\Component\Filesystem\Filesystem as sfFilesystem;
9
10 /**
11  * Update the robo.phar from the latest github release
12  *
13  * @author Alexander Menk <alex.menk@gmail.com>
14  */
15 class SelfUpdateCommand extends Command
16 {
17     const SELF_UPDATE_COMMAND_NAME = 'self:update';
18
19     protected $gitHubRepository;
20
21     protected $currentVersion;
22
23     protected $applicationName;
24
25     public function __construct($applicationName = null, $currentVersion = null, $gitHubRepository = null)
26     {
27         $this->applicationName = $applicationName;
28         $this->currentVersion = $currentVersion;
29         $this->gitHubRepository = $gitHubRepository;
30
31         parent::__construct(self::SELF_UPDATE_COMMAND_NAME);
32     }
33
34     /**
35      * {@inheritdoc}
36      */
37     protected function configure()
38     {
39         $app = $this->applicationName;
40
41         $this
42             ->setAliases(array('update'))
43             ->setDescription("Updates $app to the latest version.")
44             ->setHelp(
45                 <<<EOT
46 The <info>self-update</info> command checks github for newer
47 versions of $app and if found, installs the latest.
48 EOT
49             );
50     }
51
52     protected function getLatestReleaseFromGithub()
53     {
54         $opts = [
55             'http' => [
56                 'method' => 'GET',
57                 'header' => [
58                     'User-Agent: ' . $this->applicationName  . ' (' . $this->gitHubRepository . ')' . ' Self-Update (PHP)'
59                 ]
60             ]
61         ];
62
63         $context = stream_context_create($opts);
64
65         $releases = file_get_contents('https://api.github.com/repos/' . $this->gitHubRepository . '/releases', false, $context);
66         $releases = json_decode($releases);
67
68         if (! isset($releases[0])) {
69             throw new \Exception('API error - no release found at GitHub repository ' . $this->gitHubRepository);
70         }
71
72         $version = $releases[0]->tag_name;
73         $url     = $releases[0]->assets[0]->browser_download_url;
74
75         return [ $version, $url ];
76     }
77
78     /**
79      * {@inheritdoc}
80      */
81     protected function execute(InputInterface $input, OutputInterface $output)
82     {
83         if (empty(\Phar::running())) {
84             throw new \Exception(self::SELF_UPDATE_COMMAND_NAME . ' only works when running the phar version of ' . $this->applicationName . '.');
85         }
86
87         $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
88         $programName   = basename($localFilename);
89         $tempFilename  = dirname($localFilename) . '/' . basename($localFilename, '.phar') . '-temp.phar';
90
91         // check for permissions in local filesystem before start connection process
92         if (! is_writable($tempDirectory = dirname($tempFilename))) {
93             throw new \Exception(
94                 $programName . ' update failed: the "' . $tempDirectory .
95                 '" directory used to download the temp file could not be written'
96             );
97         }
98
99         if (! is_writable($localFilename)) {
100             throw new \Exception(
101                 $programName . ' update failed: the "' . $localFilename . '" file could not be written (execute with sudo)'
102             );
103         }
104
105         list( $latest, $downloadUrl ) = $this->getLatestReleaseFromGithub();
106
107
108         if ($this->currentVersion == $latest) {
109             $output->writeln('No update available');
110             return;
111         }
112
113         $fs = new sfFilesystem();
114
115         $output->writeln('Downloading ' . $this->applicationName . ' (' . $this->gitHubRepository . ') ' . $latest);
116
117         $fs->copy($downloadUrl, $tempFilename);
118
119         $output->writeln('Download finished');
120
121         try {
122             \error_reporting(E_ALL); // supress notices
123
124             @chmod($tempFilename, 0777 & ~umask());
125             // test the phar validity
126             $phar = new \Phar($tempFilename);
127             // free the variable to unlock the file
128             unset($phar);
129             @rename($tempFilename, $localFilename);
130             $output->writeln('<info>Successfully updated ' . $programName . '</info>');
131             $this->_exit();
132         } catch (\Exception $e) {
133             @unlink($tempFilename);
134             if (! $e instanceof \UnexpectedValueException && ! $e instanceof \PharException) {
135                 throw $e;
136             }
137             $output->writeln('<error>The download is corrupted (' . $e->getMessage() . ').</error>');
138             $output->writeln('<error>Please re-run the self-update command to try again.</error>');
139         }
140     }
141
142     /**
143      * Stop execution
144      *
145      * This is a workaround to prevent warning of dispatcher after replacing
146      * the phar file.
147      *
148      * @return void
149      */
150     protected function _exit()
151     {
152         exit;
153     }
154 }