Diff #4 - trunk/share/HttpControllers/SvnSync.php
4,528 bytes
|
|
January 20, 2025 at 08:43
|
Diff
Index: SvnSync.php
--- SvnSync.php (nonexistent) +++ SvnSync.php (revision 4) @@ -0,0 +1,140 @@ +<?php +declare(strict_types = 1); + +namespace App\HttpControllers; + +use Apex\Svc{Logger, Convert}; +use Apex\App\Network\Stores\PackagesStore; +use Apex\App\Pkg\Helpers\PackageConfig; +use Nyholm\Psr7\Response; +use Psr\Http\Message{ServerRequestInterface, ResponseInterface}; +use Psr\Http\Server{MiddlewareInterface, RequestHandlerInterface}; +use Apex\Migrations\Handlers\Installer; +use redis; + +/** + * Http Controller - ~alias~ + */ +class SvnSync implements MiddlewareInterface +{ + + #[Inject(Installer::class)] + private Installer $installer; + + #[Inject(PackageConfig::class)] + private PackageConfig $pkg_config; + + #[Inject(Logger::class)] + private ?Logger $logger; + + #[Inject(Convert::class)] + private Convert $convert; + + #[Inject(redis::class)] + private redis $redis; + + #[Inject(PackagesStore::class)] + private PackagesStore $pkg_store; + + /** + * Process request + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $app): ResponseInterface + { + + // Check if enabled + if ($app->config('svn-sync.enabled') != 1) { + $this->logger?->notice("SVN Sync is not enabled, you may enable by running the command 'apex project sync'"); + return new Response(401, [], "SVN Sync feature is not enabled."); + } elseif ($app->config('svn-sync.apikey') != $app->get('apikey')) { + $this->logger?->notice("SVN Sync received an invalid API key. You may regenerate the API key with the command 'apex project sync'"); + return new Response(401, [], "Invalid API key."); + } elseif (!$pkg_alias = $this->redis->hget('config:project', 'pkg_alias')) { + $this->logger?->notice("SVN Sync: No 'pkg_alias' field counf within the 'config:project' hash within redis, hence can not sync."); + return new Response(401, [], "No project checked out on this system."); + } elseif (!$pkg = $this->pkg_store->get($pkg_alias)) { + $this->logger?->notice("SVN Sync: Unable to sync as the package alias '$pkg_alias' is not installed on the local system."); + return new Response(400, [], "Package does not exist on this system, $pkg_alias"); + } + + // Ensure updating trunk branch + if ($app->post('branch') != 'trunk') { + $this->logger?->info("SVN Sync: Received sync request for branch other than /trunk/, hence will not sync."); + return new response(200, [], "Ok"); + } + + // Update + $svn = $pkg->getSvnRepo(); + $svn->setTarget('', 0, true); + if (!$res = $svn->exec(['update'])) { + $this->logger?->error("SVN Sync: Unable to update the local system, error received from SVN: $svn->error_output"); + return new Response(500, [], $svn->error_output); + } + $update_log = explode("\n", $res); + + // Install migrations + $this->installer->migrateAll(); + + // Update package.yml files + $this->updatePackageConfig($update_log); + + // Update composer, if needed + $this->updateComposer($update_log); + + // Return + $this->logger?->info("Completed SVN sync of package $pkg_alias"); + return new response(200, [], "Ok"); + } + + /** + * Update package config + */ + private function updatePackageConfig(array $update_log):void + { + + // Go through log + foreach ($update_log as $line) { + + // Skip, if needed + if (!preg_match("/^(U|A)(\s+?)etc\/(.+?)\/package.yml/", $line, $m)) { + continue; + } + + // Update config + $pkg_alias = $this->convert->case($m[3], 'lower'); + $this->pkg_config->install($pkg_alias); + $this->logger?->info("Svn Sync: Updated package.yml configuration for package $pkg_alias"); + } + + } + + /** + * Update composer + */ + private function updateComposer(array $update_log):void + { + + // Go through update log + $is_updated = false; + foreach ($update_log as $line) { + + // Check if composer.json updated + if (preg_match("/^U(\s+?)composer.json/", $line)) { + $is_updated = true; + break; + } + } + + // Return, if not updated + if ($is_updated !== true) { + return; + } + + // Update composer + shell_exec("composer update -n --working-dir=" . SITE_PATH); + $this->logger?->info("SVN Sync: Updated composer dependencies."); + } + +} + +
Full Code
<?php declare(strict_types = 1);
namespace App\HttpControllers;
use Apex\Svc{Logger, Convert}; use Apex\App\Network\Stores\PackagesStore; use Apex\App\Pkg\Helpers\PackageConfig; use Nyholm\Psr7\Response; use Psr\Http\Message{ServerRequestInterface, ResponseInterface}; use Psr\Http\Server{MiddlewareInterface, RequestHandlerInterface}; use Apex\Migrations\Handlers\Installer; use redis;
/** * Http Controller - ~alias~ */ class SvnSync implements MiddlewareInterface {
#[Inject(Installer::class)]
private Installer $installer;
#[Inject(PackageConfig::class)]
private PackageConfig $pkg_config;
#[Inject(Logger::class)]
private ?Logger $logger;
#[Inject(Convert::class)]
private Convert $convert;
#[Inject(redis::class)]
private redis $redis;
#[Inject(PackagesStore::class)]
private PackagesStore $pkg_store;
/**
* Process request
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $app): ResponseInterface
{
// Check if enabled
if ($app->config('svn-sync.enabled') != 1) {
$this->logger?->notice("SVN Sync is not enabled, you may enable by running the command 'apex project sync'");
return new Response(401, [], "SVN Sync feature is not enabled.");
} elseif ($app->config('svn-sync.apikey') != $app->get('apikey')) {
$this->logger?->notice("SVN Sync received an invalid API key. You may regenerate the API key with the command 'apex project sync'");
return new Response(401, [], "Invalid API key.");
} elseif (!$pkg_alias = $this->redis->hget('config:project', 'pkg_alias')) {
$this->logger?->notice("SVN Sync: No 'pkg_alias' field counf within the 'config:project' hash within redis, hence can not sync.");
return new Response(401, [], "No project checked out on this system.");
} elseif (!$pkg = $this->pkg_store->get($pkg_alias)) {
$this->logger?->notice("SVN Sync: Unable to sync as the package alias '$pkg_alias' is not installed on the local system.");
return new Response(400, [], "Package does not exist on this system, $pkg_alias");
}
// Ensure updating trunk branch
if ($app->post('branch') != 'trunk') {
$this->logger?->info("SVN Sync: Received sync request for branch other than /trunk/, hence will not sync.");
return new response(200, [], "Ok");
}
// Update
$svn = $pkg->getSvnRepo();
$svn->setTarget('', 0, true);
if (!$res = $svn->exec(['update'])) {
$this->logger?->error("SVN Sync: Unable to update the local system, error received from SVN: $svn->error_output");
return new Response(500, [], $svn->error_output);
}
$update_log = explode("\n", $res);
// Install migrations
$this->installer->migrateAll();
// Update package.yml files
$this->updatePackageConfig($update_log);
// Update composer, if needed
$this->updateComposer($update_log);
// Return
$this->logger?->info("Completed SVN sync of package $pkg_alias");
return new response(200, [], "Ok");
}
/**
* Update package config
*/
private function updatePackageConfig(array $update_log):void
{
// Go through log
foreach ($update_log as $line) {
// Skip, if needed
if (!preg_match("/^(U|A)(\s+?)etc\/(.+?)\/package.yml/", $line, $m)) {
continue;
}
// Update config
$pkg_alias = $this->convert->case($m[3], 'lower');
$this->pkg_config->install($pkg_alias);
$this->logger?->info("Svn Sync: Updated package.yml configuration for package $pkg_alias");
}
}
/**
* Update composer
*/
private function updateComposer(array $update_log):void
{
// Go through update log
$is_updated = false;
foreach ($update_log as $line) {
// Check if composer.json updated
if (preg_match("/^U(\s+?)composer.json/", $line)) {
$is_updated = true;
break;
}
}
// Return, if not updated
if ($is_updated !== true) {
return;
}
// Update composer
shell_exec("composer update -n --working-dir=" . SITE_PATH);
$this->logger?->info("SVN Sync: Updated composer dependencies.");
}
}