Skip to content

Commit

Permalink
#60: Build interactive configuration tool for populating .env properties
Browse files Browse the repository at this point in the history
  • Loading branch information
lenaorobei committed Mar 26, 2018
1 parent 08c089a commit af460ab
Show file tree
Hide file tree
Showing 7 changed files with 294 additions and 3 deletions.
6 changes: 3 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
MAGENTO_BASE_URL=http://devdocs.magento.com/

#*** Set the Admin Username and Password for your Magento instance ***#
MAGENTO_BACKEND_NAME=
MAGENTO_ADMIN_USERNAME=
MAGENTO_ADMIN_PASSWORD=
MAGENTO_BACKEND_NAME=admin
MAGENTO_ADMIN_USERNAME=admin
MAGENTO_ADMIN_PASSWORD=123123q

#*** Path to CLI entry point and command parameter name. Uncomment and change if folder structure differs from standard Magento installation
#MAGENTO_CLI_COMMAND_PATH=dev/tests/acceptance/utils/command.php
Expand Down
1 change: 1 addition & 0 deletions RoboFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function cloneFiles()
*/
function buildProject()
{
$this->writeln("<error>This command will be removed in MFTF v3.0.0. Please use bin/mftf build:project instead.</error>\n");
$this->cloneFiles();
$this->_exec('vendor'. DIRECTORY_SEPARATOR .'bin'. DIRECTORY_SEPARATOR .'codecept build');
}
Expand Down
30 changes: 30 additions & 0 deletions bin/mftf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env php

<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

if (PHP_SAPI !== 'cli') {
echo 'bin/mftf must be run as a CLI application';
exit(1);
}

try {
require_once __DIR__ . '/../bootstrap.php';
$application = new Symfony\Component\Console\Application();
$application->setName('Magento Functional Testing Framework CLI');
$application->setVersion('1.0.0');
$application->add(new Magento\FunctionalTestingFramework\Console\SetupEnvCommand());
$application->add(new Magento\FunctionalTestingFramework\Console\BuildProjectCommand());
$application->run();
} catch (\Exception $e) {
while ($e) {
echo $e->getMessage();
echo $e->getTraceAsString();
echo "\n\n";
$e = $e->getPrevious();
}
exit(1);
}
8 changes: 8 additions & 0 deletions bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

require_once 'vendor/autoload.php';
define('BP', __DIR__);
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
// @codingStandardsIgnoreFile
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types = 1);

namespace Magento\FunctionalTestingFramework\Console;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;
use Magento\FunctionalTestingFramework\Util\Env\EnvProcessor;

