Skip to content

Commit 3469a96

Browse files
committed
feat: add a warning if the cli version is out of date
1 parent 8ac8f93 commit 3469a96

File tree

5 files changed

+168
-31
lines changed

5 files changed

+168
-31
lines changed

config/services.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ parameters:
66
hidden_directory: '%working_directory%/.ymir'
77
project_configuration_filepath: '%working_directory%/ymir.yml'
88
stub_directory: '%application_directory%/stubs'
9+
version: '1.4.3'
910

1011
services:
1112
_defaults:
@@ -20,6 +21,7 @@ services:
2021
string $homeDirectory: '%home_directory%'
2122
string $projectDirectory: '%working_directory%'
2223
string $stubDirectory: '%stub_directory%'
24+
string $version: '%version%'
2325

2426
_instanceof:
2527
Symfony\Component\Console\Command\Command:

src/Application.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ class Application extends BaseApplication
2222
/**
2323
* Constructor.
2424
*/
25-
public function __construct(iterable $commands = [])
25+
public function __construct(iterable $commands, string $version)
2626
{
27-
parent::__construct('Ymir', '1.4.3');
27+
parent::__construct('Ymir', $version);
2828

2929
foreach ($commands as $command) {
3030
$this->add($command);

src/Command/InstallPluginCommand.php

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Ymir\Cli\ApiClient;
2323
use Ymir\Cli\CliConfiguration;
2424
use Ymir\Cli\Console\ConsoleOutput;
25+
use Ymir\Cli\GitHubClient;
2526
use Ymir\Cli\Process\Process;
2627
use Ymir\Cli\ProjectConfiguration;
2728

@@ -41,6 +42,13 @@ class InstallPluginCommand extends AbstractProjectCommand
4142
*/
4243
private $filesystem;
4344

45+
/**
46+
* The API client that interacts with the GitHub API.
47+
*
48+
* @var GitHubClient
49+
*/
50+
private $gitHubClient;
51+
4452
/**
4553
* The project directory where we want to install the plugin.
4654
*
@@ -51,11 +59,12 @@ class InstallPluginCommand extends AbstractProjectCommand
5159
/**
5260
* Constructor.
5361
*/
54-
public function __construct(ApiClient $apiClient, CliConfiguration $cliConfiguration, Filesystem $filesystem, ProjectConfiguration $projectConfiguration, string $projectDirectory)
62+
public function __construct(ApiClient $apiClient, CliConfiguration $cliConfiguration, Filesystem $filesystem, GitHubClient $gitHubClient, ProjectConfiguration $projectConfiguration, string $projectDirectory)
5563
{
5664
parent::__construct($apiClient, $cliConfiguration, $projectConfiguration);
5765

5866
$this->filesystem = $filesystem;
67+
$this->gitHubClient = $gitHubClient;
5968
$this->projectDirectory = rtrim($projectDirectory, '/');
6069
}
6170

@@ -97,35 +106,9 @@ protected function perform(InputInterface $input, ConsoleOutput $output)
97106
*/
98107
private function installFromGitHub()
99108
{
100-
$client = new Client();
101-
$response = $client->request('GET', 'https://api.github.com/repos/ymirapp/wordpress-plugin/tags');
102-
103-
if (200 !== $response->getStatusCode()) {
104-
throw new RuntimeException('Unable to get the latest WordPress plugin versions from the GitHub API');
105-
}
106-
107-
$latestTag = collect(json_decode((string) $response->getBody(), true))->first();
108-
109-
if (empty($latestTag['zipball_url'])) {
110-
throw new RuntimeException('Unable to parse the WordPress plugin versions from the GitHub API');
111-
}
112-
113-
$downloadedZipFile = tmpfile();
114-
115-
if (!is_resource($downloadedZipFile)) {
116-
throw new RuntimeException('Unable to open a temporary file');
117-
}
118-
119-
fwrite($downloadedZipFile, (string) $client->request('GET', $latestTag['zipball_url'])->getBody());
120-
121-
$downloadedZipArchive = new \ZipArchive();
122-
123-
if (true !== $downloadedZipArchive->open(stream_get_meta_data($downloadedZipFile)['uri'])) {
124-
throw new RuntimeException('Unable to open the WordPress plugin Zip archive from GitHub');
125-
}
126-
127109
$pluginsDirectory = $this->projectDirectory.'/wp-content/plugins';
128-
$downloadedZipArchive->extractTo($pluginsDirectory);
110+
111+
$this->gitHubClient->downloadLatestVersion('ymirapp/wordpress-plugin')->extractTo($pluginsDirectory);
129112

130113
$files = Finder::create()
131114
->directories()
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Ymir command-line tool.
7+
*
8+
* (c) Carl Alexander <support@ymirapp.com>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Ymir\Cli\EventListener;
15+
16+
use Symfony\Component\Console\ConsoleEvents;
17+
use Symfony\Component\Console\Event\ConsoleCommandEvent;
18+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
19+
use Ymir\Cli\Application;
20+
use Ymir\Cli\GitHubClient;
21+
22+
class VersionCheckSubscriber implements EventSubscriberInterface
23+
{
24+
/**
25+
* The API client that interacts with the GitHub API.
26+
*
27+
* @var GitHubClient
28+
*/
29+
private $gitHubClient;
30+
31+
/**
32+
* The version of the Ymir console application.
33+
*
34+
* @var string
35+
*/
36+
private $version;
37+
38+
/**
39+
* Constructor.
40+
*/
41+
public function __construct(GitHubClient $gitHubClient, string $version)
42+
{
43+
$this->gitHubClient = $gitHubClient;
44+
$this->version = $version;
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
*/
50+
public static function getSubscribedEvents()
51+
{
52+
return [
53+
ConsoleEvents::COMMAND => 'onConsoleCommand',
54+
];
55+
}
56+
57+
/**
58+
* Check for a new version of the CLI before you run a command.
59+
*/
60+
public function onConsoleCommand(ConsoleCommandEvent $event)
61+
{
62+
$latestVersion = ltrim($this->gitHubClient->getTags('ymirapp/cli')->pluck('name')->first(), 'v');
63+
64+
if (version_compare($latestVersion, $this->version, '>')) {
65+
$event->getOutput()->writeln('<comment>A new version of the Ymir CLI is available</comment>');
66+
}
67+
}
68+
}

src/GitHubClient.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Ymir command-line tool.
7+
*
8+
* (c) Carl Alexander <support@ymirapp.com>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Ymir\Cli;
15+
16+
use GuzzleHttp\ClientInterface;
17+
use Symfony\Component\Console\Exception\RuntimeException;
18+
use Tightenco\Collect\Support\Collection;
19+
20+
class GitHubClient
21+
{
22+
/**
23+
* The HTTP client used to interact with the GitHub API.
24+
*
25+
* @var ClientInterface
26+
*/
27+
private $client;
28+
29+
/**
30+
* Constructor.
31+
*/
32+
public function __construct(ClientInterface $client)
33+
{
34+
$this->client = $client;
35+
}
36+
37+
/**
38+
* Download the latest version of a repository from GitHub and return the Zip archive.
39+
*/
40+
public function downloadLatestVersion(string $repository): \ZipArchive
41+
{
42+
$latestTag = $this->getTags($repository)->first();
43+
44+
if (empty($latestTag['zipball_url'])) {
45+
throw new RuntimeException('Unable to parse the WordPress plugin versions from the GitHub API');
46+
}
47+
48+
$downloadedZipFile = tmpfile();
49+
50+
if (!is_resource($downloadedZipFile)) {
51+
throw new RuntimeException('Unable to open a temporary file');
52+
}
53+
54+
fwrite($downloadedZipFile, (string) $this->client->request('GET', $latestTag['zipball_url'])->getBody());
55+
56+
$downloadedZipArchive = new \ZipArchive();
57+
58+
if (true !== $downloadedZipArchive->open(stream_get_meta_data($downloadedZipFile)['uri'])) {
59+
throw new RuntimeException(sprintf('Unable to open the "%s" repository Zip archive from GitHub', $repository));
60+
}
61+
62+
return $downloadedZipArchive;
63+
}
64+
65+
/**
66+
* Get the tags for the given repository.
67+
*/
68+
public function getTags(string $repository): Collection
69+
{
70+
$response = $this->client->request('GET', sprintf('https://api.github.com/repos/%s/tags', $repository));
71+
72+
if (200 !== $response->getStatusCode()) {
73+
throw new RuntimeException(sprintf('Unable to get the tags for the "%s" repository from the GitHub API', $repository));
74+
}
75+
76+
$tags = json_decode((string) $response->getBody(), true);
77+
78+
if (JSON_ERROR_NONE !== json_last_error()) {
79+
throw new RuntimeException(sprintf('Failed to decode response from the GitHub API: %s.', json_last_error_msg()));
80+
}
81+
82+
return collect($tags);
83+
}
84+
}

0 commit comments

Comments
 (0)