Skip to content

Commit 33169ca

Browse files
Allow transfer command to accept a single package name too
1 parent 466eed6 commit 33169ca

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

src/Command/TransferOwnershipCommand.php

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ protected function configure(): void
4141
->setName('packagist:transfer-ownership')
4242
->setDescription('Transfer all packages of a vendor')
4343
->setDefinition([
44-
new InputArgument('vendor', InputArgument::REQUIRED,'Vendor prefix'),
44+
new InputArgument('vendorOrPackage', InputArgument::REQUIRED,'Vendor or package name'),
4545
new InputArgument('maintainers', InputArgument::IS_ARRAY|InputArgument::REQUIRED, 'The usernames of the new maintainers'),
4646
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Dry run'),
4747
])
@@ -56,17 +56,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
5656
$output->writeln('ℹ️ DRY RUN');
5757
}
5858

59-
$vendor = $input->getArgument('vendor');
59+
$vendorOrPackage = $input->getArgument('vendorOrPackage');
6060
$maintainers = $this->queryAndValidateMaintainers($input, $output);
6161

6262
if (!count($maintainers)) {
6363
return Command::FAILURE;
6464
}
6565

66-
$packages = $this->queryVendorPackages($vendor);
66+
$packages = $this->queryPackages($vendorOrPackage);
6767

6868
if (!count($packages)) {
69-
$output->writeln(sprintf('<error>No packages found for vendor %s</error>', $vendor));
69+
$output->writeln(sprintf('<error>No packages found for %s</error>', $vendorOrPackage));
7070
return Command::FAILURE;
7171
}
7272

@@ -111,13 +111,20 @@ private function queryAndValidateMaintainers(InputInterface $input, OutputInterf
111111
/**
112112
* @return Package[]
113113
*/
114-
private function queryVendorPackages(string $vendor): array
114+
private function queryPackages(string $vendorOrPackage): array
115115
{
116-
return $this->getEM()
117-
->getRepository(Package::class)
118-
->getFilteredQueryBuilder(['vendor' => $vendor], true)
119-
->getQuery()
120-
->getResult();
116+
$repository = $this->getEM()->getRepository(Package::class);
117+
$isPackageName = str_contains($vendorOrPackage, '/');
118+
119+
if ($isPackageName) {
120+
$package = $repository->findOneBy(['name' => $vendorOrPackage]);
121+
122+
return $package ? [$package] : [];
123+
}
124+
125+
return $repository->findBy([
126+
'vendor' => $vendorOrPackage
127+
]);
121128
}
122129

123130
/**
@@ -128,6 +135,8 @@ private function outputPackageTable(OutputInterface $output, array $packages, ar
128135
{
129136
$rows = [];
130137

138+
usort($packages, fn (Package $a, Package $b) => strcasecmp($a->getName(), $b->getName()));
139+
131140
$newMaintainers = array_map(fn (User $user) => $user->getUsername(), $maintainers);
132141

133142
foreach ($packages as $package) {

tests/Command/TransferOwnershipCommandTest.php

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use App\Entity\User;
2020
use App\Tests\IntegrationTestCase;
2121
use Doctrine\Persistence\ManagerRegistry;
22+
use PHPUnit\Framework\Attributes\TestWith;
2223
use Symfony\Component\Console\Command\Command;
2324
use Symfony\Component\Console\Tester\CommandTester;
2425

@@ -48,10 +49,10 @@ protected function setUp(): void
4849
$this->commandTester = new CommandTester($command);
4950
}
5051

51-
public function testExecuteSuccessWithAllMaintainersFound(): void
52+
public function testExecuteSuccessForVendor(): void
5253
{
5354
$this->commandTester->execute([
54-
'vendor' => 'vendor1',
55+
'vendorOrPackage' => 'vendor1',
5556
'maintainers' => ['bob', 'alice'],
5657
]);
5758

@@ -71,17 +72,41 @@ public function testExecuteSuccessWithAllMaintainersFound(): void
7172
$callable = fn (User $user) => $user->getUsernameCanonical();
7273
$this->assertEqualsCanonicalizing(['alice', 'bob'], array_map($callable, $package1->getMaintainers()->toArray()));
7374
$this->assertEqualsCanonicalizing(['alice', 'bob'], array_map($callable, $package2->getMaintainers()->toArray()));
74-
$this->assertEqualsCanonicalizing(['john'], array_map($callable, $package3->getMaintainers()->toArray()), 'vendor1 package maintainers should not be changed');
75+
$this->assertEqualsCanonicalizing(['john'], array_map($callable, $package3->getMaintainers()->toArray()), 'vendor2 packages should not be changed');
7576

7677
$this->assertAuditLogWasCreated($package1, ['john', 'alice'], ['alice', 'bob']);
7778
$this->assertAuditLogWasCreated($package2, ['john', 'bob'], ['alice', 'bob']);
79+
}
80+
81+
public function testExecuteSuccessForPackage(): void
82+
{
83+
$this->commandTester->execute([
84+
'vendorOrPackage' => 'vendor2/package1',
85+
'maintainers' => ['john', 'alice'],
86+
]);
87+
88+
$this->commandTester->assertCommandIsSuccessful();
89+
90+
$em = self::getEM();
91+
$em->clear();
92+
93+
$package2 = $em->find(Package::class, $this->package2->getId());
94+
$package3 = $em->find(Package::class, $this->package3->getId());
95+
96+
$this->assertNotNull($package2);
97+
$this->assertNotNull($package3);
98+
99+
$callable = fn (User $user) => $user->getUsernameCanonical();
100+
$this->assertEqualsCanonicalizing(['bob', 'john'], array_map($callable, $package2->getMaintainers()->toArray()), 'vendor1 packages should not be changed');
101+
$this->assertEqualsCanonicalizing(['alice', 'john'], array_map($callable, $package3->getMaintainers()->toArray()));
78102

103+
$this->assertAuditLogWasCreated($package3, ['john'], ['alice', 'john']);
79104
}
80105

81106
public function testExecuteWithDryRunDoesNothing(): void
82107
{
83108
$this->commandTester->execute([
84-
'vendor' => 'vendor1',
109+
'vendorOrPackage' => 'vendor1',
85110
'maintainers' => ['alice'],
86111
'--dry-run' => true,
87112
]);
@@ -105,7 +130,7 @@ public function testExecuteWithDryRunDoesNothing(): void
105130
public function testExecuteFailsWithUnknownMaintainers(): void
106131
{
107132
$this->commandTester->execute([
108-
'vendor' => 'vendor1',
133+
'vendorOrPackage' => 'vendor1',
109134
'maintainers' => ['unknown1', 'alice', 'unknown2'],
110135
]);
111136

@@ -118,14 +143,14 @@ public function testExecuteFailsWithUnknownMaintainers(): void
118143
public function testExecuteFailsIfNoVendorPackagesFound(): void
119144
{
120145
$this->commandTester->execute([
121-
'vendor' => 'foobar',
146+
'vendorOrPackage' => 'foobar',
122147
'maintainers' => ['bob', 'alice'],
123148
]);
124149

125150
$this->assertSame(Command::FAILURE, $this->commandTester->getStatusCode());
126151

127152
$output = $this->commandTester->getDisplay();
128-
$this->assertStringContainsString('No packages found for vendor', $output);
153+
$this->assertStringContainsString('No packages found for foobar', $output);
129154
}
130155

131156
/**

0 commit comments

Comments
 (0)