class BuildProjectCommand extends Command
{
/**
* Env processor manages .env files.
*
* @var \Magento\FunctionalTestingFramework\Util\Env\EnvProcessor
*/
private $envProcessor;

/**
* Configures the current command.
*
* @return void
*/
protected function configure()
{
$this->setName('build:project');
$this->setDescription('Generate configuration files for the project. Build the Codeception project.');
$this->envProcessor = new EnvProcessor(BP . DIRECTORY_SEPARATOR . '.env');
$env = $this->envProcessor->getEnv();
foreach ($env as $key => $value) {
$this->addOption($key, null, InputOption::VALUE_REQUIRED, '', $value);
}
}

/**
* Executes the current command.
*
* @param InputInterface $input
* @param OutputInterface $output
* @return void
* @throws \Symfony\Component\Console\Exception\LogicException
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$fileSystem = new Filesystem();
$fileSystem->copy(
BP . DIRECTORY_SEPARATOR . 'codeception.dist.yml',
BP . DIRECTORY_SEPARATOR . 'codeception.yml'
);
$output->writeln("codeception.yml configuration successfully applied.\n");
$fileSystem->copy(
BP . DIRECTORY_SEPARATOR . 'dev' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR .
'functional' . DIRECTORY_SEPARATOR . 'MFTF.suite.dist.yml',
BP . DIRECTORY_SEPARATOR . 'dev' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR .
'functional' . DIRECTORY_SEPARATOR . 'MFTF.suite.yml'
);
$output->writeln("MFTF.suite.yml configuration successfully applied.\n");

$setupEnvCommand = new SetupEnvCommand();
$commandInput = [];
$options = $input->getOptions();
$env = array_keys($this->envProcessor->getEnv());
foreach ($options as $key => $value) {
if (in_array($key, $env)) {
$commandInput['--' . $key] = $value;
}
}
$commandInput = new ArrayInput($commandInput);
$setupEnvCommand->run($commandInput, $output);

$process = new Process('vendor/bin/codecept build');
$process->run();
if ($process->isSuccessful()) {
$output->writeln("Codeception build run successfully.\n");
}

$output->writeln('<info>The project built successfully.</info>');
}
}
64 changes: 64 additions & 0 deletions src/Magento/FunctionalTestingFramework/Console/SetupEnvCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
// @codingStandardsIgnoreFile
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types = 1);

namespace Magento\FunctionalTestingFramework\Console;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Exception\InvalidOptionException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magento\FunctionalTestingFramework\Util\Env\EnvProcessor;

class SetupEnvCommand extends Command
{
/**
* Env processor manages .env files.
*
* @var \Magento\FunctionalTestingFramework\Util\Env\EnvProcessor
*/
private $envProcessor;

/**
* Configures the current command.
*
* @return void
*/
protected function configure()
{
$this->setName('setup:env');
$this->setDescription("Generate .env file.");
$this->envProcessor = new EnvProcessor(BP . DIRECTORY_SEPARATOR . '.env');
$env = $this->envProcessor->getEnv();
foreach ($env as $key => $value) {
$this->addOption($key, null, InputOption::VALUE_REQUIRED, '', $value);
}
}

/**
* Executes the current command.
*
* @param InputInterface $input
* @param OutputInterface $output
* @return void
* @throws \Symfony\Component\Console\Exception\LogicException
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$config = $this->envProcessor->getEnv();
$userEnv = [];
foreach ($config as $key => $value) {
if ($input->getOption($key) === '') {
throw new InvalidOptionException(sprintf("Parameter $key cannot be empty.", $key));
}
$userEnv[$key] = $input->getOption($key);
}
$this->envProcessor->putEnvFile($userEnv);
$output->writeln(".env configuration successfully applied.\n");
}
}
99 changes: 99 additions & 0 deletions src/Magento/FunctionalTestingFramework/Util/Env/EnvProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php
// @codingStandardsIgnoreFile
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types = 1);

namespace Magento\FunctionalTestingFramework\Util\Env;

/**
* Helper class EnvProcessor for reading and writing .env files.
*
* @package Magento\FunctionalTestingFramework\Util\Env
*/
class EnvProcessor
{
/**
* File .env location.
*
* @var string
*/
private $envFile = '';

/**
* File .env.example location.
*
* @var string
*/
private $envExampleFile = '';

/**
* Array of environment variables form file.
*
* @var array
*/
private $env = [];

/**
* EnvProcessor constructor.
* @param string $envFile
*/
public function __construct(
string $envFile = ''
) {
$this->envFile = $envFile;
$this->envExampleFile = $envFile . '.example';
}

/**
* Serves for parsing '.env.example' file into associative array.
*
* @return array
*/
public function parseEnvFile(): array
{
$envLines = file(
$this->envExampleFile,
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
);
$env = [];
foreach ($envLines as $line) {
// do not use commented out lines
if (strpos($line, '#') !== 0) {
list($key, $value) = explode('=', $line);
$env[$key] = $value;
}
}
return $env;
}

/**
* Serves for putting array with environment variables into .env file.
*
* @param array $config
* @return void
*/
public function putEnvFile(array $config = [])
{
$envData = '';
foreach ($config as $key => $value) {
$envData .= $key . '=' . $value . PHP_EOL;
}
file_put_contents($this->envFile, $envData);
}

/**
* Retrieves '.env.example' file as associative array.
*
* @return array
*/
public function getEnv(): array
{
if (empty($this->env)) {
$this->env = $this->parseEnvFile();
}
return $this->env;
}
}

0 comments on commit af460ab

Please sign in to comment.