From e8a68f15d11caf04deed999f88a483c68d24e36a Mon Sep 17 00:00:00 2001 From: Nick Liu Date: Sat, 29 Feb 2020 18:18:57 +0100 Subject: [PATCH] Reimplemented core_image.php deprecated checksums Format is different and currently incompatible. The checksum has been replaced with an associated array where the keys are the e107 version and the values are the checksum from that e107 version. --- .../{coreImage.php => CoreImage.php} | 114 +++++++++++++++--- .github/workflows/build-release/OsHelper.php | 87 +++++++++++++ .github/workflows/build-release/e107_make.php | 70 +++-------- 3 files changed, 199 insertions(+), 72 deletions(-) rename .github/workflows/build-release/{coreImage.php => CoreImage.php} (58%) create mode 100644 .github/workflows/build-release/OsHelper.php diff --git a/.github/workflows/build-release/coreImage.php b/.github/workflows/build-release/CoreImage.php similarity index 58% rename from .github/workflows/build-release/coreImage.php rename to .github/workflows/build-release/CoreImage.php index 4cddeb532..4e483e13f 100644 --- a/.github/workflows/build-release/coreImage.php +++ b/.github/workflows/build-release/CoreImage.php @@ -8,17 +8,16 @@ * */ -class coreImage +require_once("OsHelper.php"); + +class CoreImage { + protected $coredir = []; + public function __construct($_current, $_deprecated, $_image) { - global $coredir; set_time_limit(240); - define("IMAGE_CURRENT", $_current); - define("IMAGE_DEPRECATED", $_deprecated); - define("IMAGE_IMAGE", $_image); - $maindirs = array( 'admin' => 'e107_admin/', 'files' => 'e107_files/', @@ -33,18 +32,16 @@ class coreImage foreach ($maindirs as $maindirs_key => $maindirs_value) { - $coredir[$maindirs_key] = substr($maindirs_value, 0, -1); + $this->coredir[$maindirs_key] = substr($maindirs_value, 0, -1); } - $this->create_image(IMAGE_CURRENT, IMAGE_DEPRECATED); + $this->create_image($_current, $_deprecated, $_image); } - function create_image($_curdir, $_depdir) + function create_image($_curdir, $_depdir, $_image) { - global $coredir; - $search = $replace = []; - foreach ($coredir as $trim_key => $trim_dirs) + foreach ($this->coredir as $trim_key => $trim_dirs) { $search[$trim_key] = "'" . $trim_dirs . "'"; $replace[$trim_key] = "\$coredir['" . $trim_key . "']"; @@ -78,17 +75,17 @@ class coreImage $image_array = str_replace($search, $replace, $image_array); $data .= "\$core_image = " . $image_array . ";\n\n"; - $scan_deprecated = $this->scan($_depdir, $scan_current); + $scan_deprecated = $this->generateRemovedChecksums(); $image_array = var_export($scan_deprecated, true); $image_array = str_replace($search, $replace, $image_array); $data .= "\$deprecated_image = " . $image_array . ";\n\n"; $data .= "?>"; - $fp = fopen(IMAGE_IMAGE, 'w'); + $fp = fopen($_image, 'w'); fwrite($fp, $data); } - function scan($dir, $image = array()) + protected function scan($dir) { $absoluteBase = realpath($dir); if (!is_dir($absoluteBase)) return false; @@ -108,7 +105,7 @@ class coreImage if (empty($relativePath) || $relativePath == $absolutePath) continue; - self::array_set($files, $relativePath, $this->checksum($absolutePath)); + self::array_set($files, $relativePath, $this->checksumPath($absolutePath)); } ksort($files); @@ -159,8 +156,89 @@ class coreImage return $array; } - function checksum($filename) + protected function checksumPath($filename) { - return md5(str_replace(array(chr(13), chr(10)), '', file_get_contents($filename))); + return $this->checksum(file_get_contents($filename)); + } + + protected function checksum($body) + { + return md5(str_replace(array(chr(13), chr(10)), '', $body)); + } + + protected function generateRemovedChecksums() + { + $checksums = []; + + $stdout = ''; + OsHelper::runValidated('git tag --list ' . escapeshellarg("v*"), $stdout); + $tags = explode("\n", trim($stdout)); + $versions = []; + foreach ($tags as $tag) + { + $versions[] = preg_replace("/^v/", "", $tag); + } + $tags = array_combine($tags, $versions); + unset($versions); + uasort($tags, function ($a, $b) + { + return -version_compare($a, $b); + }); + $tags = array_filter($tags, function ($version) + { + return !preg_match("/[a-z]/i", $version); + }); + + foreach ($tags as $tag => $version) + { + OsHelper::runValidated( + 'git --no-pager diff --name-only --diff-filter D ' . escapeshellarg($tag), + $stdout + ); + $removedFiles = explode("\n", trim($stdout)); + foreach ($removedFiles as $removedFilePath) + { + OsHelper::runValidated( + 'git --no-pager show ' . escapeshellarg($tag . ":" . $removedFilePath), + $stdout + ); + $checksum = $this->checksum($stdout); + $item = self::array_get($checksums, $removedFilePath, []); + if (!in_array($checksum, $item)) $item["v{$version}"] = $checksum; + self::array_set($checksums, $removedFilePath, $item); + } + } + return $checksums; + } + + /** + * Get an item from an array using "slash" notation. + * + * Based on Illuminate\Support\Arr::get() + * + * @param array $array + * @param string $key + * @param mixed $default + * @return mixed + * @copyright Copyright (c) Taylor Otwell + * @license https://github.com/illuminate/support/blob/master/LICENSE.md MIT License + */ + private static function array_get($array, $key, $default = null) + { + if (is_null($key)) return $array; + + if (isset($array[$key])) return $array[$key]; + + foreach (explode('/', $key) as $segment) + { + if (!is_array($array) || !array_key_exists($segment, $array)) + { + return $default; + } + + $array = $array[$segment]; + } + + return $array; } } \ No newline at end of file diff --git a/.github/workflows/build-release/OsHelper.php b/.github/workflows/build-release/OsHelper.php new file mode 100644 index 000000000..46318c35a --- /dev/null +++ b/.github/workflows/build-release/OsHelper.php @@ -0,0 +1,87 @@ + ['pipe', 'w'], + 2 => ['pipe', 'w'], + ]; + $pipes = []; + $resource = proc_open($command, $descriptorspec, $pipes); + $stdout .= stream_get_contents($pipes[1]); + $stderr .= stream_get_contents($pipes[2]); + foreach ($pipes as $pipe) + { + fclose($pipe); + } + return proc_close($resource); + } + + public static function runValidated($command, &$stdout = "", &$stderr = "") + { + $rc = OsHelper::run($command, $stdout, $stderr); + if ($rc != 0) + { + throw new RuntimeException( + "Error while running command (rc=$rc): " . $command . PHP_EOL . + "========== STDOUT ==========" . PHP_EOL . + $stdout . PHP_EOL . + "========== STDERR ==========" . PHP_EOL . + $stderr . PHP_EOL + ); + } + return $rc; + } + + public static function gitVersionToPhpVersion($gitVersion, $verFileVersion = "0") + { + $verFileVersion = array_shift(explode(" ", $verFileVersion)); + $version = preg_replace("/^v/", "", $gitVersion); + $versionSplit = explode("-", $version); + if (count($versionSplit) > 1) + { + if (version_compare($verFileVersion, $versionSplit[0], '>')) $versionSplit[0] = $verFileVersion; + $versionSplit[0] .= "dev"; + } + return implode("-", $versionSplit); + } + + public static function getVerFileVersion($verFilePath) + { + $verFileTokens = token_get_all(file_get_contents($verFilePath)); + $nextConstantEncapsedStringIsVersion = false; + foreach ($verFileTokens as $verFileToken) + { + if (!isset($verFileToken[1])) continue; + $token = $verFileToken[0]; + $value = trim($verFileToken[1], "'\""); + + if ($token === T_CONSTANT_ENCAPSED_STRING) + { + if ($nextConstantEncapsedStringIsVersion) + { + return $value; + } + if ($value === 'e107_version') $nextConstantEncapsedStringIsVersion = true; + } + } + return '0'; + } +} \ No newline at end of file diff --git a/.github/workflows/build-release/e107_make.php b/.github/workflows/build-release/e107_make.php index b47c08a72..bbd4ebc9b 100644 --- a/.github/workflows/build-release/e107_make.php +++ b/.github/workflows/build-release/e107_make.php @@ -8,7 +8,8 @@ * */ -require_once("coreImage.php"); +require_once("OsHelper.php"); +require_once("CoreImage.php"); $builder = new e107Build(); $builder->makeBuild(); @@ -162,14 +163,14 @@ class e107Build { $this->status("Cleaning up old target directory ($dir)"); $cmd = "rm -rf " . escapeshellarg($dir); - $this->runValidated($cmd); + OsHelper::runValidated($cmd); $this->changeDir($this->config['baseDir']); } else { $this->status("Creating new target directory ($dir)"); $cmd = "mkdir -pv " . escapeshellarg($dir); - $this->runValidated($cmd); + OsHelper::runValidated($cmd); } if (file_exists($dir . '/temp')) @@ -178,10 +179,10 @@ class e107Build } $cmd = "mkdir -pv " . escapeshellarg($dir . "/temp"); - $this->runValidated($cmd); + OsHelper::runValidated($cmd); $cmd = "mkdir -pv " . escapeshellarg($dir . "/release"); - $this->runValidated($cmd); + OsHelper::runValidated($cmd); $releaseDir = "e107_" . $this->version; @@ -189,27 +190,11 @@ class e107Build $this->status("Creating new release directory ($releaseDir)", true); $cmd = "mkdir -pv " . escapeshellarg($dir . "/release/" . $releaseDir); - $this->runValidated($cmd); + OsHelper::runValidated($cmd); return true; } - protected function runValidated($command, &$stdout = "", &$stderr = "") - { - $rc = $this->run($command, $stdout, $stderr); - if ($rc != 0) - { - throw new RuntimeException( - "Error while running command (rc=$rc): " . $command . PHP_EOL . - "========== STDOUT ==========" . PHP_EOL . - $stdout . PHP_EOL . - "========== STDERR ==========" . PHP_EOL . - $stderr . PHP_EOL - ); - } - return $rc; - } - /* private function targetClone() { @@ -243,29 +228,6 @@ class e107Build } */ - /** - * @param string $command The command to run - * @param string $stdout Reference to the STDOUT output as a string - * @param string $stderr Reference to the STDERR output as a string - * @return int Return code of the command that was run - */ - protected function run($command, &$stdout = "", &$stderr = "") - { - $descriptorspec = [ - 1 => ['pipe', 'w'], - 2 => ['pipe', 'w'], - ]; - $pipes = []; - $resource = proc_open($command, $descriptorspec, $pipes); - $stdout .= stream_get_contents($pipes[1]); - $stderr .= stream_get_contents($pipes[2]); - foreach ($pipes as $pipe) - { - fclose($pipe); - } - return proc_close($resource); - } - private function changeDir($dir) { $this->status("Changing to dir: " . $dir); @@ -367,14 +329,14 @@ class e107Build $this->status('Creating ZIP archive'); $this->status($zipcmd); - $this->runValidated($zipcmd); + OsHelper::runValidated($zipcmd); $this->status('Creating TAR archive'); $this->status($tarcmd); - $this->runValidated($tarcmd); + OsHelper::runValidated($tarcmd); $this->status('Creating TAR.GZ archive'); - $this->runValidated("(cat $tarfile | gzip -9 > $tarfile.gz)"); + OsHelper::runValidated("(cat $tarfile | gzip -9 > $tarfile.gz)"); // $this->status('Creating TAR.XZ archive'); // $this->runValidated(cat $tarfile | xz -9e > $tarfile.xz)"); @@ -409,7 +371,7 @@ class e107Build $cmd = "rm -rf " . escapeshellarg($dir); $this->status($cmd); - $this->runValidated($cmd); + OsHelper::runValidated($cmd); return true; } @@ -431,7 +393,7 @@ class e107Build $this->changeDir($this->gitDir); - $this->runValidated($cmd); + OsHelper::runValidated($cmd); } private function gitArchiveUnzip($file) @@ -440,8 +402,8 @@ class e107Build $filepath = $this->tempDir . $file; $cmd = 'unzip -q -o ' . escapeshellarg($filepath) . ' -d ' . escapeshellarg($this->exportDir); - $this->runValidated($cmd); - $this->runValidated('chmod -R a=,u+rwX,go+rX ' . escapeshellarg($this->exportDir)); + OsHelper::runValidated($cmd); + OsHelper::runValidated('chmod -R a=,u+rwX,go+rX ' . escapeshellarg($this->exportDir)); } private function editVersion($dir = 'export') @@ -558,7 +520,7 @@ class e107Build $_image = $this->tempDir . "core_image.php"; $this->status("Creating new core_image.php file ({$_image})", true); - new coreImage($_current, $_deprecated, $_image); + new CoreImage($_current, $_deprecated, $_image); $dir = "{$this->config['baseDir']}/target/{$this->config['main']['name']}/export"; $this->changeDir($dir); @@ -575,7 +537,7 @@ class e107Build } $this->status("Copying Core Image into export directory", true); - $this->runValidated("cp -rf " . escapeshellarg($orig) . " " . escapeshellarg($dest)); + OsHelper::runValidated("cp -rf " . escapeshellarg($orig) . " " . escapeshellarg($dest)); if (!file_exists($dest)) {