#!/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/manifest_read.php * VERSION: 09.23.00 * BRIEF: Parse .manifest.xml and output requested field(s) for CI consumption */ declare(strict_types=1); require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; use MokoEnterprise\CliFramework; class ManifestReadCli extends CliFramework { protected function configure(): void { $this->setDescription('Parse manifest.xml and output requested field(s) for CI consumption'); $this->addArgument('--path', 'Repository root path', '.'); $this->addArgument('--field', 'Single field name to output', ''); $this->addArgument('--all', 'Print all fields as KEY=VALUE lines', false); $this->addArgument('--github-output', 'Append all fields to $GITHUB_OUTPUT', false); $this->addArgument('--json', 'Output all fields as JSON', false); } protected function run(): int { $path = $this->getArgument('--path'); $field = $this->getArgument('--field'); $showAll = $this->getArgument('--all'); $ghOutput = $this->getArgument('--github-output'); $jsonMode = $this->getArgument('--json'); // Determine mode if ($ghOutput) { $mode = 'github-output'; } elseif ($showAll) { $mode = 'all'; } elseif ($jsonMode) { $mode = 'json'; } else { $mode = 'field'; } // -- Locate manifest -- $root = realpath($path) ?: $path; $manifestFile = null; // Priority: manifest.xml (current standard) $candidates = [ "{$root}/.mokogitea/manifest.xml", "{$root}/.mokogitea/.manifest.xml", // legacy (dot-prefixed) "{$root}/.mokogitea/.moko-platform", // legacy v4 ]; foreach ($candidates as $candidate) { if (file_exists($candidate)) { $manifestFile = $candidate; break; } } if ($manifestFile === null) { $this->log('ERROR', "No manifest found in {$root}"); return 1; } // -- Parse XML -- $xml = @simplexml_load_file($manifestFile); if ($xml === false) { // Fallback: try YAML format (.mokostandards legacy) $content = file_get_contents($manifestFile); $fields = []; if (preg_match('/^platform:\s*(.+)/m', $content, $m)) { $fields['platform'] = trim($m[1], " \t\n\r\"'"); } if (preg_match('/^standards_version:\s*(.+)/m', $content, $m)) { $fields['standards-version'] = trim($m[1], " \t\n\r\"'"); } if (preg_match('/^governed_repo:\s*(.+)/m', $content, $m)) { $fields['name'] = trim($m[1], " \t\n\r\"'"); } } else { // Register namespace for XPath (optional, simple path works without) $fields = [ 'name' => (string)($xml->identity->name ?? ''), 'display-name' => (string)($xml->identity->{"display-name"} ?? ''), 'org' => (string)($xml->identity->org ?? ''), 'description' => (string)($xml->identity->description ?? ''), 'license' => (string)($xml->identity->license ?? ''), 'license-spdx' => (string)($xml->identity->license['spdx'] ?? ''), 'platform' => (string)($xml->governance->platform ?? ''), 'standards-version' => (string)($xml->governance->{"standards-version"} ?? ''), 'standards-source' => (string)($xml->governance->{"standards-source"} ?? ''), 'language' => (string)($xml->build->language ?? ''), 'package-type' => (string)($xml->build->{"package-type"} ?? ''), 'entry-point' => (string)($xml->build->{"entry-point"} ?? ''), 'version' => (string)($xml->identity->version ?? ''), 'source-dir' => (string)($xml->deploy->{"source-dir"} ?? ''), 'remote-subdir' => (string)($xml->deploy->{"remote-subdir"} ?? ''), 'excludes' => (string)($xml->deploy->excludes ?? ''), 'dev-host' => (string)($xml->deploy->{"dev-host"} ?? ''), 'demo-host' => (string)($xml->deploy->{"demo-host"} ?? ''), 'manifest-file' => $manifestFile, ]; } // Strip empty values for cleaner output $fields = array_filter($fields, fn($v) => $v !== ''); // -- Output -- switch ($mode) { case 'field': if ($field === '') { $this->log('ERROR', "Usage: manifest_read.php --path