Skip to content

Commit 0d60c0e

Browse files
committed
#60: Build interactive configuration tool for populating .env properties
1 parent 08c089a commit 0d60c0e

File tree

7 files changed

+292
-3
lines changed

7 files changed

+292
-3
lines changed

.env.example

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
MAGENTO_BASE_URL=http://devdocs.magento.com/
66

77
#*** Set the Admin Username and Password for your Magento instance ***#
8-
MAGENTO_BACKEND_NAME=
9-
MAGENTO_ADMIN_USERNAME=
10-
MAGENTO_ADMIN_PASSWORD=
8+
MAGENTO_BACKEND_NAME=admin
9+
MAGENTO_ADMIN_USERNAME=admin
10+
MAGENTO_ADMIN_PASSWORD=123123q
1111

1212
#*** Path to CLI entry point and command parameter name. Uncomment and change if folder structure differs from standard Magento installation
1313
#MAGENTO_CLI_COMMAND_PATH=dev/tests/acceptance/utils/command.php

RoboFile.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function cloneFiles()
3333
*/
3434
function buildProject()
3535
{
36+
$this->writeln("<error>This command will be removed in MFTF v3.0.0. Please use bin/mftf build:project instead.</error>\n");
3637
$this->cloneFiles();
3738
$this->_exec('vendor'. DIRECTORY_SEPARATOR .'bin'. DIRECTORY_SEPARATOR .'codecept build');
3839
}

bin/mftf

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env php
2+
3+
<?php
4+
/**
5+
* Copyright © Magento, Inc. All rights reserved.
6+
* See COPYING.txt for license details.
7+
*/
8+
9+
if (PHP_SAPI !== 'cli') {
10+
echo 'bin/mftf must be run as a CLI application';
11+
exit(1);
12+
}
13+
14+
try {
15+
require_once __DIR__ . '/../bootstrap.php';
16+
$application = new Symfony\Component\Console\Application();
17+
$application->setName('Magento Functional Testing Framework CLI');
18+
$application->setVersion('1.0.0');
19+
$application->add(new Magento\FunctionalTestingFramework\Console\SetupEnvCommand());
20+
$application->add(new Magento\FunctionalTestingFramework\Console\BuildProjectCommand());
21+
$application->run();
22+
} catch (\Exception $e) {
23+
while ($e) {
24+
echo $e->getMessage();
25+
echo $e->getTraceAsString();
26+
echo "\n\n";
27+
$e = $e->getPrevious();
28+
}
29+
exit(1);
30+
}

