Skip to content

Commit 230e37f

Browse files
committed
Fix wildcard matching for environment IDs that contain a / character
Affected commands: `environment:delete` and `user:add`
1 parent c7a0a34 commit 230e37f

File tree

4 files changed

+62
-23
lines changed

4 files changed

+62
-23
lines changed

src/Command/Environment/EnvironmentDeleteCommand.php

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use Platformsh\Cli\Command\CommandBase;
55
use Platformsh\Cli\Console\ArrayArgument;
6+
use Platformsh\Cli\Util\Wildcard;
67
use Platformsh\Client\Model\Environment;
78
use Symfony\Component\Console\Input\InputArgument;
89
use Symfony\Component\Console\Input\InputInterface;
@@ -60,7 +61,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
6061
}
6162
if ($specifiedEnvironmentIds) {
6263
$anythingSpecified = true;
63-
$specifiedEnvironmentIds = $this->findEnvironmentIDsByWildcards($environments, $specifiedEnvironmentIds);
64+
$allIds = \array_map(function (Environment $e) { return $e->id; }, $environments);
65+
$specifiedEnvironmentIds = Wildcard::select($allIds, $specifiedEnvironmentIds);
6466
$notFound = array_diff($specifiedEnvironmentIds, array_keys($environments));
6567
if (!empty($notFound)) {
6668
// Refresh the environments list if any environment is not found.
@@ -146,7 +148,8 @@ function ($environment) {
146148
// Exclude environment ID(s) specified in --exclude.
147149
$excludeIds = ArrayArgument::getOption($input, 'exclude');
148150
if (!empty($excludeIds)) {
149-
$resolved = $this->findEnvironmentIdsByWildcards($selectedEnvironments, $excludeIds);
151+
$selectedIds = \array_map(function (Environment $e) { return $e->id; }, $selectedEnvironments);
152+
$resolved = Wildcard::select($selectedIds, $excludeIds);
150153
if (count($resolved)) {
151154
$selectedEnvironments = \array_filter($selectedEnvironments, function (Environment $e) use ($resolved) {
152155
return !\in_array($e->id, $resolved, true);
@@ -234,25 +237,6 @@ function ($environment) {
234237
return $success ? 0 : 1;
235238
}
236239

237-
/**
238-
* Finds environments in a list matching a list of ID wildcards.
239-
*
240-
* @param Environment[] $environments
241-
* @param string[] $wildcards
242-
*
243-
* @return string[]
244-
*/
245-
private function findEnvironmentIDsByWildcards(array $environments, $wildcards)
246-
{
247-
$ids = \array_map(function (Environment $e) { return $e->id; }, $environments);
248-
$found = [];
249-
foreach ($wildcards as $wildcard) {
250-
$pattern = '/^' . str_replace('%', '.*', preg_quote($wildcard)) . '$/';
251-
$found = array_merge($found, \preg_grep($pattern, $ids));
252-
}
253-
return \array_unique($found);
254-
}
255-
256240
/**
257241
* @param array $toDeactivate
258242
* @param array $toDeleteBranch

src/Command/User/UserAddCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ private function getSpecifiedEnvironmentRoles(array $roles)
810810
$role = $this->validateEnvironmentRole($role);
811811
// Match environment IDs by wildcard.
812812
if (strpos($id, '%') !== false) {
813-
$pattern = '/^' . str_replace('%', '.*', preg_quote($id)) . '$/';
813+
$pattern = '/^' . str_replace('%', '.*', preg_quote($id, '/')) . '$/';
814814
$matched = preg_grep($pattern, array_keys($environments));
815815
if (empty($matched)) {
816816
throw new InvalidArgumentException('No environment IDs match: ' . $id);
@@ -856,7 +856,7 @@ private function getSpecifiedEnvironmentTypeRoles(array &$roles)
856856
$role = $this->validateEnvironmentRole($role);
857857
// Match type IDs by wildcard.
858858
if (strpos($id, '%') !== false) {
859-
$pattern = '/^' . str_replace('%', '.*', preg_quote($id)) . '$/';
859+
$pattern = '/^' . str_replace('%', '.*', preg_quote($id, '/')) . '$/';
860860
$matched = preg_grep($pattern, $typeIds);
861861
if (empty($matched)) {
862862
throw new InvalidArgumentException('No environment type IDs match: ' . $id);

src/Util/Wildcard.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Platformsh\Cli\Util;
4+
5+
class Wildcard
6+
{
7+
/**
8+
* Selects strings in a list matching a list of wildcards.
9+
*
10+
* @param string[] $subjects
11+
* @param string[] $wildcards
12+
*
13+
* @return string[]
14+
*/
15+
public static function select(array $subjects, $wildcards)
16+
{
17+
$found = [];
18+
foreach ($wildcards as $wildcard) {
19+
$pattern = '/^' . \str_replace('%', '.*', \preg_quote($wildcard, '/')) . '$/';
20+
$found = \array_merge($found, \preg_grep($pattern, $subjects));
21+
}
22+
return \array_unique($found);
23+
}
24+
}

tests/Util/WildcardTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Platformsh\Cli\Tests\Util;
4+
5+
use Platformsh\Cli\Util\Wildcard;
6+
7+
class WildcardTest extends \PHPUnit_Framework_TestCase
8+
{
9+
public function testSelect()
10+
{
11+
$cases = [
12+
[['a', 'b', 'c'], ['a'], ['a']],
13+
[['foo', 'bar', 'baz'], ['foo'], ['foo']],
14+
[['foo', 'bar', 'baz', 'bazz', 'boz'], ['ba%'], ['bar', 'baz', 'bazz']],
15+
[
16+
['feature/apple', 'feature/pear', 'feature/banana', 'feature/blueberry'],
17+
['feature/banana'],
18+
['feature/banana'],
19+
],
20+
[
21+
['feature/apple', 'feature/pear', 'feature/banana', 'feature/blueberry'],
22+
['f%b%y', 'f%/pear', 'hotfix/%'],
23+
['feature/blueberry', 'feature/pear'],
24+
],
25+
];
26+
foreach ($cases as $i => $case) {
27+
list($subjects, $wildcards, $result) = $case;
28+
$this->assertEquals($result, Wildcard::select($subjects, $wildcards), "Case $i");
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)