Skip to content

Commit da66878

Browse files
committed
Implemented command for updating Factorio if a new version is available.
1 parent 298cb3c commit da66878

File tree

9 files changed

+537
-0
lines changed

9 files changed

+537
-0
lines changed

config/autoload/commands.global.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
'commands' => [
1818
CommandName::DOWNLOAD_FACTORIO => Command\DownloadFactorioCommand::class,
1919
CommandName::PROCESS => Command\ProcessCommand::class,
20+
CommandName::UPDATE_FACTORIO => Command\UpdateFactorioCommand::class,
2021
],
2122
];

config/autoload/dependencies.global.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
Command\ProcessStep\ParserStep::class => AutoWireFactory::class,
4040
Command\ProcessStep\RenderIconsStep::class => AutoWireFactory::class,
4141
Command\ProcessStep\UploadStep::class => AutoWireFactory::class,
42+
Command\UpdateFactorioCommand::class => AutoWireFactory::class,
4243

4344
Helper\HashCalculator::class => AutoWireFactory::class,
4445
Helper\ZipArchiveExtractor::class => AutoWireFactory::class,

src/Command/UpdateFactorioCommand.php

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FactorioItemBrowser\Export\Command;
6+
7+
use BluePsyduck\FactorioModPortalClient\Entity\Version;
8+
use FactorioItemBrowser\CombinationApi\Client\ClientInterface;
9+
use FactorioItemBrowser\CombinationApi\Client\Constant\JobPriority;
10+
use FactorioItemBrowser\CombinationApi\Client\Exception\ClientException;
11+
use FactorioItemBrowser\CombinationApi\Client\Request\Job\CreateRequest;
12+
use FactorioItemBrowser\Common\Constant\Constant;
13+
use FactorioItemBrowser\Common\Constant\Defaults;
14+
use FactorioItemBrowser\Export\Constant\CommandName;
15+
use FactorioItemBrowser\Export\Exception\CommandException;
16+
use FactorioItemBrowser\Export\Exception\ExportException;
17+
use FactorioItemBrowser\Export\Output\Console;
18+
use FactorioItemBrowser\Export\Process\CommandProcess;
19+
use FactorioItemBrowser\Export\Service\FactorioDownloadService;
20+
use FactorioItemBrowser\Export\Service\ModFileService;
21+
use Symfony\Component\Console\Command\Command;
22+
use Symfony\Component\Console\Input\InputInterface;
23+
use Symfony\Component\Console\Output\OutputInterface;
24+
25+
/**
26+
* The command for updating Factorio to its latest version.
27+
*
28+
* @author BluePsyduck <[email protected]>
29+
* @license http://opensource.org/licenses/GPL-3.0 GPL v3
30+
*/
31+
class UpdateFactorioCommand extends Command
32+
{
33+
protected ClientInterface $combinationApiClient;
34+
protected Console $console;
35+
protected FactorioDownloadService $factorioDownloadService;
36+
protected ModFileService $modFileService;
37+
38+
public function __construct(
39+
ClientInterface $combinationApiClient,
40+
Console $console,
41+
FactorioDownloadService $factorioDownloadService,
42+
ModFileService $modFileService,
43+
) {
44+
parent::__construct();
45+
46+
$this->combinationApiClient = $combinationApiClient;
47+
$this->console = $console;
48+
$this->factorioDownloadService = $factorioDownloadService;
49+
$this->modFileService = $modFileService;
50+
}
51+
52+
protected function configure(): void
53+
{
54+
parent::configure();
55+
56+
$this->setName(CommandName::UPDATE_FACTORIO);
57+
$this->setDescription('Updates the Factorio game to its latest version.');
58+
}
59+
60+
/**
61+
* @param InputInterface $input
62+
* @param OutputInterface $output
63+
* @return int
64+
* @throws ExportException
65+
*/
66+
protected function execute(InputInterface $input, OutputInterface $output): int
67+
{
68+
$currentVersion = $this->modFileService->getInfo(Constant::MOD_NAME_BASE)->version;
69+
$this->console->writeMessage(sprintf('Current version: <fg=green>%s</>', $currentVersion));
70+
71+
$latestVersion = $this->factorioDownloadService->getLatestVersion();
72+
$this->console->writeMessage(sprintf('Latest version: <fg=green>%s</>', $latestVersion));
73+
74+
if ((new Version($latestVersion))->compareTo($currentVersion) <= 0) {
75+
$this->console->writeMessage('Already up-to-date. Done.');
76+
return 0;
77+
}
78+
79+
$this->console->writeAction('Downloading new version of Factorio');
80+
$process = $this->createDownloadProcess($latestVersion);
81+
$process->run(function (string $type, string $message) use ($output): void {
82+
$output->write($message);
83+
});
84+
85+
if ($process->getExitCode() !== 0) {
86+
$this->console->writeMessage('<fg=red>Factorio download failed.</>');
87+
return 1;
88+
}
89+
90+
$this->createExportJob();
91+
return 0;
92+
}
93+
94+
/**
95+
* @param string $version
96+
* @return CommandProcess<string>
97+
*/
98+
protected function createDownloadProcess(string $version): CommandProcess
99+
{
100+
return new CommandProcess(CommandName::DOWNLOAD_FACTORIO, [$version]);
101+
}
102+
103+
/**
104+
* @throws CommandException
105+
*/
106+
protected function createExportJob(): void
107+
{
108+
$request = new CreateRequest();
109+
$request->combinationId = Defaults::COMBINATION_ID;
110+
$request->priority = JobPriority::ADMIN;
111+
112+
try {
113+
$this->combinationApiClient->sendRequest($request);
114+
} catch (ClientException $e) {
115+
throw new CommandException('Request to Combination API failed.', 500, $e);
116+
}
117+
}
118+
}