bootstrap.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
require_once 'vendor/autoload.php';
8+
define('BP', __DIR__);
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types = 1);
8+
9+
namespace Magento\FunctionalTestingFramework\Console;
10+
11+
use Symfony\Component\Console\Command\Command;
12+
use Symfony\Component\Console\Input\ArrayInput;
13+
use Symfony\Component\Filesystem\Filesystem;
14+
use Symfony\Component\Console\Input\InputOption;
15+
use Magento\FunctionalTestingFramework\Util\Env\EnvProcessor;
16+
use Symfony\Component\Console\Input\InputInterface;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
use Codeception\Command\Build;
19+
use Symfony\Component\Process\Process;
20+
21+
class BuildProjectCommand extends Command
22+
{
23+
/**
24+
* Env processor manages .env files.
25+
*
26+
* @var \Magento\FunctionalTestingFramework\Util\Env\EnvProcessor
27+
*/
28+
private $envProcessor;
29+
30+
/**
31+
* Configures the current command.
32+
*
33+
* @return void
34+
*/
35+
protected function configure()
36+
{
37+
$this->setName('build:project');
38+
$this->setDescription('Generate configuration files for the project. Build the Codeception project.');
39+
$this->envProcessor = new EnvProcessor(BP . DIRECTORY_SEPARATOR . '.env');
40+
$env = $this->envProcessor->getEnv();
41+
foreach ($env as $key => $value) {
42+
$this->addOption($key, null, InputOption::VALUE_REQUIRED, '', $value);
43+
}
44+
}
45+
46+
/**
47+
* Executes the current command.
48+
*
49+
* @param InputInterface $input
50+
* @param OutputInterface $output
51+
* @return null|int
52+
* @throws \Symfony\Component\Console\Exception\LogicException
53+
*/
54+
protected function execute(InputInterface $input, OutputInterface $output)
55+
{
56+
$fileSystem = new Filesystem();
57+
$fileSystem->copy(
58+
BP . DIRECTORY_SEPARATOR . 'codeception.dist.yml',
59+
BP . DIRECTORY_SEPARATOR . 'codeception.yml'
60+
);
61+
$output->writeln("codeception.yml configuration successfully applied.\n");
62+
$fileSystem->copy(
63+
BP . DIRECTORY_SEPARATOR . 'dev' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . 'MFTF.suite.dist.yml',
64+
BP . DIRECTORY_SEPARATOR . 'dev' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . 'MFTF.suite.yml'
65+
);
66+
$output->writeln("MFTF.suite.yml configuration successfully applied.\n");
67+
68+
$setupEnvCommand = new SetupEnvCommand();
69+
$commandInput = [];
70+
$options = $input->getOptions();
71+
$env = array_keys($this->envProcessor->getEnv());
72+
foreach ($options as $key => $value) {
73+
if (in_array($key, $env)) {
74+
$commandInput['--' . $key] = $value;
75+
}
76+
}
77+
$commandInput = new ArrayInput($commandInput);
78+
$setupEnvCommand->run($commandInput, $output);
79+
80+
$process = new Process('vendor/bin/codecept build');
81+
$process->run();
82+
if ($process->isSuccessful()) {
83+
$output->writeln("Codeception build run successfully.\n");
84+
}
85+
86+
$output->writeln('<info>The project built successfully.</info>');
87+
}
88+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types = 1);
8+
9+
namespace Magento\FunctionalTestingFramework\Console;
10+
11+
use Symfony\Component\Console\Command\Command;
12+
use Symfony\Component\Console\Input\InputOption;
13+
use Symfony\Component\Console\Exception\InvalidOptionException;
14+
use Magento\FunctionalTestingFramework\Util\Env\EnvProcessor;
15+
use \Symfony\Component\Console\Input\InputInterface;
16+
use \Symfony\Component\Console\Output\OutputInterface;
17+
18+
class SetupEnvCommand extends Command
19+
{
20+
/**
21+
* Env processor manages .env files.
22+
*
23+
* @var \Magento\FunctionalTestingFramework\Util\Env\EnvProcessor
24+
*/
25+
private $envProcessor;
26+
27+
/**
28+
* Configures the current command.
29+
*
30+
* @return void
31+
*/
32+
protected function configure()
33+
{
34+
$this->setName('setup:env');
35+
$this->setDescription("Generate .env file.");
36+
$this->envProcessor = new EnvProcessor(BP . DIRECTORY_SEPARATOR . '.env');
37+
$env = $this->envProcessor->getEnv();
38+
foreach ($env as $key => $value) {
39+
$this->addOption($key, null, InputOption::VALUE_REQUIRED, '', $value);
40+
}
41+
}
42+
43+
/**
44+
* Executes the current command.
45+
*
46+
* @param InputInterface $input
47+
* @param OutputInterface $output
48+
* @return null|int
49+
* @throws \Symfony\Component\Console\Exception\LogicException
50+
*/
51+
protected function execute(InputInterface $input, OutputInterface $output)
52+
{
53+
$config = $this->envProcessor->getEnv();
54+
$userEnv = [];
55+
foreach ($config as $key => $value) {
56+
if ($input->getOption($key) === '') {
57+
throw new InvalidOptionException(sprintf("Parameter $key cannot be empty.", $key));
58+
}
59+
$userEnv[$key] = $input->getOption($key);
60+
}
61+
$this->envProcessor->putEnvFile($userEnv);
62+
$output->writeln(".env configuration successfully applied.\n");
63+
}
64+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types = 1);
7+
8+
namespace Magento\FunctionalTestingFramework\Util\Env;
9+
10+
/**
11+
* Helper class EnvProcessor for reading and writing .env files.
12+
*
13+
* @package Magento\FunctionalTestingFramework\Util\Env
14+
*/
15+
class EnvProcessor
16+
{
17+
/**
18+
* .env file location.
19+
*
20+
* @var string
21+
*/
22+
private $envFile = '';
23+
24+
/**
25+
* .env.example file location.
26+
*
27+
* @var string
28+
*/
29+
private $envExampleFile = '';
30+
31+
/**
32+
* Array of environment variables form file.
33+
*
34+
* @var array
35+
*/
36+
private $env = [];
37+
38+
/**
39+
* EnvProcessor constructor.
40+
* @param $envFile
41+
*/
42+
public function __construct(
43+
$envFile
44+
) {
45+
$this->envFile = $envFile;
46+
$this->envExampleFile = $envFile . '.example';
47+
}
48+
49+
/**
50+
* Serves for parsing '.env.example' file into associative array.
51+
*
52+
* @return array
53+
*/
54+
public function parseEnvFile(): array
55+
{
56+
$envLines = file(
57+
$this->envExampleFile,
58+
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
59+
);
60+
$env = [];
61+
foreach ($envLines as $line) {
62+
// do not use commented out lines
63+
if (strpos($line, '#') !== 0) {
64+
list($key, $value) = explode('=', $line);
65+
$env[$key] = $value;
66+
}
67+
}
68+
return $env;
69+
}
70+
71+
/**
72+
* Serves for putting array with environment variables into .env file.
73+
*
74+
* @param array $config
75+
* @return void
76+
*/
77+
public function putEnvFile(array $config = [])
78+
{
79+
$envData = '';
80+
foreach ($config as $key => $value) {
81+
$envData .= $key . '=' . $value . PHP_EOL;
82+
}
83+
file_put_contents($this->envFile, $envData);
84+
}
85+
86+
/**
87+
* Retrieves '.env.example' file as associative array.
88+
*
89+
* @return array
90+
*/
91+
public function getEnv(): array
92+
{
93+
if (empty($this->env)) {
94+
$this->env = $this->parseEnvFile();
95+
}
96+
return $this->env;
97+
}
98+
}

0 commit comments

Comments
 (0)