├── .dockerignore
├── tests
├── fixtures
│ ├── example.env
│ ├── expected-output.env
│ └── output.env
├── EnvFactoryTest.php
├── EnvTest.php
├── ScriptHandlerTest.php
└── ProcessorTest.php
├── examples
├── single-env-file
│ ├── .gitignore
│ ├── .env.example
│ └── composer.json
└── multiple-env-files
│ ├── .gitignore
│ ├── .env.dist
│ ├── .env.server.dist
│ └── composer.json
├── .gitignore
├── src
├── File
│ ├── Factory
│ │ ├── FileFactory.php
│ │ └── EnvFactory.php
│ ├── FileInterface.php
│ └── Env.php
├── ScriptHandler.php
└── Processor.php
├── phpcs.xml.dist
├── gitattributes
├── CHANGELOG.md
├── Dockerfile
├── phpunit.xml.dist
├── composer.json
├── LICENSE
├── .github
└── workflows
│ └── php.yaml
└── README.md
/.dockerignore:
--------------------------------------------------------------------------------
1 | vendor/
2 |
--------------------------------------------------------------------------------
/tests/fixtures/example.env:
--------------------------------------------------------------------------------
1 | VALUE_1=true
2 | VALUE_2=string
--------------------------------------------------------------------------------
/examples/single-env-file/.gitignore:
--------------------------------------------------------------------------------
1 | .env*
2 | !.env.example
3 |
4 | composer.lock
5 | vendor/
6 |
--------------------------------------------------------------------------------
/examples/multiple-env-files/.gitignore:
--------------------------------------------------------------------------------
1 | .env*
2 | !.env.dist
3 | !.env.server.dist
4 |
5 | composer.lock
6 | vendor/
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | /coverage/
3 | /composer.lock
4 |
5 | /examples/composer.lock
6 | /examples/vendor/
7 | /examples/.env
8 |
--------------------------------------------------------------------------------
/tests/fixtures/expected-output.env:
--------------------------------------------------------------------------------
1 | # This file is auto-generated during the composer install
2 | # Changes will be overwritten
3 | STRING="string"
4 |
--------------------------------------------------------------------------------
/examples/multiple-env-files/.env.dist:
--------------------------------------------------------------------------------
1 | #Master database
2 | DB_HOST='127.0.0.1' #Local database
3 | DB_USERNAME='db_user'
4 | DB_PASSWORD=
5 |
6 | ENABLE_LOGS=true
7 |
--------------------------------------------------------------------------------
/examples/single-env-file/.env.example:
--------------------------------------------------------------------------------
1 | #Master database
2 | DB_HOST='127.0.0.1' #Local database
3 | DB_USERNAME='db_user'
4 | DB_PASSWORD=
5 |
6 | ENABLE_LOGS=true
7 |
--------------------------------------------------------------------------------
/examples/multiple-env-files/.env.server.dist:
--------------------------------------------------------------------------------
1 | #Master database
2 | DB_HOST='127.0.0.1' #Local database
3 | DB_USERNAME='db_user'
4 | DB_PASSWORD=
5 |
6 | ENABLE_LOGS=true
7 |
--------------------------------------------------------------------------------
/tests/fixtures/output.env:
--------------------------------------------------------------------------------
1 | # This file is auto-generated during the composer install
2 | # Changes will be overwritten
3 | STRING="string"
4 | VALUE_1=true
5 | VALUE_2="string"
6 |
--------------------------------------------------------------------------------
/src/File/Factory/FileFactory.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | ./src
4 | ./tests
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/gitattributes:
--------------------------------------------------------------------------------
1 | /coverage export-ignore
2 | /tests export-ignore
3 | /.gitattributes export-ignore
4 | /.gitignore export-ignore
5 | /.github export-ignore
6 | /phpunit.xml.dist export-ignore
7 | /phpcs.xml.dist export-ignore
8 | /examples export-ignore
9 |
--------------------------------------------------------------------------------
/src/File/Factory/EnvFactory.php:
--------------------------------------------------------------------------------
1 | create('filename.txt');
16 |
17 | $this->assertInstanceOf('Diarmuidie\EnvPopulate\File\Env', $file);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:8-cli
2 |
3 | RUN apt-get update && apt-get install -y \
4 | git \
5 | zip \
6 | && rm -rf /var/lib/apt/lists/*
7 |
8 | ENV XDEBUG_MODE=coverage
9 | RUN pecl install xdebug-3.0.3 \
10 | && docker-php-ext-enable xdebug
11 |
12 | # Install Composer
13 | ENV COMPOSER_ALLOW_SUPERUSER 1
14 | ENV COMPOSER_HOME /tmp
15 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
16 |
17 | WORKDIR /app
18 |
19 | COPY composer.json ./
20 |
21 | RUN composer install
22 |
23 | COPY . .
24 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | tests
7 |
8 |
9 |
10 |
11 |
12 | src
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/multiple-env-files/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "diarmuidie/envpopulate": "^2.0"
4 | },
5 | "scripts": {
6 | "post-install-cmd": [
7 | "Diarmuidie\\EnvPopulate\\ScriptHandler::populateEnv"
8 | ],
9 | "post-update-cmd": [
10 | "Diarmuidie\\EnvPopulate\\ScriptHandler::populateEnv"
11 | ]
12 | },
13 | "extra": {
14 | "env-populate": {
15 | "files": [
16 | {
17 | "example-file": ".env.server.dist",
18 | "generated-file": ".env.server"
19 | },
20 | {
21 | "example-file": ".env.dist",
22 | "generated-file": ".env"
23 | }
24 | ],
25 | "run-non-interactively": false
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "diarmuidie/envpopulate",
3 | "description": "Tool to interactively populate a `.env` file based on an `.env.example` file whenever Composer installs or updates.",
4 | "type": "library",
5 | "keywords": ["parameters management", "dotenv", "env", ".env", "environment"],
6 | "require": {
7 | "php": ">=7.3",
8 | "m1/env": "^2.0"
9 | },
10 | "require-dev": {
11 | "phpunit/phpunit": "^9.0",
12 | "squizlabs/php_codesniffer": "^3.6",
13 | "composer/composer": ">=2.0.13"
14 | },
15 | "license": "MIT",
16 | "authors": [
17 | {
18 | "name": "Diarmuid",
19 | "email": "contact@diarmuid.ie"
20 | }
21 | ],
22 | "autoload": {
23 | "psr-4": {
24 | "Diarmuidie\\EnvPopulate\\": "src/"
25 | }
26 | },
27 | "scripts": {
28 | "test": [
29 | "@lint",
30 | "@unittest"
31 | ],
32 | "unittest": "phpunit --coverage-text",
33 | "lint": "phpcs"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Diarmuid
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/.github/workflows/php.yaml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 |
10 | jobs:
11 | run:
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | operating-system: ['ubuntu-latest']
16 | php-versions: ['7.3', '7.4', '8.0']
17 |
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v2
21 |
22 | - name: Setup PHP
23 | uses: shivammathur/setup-php@v2
24 | with:
25 | php-version: ${{ matrix.php-versions }}
26 | coverage: xdebug
27 |
28 | - name: Validate composer.json and composer.lock
29 | run: composer validate --strict
30 |
31 | - name: Cache Composer packages
32 | id: composer-cache
33 | uses: actions/cache@v2
34 | with:
35 | path: vendor
36 | key: ${{ runner.os }}-php-${{ matrix.php-versions }}-${{ hashFiles('**/composer.lock') }}
37 | restore-keys: |
38 | ${{ runner.os }}-php-${{ matrix.php-versions }}-
39 |
40 | - name: Install dependencies
41 | run: composer install --prefer-dist --no-progress
42 |
43 | - name: Run test suite
44 | run: composer run-script test
45 |
--------------------------------------------------------------------------------
/src/ScriptHandler.php:
--------------------------------------------------------------------------------
1 | getComposer()->getPackage()->getExtra();
17 | $config = array();
18 |
19 | if (isset($extras[self::EXTRA_KEY]) && is_array($extras[self::EXTRA_KEY])) {
20 | $config = $extras[self::EXTRA_KEY];
21 | }
22 |
23 | if (isset($config['run-non-interactively'])
24 | && !$config['run-non-interactively']
25 | && !$event->getIO()->isInteractive()
26 | ) {
27 | return;
28 | }
29 |
30 | $envFileFactory = new EnvFactory();
31 |
32 | $processor = new Processor($event->getIO(), $envFileFactory);
33 |
34 | if (isset($config['files']) && is_array($config['files'])) {
35 | foreach ($config['files'] as $file) {
36 | $processor->processFile($file['example-file'], $file['generated-file']);
37 | }
38 | } else {
39 | # Process legacy config file
40 | $processor->processFile(
41 | self::getExampleFile($config),
42 | self::getGeneratedFile($config)
43 | );
44 | }
45 | }
46 |
47 | private static function getExampleFile($config)
48 | {
49 | if (!empty($config['example-file'])) {
50 | return $config['example-file'];
51 | }
52 | return self::DEFAULT_EXAMPLE_FILE;
53 | }
54 |
55 | private static function getGeneratedFile($config)
56 | {
57 | if (!empty($config['generated-file'])) {
58 | return $config['generated-file'];
59 | }
60 | return self::DEFAULT_GENERATED_FILE;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/File/Env.php:
--------------------------------------------------------------------------------
1 | filename = $filename;
17 | }
18 |
19 | public function getFilename()
20 | {
21 | return $this->filename;
22 | }
23 |
24 | public function fileExists()
25 | {
26 | return is_file($this->filename);
27 | }
28 |
29 | public function load()
30 | {
31 | $env = new Parser(file_get_contents($this->filename));
32 | $this->envValues = $env->getContent();
33 | }
34 |
35 | public function getVariables()
36 | {
37 | return $this->envValues;
38 | }
39 |
40 | public function setVariable($name, $value)
41 | {
42 | $this->envValues[$name] = $value;
43 | }
44 |
45 | public function save()
46 | {
47 | $contents = $this->formatContents();
48 |
49 | file_put_contents($this->filename, $contents);
50 | }
51 |
52 | protected function formatContents()
53 | {
54 | $contents = self::FILE_HEADER . "\n";
55 |
56 | foreach ($this->envValues as $name => $value) {
57 | $contents .= $name . "=" . $this->formatValueForEnv($value) . "\n";
58 | }
59 |
60 | return $contents;
61 | }
62 |
63 | public function formatValueForEnv($value)
64 | {
65 | if (is_bool($value)) {
66 | return ($value) ? 'true' : 'false';
67 | }
68 |
69 | if ($value === 'true' || $value === 'false') {
70 | return $value;
71 | }
72 |
73 | if (is_int($value)) {
74 | return $value;
75 | }
76 |
77 | if (empty($value)) {
78 | return '';
79 | }
80 |
81 | $singelAndDoubleQuotes = '"\'';
82 |
83 | return '"' . trim($value, $singelAndDoubleQuotes) . '"';
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/tests/EnvTest.php:
--------------------------------------------------------------------------------
1 | env = new Env('fixtures/example.env');
16 | }
17 |
18 | public function testGettingFilename()
19 | {
20 | $this->assertEquals("fixtures/example.env", $this->env->getFilename());
21 | }
22 |
23 | public function testLoadingEnvFile()
24 | {
25 | $this->env->load();
26 |
27 | $expected = array(
28 | 'VALUE_1' => true,
29 | 'VALUE_2' => 'string'
30 | );
31 |
32 | $this->assertEquals($expected, $this->env->getVariables());
33 | }
34 |
35 | public function testSettingVariables()
36 | {
37 | $this->env->setVariable('NAME', 'value');
38 |
39 | $expected = array(
40 | 'NAME' => 'value'
41 | );
42 |
43 | $this->assertEquals($expected, $this->env->getVariables());
44 | }
45 |
46 | public function testSavingFile()
47 | {
48 | $env = new Env('fixtures/output.env');
49 | $env->setVariable('STRING', 'string');
50 | $env->save();
51 |
52 | $this->assertFileEquals('fixtures/output.env', 'fixtures/expected-output.env');
53 | }
54 |
55 | /**
56 | * @dataProvider variableProvider
57 | */
58 | public function testVariableFormatting($variable, $expected)
59 | {
60 | $actual = $this->env->formatValueForEnv($variable);
61 |
62 | $this->assertEquals($expected, $actual);
63 | }
64 |
65 | public function variableProvider()
66 | {
67 | return array(
68 | array(true, 'true'),
69 | array(false, 'false'),
70 | array('true', 'true'),
71 | array('false', 'false'),
72 | array(123, 123),
73 | array("string", '"string"'),
74 | array('string', '"string"'),
75 | array(1.234, '"1.234"'),
76 | array('', ''),
77 | array(null, '')
78 | );
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/Processor.php:
--------------------------------------------------------------------------------
1 | io = $io;
19 | $this->fileFactory = $fileFactory;
20 | }
21 |
22 | public function processFile($exampleFile, $generatedFile)
23 | {
24 | $this->loadFiles($exampleFile, $generatedFile);
25 |
26 | $unsetValues = $this->findUnsetValues();
27 | if (!empty($unsetValues)) {
28 | $this->getUnsetValues($unsetValues);
29 | $this->saveFile();
30 | }
31 | }
32 |
33 | protected function loadFiles($exampleFile, $generatedFile)
34 | {
35 | $this->exampleFile = $this->fileFactory->create($exampleFile);
36 | if (!$this->exampleFile->fileExists()) {
37 | throw new \InvalidArgumentException(
38 | sprintf(
39 | 'The example env file "%s" does not exist. Check your example-file config or create it.',
40 | $exampleFile
41 | )
42 | );
43 | }
44 | $this->exampleFile->load();
45 |
46 | $this->generatedFile = $this->fileFactory->create($generatedFile);
47 | if ($this->generatedFile->fileExists()) {
48 | $this->generatedFile->load();
49 | }
50 | }
51 |
52 | protected function findUnsetValues()
53 | {
54 | $exampleValues = $this->exampleFile->getVariables();
55 | $generatedValues = $this->generatedFile->getVariables();
56 |
57 | $unsetEnvValues = array_diff_key($exampleValues, $generatedValues);
58 |
59 | return array_keys($unsetEnvValues);
60 | }
61 |
62 | protected function getUnsetValues(array $unsetValues)
63 | {
64 | if ($this->io->isInteractive()) {
65 | $this->interactiveGetUnsetValues($unsetValues);
66 | } else {
67 | $this->nonInteractiveGetUnsetValues($unsetValues);
68 | }
69 | }
70 |
71 | protected function interactiveGetUnsetValues(array $unsetValues)
72 | {
73 | $exampleValues = $this->exampleFile->getVariables();
74 |
75 | $isStarted = false;
76 | foreach ($unsetValues as $key) {
77 | if (!$isStarted) {
78 | $isStarted = true;
79 | $this->io->write(
80 | 'Some parameters are missing from '
81 | . $this->generatedFile->getFilename()
82 | . '. Please provide them.'
83 | );
84 | }
85 |
86 | $default = $exampleValues[$key];
87 | $value = $this->io->ask(
88 | sprintf('%s (%s): ', $key, $this->convertToString($default)),
89 | $default
90 | );
91 | $this->generatedFile->setVariable($key, $value);
92 | }
93 | }
94 |
95 | protected function nonInteractiveGetUnsetValues(array $unsetValues)
96 | {
97 | $exampleValues = $this->exampleFile->getVariables();
98 |
99 | foreach ($unsetValues as $key) {
100 | $this->generatedFile->setVariable($key, $exampleValues[$key]);
101 | }
102 | }
103 |
104 | protected function saveFile()
105 | {
106 | $this->generatedFile->save();
107 | }
108 |
109 | protected function convertToString($value)
110 | {
111 | if (is_bool($value)) {
112 | $value = ($value) ? 'true' : 'false';
113 | }
114 | return (string) $value;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | diarmuidie/envpopulate
2 | =============
3 |
4 | PHP tool to interactively populate a `.env` file based on an `.env.example` file whenever Composer installs or updates.
5 |
6 | Based on the similar package [Incenteev/ParameterHandler](https://github.com/Incenteev/ParameterHandler). Go check that out if you need to save parameters to a YAML file instead of a env file :+1:.
7 |
8 | Developed by [Diarmuid](https://diarmuid.ie/).
9 |
10 | [](https://packagist.org/packages/diarmuidie/envpopulate)
11 | [](https://packagist.org/packages/diarmuidie/envpopulate)
12 |
13 | Installation
14 | ------------
15 |
16 | You can install EnvPopulate through [Composer](https://getcomposer.org):
17 |
18 | ```shell
19 | $ composer require diarmuidie/envpopulate
20 | ```
21 |
22 | To trigger the EnvPopulate script on composer install and updates you have to add the following scripts to your `composer.json` file:
23 |
24 | ```JSON
25 | {
26 | "scripts": {
27 | "post-install-cmd": [
28 | "Diarmuidie\\EnvPopulate\\ScriptHandler::populateEnv"
29 | ],
30 | "post-update-cmd": [
31 | "Diarmuidie\\EnvPopulate\\ScriptHandler::populateEnv"
32 | ]
33 | }
34 | }
35 | ```
36 |
37 | #### Optional
38 | If you want to change the location of the example or generated env file, or add multiple files you can also add an extra section to the `composer.json` file:
39 | ```JSON
40 | "extra": {
41 | "env-populate": {
42 | "files": [
43 | {
44 | "example-file": ".env.server.dist",
45 | "generated-file": ".env.server"
46 | },
47 | {
48 | "example-file": ".env.dist",
49 | "generated-file": ".env"
50 | }
51 | ]
52 | }
53 | }
54 | ```
55 |
56 | You can also specify if you want to not run the env populate scripts when in non-interactive mode (automated systems):
57 | ```JSON
58 | "extra": {
59 | "env-populate": {
60 | "run-non-interactively": false
61 | }
62 | }
63 | ```
64 |
65 |
66 | Usage
67 | -----
68 |
69 | Make sure you have an `.env.example` file in the root of your project (or in a different location by [setting the extra options](#optional).
70 |
71 | The script will run every time you do a `composer install` or `composer update`. Press enter to accept the default value or type to overwrite it.
72 |
73 | See it in action:
74 |
75 | [](https://asciinema.org/a/7tkeaspz0wqahr314p7khlehh)
76 |
77 | #### Disabling in Automated Environments
78 |
79 | You can disable the EnvPopulate script in automated environments (CI Server like Travis or Jenkins for example). You have two options to do this:
80 |
81 | - Run composer with `--noscripts` option. This will stop any scripts from being run (including EnvPopulate).
82 |
83 | - Run Composer in non interactive mode (`--no-interaction`). This will cause EnvPopulate to take the default values from `.env.example`, when generating the `.env` file, without asking for user input.
84 |
85 | Contributing
86 | ---------
87 |
88 | Feel free to contribute features, bug fixes or just helpful advice :smile:
89 |
90 | 1. Fork this repo
91 | 2. Create a feature branch
92 | 3. Submit a PR
93 | ...
94 | 4. Profit :sunglasses:
95 |
96 | ## Running Tests
97 | You can run the tests through Docker:
98 |
99 | ```
100 | # Build the dockerfile:
101 | $ docker build . --tag envpopulate:latest
102 |
103 | # Run the tests
104 | $ docker run envpopulate:latest composer run-script test
105 | ```
106 |
107 | Changelog
108 | ---------
109 |
110 | See the [CHANGELOG.md](https://github.com/diarmuidie/EnvPopulate/blob/master/CHANGELOG.md) file.
111 |
112 |
113 | Authors
114 | -------
115 |
116 | - [Diarmuid](http://diarmuid.ie)
117 |
118 |
119 | License
120 | -------
121 |
122 | The MIT License (MIT)
123 |
124 | Copyright (c) 2016 Diarmuid
125 |
126 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
127 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
128 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
129 | persons to whom the Software is furnished to do so, subject to the following conditions:
130 |
131 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
132 | Software.
133 |
134 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
135 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
136 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
137 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
138 |
--------------------------------------------------------------------------------
/tests/ScriptHandlerTest.php:
--------------------------------------------------------------------------------
1 | getMockBuilder($className)
13 | ->disableOriginalConstructor()
14 | ->getMock();
15 | }
16 |
17 | /**
18 | * @param array $extras
19 | * @dataProvider singleFileExtrasProvider
20 | */
21 | public function testSingleFileConfiguration(array $extras)
22 | {
23 | $package = $this->getClassMock('\Composer\Package\RootPackageInterface');
24 | $package->expects($this->once())
25 | ->method('getExtra')
26 | ->willReturn($extras);
27 |
28 | $composer = $this->getClassMock('\Composer\Composer');
29 | $composer->expects($this->once())
30 | ->method('getPackage')
31 | ->willReturn($package);
32 |
33 | $event = $this->getClassMock('\Composer\Script\Event');
34 | $event->expects($this->once())
35 | ->method('getComposer')
36 | ->willReturn($composer);
37 | $event->expects($this->once())
38 | ->method('getIo')
39 | ->willReturn($this->getClassMock('\Composer\IO\IOInterface'));
40 |
41 | ScriptHandler::populateEnv($event);
42 | }
43 |
44 | public function singleFileExtrasProvider()
45 | {
46 | return array(
47 | array(
48 | array(
49 | ScriptHandler::EXTRA_KEY => array(
50 | 'example-file' => 'tests/fixtures/example.env',
51 | 'generated-file' => 'tests/fixtures/output.env'
52 | )
53 | )
54 | )
55 | );
56 | }
57 |
58 | /**
59 | * @param array $extras
60 | * @dataProvider multipleFilesExtrasProvider
61 | */
62 | public function testMultipleFilesConfiguration(array $extras)
63 | {
64 | $package = $this->getClassMock('\Composer\Package\RootPackageInterface');
65 | $package->expects($this->once())
66 | ->method('getExtra')
67 | ->willReturn($extras);
68 |
69 | $composer = $this->getClassMock('\Composer\Composer');
70 | $composer->expects($this->once())
71 | ->method('getPackage')
72 | ->willReturn($package);
73 |
74 | $event = $this->getClassMock('\Composer\Script\Event');
75 | $event->expects($this->once())
76 | ->method('getComposer')
77 | ->willReturn($composer);
78 | $event->expects($this->once())
79 | ->method('getIo')
80 | ->willReturn($this->getClassMock('\Composer\IO\IOInterface'));
81 |
82 | ScriptHandler::populateEnv($event);
83 | }
84 |
85 | public function multipleFilesExtrasProvider()
86 | {
87 | return array(
88 | array(
89 | array(
90 | ScriptHandler::EXTRA_KEY => array(
91 | 'files' => array(
92 | array(
93 | 'example-file' => 'tests/fixtures/example.env',
94 | 'generated-file' => 'tests/fixtures/output.env'
95 | )
96 | )
97 | )
98 | ),
99 | array(
100 | ScriptHandler::EXTRA_KEY => array(
101 | 'files' => array(
102 | array(
103 | 'example-file' => 'tests/fixtures/example.env',
104 | 'generated-file' => 'tests/fixtures/output.env'
105 | ),
106 | array(
107 | 'example-file' => 'tests/fixtures/example.env',
108 | 'generated-file' => 'tests/fixtures/output.env'
109 | )
110 | )
111 | )
112 | )
113 | )
114 | );
115 | }
116 |
117 | public function testNonInteractivity()
118 | {
119 | $extras = array(
120 | ScriptHandler::EXTRA_KEY => array(
121 | 'run-non-interactively' => false
122 | )
123 | );
124 |
125 | $package = $this->getClassMock('\Composer\Package\RootPackageInterface');
126 | $package->expects($this->once())
127 | ->method('getExtra')
128 | ->willReturn($extras);
129 |
130 | $composer = $this->getClassMock('\Composer\Composer');
131 | $composer->expects($this->once())
132 | ->method('getPackage')
133 | ->willReturn($package);
134 |
135 | $event = $this->getClassMock('\Composer\Script\Event');
136 | $event->expects($this->once())
137 | ->method('getComposer')
138 | ->willReturn($composer);
139 |
140 | $io = $this->getClassMock('\Composer\IO\IOInterface');
141 | $io->expects($this->once())
142 | ->method('isInteractive')
143 | ->willReturn(false);
144 |
145 | $event->expects($this->once())
146 | ->method('getIo')
147 | ->willReturn($io);
148 |
149 | ScriptHandler::populateEnv($event);
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/tests/ProcessorTest.php:
--------------------------------------------------------------------------------
1 | file = $this->getMockBuilder('Diarmuidie\EnvPopulate\File\Env')
23 | ->setConstructorArgs(array('file.env'))
24 | ->getMock();
25 | $this->composerIO = $this->getMockBuilder('Composer\IO\IOInterface')
26 | ->getMock();
27 | $this->fileFactory = $this->getMockBuilder('Diarmuidie\EnvPopulate\File\Factory\FileFactory')
28 | ->getMock();
29 | }
30 |
31 | public function testInitialiseClass()
32 | {
33 | $processor = new Processor($this->composerIO, $this->fileFactory);
34 |
35 | $this->assertInstanceOf('Diarmuidie\EnvPopulate\Processor', $processor);
36 | }
37 |
38 | public function testThrowsExceptionForMissingExampleFile()
39 | {
40 | $this->file->method('fileExists')
41 | ->willReturn(false);
42 |
43 | $this->fileFactory->method('create')
44 | ->willReturn($this->file);
45 |
46 | $this->expectException(InvalidArgumentException::class);
47 |
48 | $processor = new Processor($this->composerIO, $this->fileFactory);
49 | $processor->processFile('example.file', 'generated.file');
50 | }
51 |
52 | public function testDoesWriteOutputIfNoValueNeedsToBeUpdated()
53 | {
54 | $exampleValues = array(
55 | 'VALUE_1' => '123',
56 | 'VALUE_2' => 'true'
57 | );
58 |
59 | $this->file->method('fileExists')
60 | ->willReturn(true);
61 | $this->file->method('getVariables')
62 | ->willReturn($exampleValues);
63 |
64 | $this->fileFactory->method('create')
65 | ->willReturn($this->file);
66 |
67 | $this->composerIO->expects($this->never())
68 | ->method('write');
69 |
70 | $processor = new Processor($this->composerIO, $this->fileFactory);
71 | $processor->processFile('example.file', 'generated.file');
72 | }
73 |
74 | public function testDoesntAskForValueIfNotInInteractiveMode()
75 | {
76 |
77 | $exampleFile = $this->file;
78 |
79 | $exampleFile->expects($this->once())
80 | ->method('fileExists')
81 | ->willReturn(true);
82 | $exampleFile->method('getVariables')
83 | ->willReturn(array('VALUE_1' => true));
84 |
85 | $generatedFile = $this->getMockBuilder('Diarmuidie\EnvPopulate\File\Env')
86 | ->setConstructorArgs(array('file.env'))
87 | ->getMock();
88 | $generatedFile->expects($this->once())
89 | ->method('fileExists')
90 | ->willReturn(false);
91 | $generatedFile->method('getVariables')
92 | ->willReturn(array());
93 | $generatedFile->expects($this->once())
94 | ->method('setVariable')
95 | ->with(
96 | $this->equalTo('VALUE_1'),
97 | $this->equalTo(true)
98 | );
99 | $generatedFile->expects($this->once())
100 | ->method('save');
101 |
102 | $this->fileFactory->method('create')
103 | ->will($this->onConsecutiveCalls($exampleFile, $generatedFile));
104 |
105 | $this->composerIO
106 | ->method('isInteractive')
107 | ->willReturn(false);
108 | $this->composerIO->expects($this->never())
109 | ->method('write');
110 |
111 | $processor = new Processor($this->composerIO, $this->fileFactory);
112 | $processor->processFile('example.file', 'generated.file');
113 | }
114 |
115 | public function testAsksForValueIfValueNeedsToBeUpdated()
116 | {
117 |
118 | $exampleFile = $this->file;
119 |
120 | $exampleFile->expects($this->once())
121 | ->method('fileExists')
122 | ->willReturn(true);
123 | $exampleFile->method('getVariables')
124 | ->willReturn(array('VALUE_1' => true));
125 |
126 | $generatedFile = $this->getMockBuilder('Diarmuidie\EnvPopulate\File\Env')
127 | ->setConstructorArgs(array('file.env'))
128 | ->getMock();
129 | $generatedFile->expects($this->once())
130 | ->method('fileExists')
131 | ->willReturn(false);
132 | $generatedFile->method('getVariables')
133 | ->willReturn(array());
134 | $generatedFile->expects($this->once())
135 | ->method('save');
136 |
137 | $this->fileFactory->method('create')
138 | ->will($this->onConsecutiveCalls($exampleFile, $generatedFile));
139 |
140 | $this->composerIO
141 | ->method('isInteractive')
142 | ->willReturn(true);
143 | $this->composerIO->expects($this->once())
144 | ->method('write');
145 | $this->composerIO->expects($this->once())
146 | ->method('ask')
147 | ->with($this->equalTo('VALUE_1 (true): '));
148 |
149 | $processor = new Processor($this->composerIO, $this->fileFactory);
150 | $processor->processFile('example.file', 'generated.file');
151 | }
152 | }
153 |
--------------------------------------------------------------------------------