src/Constant/CommandName.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ interface CommandName
2121
* The name of the processing command.
2222
*/
2323
public const PROCESS = 'process';
24+
25+
/**
26+
* The name of the command for updating Factorio to its latest version.
27+
*/
28+
public const UPDATE_FACTORIO = 'update-factorio';
2429
}

src/Process/CommandProcess.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FactorioItemBrowser\Export\Process;
6+
7+
use Symfony\Component\Process\Process;
8+
9+
/**
10+
* The process to run another command.
11+
*
12+
* @author BluePsyduck <[email protected]>
13+
* @license http://opensource.org/licenses/GPL-3.0 GPL v3
14+
*/
15+
class CommandProcess extends Process
16+
{
17+
/**
18+
* @param string $commandName
19+
* @param array<string> $additionalArguments
20+
*/
21+
public function __construct(string $commandName, array $additionalArguments = [])
22+
{
23+
parent::__construct([
24+
$_SERVER['_'] ?? 'php',
25+
$_SERVER['SCRIPT_FILENAME'],
26+
$commandName,
27+
...$additionalArguments,
28+
]);
29+
30+
$this->setTimeout(null);
31+
}
32+
}

src/Service/FactorioDownloadService.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace FactorioItemBrowser\Export\Service;
66

7+
use FactorioItemBrowser\Export\Exception\CommandException;
78
use FactorioItemBrowser\Export\Process\DownloadProcess;
89
use Symfony\Component\Filesystem\Filesystem;
910
use Symfony\Component\Process\Process;
@@ -23,6 +24,7 @@ class FactorioDownloadService
2324
self::VARIANT_FULL => 'https://www.factorio.com/get-download/%s/alpha/linux64',
2425
self::VARIANT_HEADLESS => 'https://www.factorio.com/get-download/%s/headless/linux64',
2526
];
27+
private const LATEST_VERSION_URL = 'https://factorio.com/api/latest-releases';
2628

2729
private Filesystem $fileSystem;
2830
private string $factorioApiUsername;
@@ -90,6 +92,31 @@ protected function createExtractArchiveProcess(string $archiveFile, string $dest
9092
return $process;
9193
}
9294

95+
/**
96+
* Fetches and returns the latest version of Factorio.
97+
* @return string
98+
* @throws CommandException
99+
*/
100+
public function getLatestVersion(): string
101+
{
102+
$response = @file_get_contents($this->buildUrl(self::LATEST_VERSION_URL));
103+
if ($response === false) {
104+
throw new CommandException('Failed to fetch latest version of Factorio.');
105+
}
106+
107+
$data = json_decode($response, true);
108+
if (!is_array($data)) {
109+
throw new CommandException(sprintf('Invalid response: %s', json_last_error()));
110+
}
111+
112+
$version = $data['stable']['alpha'] ?? null;
113+
if (!$version) {
114+
throw new CommandException('Unable to read latest version from response.');
115+
}
116+
117+
return $version;
118+
}
119+
93120
/**
94121
* @param string $url
95122
* @param array<string, string> $parameters

0 commit comments

Comments
 (0)