Skip to content

Commit f1ab0a0

Browse files
committed
Refactor packages:update command
Signed-off-by: Tim Goudriaan <tim@codedmonkey.com>
1 parent ba93574 commit f1ab0a0

4 files changed

Lines changed: 83 additions & 36 deletions

File tree

src/Command/PackagesUpdateCommand.php

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

55
use CodedMonkey\Dirigent\Doctrine\Repository\PackageRepository;
66
use CodedMonkey\Dirigent\Message\SchedulePackageUpdate;
7+
use CodedMonkey\Dirigent\Message\UpdatePackage;
78
use Symfony\Component\Console\Attribute\AsCommand;
89
use Symfony\Component\Console\Command\Command;
910
use Symfony\Component\Console\Input\InputArgument;
@@ -29,48 +30,92 @@ public function __construct(
2930
protected function configure(): void
3031
{
3132
$this
32-
->addArgument('package', InputArgument::OPTIONAL, 'Package to update')
33-
->addOption('force', null, InputOption::VALUE_NONE, 'Forces a re-crawl of all packages');
33+
->addArgument('package', InputArgument::IS_ARRAY, 'Package to update')
34+
->addOption('all', null, InputOption::VALUE_NONE, 'Update all packages')
35+
->addOption('sync', null, InputOption::VALUE_NONE, 'Update packages synchronously')
36+
->setHelp(<<<'TXT'
37+
The <info>%command.name%</info> command schedules packages in the registry for update:
38+
39+
<info>%command.full_name%</info>
40+
41+
By default, only packages that have passed the periodic update interval will be scheduled for update.
42+
43+
Use the <comment>--all</comment> option to schedule all packages for update instead:
44+
45+
<info>%command.full_name% --all</info>
46+
47+
It's possible to update specific packages by passing their name as arguments:
48+
49+
<info>%command.full_name% psr/cache psr/log</info>
50+
51+
Use the <comment>--sync</comment> option to update packages synchronously:
52+
53+
<info>%command.full_name% psr/cache psr/log --sync</info>
54+
TXT);
3455
}
3556

3657
protected function execute(InputInterface $input, OutputInterface $output): int
3758
{
3859
$io = new SymfonyStyle($input, $output);
3960

40-
$force = $input->getOption('force');
41-
$packageName = $input->getArgument('package');
61+
$all = $input->getOption('all');
62+
$packageNames = $input->getArgument('package');
63+
$sync = $input->getOption('sync');
64+
65+
if ($sync && !count($packageNames)) {
66+
$io->error('Specify a package to update when using the --sync option.');
4267

68+
return Command::FAILURE;
69+
}
70+
71+
// Force refresh updates even if alread
72+
$forceRefresh = false;
73+
// Randomize time of updates
4374
$randomTimes = true;
75+
// Schedule update even if already scheduled
4476
$reschedule = false;
4577

46-
if ($packageName) {
47-
if (null === $package = $this->packageRepository->findOneByName($packageName)) {
48-
$io->error("Package $packageName not found");
78+
if (count($packageNames)) {
79+
$packageIds = [];
80+
foreach ($packageNames as $packageName) {
81+
if (null === $package = $this->packageRepository->findOneByName($packageName)) {
82+
$io->error("Package $packageName not found");
4983

50-
return Command::FAILURE;
51-
}
84+
return Command::FAILURE;
85+
}
5286

53-
$io->writeln("Scheduling package $packageName for update...");
54-
55-
$packages = [['id' => $package->getId()]];
87+
$io->writeln("Scheduling package $packageName for update...");
88+
$packageIds[] = $package->getId();
89+
}
5690

91+
$forceRefresh = true;
5792
$randomTimes = false;
5893
$reschedule = true;
59-
} elseif ($force) {
94+
} elseif ($all) {
6095
$io->writeln('Scheduling all packages for update...');
61-
$packages = $this->packageRepository->getAllPackageIds();
96+
$packageIds = $this->packageRepository->getAllPackageIds();
6297

98+
$forceRefresh = true;
6399
$reschedule = true;
64100
} else {
65101
$io->writeln('Scheduling stale packages for update...');
66-
$packages = $this->packageRepository->getStalePackageIds();
102+
$packageIds = $this->packageRepository->getStalePackageIds();
103+
}
104+
105+
if ($sync) {
106+
foreach ($packageIds as $packageId) {
107+
$this->messenger->dispatch(new UpdatePackage($packageId, forceRefresh: $forceRefresh));
108+
}
109+
110+
$packageCount = count($packageIds);
111+
$io->success("Updated $packageCount package(s).");
67112
}
68113

69-
foreach ($packages as $package) {
70-
$this->messenger->dispatch(new SchedulePackageUpdate($package['id'], randomTime: $randomTimes, reschedule: $reschedule, forceRefresh: $force));
114+
foreach ($packageIds as $packageId) {
115+
$this->messenger->dispatch(new SchedulePackageUpdate($packageId, randomTime: $randomTimes, reschedule: $reschedule, forceRefresh: $forceRefresh));
71116
}
72117

73-
$packageCount = count($packages);
118+
$packageCount = count($packageIds);
74119
$io->success("Scheduled $packageCount package(s) for update.");
75120

76121
return Command::SUCCESS;

src/Doctrine/Entity/Package.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,11 @@ public function setUpdateScheduledAt(?\DateTimeInterface $updateScheduledAt): vo
333333
$this->updateScheduledAt = $updateScheduledAt;
334334
}
335335

336+
public function isUpdateScheduled(): bool
337+
{
338+
return null !== $this->updateScheduledAt;
339+
}
340+
336341
public function getDumpedAt(): ?\DateTimeInterface
337342
{
338343
return $this->dumpedAt;

src/Doctrine/Repository/PackageRepository.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,17 @@ public function findOneByName(string $name): ?Package
5555
}
5656

5757
/**
58-
* @return list<array{id: int}>
58+
* @return int[]
5959
*/
6060
public function getAllPackageIds(): array
6161
{
6262
$connection = $this->getEntityManager()->getConnection();
6363

64-
return $connection->fetchAllAssociative('SELECT id FROM package ORDER BY id');
64+
return $connection->fetchFirstColumn('SELECT id FROM package ORDER BY id');
6565
}
6666

6767
/**
68-
* @return list<array{id: int}>
68+
* @return int[]
6969
*/
7070
public function getStalePackageIds(): array
7171
{
@@ -74,12 +74,13 @@ public function getStalePackageIds(): array
7474
$now = (new \DateTimeImmutable())->setTimezone(new \DateTimeZone('UTC'));
7575
$before = $now->sub($this->updateInterval);
7676

77-
return $connection->fetchAllAssociative(
78-
'SELECT p.id FROM package p
79-
WHERE p.update_scheduled_at IS NULL
80-
AND (p.updated_at IS NULL OR p.updated_at < :crawled)
81-
ORDER BY p.id',
82-
[
77+
return $connection->fetchFirstColumn(
78+
<<<'SQL'
79+
SELECT p.id FROM package p
80+
WHERE p.update_scheduled_at IS NULL
81+
AND (p.updated_at IS NULL OR p.updated_at < :crawled)
82+
ORDER BY p.id
83+
SQL, [
8384
'crawled' => $before->format('Y-m-d H:i:s'),
8485
]
8586
);

src/Message/SchedulePackageUpdateHandler.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,22 @@ public function __invoke(SchedulePackageUpdate $message): void
2222
{
2323
$package = $this->packageRepository->find($message->packageId);
2424

25-
if (!$message->reschedule && null !== $package->getUpdateScheduledAt()) {
25+
if (!$message->reschedule && $package->isUpdateScheduled()) {
2626
return;
2727
}
2828

29-
$updateMessage = new UpdatePackage($message->packageId, scheduled: true, forceRefresh: $message->forceRefresh);
30-
$updateEnvelope = new Envelope($updateMessage, [
31-
new TransportNamesStamp('async'),
32-
]);
29+
$updateMessage = Envelope::wrap(new UpdatePackage($message->packageId, scheduled: true, forceRefresh: $message->forceRefresh))
30+
->with(new TransportNamesStamp('async'));
3331

3432
if ($message->randomTime) {
3533
// Delay message up to 12 minutes
36-
$updateEnvelope = $updateEnvelope->with(
37-
new DelayStamp(random_int(1, 720) * 1000),
38-
);
34+
$updateMessage = $updateMessage->with(new DelayStamp(random_int(1, 720) * 1000));
3935
}
4036

4137
$package->setUpdateScheduledAt(new \DateTime());
4238

4339
$this->packageRepository->save($package, true);
4440

45-
$this->messenger->dispatch($updateEnvelope);
41+
$this->messenger->dispatch($updateMessage);
4642
}
4743
}

0 commit comments

Comments
 (0)