From 2e5bdf5b9194c34cd7196339e2a87f564dbc4803 Mon Sep 17 00:00:00 2001 From: nicolaschautard Date: Fri, 2 Oct 2020 09:21:41 +0200 Subject: [PATCH] #12 : Add Set & Unset commands + changed PHP requirements + small cs fixer --- README.md | 5 + bin/kloud | 12 +- src/Domain/Environment/DTO/Context.php | 16 +- src/Domain/Environment/DTO/Deployment.php | 4 +- .../DTO/DirectValueEnvironmentVariable.php | 9 +- .../Environment/DTO/EnvironmentVariable.php | 4 +- .../DTO/EnvironmentVariableInterface.php | 4 +- src/Domain/Environment/DTO/Expression.php | 4 +- .../Environment/DTO/ExpressionParser.php | 6 +- .../DTO/SecretValueEnvironmentVariable.php | 9 +- src/Domain/Environment/DTO/Server.php | 4 +- .../ValuedEnvironmentVariableInterface.php | 10 +- src/Domain/Environment/DTO/Variable.php | 4 +- .../Environment/Variable/SetCommand.php | 170 ++++++++++++++++++ .../Environment/Variable/UnsetCommand.php | 107 +++++++++++ 15 files changed, 353 insertions(+), 15 deletions(-) create mode 100644 src/Platform/Console/Command/Environment/Variable/SetCommand.php create mode 100644 src/Platform/Console/Command/Environment/Variable/UnsetCommand.php diff --git a/README.md b/README.md index c4deee8..72d6c4f 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This project aims at building your Docker stack for [OroCommerce](https://oroinc > ⚠️ Nota: Those stacks are not suited for production hosting, but to provide an environment based on Docker as identical as possible to OroCloud on a personal computer. +* [Requirements](#requirements) * [Installation](#installation) * [Usage](#usage) * [Frequently Asked Questions](#frequently-asked-questions) @@ -15,6 +16,10 @@ This project aims at building your Docker stack for [OroCommerce](https://oroinc * [Marello](#marello) * [Middleware](#middleware) +- Requirements: +--- +- PHP 7.4 + Installation --- diff --git a/bin/kloud b/bin/kloud index b47f987..c760b98 100755 --- a/bin/kloud +++ b/bin/kloud @@ -1,8 +1,8 @@ #!/usr/bin/env php addCommands([ (new Command\Environment\Variable\GetCommand( Command\Environment\Variable\GetCommand::$defaultName, )), + + (new Command\Environment\Variable\SetCommand( + Command\Environment\Variable\SetCommand::$defaultName, + )), + + (new Command\Environment\Variable\UnsetCommand( + Command\Environment\Variable\UnsetCommand::$defaultName, + )), ]); $app->run(new ArgvInput($argv), new ConsoleOutput()); diff --git a/src/Domain/Environment/DTO/Context.php b/src/Domain/Environment/DTO/Context.php index 282961a..5ff19b2 100644 --- a/src/Domain/Environment/DTO/Context.php +++ b/src/Domain/Environment/DTO/Context.php @@ -39,6 +39,20 @@ public function getVariable(string $variableName): EnvironmentVariableInterface throw new VariableNotFoundException(strtr('The variable %name% does not exist.', ['%name%' => $variableName])); } + public function setVariable(EnvironmentVariableInterface $newVariable) + { + $i = 0; + foreach ($this->environmentVariables as $variable) { + if ((string) $newVariable->getVariable() !== (string) $variable->getVariable()) { + ++$i; + continue; + } + $this->environmentVariables[$i] = $newVariable; + + return; + } + } + public function denormalize(DenormalizerInterface $denormalizer, $data, string $format = null, array $context = []) { $this->deployment = $denormalizer->denormalize($data['deployment'], Deployment::class, $format, $context); @@ -49,7 +63,7 @@ public function denormalize(DenormalizerInterface $denormalizer, $data, string $ if (isset($variable['value'])) { $this->environmentVariables[] = new DirectValueEnvironmentVariable( new Variable($variable['name']), - $parser->parse($variable['value']) + $variable['value'] ); } elseif (isset($variable['secret'])) { $this->environmentVariables[] = new SecretValueEnvironmentVariable( diff --git a/src/Domain/Environment/DTO/Deployment.php b/src/Domain/Environment/DTO/Deployment.php index f626ff2..ff3c42c 100644 --- a/src/Domain/Environment/DTO/Deployment.php +++ b/src/Domain/Environment/DTO/Deployment.php @@ -1,4 +1,6 @@ -value; } + + public function setValue(string $value) + { + $this->value = $value; + } } diff --git a/src/Domain/Environment/DTO/EnvironmentVariable.php b/src/Domain/Environment/DTO/EnvironmentVariable.php index 323966c..bbe038c 100644 --- a/src/Domain/Environment/DTO/EnvironmentVariable.php +++ b/src/Domain/Environment/DTO/EnvironmentVariable.php @@ -1,4 +1,6 @@ -secret; } + + public function setSecret(string $secret) + { + $this->secret = $secret; + } } diff --git a/src/Domain/Environment/DTO/Server.php b/src/Domain/Environment/DTO/Server.php index 874428f..c63f8c8 100644 --- a/src/Domain/Environment/DTO/Server.php +++ b/src/Domain/Environment/DTO/Server.php @@ -1,4 +1,6 @@ -wizard = new EnvironmentWizard(); + parent::__construct($name); + } + + protected function configure() + { + $this->setDescription('Prints an environment variable'); + + $this->wizard->configureConsoleCommand($this); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $workingDirectory = $input->getOption('working-directory') ?: getcwd(); + + $finder = (new Finder()) + ->files() + ->ignoreDotFiles(false) + ->in($workingDirectory); + + $format = new SymfonyStyle($input, $output); + + $serializer = new Serializer( + [ + new CustomNormalizer(), + new PropertyNormalizer(), + ], + [ + new YamlEncoder(), + ] + ); + + if ($finder->hasResults()) { + /** @var SplFileInfo $file */ + foreach ($finder->name('/^\.?kloud.environment.ya?ml$/') as $file) { + try { + /** @var Context $context */ + $context = $serializer->deserialize($file->getContents(), Context::class, 'yaml'); + } catch (\Throwable $exception) { + $format->error($exception->getMessage()); + continue; + } + + break; + } + } + + if (!isset($context)) { + $format->error('No .kloud.environment.yaml file found in your directory. You must initialize it using environment:init command'); + + return 1; + } + + $variableName = $format->askQuestion(new Question('Please enter a variable name')); + + try { + /** @var EnvironmentVariableInterface $variable */ + $variable = $context->getVariable($variableName); + } catch (VariableNotFoundException $exception) { + $format->error($exception->getMessage()); + + return 1; + } + + $format->table( + ['Variable', 'Value'], + [ + [ + $variableName, + $variable instanceof ValuedEnvironmentVariableInterface ? + $variable->getValue() : + ($variable instanceof SecretValueEnvironmentVariable ? + sprintf('SECRET: %s', $variable->getSecret()) : + null), + ], + ] + ); + + // If value is empty, $variable becomes/stay an EnvironmentVariable without any value. + if (!$value = $this->verifyValue($context, $format, $variable)) { + $this->sendResponse($context, $format, $serializer, $workingDirectory); + + return 0; + } + + $isSecret = $format->askQuestion(new ConfirmationQuestion('Is this a secret variable ?', false)); + + // Test $variable type and potentially change it according to the answer + if ($variable instanceof ValuedEnvironmentVariableInterface) { + if ($isSecret) { + $context->setVariable(new SecretValueEnvironmentVariable($variable->getVariable(), $value)); + } else { + $variable->setValue($value); + } + } + if ($variable instanceof SecretValueEnvironmentVariable) { + if ($isSecret) { + $variable->setSecret($value); + } else { + $context->setVariable(new DirectValueEnvironmentVariable($variable->getVariable(), $value)); + } + } + if ($variable instanceof EnvironmentVariable) { + if ($isSecret) { + $context->setVariable(new SecretValueEnvironmentVariable($variable->getVariable(), $value)); + } else { + $context->setVariable(new DirectValueEnvironmentVariable($variable->getVariable(), $value)); + } + } + $this->sendResponse($context, $format, $serializer, $workingDirectory); + + return 0; + } + + private function sendResponse(Context $context, SymfonyStyle $format, Serializer $serializer, string $workingDirectory): void + { + $format->success('Variable was successfully changed'); + file_put_contents($workingDirectory.'/.kloud.environment.yaml', $serializer->serialize($context, 'yaml', [ + 'yaml_inline' => 4, + 'yaml_indent' => 0, + 'yaml_flags' => 0, + ])); + } + + private function verifyValue(Context $context, SymfonyStyle $format, EnvironmentVariableInterface $variable): ?string + { + if (!$value = $format->askQuestion(new Question('Please provide the new value'))) { + $context->setVariable(new EnvironmentVariable($variable->getVariable())); + + return null; + } + + return $value; + } +} diff --git a/src/Platform/Console/Command/Environment/Variable/UnsetCommand.php b/src/Platform/Console/Command/Environment/Variable/UnsetCommand.php new file mode 100644 index 0000000..68bda77 --- /dev/null +++ b/src/Platform/Console/Command/Environment/Variable/UnsetCommand.php @@ -0,0 +1,107 @@ +wizard = new EnvironmentWizard(); + parent::__construct($name); + } + + protected function configure() + { + $this->setDescription('Prints an environment variable'); + + $this->wizard->configureConsoleCommand($this); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $workingDirectory = $input->getOption('working-directory') ?: getcwd(); + + $finder = (new Finder()) + ->files() + ->ignoreDotFiles(false) + ->in($workingDirectory); + + $format = new SymfonyStyle($input, $output); + + $serializer = new Serializer( + [ + new CustomNormalizer(), + new PropertyNormalizer(), + ], + [ + new YamlEncoder(), + ] + ); + + if ($finder->hasResults()) { + /** @var SplFileInfo $file */ + foreach ($finder->name('/^\.?kloud.environment.ya?ml$/') as $file) { + try { + /** @var Context $context */ + $context = $serializer->deserialize($file->getContents(), Context::class, 'yaml'); + } catch (\Throwable $exception) { + $format->error($exception->getMessage()); + continue; + } + + break; + } + } + + if (!isset($context)) { + $format->error('No .kloud.environment.yaml file found in your directory. You must initialize it using environment:init command'); + + return 1; + } + + $variableName = $format->askQuestion(new Question('Please enter the variable to unset')); + + try { + /** @var EnvironmentVariableInterface $variable */ + $variable = $context->getVariable($variableName); + } catch (VariableNotFoundException $exception) { + $format->error($exception->getMessage()); + + return 1; + } + + $context->setVariable(new EnvironmentVariable($variable->getVariable())); + + $format->success('Variable was successfully unset'); + file_put_contents($workingDirectory.'/.kloud.environment.yaml', $serializer->serialize($context, 'yaml', [ + 'yaml_inline' => 4, + 'yaml_indent' => 0, + 'yaml_flags' => 0, + ])); + + return 0; + } +}