Skip to content

Commit

Permalink
pickFiles - Move helpers into class `UpgradeSnapshots'
Browse files Browse the repository at this point in the history
  • Loading branch information
totten committed Jul 21, 2022
1 parent e7e1b70 commit b5dcea5
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 107 deletions.
2 changes: 1 addition & 1 deletion tests/ParseFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function assertEquals($expected, $actual, $message = '') {
function assertFilterExpr($expected, $filterExpr) {
global $assertionCount;
try {
$parsed = parseFilterExpr($filterExpr);
$parsed = UpgradeSnapshots::parseFilterExpr($filterExpr);
}
catch (RuntimeException $e) {
printf("Exception: %s\n", $e->getMessage());
Expand Down
208 changes: 106 additions & 102 deletions util/pickFiles.lib.php
Original file line number Diff line number Diff line change
@@ -1,121 +1,125 @@
<?php
namespace Civi\UpgradeTest;

/**
* @param string $a
* Filter expression that selects range of test examples.
* Ex: '@4.5', '@4.2..4.5', '@4.2..', '@4.5:10'
* Should match this formula:
* '@' [MinVersion '..'] MaxVersion [":" MaxCount]
* @return array
* Array with keys 'minVer', 'maxVer', 'maxCount'.
* Ex: ['minVer' => 4.5, 'maxVer' => NULL, 'maxCount' => 10]
*/
function parseFilterExpr(string $a): array {
// old: (\.\d+)*
$dig = '(\.(?:\d|alpha|beta)+)*';
// $a = preg_replace('/\.(alpha|beta)\d*$/', '.0', $a);
if (preg_match("/^@((\d+$dig)\.\.)?(\d+$dig)?(:(\d+))?$/", $a, $matches)) {
// print_r(['matches'=>$matches]);
return array(
'minVer' => isset($matches[2]) ? $matches[2] : NULL,
'maxVer' => isset($matches[4]) ? $matches[4] : NULL,
'maxCount' => isset($matches[7]) ? $matches[7] : NULL,
);
class UpgradeSnapshots {

/**
* @param string $a
* Filter expression that selects range of test examples.
* Ex: '@4.5', '@4.2..4.5', '@4.2..', '@4.5:10'
* Should match this formula:
* '@' [MinVersion '..'] MaxVersion [":" MaxCount]
* @return array
* Array with keys 'minVer', 'maxVer', 'maxCount'.
* Ex: ['minVer' => 4.5, 'maxVer' => NULL, 'maxCount' => 10]
*/
public static function parseFilterExpr(string $a): array {
// old: (\.\d+)*
$dig = '(\.(?:\d|alpha|beta)+)*';
// $a = preg_replace('/\.(alpha|beta)\d*$/', '.0', $a);
if (preg_match("/^@((\d+$dig)\.\.)?(\d+$dig)?(:(\d+))?$/", $a, $matches)) {
// print_r(['matches'=>$matches]);
return array(
'minVer' => isset($matches[2]) ? $matches[2] : NULL,
'maxVer' => isset($matches[4]) ? $matches[4] : NULL,
'maxCount' => isset($matches[7]) ? $matches[7] : NULL,
);
}
else {
throw new \RuntimeException("Malformed filter expression: $a");
}
}
else {
throw new \RuntimeException("Malformed filter expression: $a");

/**
* @param string[] $files
* @return string[]
* List of files, re-sorted.
*/
public static function sortFilesByVer(array $files): array {
$files = array_unique($files);
usort($files, function($a, $b) {
return version_compare(UpgradeSnapshots::parseFileVer($a), UpgradeSnapshots::parseFileVer($b));
});
return $files;
}
}

/**
* @param string[] $files
* @return string[]
* List of files, re-sorted.
*/
function sortFilesByVer(array $files): array {
$files = array_unique($files);
usort($files, function($a, $b) {
return version_compare(parseFileVer($a), parseFileVer($b));
});
return $files;
}
/**
* Extract the version-part of a filename.
*
* @param string $file
* Ex: '/path/to/4.2.0-setupsh.sql.bz2'.
* @return string
* Ex: '4.2.0'.
*/
public static function parseFileVer(string $file): string {
$name = basename($file);
$parts = explode('-', $name);
return $parts[0];
}

/**
* Extract the version-part of a filename.
*
* @param string $file
* Ex: '/path/to/4.2.0-setupsh.sql.bz2'.
* @return string
* Ex: '4.2.0'.
*/
function parseFileVer(string $file): string {
$name = basename($file);
$parts = explode('-', $name);
return $parts[0];
}
/**
* Extract the "major.minor" from a version expression.
*
* @param string $ver
* Ex: '4.2', '4.2.10'.
* @return string
* Ex: '4.2'
*/
public static function parseMajorMinor(string $ver): string {
[$a, $b] = explode('.', $ver);
return "$a.$b";
}

/**
* Extract the "major.minor" from a version expression.
*
* @param string $ver
* Ex: '4.2', '4.2.10'.
* @return string
* Ex: '4.2'
*/
function parseMajorMinor(string $ver): string {
[$a, $b] = explode('.', $ver);
return "$a.$b";
}
/**
* Pick a subset of elements, including the first element,
* last element, and random in-between. Try to avoid
* picking multiple items in the same series.
*
* @param string[] $files
* @param int $maxCount
* @return string[]
*/
public static function pickSubset($files, $maxCount) {
$files = UpgradeSnapshots::sortFilesByVer($files);

/**
* Pick a subset of elements, including the first element,
* last element, and random in-between. Try to avoid
* picking multiple items in the same series.
*
* @param string[] $files
* @param int $maxCount
* @return string[]
*/
function pickSubset($files, $maxCount) {
$files = sortFilesByVer($files);
if ($maxCount >= count($files)) {
return $files;
}

if ($maxCount >= count($files)) {
return $files;
}
$selections = array();
if ($maxCount > 0) {
$selections[] = array_shift($files);
$maxCount--;
}

$selections = array();
if ($maxCount > 0) {
$selections[] = array_shift($files);
$maxCount--;
}
if ($maxCount > 0) {
$selections[] = array_pop($files);
$maxCount--;
}

if ($maxCount > 0) {
$selections[] = array_pop($files);
$maxCount--;
}
$allMajorMinors = array_unique(array_map(function($s) {
return UpgradeSnapshots::parseMajorMinor(UpgradeSnapshots::parseFileVer($s));
}, $files));
$allowDupeMajorMinor = FALSE;
while ($maxCount > 0) {
$i = rand(0, count($files) - 1);

$allMajorMinors = array_unique(array_map(function($s) {
return parseMajorMinor(parseFileVer($s));
}, $files));
$allowDupeMajorMinor = FALSE;
while ($maxCount > 0) {
$i = rand(0, count($files) - 1);
$selectedMajorMinors = array_unique(array_map(function($s) {
return UpgradeSnapshots::parseMajorMinor(UpgradeSnapshots::parseFileVer($s));
}, $selections));
$hasAllMajorMinor = count(array_diff($allMajorMinors, $selectedMajorMinors)) == 0;
$myMajorMinor = UpgradeSnapshots::parseMajorMinor(UpgradeSnapshots::parseFileVer($files[$i]));
if (!$hasAllMajorMinor && in_array($myMajorMinor, $selectedMajorMinors)) {
continue;
}

$selectedMajorMinors = array_unique(array_map(function($s) {
return parseMajorMinor(parseFileVer($s));
}, $selections));
$hasAllMajorMinor = count(array_diff($allMajorMinors, $selectedMajorMinors)) == 0;
$myMajorMinor = parseMajorMinor(parseFileVer($files[$i]));
if (!$hasAllMajorMinor && in_array($myMajorMinor, $selectedMajorMinors)) {
continue;
$selections[] = $files[$i];
unset($files[$i]);
$files = array_values($files);
$maxCount--;
}

$selections[] = $files[$i];
unset($files[$i]);
$files = array_values($files);
$maxCount--;
return UpgradeSnapshots::sortFilesByVer($selections);
}

return sortFilesByVer($selections);
}
8 changes: 4 additions & 4 deletions util/pickFiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ function main($args) {
$files[] = $arg;
}
elseif ($arg[0] === '@') {
$filters = parseFilterExpr($arg);
$filters = UpgradeSnapshots::parseFilterExpr($arg);

$matches = array_filter($allFiles, function($f) use ($filters) {
$fileVer = parseFileVer($f);
$fileVer = UpgradeSnapshots::parseFileVer($f);
if ($filters['minVer'] && version_compare($fileVer, $filters['minVer'], '<=')) {
return FALSE;
}
Expand All @@ -65,7 +65,7 @@ function main($args) {
});

if ($filters['maxCount'] > 0) {
$matches = pickSubset($matches, $filters['maxCount']);
$matches = UpgradeSnapshots::pickSubset($matches, $filters['maxCount']);
}

$files = array_merge($files, $matches);
Expand All @@ -82,7 +82,7 @@ function main($args) {
}
}

$files = sortFilesByVer(array_unique($files));
$files = UpgradeSnapshots::sortFilesByVer(array_unique($files));
foreach ($files as $file) {
echo "$file\n";
}
Expand Down

0 comments on commit b5dcea5

Please sign in to comment.