From 1bae33a5764455e8bf4d6eabb92d845665e8d7c2 Mon Sep 17 00:00:00 2001 From: daniwe4 Date: Tue, 13 Feb 2024 15:59:59 +0100 Subject: [PATCH] master Import/Export:411 ensure to export current branch, php version, repository name and url --- app/src/App.php | 2 +- app/src/Commands/Pack/ExportCommand.php | 79 +++++++++++++++++-- app/src/Commands/Pack/ImportCommand.php | 8 +- app/src/Lib/Docker/Docker.php | 1 + app/src/Lib/Docker/DockerShell.php | 17 ++++ app/src/Lib/Git/Git.php | 3 + app/src/Lib/Git/GitShell.php | 55 +++++++++++++ app/src/cli.php | 5 +- app/tests/Commands/Pack/ExportCommandTest.php | 23 +++++- setup/updates/update-20240214.sh | 8 ++ 10 files changed, 187 insertions(+), 14 deletions(-) create mode 100644 setup/updates/update-20240214.sh diff --git a/app/src/App.php b/app/src/App.php index f65fbfd1..d338a83f 100644 --- a/app/src/App.php +++ b/app/src/App.php @@ -9,7 +9,7 @@ class App extends Application { - const NAME = "Doil Version 20231116 - build 2023-11-16"; + const NAME = "Doil Version 20240214 - build 2024-02-14"; public function __construct(Command ...$commands) { diff --git a/app/src/Commands/Pack/ExportCommand.php b/app/src/Commands/Pack/ExportCommand.php index ebfb52fc..ca5f4d00 100644 --- a/app/src/Commands/Pack/ExportCommand.php +++ b/app/src/Commands/Pack/ExportCommand.php @@ -6,10 +6,14 @@ use Closure; use RuntimeException; +use CaT\Doil\Lib\Git\Git; use CaT\Doil\Lib\Posix\Posix; use CaT\Doil\Lib\Docker\Docker; +use CaT\Doil\Lib\ProjectConfig; +use CaT\Doil\Commands\Repo\Repo; use CaT\Doil\Lib\ConsoleOutput\Writer; use CaT\Doil\Lib\FileSystem\Filesystem; +use CaT\Doil\Commands\Repo\RepoManager; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; @@ -28,15 +32,28 @@ class ExportCommand extends Command protected Posix $posix; protected Filesystem $filesystem; protected Writer $writer; - - public function __construct(Docker $docker, Posix $posix, Filesystem $filesystem, Writer $writer) - { + protected ProjectConfig $project_config; + protected Git $git; + protected RepoManager $repo_manager; + + public function __construct( + Docker $docker, + Posix $posix, + Filesystem $filesystem, + Writer $writer, + ProjectConfig $project_config, + Git $git, + RepoManager $repo_manager + ) { parent::__construct(); $this->docker = $docker; $this->posix = $posix; $this->filesystem = $filesystem; $this->writer = $writer; + $this->project_config = $project_config; + $this->git = $git; + $this->repo_manager = $repo_manager; } public function configure() : void @@ -75,8 +92,6 @@ public function execute(InputInterface $input, OutputInterface $output) : int return Command::FAILURE; } - $this->writer->beginBlock($output, "Building zip file for " . $instance . "_" . $suffix); - if (! $this->docker->isInstanceUp($path)) { $this->writer->beginBlock($output, "Starting instance $instance"); $this->docker->startContainerByDockerCompose($path); @@ -85,6 +100,10 @@ public function execute(InputInterface $input, OutputInterface $output) : int $this->writer->endBlock(); } + $this->writer->beginBlock($output, "Update project config for " . $instance . "_" . $suffix); + $this->updateProjectConfig($path, $instance . "_" . $suffix); + $this->writer->beginBlock($output, "Building zip file for " . $instance . "_" . $suffix); + $this->writer->beginBlock($output, "Exporting database"); if ($input->getOption("cron")) { @@ -186,4 +205,54 @@ public function hasDockerComposeFile(string $path, OutputInterface $output) : bo return false; } + + protected function updateProjectConfig(string $path, string $instance) : void + { + $project_config = $this->filesystem->readFromJsonFile($path . "/conf/project_config.json"); + $project_config = array_shift($project_config); + + $branch = $this->git->getCurrentBranch($path . "/volumes/ilias"); + + $cmd = "php -v | head -n 1 | cut -d ' ' -f2 | cut -d . -f1,2"; + $php_version = trim($this->docker->executeDockerCommandWithReturn($instance, $cmd)); + + $repos = $this->git->getRemotes($path . "/volumes/ilias"); + + $repo_name = array_key_first($repos); + $repo_url = $repos[$repo_name]; + + if (count($repos) > 1) { + $repos = array_filter($repos, function ($url) use ($branch, $path) { + return $this->git->isBranchInRepo($path . "/volumes/ilias", $url, $branch); + }); + foreach ($repos as $name => $url) { + $repo = new Repo($name, $url); + + if ($this->repo_manager->repoUrlExists($repo)) { + $repo_name = $name; + $repo_url = $url; + break; + } + + $repo = $repo->withIsGlobal(true); + if ($this->repo_manager->repoUrlExists($repo)) { + $repo_name = $name; + $repo_url = $url; + break; + } + + $repo_name = $name; + $repo_url = $url; + } + } + + $project_config = $project_config + ->withRepositoryBranch($branch) + ->withPhpVersion($php_version) + ->withRepositoryName($repo_name) + ->withRepositoryUrl($repo_url) + ; + $this->filesystem->saveToJsonFile($path . "/conf/project_config.json", [$project_config]); + $this->writer->endBlock(); + } } \ No newline at end of file diff --git a/app/src/Commands/Pack/ImportCommand.php b/app/src/Commands/Pack/ImportCommand.php index 7a16ec2a..77b28237 100644 --- a/app/src/Commands/Pack/ImportCommand.php +++ b/app/src/Commands/Pack/ImportCommand.php @@ -67,6 +67,7 @@ public function execute(InputInterface $input, OutputInterface $output) : int $instance = $input->getArgument("instance"); $package = $input->getArgument("package"); $create = false; + $repo_added = false; $check = $this->checkName(); $check($instance); @@ -147,6 +148,7 @@ public function execute(InputInterface $input, OutputInterface $output) : int } $this->repo_manager->addRepo($repo); + $repo_added = true; } $create_command = $this->getApplication()->find('instances:create'); @@ -245,9 +247,6 @@ public function execute(InputInterface $input, OutputInterface $output) : int $this->writer->endBlock(); $this->writer->beginBlock($output, "Setting permissions"); - $this->docker->stopContainerByDockerCompose($path); - $this->docker->startContainerByDockerCompose($path); - sleep(15); $this->docker->applyState($instance . "." . $suffix, "access"); $this->writer->endBlock(); @@ -264,6 +263,9 @@ public function execute(InputInterface $input, OutputInterface $output) : int "-c", "rm /var/ilias/data/ilias.sql" ); + if ($repo_added) { + $this->repo_manager->deleteRepo($repo); + } $this->docker->stopContainerByDockerCompose($path); $this->writer->endBlock(); diff --git a/app/src/Lib/Docker/Docker.php b/app/src/Lib/Docker/Docker.php index c2c340bb..87fc0b5e 100644 --- a/app/src/Lib/Docker/Docker.php +++ b/app/src/Lib/Docker/Docker.php @@ -34,6 +34,7 @@ public function runContainer(string $name) : void; public function stop(string $name) : void; public function removeContainer(string $name) : void; public function executeDockerCommand(string $name, string $cmd) : void; + public function executeDockerCommandWithReturn(string $name, string $cmd) : string; public function setGrain(string $name, string $key, string $value) : void; public function deleteInstances(array $instances) : void; public function pruneNetworks() : void; diff --git a/app/src/Lib/Docker/DockerShell.php b/app/src/Lib/Docker/DockerShell.php index ceb6f45d..753bed16 100644 --- a/app/src/Lib/Docker/DockerShell.php +++ b/app/src/Lib/Docker/DockerShell.php @@ -460,6 +460,23 @@ public function executeDockerCommand(string $name, string $cmd) : void $this->run($cmd, $logger); } + public function executeDockerCommandWithReturn(string $name, string $cmd) : string + { + $cmd = [ + "docker", + "exec", + "-i", + $name, + "bash", + "-c", + $cmd + ]; + + $logger = $this->logger->getDoilLogger($name); + $logger->info("Execute docker command", $cmd); + return $this->run($cmd, $logger); + } + public function setGrain(string $name, string $key, string $value) : void { $cmd = [ diff --git a/app/src/Lib/Git/Git.php b/app/src/Lib/Git/Git.php index 27dbe127..1402491b 100644 --- a/app/src/Lib/Git/Git.php +++ b/app/src/Lib/Git/Git.php @@ -7,8 +7,11 @@ interface Git { public function getBranches(string $path) : array; + public function getCurrentBranch(string $path) : string; public function fetchBare(string $path) : void; public function cloneBare(string $url, string $path) : void; public function setLocalConfig(string $path, ...$commands) : void; public function checkoutRemote(string $path, string $branch) : void; + public function getRemotes(string $path) : array; + public function isBranchInRepo(string $path, string $url, string $branch) : bool; } \ No newline at end of file diff --git a/app/src/Lib/Git/GitShell.php b/app/src/Lib/Git/GitShell.php index b812d62b..74a65be4 100644 --- a/app/src/Lib/Git/GitShell.php +++ b/app/src/Lib/Git/GitShell.php @@ -33,6 +33,19 @@ public function getBranches(string $path) : array return array_filter(explode("\n", $this->run($cmd, $this->logger))); } + public function getCurrentBranch(string $path) : string + { + $cmd = [ + "git", + "-C", + $path, + "rev-parse", + "--abbrev-ref", + "HEAD" + ]; + return trim($this->run($cmd, $this->logger)); + } + public function fetchBare(string $path) : void { $cmd = [ @@ -90,4 +103,46 @@ public function checkoutRemote(string $path, string $branch) : void $this->logger->info("Check out remote branch '$branch' for path '$path'"); $this->run($cmd, $this->logger); } + + public function getRemotes(string $path) : array + { + $cmd = [ + "git", + "-C", + $path, + "remote", + "-v" + ]; + + $this->logger->info("Get remote repos for $path"); + $result = $this->run($cmd, $this->logger); + $result = explode("\n", $result); + array_pop($result); + + foreach ($result as $r) { + $r = preg_split('/\s+/', $r); + $arr[$r[0]] = $r[1]; + } + + return $arr; + } + + public function isBranchInRepo(string $path, string $url, string $branch) : bool + { + $cmd = [ + "git", + "ls-remote", + "--heads", + $url, + "refs/heads/$branch" + ]; + + $this->logger->info("Get remote repos for $path"); + $result = $this->run($cmd, $this->logger); + + if ($result == "") { + return false; + } + return true; + } } \ No newline at end of file diff --git a/app/src/cli.php b/app/src/cli.php index cc0abad8..1076a145 100644 --- a/app/src/cli.php +++ b/app/src/cli.php @@ -270,7 +270,10 @@ function buildContainerForApp() : Container $c["docker.shell"], $c["posix.shell"], $c["filesystem.shell"], - $c["command.writer"] + $c["command.writer"], + $c["project.config"], + $c["git.shell"], + $c["repo.manager"] ); }; diff --git a/app/tests/Commands/Pack/ExportCommandTest.php b/app/tests/Commands/Pack/ExportCommandTest.php index b037b2ea..c9d86422 100644 --- a/app/tests/Commands/Pack/ExportCommandTest.php +++ b/app/tests/Commands/Pack/ExportCommandTest.php @@ -3,10 +3,13 @@ namespace CaT\Doil\Commands\Pack; use RuntimeException; +use CaT\Doil\Lib\Git\Git; use CaT\Doil\Lib\Posix\Posix; use PHPUnit\Framework\TestCase; use CaT\Doil\Lib\Docker\Docker; +use CaT\Doil\Lib\ProjectConfig; use CaT\Doil\Lib\FileSystem\Filesystem; +use CaT\Doil\Commands\Repo\RepoManager; use CaT\Doil\Lib\ConsoleOutput\CommandWriter; use Symfony\Component\Console\Tester\CommandTester; @@ -17,9 +20,12 @@ public function test_execute_without_instance_param() : void $docker = $this->createMock(Docker::class); $posix = $this->createMock(Posix::class); $filesystem = $this->createMock(Filesystem::class); + $project_config = $this->createMock(ProjectConfig::class); + $git = $this->createMock(Git::class); + $repo_manager = $this->createMock(RepoManager::class); $writer = new CommandWriter(); - $command = new ExportCommand($docker, $posix, $filesystem, $writer); + $command = new ExportCommand($docker, $posix, $filesystem, $writer, $project_config, $git, $repo_manager); $tester = new CommandTester($command); $this->expectException(RuntimeException::class); @@ -32,9 +38,12 @@ public function test_execute_with_empty_instance_param() : void $docker = $this->createMock(Docker::class); $posix = $this->createMock(Posix::class); $filesystem = $this->createMock(Filesystem::class); + $project_config = $this->createMock(ProjectConfig::class); + $git = $this->createMock(Git::class); + $repo_manager = $this->createMock(RepoManager::class); $writer = new CommandWriter(); - $command = new ExportCommand($docker, $posix, $filesystem, $writer); + $command = new ExportCommand($docker, $posix, $filesystem, $writer, $project_config, $git, $repo_manager); $tester = new CommandTester($command); $this->expectException(RuntimeException::class); @@ -47,9 +56,12 @@ public function test_execute_with_wrong_chars_in_instance_param() : void $docker = $this->createMock(Docker::class); $posix = $this->createMock(Posix::class); $filesystem = $this->createMock(Filesystem::class); + $project_config = $this->createMock(ProjectConfig::class); + $git = $this->createMock(Git::class); + $repo_manager = $this->createMock(RepoManager::class); $writer = new CommandWriter(); - $command = new ExportCommand($docker, $posix, $filesystem, $writer); + $command = new ExportCommand($docker, $posix, $filesystem, $writer, $project_config, $git, $repo_manager); $tester = new CommandTester($command); $this->expectException(RuntimeException::class); @@ -62,9 +74,12 @@ public function test_execute_with_no_docker_compose_file() : void $docker = $this->createMock(Docker::class); $posix = $this->createMock(Posix::class); $filesystem = $this->createMock(Filesystem::class); + $project_config = $this->createMock(ProjectConfig::class); + $git = $this->createMock(Git::class); + $repo_manager = $this->createMock(RepoManager::class); $writer = new CommandWriter(); - $command = new ExportCommand($docker, $posix, $filesystem, $writer); + $command = new ExportCommand($docker, $posix, $filesystem, $writer, $project_config, $git, $repo_manager); $tester = new CommandTester($command); $posix diff --git a/setup/updates/update-20240214.sh b/setup/updates/update-20240214.sh new file mode 100644 index 00000000..2eeae62e --- /dev/null +++ b/setup/updates/update-20240214.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +source ${SCRIPT_DIR}/updates/update.sh + +doil_update_20240214() { + update + return $? +}