Skip to content

Commit 8703e00

Browse files
authored
Merge pull request #69 from lenaorobei/issue60
#60: Build interactive configuration tool for populating .env properties
2 parents 8e7d4d8 + ff2bce5 commit 8703e00

File tree

7 files changed

+294
-3
lines changed

7 files changed

+294
-3
lines changed

.env.example

+3-3
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

+1
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

+30
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

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

0 commit comments

Comments
 (0)