feat(core): add SourceResolver for backwards-compatible src/ → source/ migration

Introduces SourceResolver utility class with source/ → src/ → htdocs/
fallback chain, replacing hardcoded src/ references across 28 files.
This enables renaming root-level src/ to source/ in all repos while
maintaining backwards compatibility during the transition.

Phase 1: New lib/Enterprise/SourceResolver.php with resolve(),
resolveAbsolute(), globSource(), findUnderSource(), warnIfLegacy()
Phase 2: Updated 19 CLI/deploy tools to use SourceResolver
Phase 3: Updated 7 validator/lib files (McpServerPlugin,
PackageBuilder, RepositorySynchronizer, auto_detect_platform,
check_dolibarr_module, check_client_theme, check_structure)

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan Miller
2026-06-06 08:58:52 -05:00
parent 9526d006c4
commit ca55e5d2d2
28 changed files with 387 additions and 184 deletions
+17 -12
View File
@@ -27,7 +27,8 @@ use MokoEnterprise\{
PluginFactory,
PluginRegistry,
AuditLogger,
MetricsCollector
MetricsCollector,
SourceResolver
};
/**
@@ -228,8 +229,9 @@ class AutoDetectPlatform extends CliFramework
}
}
// Legacy: site structure inside src/
$siteDirs = ['src/administrator', 'src/components', 'src/plugins', 'src/templates', 'src/media'];
// Legacy: site structure inside source/ or src/
$srcName = SourceResolver::resolve($repoPath);
$siteDirs = ["{$srcName}/administrator", "{$srcName}/components", "{$srcName}/plugins", "{$srcName}/templates", "{$srcName}/media"];
$siteDirCount = 0;
foreach ($siteDirs as $dir) {
if (is_dir($repoPath . '/' . $dir)) {
@@ -238,7 +240,7 @@ class AutoDetectPlatform extends CliFramework
}
if ($siteDirCount >= 3) {
$score += 20;
$indicators[] = "Joomla site structure in src/ ({$siteDirCount}/5 dirs)";
$indicators[] = "Joomla site structure in {$srcName}/ ({$siteDirCount}/5 dirs)";
}
// Negative: if there's a Joomla extension manifest (not type="file"), it's an extension
@@ -710,17 +712,19 @@ class AutoDetectPlatform extends CliFramework
}
// Check for MCP server entry point with McpServer usage
if (file_exists("{$repoPath}/src/index.ts")) {
$content = @file_get_contents("{$repoPath}/src/index.ts");
$mcpEntry = SourceResolver::findUnderSource($repoPath, 'index.ts');
if ($mcpEntry !== null) {
$content = @file_get_contents($mcpEntry);
$mcpSrcName = SourceResolver::resolve($repoPath);
if ($content) {
if (strpos($content, 'McpServer') !== false) {
$score += 0.3;
$indicators[] = "Found McpServer import in src/index.ts";
$indicators[] = "Found McpServer import in {$mcpSrcName}/index.ts";
}
if (strpos($content, 'server.tool(') !== false) {
$score += 0.1;
$toolCount = substr_count($content, 'server.tool(');
$indicators[] = "Found {$toolCount} tool registrations in src/index.ts";
$indicators[] = "Found {$toolCount} tool registrations in {$mcpSrcName}/index.ts";
}
if (strpos($content, 'StdioServerTransport') !== false) {
$score += 0.1;
@@ -730,16 +734,17 @@ class AutoDetectPlatform extends CliFramework
}
// Check for the standard 4-file MCP structure
$mcpFiles = ['src/index.ts', 'src/client.ts', 'src/config.ts', 'src/types.ts'];
$mcpRequired = ['index.ts', 'client.ts', 'config.ts', 'types.ts'];
$foundCount = 0;
foreach ($mcpFiles as $file) {
if (file_exists("{$repoPath}/{$file}")) {
foreach ($mcpRequired as $file) {
if (SourceResolver::findUnderSource($repoPath, $file) !== null) {
$foundCount++;
}
}
if ($foundCount === 4) {
$score += 0.1;
$indicators[] = "Found standard MCP 4-file src/ structure";
$mcpSrcName = $mcpSrcName ?? SourceResolver::resolve($repoPath);
$indicators[] = "Found standard MCP 4-file {$mcpSrcName}/ structure";
}
// Check for setup wizard