#!/usr/bin/env php * * SPDX-License-Identifier: GPL-3.0-or-later * * FILE INFORMATION * DEFGROUP: moko-platform.CLI * INGROUP: moko-platform * REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform * PATH: /cli/version_read.php * BRIEF: Read version — manifest.xml is canonical, falls back to README.md and Joomla XML */ declare(strict_types=1); $path = '.'; foreach ($argv as $i => $arg) { if ($arg === '--path' && isset($argv[$i + 1])) { $path = $argv[$i + 1]; } } $root = realpath($path) ?: $path; // -- 1. Read from .mokogitea/manifest.xml (canonical source) -- $mokoVersion = null; $mokoManifest = "{$root}/.mokogitea/manifest.xml"; if (file_exists($mokoManifest)) { $xml = @simplexml_load_file($mokoManifest); if ($xml !== false) { $v = (string)($xml->identity->version ?? ''); if (preg_match('/^\d{2}\.\d{2}\.\d{2}$/', $v)) { $mokoVersion = $v; } } } // If manifest.xml has a version, that is authoritative if ($mokoVersion !== null) { echo $mokoVersion . "\n"; exit(0); } // -- 2. Fallback: README.md -- $readmeVersion = null; $readme = "{$root}/README.md"; if (file_exists($readme)) { $content = file_get_contents($readme); if (preg_match('/VERSION:\s*(\d{2}\.\d{2}\.\d{2})/m', $content, $m)) { $readmeVersion = $m[1]; } } // -- 3. Fallback: Joomla manifest XML -- $manifestVersion = null; $manifestVersionSuffix = ''; $manifestFiles = array_merge( glob("{$root}/src/pkg_*.xml") ?: [], glob("{$root}/src/*.xml") ?: [], glob("{$root}/src/packages/*/*.xml") ?: [], glob("{$root}/*.xml") ?: [] ); foreach ($manifestFiles as $xmlFile) { $xmlContent = file_get_contents($xmlFile); if (strpos($xmlContent, '') === false) { continue; } if (preg_match('|(\d{2}\.\d{2}\.\d{2})(-[a-z]+)?|', $xmlContent, $xm)) { $candidate = $xm[1]; $candidateSuffix = isset($xm[2]) ? $xm[2] : ''; if ($manifestVersion === null || version_compare($candidate, $manifestVersion, '>')) { $manifestVersion = $candidate; $manifestVersionSuffix = $candidateSuffix; } } } // -- 4. Fallback: package.json (Node.js / MCP) -- $packageJsonVersion = null; $packageJsonFile = "{$root}/package.json"; if (file_exists($packageJsonFile)) { $pkgData = json_decode(file_get_contents($packageJsonFile), true); if (isset($pkgData['version']) && preg_match('/^\d{2}\.\d{2}\.\d{2}$/', $pkgData['version'])) { $packageJsonVersion = $pkgData['version']; } } // -- 5. Fallback: pyproject.toml (Python) -- $pyprojectVersion = null; $pyprojectFile = "{$root}/pyproject.toml"; if (file_exists($pyprojectFile)) { $pyContent = file_get_contents($pyprojectFile); if (preg_match('/^version\s*=\s*"(\d{2}\.\d{2}\.\d{2})"/m', $pyContent, $pm)) { $pyprojectVersion = $pm[1]; } } // -- Output the higher version -- $candidates = array_filter([ $readmeVersion, $manifestVersion, $packageJsonVersion, $pyprojectVersion, ]); $version = null; $versionSource = ''; foreach ($candidates as $candidate) { if ($version === null || version_compare($candidate, $version, '>')) { $version = $candidate; $versionSource = ($candidate === $manifestVersion) ? 'manifest' : 'other'; } } if ($version === null) { fwrite(STDERR, "No version found in manifest.xml, README.md, Joomla XML, package.json, or pyproject.toml\n"); exit(1); } // Append suffix if the version came from a Joomla manifest with a suffix if ($versionSource === 'manifest' && !empty($manifestVersionSuffix)) { $version .= $manifestVersionSuffix; } // -- Backfill: if manifest.xml exists but lacks , insert it -- if (file_exists($mokoManifest)) { $content = file_get_contents($mokoManifest); if (!preg_match('|\d{2}\.\d{2}\.\d{2}|', $content)) { if (strpos($content, '{$version}\$1", $content, 1 ); } elseif (strpos($content, '') !== false) { $content = preg_replace( '|()|', " {$version}\n \$1", $content, 1 ); } file_put_contents($mokoManifest, $content); fwrite(STDERR, "Backfilled manifest.xml with version {$version}\n"); } } echo $version . "\n"; exit(0);