├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .php_cs
├── .scrutinizer.yml
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── chkipper.json
├── composer.json
├── hidev.yml
├── history.md
├── logo.png
├── phpunit.xml.dist
├── src
├── Builder.php
├── Package.php
├── Plugin.php
├── configs
│ ├── Config.php
│ ├── ConfigFactory.php
│ ├── Defines.php
│ ├── DotEnv.php
│ ├── Params.php
│ ├── Rebuild.php
│ ├── System.php
│ └── __rebuild.php
├── exceptions
│ ├── BadConfigurationException.php
│ ├── CircularDependencyException.php
│ ├── Exception.php
│ ├── FailedReadException.php
│ ├── FailedWriteException.php
│ └── UnsupportedFileTypeException.php
├── readers
│ ├── AbstractReader.php
│ ├── EnvReader.php
│ ├── JsonReader.php
│ ├── PhpReader.php
│ ├── ReaderFactory.php
│ └── YamlReader.php
└── utils
│ ├── ClosureEncoder.php
│ ├── Helper.php
│ ├── RemoveArrayKeys.php
│ └── Resolver.php
├── tests
├── _bootstrap.php
├── composer.json
└── unit
│ ├── HelperTest.php
│ ├── PluginTest.php
│ ├── configs
│ └── ConfigFactoryTest.php
│ └── readers
│ └── ReaderFactoryTest.php
└── version
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ### What steps will reproduce the problem?
4 |
5 | ### What is the expected result?
6 |
7 | ### What do you get instead?
8 |
9 |
10 | ### Additional info
11 |
12 | | Q | A
13 | | ---------------- | ---
14 | | Version | 0.3.?
15 | | Composer Version | 1.8.?
16 | | PHP version | 7.?.?
17 | | Operating system |
18 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | | Q | A
2 | | -------------------- | ---
3 | | Bugfix? | ✔️/❌
4 | | Feature? | ✔️/❌
5 | | Break compatibility? | ✔️/❌
6 | | Tests pass? | ✔️/❌
7 | | Fix issues | #
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # local config
2 | /.env
3 | /hidev-local.yml
4 |
5 | # IDE & OS files
6 | .*.swp
7 | .DS_Store
8 | .buildpath
9 | .idea
10 | .project
11 | .settings
12 | Thumbs.db
13 | nbproject
14 |
15 | # composer internals
16 | /composer.lock
17 | /vendor
18 |
19 | # php-cs-fixer cache
20 | .php_cs.cache
21 |
22 | # phpunit generated files
23 | coverage.clover
24 |
25 | # dynamic files
26 | .phpunit.result.cache
27 |
28 | # Binaries
29 | chkipper.phar
30 | composer.phar
31 | ocular.phar
32 | php-cs-fixer.phar
33 | phpstan.phar
34 | phpunit-skelgen.phar
35 | phpunit.phar
36 |
37 | # hidev internals
38 | /.hidev/composer.json
39 | /.hidev/composer.lock
40 | /.hidev/runtime
41 | /.hidev/vendor
42 |
--------------------------------------------------------------------------------
/.php_cs:
--------------------------------------------------------------------------------
1 | setUsingCache(true)
14 | ->setRiskyAllowed(true)
15 | ->setRules(array(
16 | '@Symfony' => true,
17 | 'header_comment' => [
18 | 'header' => $header,
19 | 'separate' => 'bottom',
20 | 'location' => 'after_declare_strict',
21 | 'commentType' => 'PHPDoc',
22 | ],
23 | 'binary_operator_spaces' => [
24 | 'default' => null,
25 | ],
26 | 'concat_space' => ['spacing' => 'one'],
27 | 'array_syntax' => ['syntax' => 'short'],
28 | 'phpdoc_no_alias_tag' => ['replacements' => ['type' => 'var']],
29 | 'blank_line_before_return' => false,
30 | 'phpdoc_align' => false,
31 | 'phpdoc_scalar' => false,
32 | 'phpdoc_separation' => false,
33 | 'phpdoc_to_comment' => false,
34 | 'method_argument_space' => false,
35 | 'ereg_to_preg' => true,
36 | 'blank_line_after_opening_tag' => true,
37 | 'single_blank_line_before_namespace' => true,
38 | 'ordered_imports' => true,
39 | 'phpdoc_order' => true,
40 | 'pre_increment' => true,
41 | 'strict_comparison' => true,
42 | 'strict_param' => true,
43 | 'no_multiline_whitespace_before_semicolons' => true,
44 | 'semicolon_after_instruction' => false,
45 | 'yoda_style' => false,
46 | ))
47 | ->setFinder(
48 | PhpCsFixer\Finder::create()
49 | ->in(__DIR__)
50 | ->notPath('vendor')
51 | ->notPath('runtime')
52 | ->notPath('web/assets')
53 | )
54 | ;
55 |
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | checks:
2 | php:
3 | code_rating: true
4 | duplication: true
5 | tools:
6 | php_code_coverage:
7 | enabled: true
8 | external_code_coverage:
9 | timeout: 600
10 | build:
11 | nodes:
12 | analysis:
13 | tests:
14 | override: [php-scrutinizer-run]
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 7.2
5 | - 7.3
6 |
7 | # faster builds on new travis setup not using sudo
8 | sudo: false
9 |
10 | # cache vendor dirs
11 | cache:
12 | directories:
13 | - $HOME/.composer/cache
14 |
15 | install:
16 | - travis_retry composer self-update && composer --version
17 | - export PATH="$HOME/.composer/vendor/bin:$PATH"
18 | - travis_retry composer install --prefer-dist --no-interaction
19 |
20 | script:
21 | - |
22 | vendor/bin/phpunit $PHPUNIT_FLAGS --coverage-clover=coverage.clover
23 |
24 | after_script:
25 | - wget -c https://scrutinizer-ci.com/ocular.phar
26 | - php php-ocular code-coverage:upload --format=php-clover coverage.clover
27 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # hiqdev/composer-config-plugin
2 |
3 | ## [0.4.0] - 2020-03-08
4 |
5 | - Fixed config assembling on Windows ([@samdark])
6 | - Added configuring of output dir ([@hiqsol])
7 | - Added building alternative configs ([@hiqsol])
8 | - Added support for `vlucas/phpdotenv` v4 ([@jseliga])
9 | - Better work with env vars ([@hiqsol])
10 | - Used `riimu/kit-phpencoder` for variable exporting ([@hiqsol])
11 | - Bug fixes ([@hiqsol], [@SilverFire], [@samdark], [@noname007], [@jomonkj], [@machour])
12 |
13 | ## [0.3.0] - 2019-04-11
14 |
15 | - Fixed config reading and merging ([@hiqsol])
16 | - Added dev-only configs ([@hiqsol], [@samdark])
17 | - Changed to use `defines` files as is to keep values ([@hiqsol])
18 | - Reworked configuration files building ([@hiqsol], [@marclaporte], [@loveorigami])
19 |
20 | ## [0.2.5] - 2017-05-19
21 |
22 | - Added showing package dependencies hierarchy tree with `composer du -v` ([@hiqsol])
23 |
24 | ## [0.2.4] - 2017-05-18
25 |
26 | - Added proper resolving of config dependencies with `Resolver` class ([@hiqsol])
27 | - Fixed exportVar closures in Windows ([@SilverFire], [@edgardmessias])
28 |
29 | ## [0.2.3] - 2017-04-18
30 |
31 | - Added vendor dir arg to `Builder::path` to get config path at given vendor dir ([@hiqsol])
32 |
33 | ## [0.2.2] - 2017-04-12
34 |
35 | - Improved README ([@hiqsol])
36 | - Added support for `.env`, JSON and YAML ([@hiqsol])
37 |
38 | ## [0.2.1] - 2017-03-23
39 |
40 | - Fixed wrong call of `Composer\Config::get()` ([@SilverFire])
41 |
42 | ## [0.2.0] - 2017-03-15
43 |
44 | - Added initializaion of composer autoloading for project classes become usable in configs ([@hiqsol])
45 | - Added work with `$config_name` paths for use of already built config ([@hiqsol])
46 | - Renamed pathes -> paths everywhere ([@hiqsol])
47 | - Added collecting dev aliases for root package ([@hiqsol])
48 |
49 | ## [0.1.0] - 2016-12-26
50 |
51 | - Added proper rebuild ([@hiqsol])
52 | - Changed output dir to `composer-config-plugin-output` ([@hiqsol])
53 | - Changed: splitted out `Builder` ([@hiqsol])
54 | - Changed namespace to `hiqdev\composer\config` ([@hiqsol])
55 |
56 | ## [0.0.9] - 2016-09-22
57 |
58 | - Fixed infinite loop in case of circular dependencies in composer ([@hiqsol])
59 |
60 | ## [0.0.8] - 2016-08-27
61 |
62 | - Added showing ordered list of packages when verbose option ([@hiqsol])
63 |
64 | ## [0.0.7] - 2016-08-26
65 |
66 | - Fixed packages processing order again, used original `composer.json` ([@hiqsol])
67 |
68 | ## [0.0.6] - 2016-08-23
69 |
70 | - Fixed packages processing order ([@hiqsol])
71 |
72 | ## [0.0.5] - 2016-06-22
73 |
74 | - Added multiple defines ([@hiqsol])
75 |
76 | ## [0.0.4] - 2016-05-21
77 |
78 | - Added multiple configs and params ([@hiqsol])
79 |
80 | ## [0.0.3] - 2016-05-20
81 |
82 | - Changed aliases assembling ([@hiqsol])
83 |
84 | ## [0.0.2] - 2016-05-19
85 |
86 | - Removed replace composer-extension-plugin ([@hiqsol])
87 |
88 | ## [0.0.1] - 2016-05-18
89 |
90 | - Added basics ([@hiqsol])
91 |
92 | ## [Development started] - 2016-05-18
93 |
94 | [@SilverFire]: https://github.com/SilverFire
95 | [d.naumenko.a@gmail.com]: https://github.com/SilverFire
96 | [@tafid]: https://github.com/tafid
97 | [andreyklochok@gmail.com]: https://github.com/tafid
98 | [@BladeRoot]: https://github.com/BladeRoot
99 | [bladeroot@gmail.com]: https://github.com/BladeRoot
100 | [@hiqsol]: https://github.com/hiqsol
101 | [sol@hiqdev.com]: https://github.com/hiqsol
102 | [@edgardmessias]: https://github.com/edgardmessias
103 | [edgardmessias@gmail.com]: https://github.com/edgardmessias
104 | [@samdark]: https://github.com/samdark
105 | [sam@rmcreative.ru]: https://github.com/samdark
106 | [@loveorigami]: https://github.com/loveorigami
107 | [loveorigami@mail.ru]: https://github.com/loveorigami
108 | [@marclaporte]: https://github.com/marclaporte
109 | [marc@laporte.name]: https://github.com/marclaporte
110 | [@jseliga]: https://github.com/jseliga
111 | [seliga.honza@gmail.com]: https://github.com/jseliga
112 | [@machour]: https://github.com/machour
113 | [machour@gmail.com]: https://github.com/machour
114 | [@jomonkj]: https://github.com/jomonkj
115 | [jomon.entero@gmail.com]: https://github.com/jomonkj
116 | [@noname007]: https://github.com/noname007
117 | [soul11201@gmail.com]: https://github.com/noname007
118 | [Under development]: https://github.com/hiqdev/composer-config-plugin/compare/0.3.0...HEAD
119 | [0.0.9]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.8...0.0.9
120 | [0.0.8]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.7...0.0.8
121 | [0.0.7]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.6...0.0.7
122 | [0.0.6]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.5...0.0.6
123 | [0.0.5]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.4...0.0.5
124 | [0.0.4]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.3...0.0.4
125 | [0.0.3]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.2...0.0.3
126 | [0.0.2]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.1...0.0.2
127 | [0.0.1]: https://github.com/hiqdev/composer-config-plugin/releases/tag/0.0.1
128 | [0.1.0]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.9...0.1.0
129 | [0.2.0]: https://github.com/hiqdev/composer-config-plugin/compare/0.1.0...0.2.0
130 | [0.2.1]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.0...0.2.1
131 | [0.2.2]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.1...0.2.2
132 | [0.2.3]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.2...0.2.3
133 | [0.2.4]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.3...0.2.4
134 | [0.2.5]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.4...0.2.5
135 | [0.3.0]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.5...0.3.0
136 | [0.4.0]: https://github.com/hiqdev/composer-config-plugin/compare/0.3.0...0.4.0
137 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2016-2018, HiQDev (http://hiqdev.com/)
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in
12 | the documentation and/or other materials provided with the
13 | distribution.
14 | * Neither the name of HiQDev nor the names of its
15 | contributors may be used to endorse or promote products derived
16 | from this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DEPRECATED
2 |
3 | **in favour of [yiisoft/composer-config-plugin]**
4 |
5 | Create an issue if you have any problems.
6 |
7 | [yiisoft/composer-config-plugin]: https://github.com/yiisoft/composer-config-plugin
8 |
--------------------------------------------------------------------------------
/chkipper.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hiqdev/composer-config-plugin",
3 | "authors": {
4 | "hiqsol": {
5 | "name": "Andrii Vasyliev",
6 | "role": "Project lead",
7 | "email": "sol@hiqdev.com",
8 | "github": "https://github.com/hiqsol",
9 | "homepage": "http://hipanel.com/"
10 | },
11 | "SilverFire": {
12 | "name": "Dmitry Naumenko",
13 | "role": "Lead backend developer",
14 | "email": "d.naumenko.a@gmail.com",
15 | "github": "https://github.com/SilverFire",
16 | "homepage": "http://silverfire.me/"
17 | },
18 | "tafid": {
19 | "name": "Andrey Klochok",
20 | "role": "Lead frontend developer",
21 | "email": "andreyklochok@gmail.com",
22 | "github": "https://github.com/tafid",
23 | "homepage": "http://hiqdev.com/"
24 | },
25 | "BladeRoot": {
26 | "name": "Yuriy Myronchuk",
27 | "role": "QA Lead",
28 | "email": "bladeroot@gmail.com",
29 | "github": "https://github.com/BladeRoot",
30 | "homepage": "http://hiqdev.com/"
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hiqdev/composer-config-plugin",
3 | "type": "composer-plugin",
4 | "description": "Composer plugin for config assembling",
5 | "keywords": [
6 | "composer",
7 | "config",
8 | "assembling",
9 | "plugin"
10 | ],
11 | "homepage": "https://github.com/hiqdev/composer-config-plugin",
12 | "license": "BSD-3-Clause",
13 | "support": {
14 | "email": "support@hiqdev.com",
15 | "source": "https://github.com/hiqdev/composer-config-plugin",
16 | "issues": "https://github.com/hiqdev/composer-config-plugin/issues",
17 | "wiki": "https://github.com/hiqdev/composer-config-plugin/wiki",
18 | "forum": "http://forum.hiqdev.com/"
19 | },
20 | "authors": [
21 | {
22 | "name": "Andrii Vasyliev",
23 | "role": "Project lead",
24 | "email": "sol@hiqdev.com",
25 | "homepage": "http://hipanel.com/"
26 | },
27 | {
28 | "name": "Dmitry Naumenko",
29 | "role": "Lead backend developer",
30 | "email": "d.naumenko.a@gmail.com",
31 | "homepage": "http://silverfire.me/"
32 | },
33 | {
34 | "name": "Andrey Klochok",
35 | "role": "Lead frontend developer",
36 | "email": "andreyklochok@gmail.com",
37 | "homepage": "http://hiqdev.com/"
38 | },
39 | {
40 | "name": "Yuriy Myronchuk",
41 | "role": "QA Lead",
42 | "email": "bladeroot@gmail.com",
43 | "homepage": "http://hiqdev.com/"
44 | }
45 | ],
46 | "require": {
47 | "php": ">=7.1",
48 | "composer-plugin-api": "^1.0",
49 | "riimu/kit-phpencoder": "^2.4",
50 | "opis/closure": "^3.3"
51 | },
52 | "require-dev": {
53 | "phpunit/phpunit": "^7.0",
54 | "composer/composer": "~1.0@dev"
55 | },
56 | "suggest": {
57 | "vlucas/phpdotenv": "^2.0 for `.env` files support",
58 | "symfony/yaml": "^2.0 || ^3.0 || ^4.0 for YAML files support"
59 | },
60 | "autoload": {
61 | "psr-4": {
62 | "hiqdev\\composer\\config\\": "src"
63 | }
64 | },
65 | "extra": {
66 | "class": "hiqdev\\composer\\config\\Plugin",
67 | "branch-alias": {
68 | "dev-master": "1.0.x-dev"
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/hidev.yml:
--------------------------------------------------------------------------------
1 | package:
2 | type: composer-plugin
3 | name: composer-config-plugin
4 | title: Composer plugin for config assembling
5 | headline: Composer Config Plugin
6 | keywords: composer, config, assembling, plugin
7 | description: |
8 | This [Composer] plugin provides assembling
9 | of configurations distributed with composer packages.
10 | This allows to put configuration needed to use package right inside of
11 | the package thus implementing plugin system: package becomes a plugin
12 | holding both the code and it's configuration.
13 |
14 | How it works?
15 |
16 | - scans installed packages for `config-plugin` extra option in their
17 | `composer.json`
18 | - loads `dotenv` files to set `$_ENV` variables
19 | - requires `defines` files to set constants
20 | - requires `params` files
21 | - requires config files
22 | - options collected on earlier steps could and should be used in later
23 | steps, e.g. `$_ENV` should be used for constants and parameters, which
24 | in turn should be used for configs
25 | - files processing order is crucial to achieve expected behavior: options
26 | in root package have priority over options from included packages, more
27 | about it see below in **Files processing order** section
28 | - collected configs are written as PHP files in
29 | `vendor/hiqdev/composer-config-plugin-output`
30 | directory along with information needed to rebuild configs on demand
31 | - then assembled configs can be loaded into application with `require`
32 |
33 | **Read more** about the general idea behind this plugin in [english] or
34 | [russian].
35 |
36 | [composer]: https://getcomposer.org/
37 | [english]: https://hiqdev.com/pages/articles/app-organization
38 | [russian]: https://habrahabr.ru/post/329286/
39 |
40 | readme:
41 | forceRewrite: false
42 |
43 | plugins:
44 | hiqdev/composer-config-plugin: "dev-master"
45 | hiqdev/hidev-php: "dev-master"
46 | hiqdev/hidev-hiqdev: "dev-master"
47 | hiqdev/hidev-readme: "dev-master"
48 | hiqdev/hidev-chkipper: "dev-master"
49 | hiqdev/hidev-composer: "dev-master"
50 | hiqdev/hidev-license: "dev-master"
51 | hiqdev/hidev-php-cs-fixer: "dev-master"
52 | hiqdev/hidev-phpstan: "dev-master"
53 | hiqdev/hidev-phpunit: "dev-master"
54 | hiqdev/hidev-scrutinizer: "dev-master"
55 | hiqdev/hidev-travis: "dev-master"
56 |
--------------------------------------------------------------------------------
/history.md:
--------------------------------------------------------------------------------
1 | # hiqdev/composer-config-plugin
2 |
3 | ## [0.4.0] - 2020-03-08
4 |
5 | - Fixed config assembling on Windows
6 | - [217fcbe] 2020-02-21 Fix building config with custom dir under Windows [@samdark]
7 | - [341d3ad] 2020-02-06 Fix config assembly on Windows [@samdark]
8 | - Added configuring of output dir
9 | - [892eb6b] 2020-02-03 Fixed `findOutputDir` to work properly when output dir is not default [@hiqsol]
10 | - [2a84e31] 2020-01-21 Removed unused `OutputDir` class [@hiqsol]
11 | - [4d68359] 2020-02-20 Fixed problem with env vars leaking between alternatives [@hiqsol]
12 | - [0d92a2d] 2019-07-30 Added `config-plugin-output-dir` option description [@hiqsol]
13 | - [7e7b36e] 2019-07-30 Fixed writing to changed output dir [@hiqsol]
14 | - [8a6a588] 2019-07-25 Fixed taking proper dirname depth [@hiqsol]
15 | - [f1b4ff1] 2019-07-25 Added `OutputDir` NOT finished [@hiqsol]
16 | - Added building alternative configs
17 | - [e06125e] 2019-07-26 Fixed getting alternatives [@hiqsol]
18 | - [6a4eb47] 2019-07-25 Fixed bugs in getting alternatives, allowed alternatives file [@hiqsol]
19 | - [7317438] 2019-07-25 Added building `alternatives` [@hiqsol]
20 | - [b1c9639] 2019-07-25 Added more get extra values methods to `Package` class [@hiqsol]
21 | - [42f3c4e] 2019-07-25 Added `Config::clone()` [@hiqsol]
22 | - [910c127] 2019-07-25 Changed `EnvReader` to return all ENV values (was only new) [@hiqsol]
23 | - [1d6dd28] 2019-07-25 Fixed `ReaderFactory` to distinguish builders [@hiqsol]
24 | - Added support for `vlucas/phpdotenv` v4
25 | - [1db8b15] 2020-02-13 Added support for `vlucas/phpdotenv` v4 [@jseliga]
26 | - Better work with env vars
27 | - [d038a30] 2019-12-18 Allowed `-` in params for pushing env vars [@hiqsol]
28 | - [7fa31d1] 2019-10-24 Allowed to push env vars into config arrays [@hiqsol]
29 | - Used `riimu/kit-phpencoder` for variable exporting
30 | - [594aaab] 2019-07-02 Used `riimu/kit-phpencoder` for variable exporting [@hiqsol]
31 | - Bug fixes
32 | - [c18a233] 2020-03-05 Added test for `RemoveArrayKeys` [@hiqsol]
33 | - [c84e82e] 2020-03-05 Refactored out `utils` dir [@hiqsol]
34 | - [7d445fa] 2020-03-04 Added `RemoveArrayKeys` fix utility [@hiqsol]
35 | - [4a6b89c] 2020-02-29 Disabled readme generation by hidev [@hiqsol]
36 | - [fc0df4c] 2020-02-03 Disabled warning if `composer.json` not readable [@hiqsol]
37 | - [0ebcdea] 2020-01-17 Prevented infinite recursion in `getAllFiles()` #48 [@hiqsol]
38 | - [3fd5c38] 2020-01-11 Enabled wildcard config paths [@hiqsol]
39 | - [d238de7] 2019-08-13 Config::putFile() should throw an exception when dir can not be created [@SilverFire]
40 | - [e2e8c7b] 2019-08-25 Fixing files doubling #42 [@hiqsol]
41 | - [3babef6] 2019-08-25 Extended error message for better debugging [@hiqsol]
42 | - [266138a] 2019-08-20 Update README.md [@SilverFire]
43 | - [3e18cbe] 2019-08-01 Greatly simplified export of closures [@hiqsol]
44 | - [fb5a5d8] 2019-07-31 Fix #39: use opis/closure for dumping closure code [@samdark]
45 | - [b5fe4d5] 2019-07-31 Added `$params` initialization in configs [@hiqsol]
46 | - [ef8a42c] 2019-07-31 Redone travis config and require-dev phpunit [@hiqsol]
47 | - [a0401ea] 2019-07-31 Returned back memoization in ReaderFactory [@hiqsol]
48 | - [3d9bb59] 2019-07-31 Add issue and pull request templates [@samdark]
49 | - [77a8eac] 2019-07-04 Raised PHP version requirement to 7.1 #32 [@hiqsol]
50 | - [b36d5ad] 2019-07-04 add 7.0 [@noname007]
51 | - [820a9e6] 2019-05-12 Update Plugin.php [@jomonkj]
52 | - [4f8d841] 2019-04-23 Check both old & new Yii Array helpers classes [@machour]
53 |
54 | ## [0.3.0] - 2019-04-11
55 |
56 | - Fixed config reading and merging
57 | - [efcb091] 2019-04-11 Changed plugin versions to all dev-master [@hiqsol]
58 | - [597227a] 2019-03-22 Added support for both 2nd and 3rd versions of `phpdotenv` [@hiqsol]
59 | - [9f61a78] 2019-01-11 Added processing `UnsetArrayValue` and `ReplaceArrayValue`, allows to fix #20 [@hiqsol]
60 | - [83bc091] 2019-01-11 Added substitution and files reordering, fixes #19 [@hiqsol]
61 | - [0c8c821] 2018-12-20 Added `Plugin::addFile()` and used in loadDotEnv to prevent dublicating [@hiqsol]
62 | - Added dev-only configs
63 | - [959c971] 2018-12-08 Added `config-plugin-dev` [@hiqsol]
64 | - [faab5ed] 2018-12-05 Tuned output to fit composer 1.8+ [@hiqsol]
65 | - [49f65f7] 2018-11-15 Added skiping repeated values [@hiqsol]
66 | - [bf49430] 2018-10-08 Code style fixes (#16) [@samdark]
67 | - [e3e4f78] 2018-10-07 There's no need to duplicate docs since they're all in the readme [@samdark]
68 | - [f4ef5d2] 2018-10-07 More consistency [@samdark]
69 | - [1d807d0] 2018-10-07 Improved readme [@samdark]
70 | - [2543887] 2018-10-07 Explicitly declare PHP 7 requirement in composer.json [@samdark]
71 | - [5cbfdac] 2018-10-07 Fix wrong constructor call arguments [@samdark]
72 | - [99c5696] 2018-09-08 Added `COMPOSER_CONFIG_PLUGIN_BASEDIR` constant definition to generated configs [@hiqsol]
73 | - Changed to use `defines` files as is to keep values
74 | - [34cfa36] 2018-08-24 Fixed writing `defines` with added merging env vars [@hiqsol]
75 | - [3ec43a4] 2018-08-23 Changed `Defines` builder to `require_once` instead of require [@hiqsol]
76 | - [7e6e4fa] 2018-08-13 Redone `defines` building, require all instead of assembling [@hiqsol]
77 | - [6d2c277] 2018-08-03 Added `DotEnv` class, no defines and dotenv needed for dotenv [@hiqsol]
78 | - Reworked configuration files building
79 | - [ed34c6e] 2018-08-23 csfixed [@hiqsol]
80 | - [faf6cec] 2018-08-22 Added more type hinting [@hiqsol]
81 | - [8ba86d9] 2018-08-08 Collecting all `packages` instead of yii2-extensions only [@hiqsol]
82 | - [462c616] 2018-08-08 Removed check for `yii2-extension`, collecting aliases from all packages [@hiqsol]
83 | - [7534700] 2018-08-04 Added `1.0.x-dev` branch-alias [@hiqsol]
84 | - [22965f1] 2018-08-03 csfixed [@hiqsol]
85 | - [1d78abf] 2018-08-03 Added merging ENV vars in normal configs [@hiqsol]
86 | - [e88f547] 2018-08-01 Fixed `System::load()` to allow file not exist [@hiqsol]
87 | - [19b80be] 2018-07-31 Fixed `Builder::rebuild()` by fixing aliases loading [@hiqsol]
88 | - [3c7654c] 2018-07-31 Allowed return null in reference functions [@hiqsol]
89 | - [39fc269] 2018-07-31 Changed recommended config path to `config` (was src/config) [@hiqsol]
90 | - [03d7359] 2018-07-31 csfixed [@hiqsol]
91 | - [f73714d] 2018-07-31 Added lot of phpdocs [@hiqsol]
92 | - [3378133] 2018-07-31 Extracted package logic to `Package` class: prefer data from `composer.json` [@hiqsol]
93 | - [4e4f6b9] 2018-07-30 Added `suggest` section to composer.json [@hiqsol]
94 | - [8273a37] 2018-07-30 Moved aliases and extensions building to `Builder` [@hiqsol]
95 | - [5f84f43] 2018-07-30 Removed `__addition` config and `Builder::files` , passing files explicitly [@hiqsol]
96 | - [1d52609] 2018-07-30 Added `System` config `setValue()`, `mergeValues()` and `build()` [@hiqsol]
97 | - [5ccb875] 2018-07-30 Removed expired `Yii.php` loading stuff [@hiqsol]
98 | - [eba7d87] 2018-07-30 Removed `io` from `Builder` [@hiqsol]
99 | - [b8e8baf] 2018-07-28 Extracted `Config::renderVars()` method [@hiqsol]
100 | - [117b250] 2018-07-28 Removed `isSpecialConfig` (cleaning up) [@hiqsol]
101 | - [540be97] 2018-07-25 Fixed `substitutePath()` to substitute also exact path again [@hiqsol]
102 | - [1df0194] 2018-07-25 Merged rework [@hiqsol]
103 | - [349da2d] 2018-07-25 HUGE refactoring out config classes [@hiqsol]
104 | - [b08f320] 2018-07-25 Added tests for readers factory [@hiqsol]
105 | - [c2d1320] 2018-07-25 Refactored readers to have builder [@hiqsol]
106 | - [f4fd70b] 2018-07-25 Fixed `Helper::mergeConfig()` for empty arguments list [@hiqsol]
107 | - [8a9d349] 2018-07-25 Moved `ReaderFactory` to readers dir [@hiqsol]
108 | - [c02b3cd] 2018-07-25 csfixed [@hiqsol]
109 | - [5596670] 2018-07-20 Fixed `Builder::substitutePath()` to substitute also exact path [@hiqsol]
110 | - [77aa87a] 2018-07-10 Fixed collecting files list: adding only unique [@hiqsol]
111 | - [c3e0699] 2018-07-10 renamed application to `app` [@hiqsol]
112 | - [05af3cc] 2018-07-08 trying yii 3.0 version [@hiqsol]
113 | - [8304c24] 2018-07-08 removed unused `$rawParams` [@hiqsol]
114 | - [14a42b0] 2018-01-29 Merge pull request #5 from marclaporte/patch-1 [@hiqsol]
115 | - [af29b9b] 2018-01-27 Fix a typo [@marclaporte]
116 | - [b1a84e7] 2018-01-27 csfixed [@hiqsol]
117 | - [6796608] 2017-11-30 still fixing to work in Windows [@hiqsol]
118 | - [6621a38] 2017-11-30 Merge pull request #4 from loveorigami/patch-1 [@hiqsol]
119 | - [2e358df] 2017-11-30 normalizeDir for windows path [@loveorigami]
120 | - [167ae38] 2017-11-30 quickfixed to `normalizePath` to force unix directory separator for substitutions to work in Windows [@hiqsol]
121 | - [4c7e79d] 2017-11-19 added `normalizePath` to convert Windows backslashes to normal slashes [@hiqsol]
122 | - [fdc740a] 2017-10-17 csfixed [@hiqsol]
123 | - [2b9795d] 2017-10-17 fixed expects array error [@hiqsol]
124 | - [05fff11] 2017-10-17 added pushing env vars into params with `pushEnvVars` [@hiqsol]
125 | - [35823f1] 2017-09-27 disabled require Yii.php because it sets `Yii_` constants wrong [@hiqsol]
126 | - [32105a5] 2017-09-27 added require Yii in `Plugin::initAutoload` [@hiqsol]
127 | - [67bf230] 2017-09-27 csfixed [@hiqsol]
128 | - [bea1b98] 2017-09-27 switched to phpunit 6 [@hiqsol]
129 | - [078c488] 2017-09-27 added links to app-organization article [@hiqsol]
130 |
131 | ## [0.2.5] - 2017-05-19
132 |
133 | - Added showing package dependencies hierarchy tree with `composer du -v`
134 | - [a08ff85] 2017-05-19 csfixed [@hiqsol]
135 | - [f6b00f4] 2017-05-19 docs [@hiqsol]
136 | - [37dcf77] 2017-05-19 improved tree colors [@hiqsol]
137 | - [3ddd313] 2017-05-19 added showing packages hierarchy tree with `showDepsTree()` [@hiqsol]
138 | - [aaa59c6] 2017-05-19 docs [@hiqsol]
139 |
140 | ## [0.2.4] - 2017-05-18
141 |
142 | - Added proper resolving of config dependencies with `Resolver` class
143 | - [4889e11] 2017-05-18 removed phpunit 6 compatibility hack [@hiqsol]
144 | - [b38c0f5] 2017-05-11 csfixed [@hiqsol]
145 | - [bea8462] 2017-05-11 renamed `hidev.yml` <- .hidev/config.yml [@hiqsol]
146 | - [a0f372d] 2017-05-11 added proper resolving of config dependencies with `Resolver` class [@hiqsol]
147 | - Fixed exportVar closures in Windows
148 | - [b411092] 2017-04-28 Merge pull request #1 from edgardmessias/patch-1 [@SilverFire]
149 | - [42cf9ad] 2017-04-28 Fixed exportVar closures in Windows Environment [@edgardmessias]
150 |
151 | ## [0.2.3] - 2017-04-18
152 |
153 | - Added vendor dir arg to `Builder::path` to get config path at given vendor dir
154 | - [ed7f586] 2017-04-18 csfixed [@hiqsol]
155 | - [06c9079] 2017-04-18 added vendor dir optional argument to `Builder::path` [@hiqsol]
156 |
157 | ## [0.2.2] - 2017-04-12
158 |
159 | - Improved README
160 | - [2920c4e] 2017-04-12 added Known issues to readme [@hiqsol]
161 | - [4a317e4] 2017-04-12 greatly improved docs [@hiqsol]
162 | - Added support for `.env`, JSON and YAML
163 | - [43c0d3c] 2017-04-12 refactored out readers and ReaderFactory [@hiqsol]
164 | - [8ec1461] 2017-04-12 refactored exceptions [@hiqsol]
165 | - [e89b1ab] 2017-04-12 added saving loaded constants to `defines` [@hiqsol]
166 | - [94d957b] 2017-04-12 added saving loaded env vars [@hiqsol]
167 | - [a379609] 2017-04-12 added Collection stub [@hiqsol]
168 | - [dc0397a] 2017-04-11 changed `Plugin::addFiles`: renamed from processFiles and reversed order of `defines` [@hiqsol]
169 | - [66521da] 2017-04-05 changed dotenv loading to common used behavior: shell environment will override those set in the `.env` [@hiqsol]
170 | - [a490575] 2017-04-04 added support for JSON and YAML [@hiqsol]
171 | - [d11c2bb] 2017-04-04 added support for `.env` [@hiqsol]
172 |
173 | ## [0.2.1] - 2017-03-23
174 |
175 | - Fixed wrong call of `Composer\Config::get()`
176 | - [57e403a] 2017-03-23 csfixed [@SilverFire]
177 | - [33192bb] 2017-03-23 Added PHPUnit 6 compatibility [@SilverFire]
178 | - [d32060d] 2017-03-23 Updated travis config [@SilverFire]
179 | - [e1bea13] 2017-03-23 Fixed wrong call of composer\config::get() [@SilverFire]
180 |
181 | ## [0.2.0] - 2017-03-15
182 |
183 | - Added initializaion of composer autoloading for project classes become usable in configs
184 | - [e1d9513] 2017-03-15 added initAutoload [@hiqsol]
185 | - Added work with `$config_name` paths for use of already built config
186 | - [4555b54] 2017-03-09 csfixed [@hiqsol]
187 | - [9bba22d] 2017-03-09 added `$config` paths to include built configs [@hiqsol]
188 | - [5f3d05c] 2017-03-08 minor: grammarnazi pathes -> paths [@hiqsol]
189 | - [6d3fb2b] 2017-02-02 csfixed [@hiqsol]
190 | - [a8f42dd] 2017-02-02 return defines back to default list of files [@hiqsol]
191 | - Renamed pathes -> paths everywhere
192 | - [82a0652] 2017-02-02 renamed paths <- pathes [@hiqsol]
193 | - [c13991e] 2017-02-02 added exporting defines [@hiqsol]
194 | - [864f8b1] 2017-01-12 renamed `Builder::substitutePaths` <- substitutePathes [@hiqsol]
195 | - [2d68985] 2016-12-31 doc [@hiqsol]
196 | - Added collecting dev aliases for root package
197 | - [49f229b] 2016-12-26 + collect dev aliases for root package [@hiqsol]
198 |
199 | ## [0.1.0] - 2016-12-26
200 |
201 | - Added proper rebuild
202 | - [623d741] 2016-12-26 add FailedWriteException [@hiqsol]
203 | - [c71fd6f] 2016-12-26 fixed fileGet when file does not exist [@hiqsol]
204 | - [02019cd] 2016-12-26 csfixed work with skippable [@hiqsol]
205 | - [9f4362e] 2016-12-26 + proper propagating skippable sign [@hiqsol]
206 | - [778096f] 2016-12-26 + putFile: checks if content changed before writing [@hiqsol]
207 | - [42ffadd] 2016-12-26 fixed namespace in tests [@hiqsol]
208 | - [4554fdd] 2016-12-26 csfixed [@hiqsol]
209 | - [333717a] 2016-12-26 + use dev self for .hidev/vendor [@hiqsol]
210 | - [e61e88b] 2016-12-26 + copying `__rebuild` script [@hiqsol]
211 | - Changed output dir to `composer-config-plugin-output`
212 | - [2a4a539] 2016-12-26 CHANGED output dir to `composer-config-plugin-output` [@hiqsol]
213 | - [ec65010] 2016-12-26 changed: `path()` and substituting pathes moved into Builder [@hiqsol]
214 | - [436f10d] 2016-12-25 added work with `addition` [@hiqsol]
215 | - Changed: splitted out `Builder`
216 | - [b85299b] 2016-12-25 basically finished splitting out Builder [@hiqsol]
217 | - [c53bb32] 2016-12-24 + `Helper::className()` [@hiqsol]
218 | - Changed namespace to `hiqdev\composer\config`
219 | - [ab86c3c] 2016-12-24 started BIG redoing: changed namespace, added Builder, output to other dir [@hiqsol]
220 | - [e447659] 2016-12-23 doc [@hiqsol]
221 | - [e1565a6] 2016-10-04 removed use of `::class` to be older php compatible [@hiqsol]
222 |
223 | ## [0.0.9] - 2016-09-22
224 |
225 | - Fixed infinite loop in case of circular dependencies in composer
226 | - [434673d] 2016-09-22 fixed: prevented infinite loop in case of circular dependencies [@hiqsol]
227 | - [5b6b30e] 2016-09-14 improved readme [@hiqsol]
228 |
229 | ## [0.0.8] - 2016-08-27
230 |
231 | - Added showing ordered list of packages when verbose option
232 | - [5de8257] 2016-08-27 added showing list of packages if verbose [@hiqsol]
233 |
234 | ## [0.0.7] - 2016-08-26
235 |
236 | - Fixed packages processing order again, used original `composer.json`
237 | - [a9c0ba1] 2016-08-26 fixed scrutinizer issues [@hiqsol]
238 | - [cc15516] 2016-08-25 redone iterateDependencies and used getPrettyName() instead of getName() [@hiqsol]
239 |
240 | ## [0.0.6] - 2016-08-23
241 |
242 | - Fixed packages processing order
243 | - [c4bf7f9] 2016-08-23 more ideas [@hiqsol]
244 | - [8340080] 2016-08-23 + require-dev phpunit 5.5 [@hiqsol]
245 | - [e08e6c7] 2016-08-23 fixed tests for composer 5.5 [@hiqsol]
246 | - [94284df] 2016-08-23 csfixed [@hiqsol]
247 | - [2faafaa] 2016-08-23 redone to chkipper for bumping [@hiqsol]
248 | - [0e4f55b] 2016-08-23 added fixed packages processing order [@hiqsol]
249 |
250 | ## [0.0.5] - 2016-06-22
251 |
252 | - Added multiple defines
253 | - [e58cc7a] 2016-06-22 allowed travis build failure for PHP 5.5 [@hiqsol]
254 | - [5b84dc8] 2016-06-22 added ability to have multiple defines [@hiqsol]
255 | - [827d606] 2016-05-22 csfixed [@hiqsol]
256 |
257 | ## [0.0.4] - 2016-05-21
258 |
259 | - Added multiple configs and params
260 | - [e9c4899] 2016-05-21 forced arrays [@hiqsol]
261 | - [d1fdc77] 2016-05-20 + added multiple configs and params [@hiqsol]
262 |
263 | ## [0.0.3] - 2016-05-20
264 |
265 | - Changed aliases assembling
266 | - [1076668] 2016-05-20 csfixed [@hiqsol]
267 | - [174c848] 2016-05-19 simplified aliases assembling [@hiqsol]
268 | - [5f232e4] 2016-05-19 improved Idea [@hiqsol]
269 | - [a976f3e] 2016-05-19 added Idea readme section [@hiqsol]
270 |
271 | ## [0.0.2] - 2016-05-19
272 |
273 | - Removed replace composer-extension-plugin
274 | - [0a3d1a6] 2016-05-19 removed replace composer-extension-plugin [@hiqsol]
275 |
276 | ## [0.0.1] - 2016-05-18
277 |
278 | - Added basics
279 | - [15e92b4] 2016-05-18 fixed getting baseDir [@hiqsol]
280 | - [ec3bda1] 2016-05-18 rehideved [@hiqsol]
281 | - [470dc87] 2016-05-18 looks working [@hiqsol]
282 | - [65d1a3e] 2016-05-18 redoing [@hiqsol]
283 | - [927a73f] 2016-05-18 + replace composer-extension-plugin [@hiqsol]
284 | - [6270475] 2016-05-18 redoing [@hiqsol]
285 | - [79b5c49] 2016-05-18 inited [@hiqsol]
286 |
287 | ## [Development started] - 2016-05-18
288 |
289 | [@SilverFire]: https://github.com/SilverFire
290 | [d.naumenko.a@gmail.com]: https://github.com/SilverFire
291 | [@tafid]: https://github.com/tafid
292 | [andreyklochok@gmail.com]: https://github.com/tafid
293 | [@BladeRoot]: https://github.com/BladeRoot
294 | [bladeroot@gmail.com]: https://github.com/BladeRoot
295 | [@hiqsol]: https://github.com/hiqsol
296 | [sol@hiqdev.com]: https://github.com/hiqsol
297 | [@edgardmessias]: https://github.com/edgardmessias
298 | [edgardmessias@gmail.com]: https://github.com/edgardmessias
299 | [@samdark]: https://github.com/samdark
300 | [sam@rmcreative.ru]: https://github.com/samdark
301 | [@loveorigami]: https://github.com/loveorigami
302 | [loveorigami@mail.ru]: https://github.com/loveorigami
303 | [@marclaporte]: https://github.com/marclaporte
304 | [marc@laporte.name]: https://github.com/marclaporte
305 | [@jseliga]: https://github.com/jseliga
306 | [seliga.honza@gmail.com]: https://github.com/jseliga
307 | [@machour]: https://github.com/machour
308 | [machour@gmail.com]: https://github.com/machour
309 | [@jomonkj]: https://github.com/jomonkj
310 | [jomon.entero@gmail.com]: https://github.com/jomonkj
311 | [@noname007]: https://github.com/noname007
312 | [soul11201@gmail.com]: https://github.com/noname007
313 | [e58cc7a]: https://github.com/hiqdev/composer-config-plugin/commit/e58cc7a
314 | [5b84dc8]: https://github.com/hiqdev/composer-config-plugin/commit/5b84dc8
315 | [827d606]: https://github.com/hiqdev/composer-config-plugin/commit/827d606
316 | [e9c4899]: https://github.com/hiqdev/composer-config-plugin/commit/e9c4899
317 | [d1fdc77]: https://github.com/hiqdev/composer-config-plugin/commit/d1fdc77
318 | [1076668]: https://github.com/hiqdev/composer-config-plugin/commit/1076668
319 | [174c848]: https://github.com/hiqdev/composer-config-plugin/commit/174c848
320 | [5f232e4]: https://github.com/hiqdev/composer-config-plugin/commit/5f232e4
321 | [a976f3e]: https://github.com/hiqdev/composer-config-plugin/commit/a976f3e
322 | [0a3d1a6]: https://github.com/hiqdev/composer-config-plugin/commit/0a3d1a6
323 | [15e92b4]: https://github.com/hiqdev/composer-config-plugin/commit/15e92b4
324 | [ec3bda1]: https://github.com/hiqdev/composer-config-plugin/commit/ec3bda1
325 | [470dc87]: https://github.com/hiqdev/composer-config-plugin/commit/470dc87
326 | [65d1a3e]: https://github.com/hiqdev/composer-config-plugin/commit/65d1a3e
327 | [927a73f]: https://github.com/hiqdev/composer-config-plugin/commit/927a73f
328 | [6270475]: https://github.com/hiqdev/composer-config-plugin/commit/6270475
329 | [79b5c49]: https://github.com/hiqdev/composer-config-plugin/commit/79b5c49
330 | [0e4f55b]: https://github.com/hiqdev/composer-config-plugin/commit/0e4f55b
331 | [c4bf7f9]: https://github.com/hiqdev/composer-config-plugin/commit/c4bf7f9
332 | [8340080]: https://github.com/hiqdev/composer-config-plugin/commit/8340080
333 | [e08e6c7]: https://github.com/hiqdev/composer-config-plugin/commit/e08e6c7
334 | [94284df]: https://github.com/hiqdev/composer-config-plugin/commit/94284df
335 | [2faafaa]: https://github.com/hiqdev/composer-config-plugin/commit/2faafaa
336 | [cc15516]: https://github.com/hiqdev/composer-config-plugin/commit/cc15516
337 | [a9c0ba1]: https://github.com/hiqdev/composer-config-plugin/commit/a9c0ba1
338 | [5de8257]: https://github.com/hiqdev/composer-config-plugin/commit/5de8257
339 | [434673d]: https://github.com/hiqdev/composer-config-plugin/commit/434673d
340 | [5b6b30e]: https://github.com/hiqdev/composer-config-plugin/commit/5b6b30e
341 | [c71fd6f]: https://github.com/hiqdev/composer-config-plugin/commit/c71fd6f
342 | [02019cd]: https://github.com/hiqdev/composer-config-plugin/commit/02019cd
343 | [9f4362e]: https://github.com/hiqdev/composer-config-plugin/commit/9f4362e
344 | [778096f]: https://github.com/hiqdev/composer-config-plugin/commit/778096f
345 | [42ffadd]: https://github.com/hiqdev/composer-config-plugin/commit/42ffadd
346 | [4554fdd]: https://github.com/hiqdev/composer-config-plugin/commit/4554fdd
347 | [333717a]: https://github.com/hiqdev/composer-config-plugin/commit/333717a
348 | [e61e88b]: https://github.com/hiqdev/composer-config-plugin/commit/e61e88b
349 | [2a4a539]: https://github.com/hiqdev/composer-config-plugin/commit/2a4a539
350 | [ec65010]: https://github.com/hiqdev/composer-config-plugin/commit/ec65010
351 | [436f10d]: https://github.com/hiqdev/composer-config-plugin/commit/436f10d
352 | [b85299b]: https://github.com/hiqdev/composer-config-plugin/commit/b85299b
353 | [c53bb32]: https://github.com/hiqdev/composer-config-plugin/commit/c53bb32
354 | [ab86c3c]: https://github.com/hiqdev/composer-config-plugin/commit/ab86c3c
355 | [e447659]: https://github.com/hiqdev/composer-config-plugin/commit/e447659
356 | [e1565a6]: https://github.com/hiqdev/composer-config-plugin/commit/e1565a6
357 | [Under development]: https://github.com/hiqdev/composer-config-plugin/compare/0.3.0...HEAD
358 | [0.0.9]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.8...0.0.9
359 | [0.0.8]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.7...0.0.8
360 | [0.0.7]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.6...0.0.7
361 | [0.0.6]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.5...0.0.6
362 | [0.0.5]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.4...0.0.5
363 | [0.0.4]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.3...0.0.4
364 | [0.0.3]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.2...0.0.3
365 | [0.0.2]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.1...0.0.2
366 | [0.0.1]: https://github.com/hiqdev/composer-config-plugin/releases/tag/0.0.1
367 | [623d741]: https://github.com/hiqdev/composer-config-plugin/commit/623d741
368 | [0.1.0]: https://github.com/hiqdev/composer-config-plugin/compare/0.0.9...0.1.0
369 | [e1d9513]: https://github.com/hiqdev/composer-config-plugin/commit/e1d9513
370 | [4555b54]: https://github.com/hiqdev/composer-config-plugin/commit/4555b54
371 | [9bba22d]: https://github.com/hiqdev/composer-config-plugin/commit/9bba22d
372 | [5f3d05c]: https://github.com/hiqdev/composer-config-plugin/commit/5f3d05c
373 | [6d3fb2b]: https://github.com/hiqdev/composer-config-plugin/commit/6d3fb2b
374 | [a8f42dd]: https://github.com/hiqdev/composer-config-plugin/commit/a8f42dd
375 | [82a0652]: https://github.com/hiqdev/composer-config-plugin/commit/82a0652
376 | [c13991e]: https://github.com/hiqdev/composer-config-plugin/commit/c13991e
377 | [864f8b1]: https://github.com/hiqdev/composer-config-plugin/commit/864f8b1
378 | [2d68985]: https://github.com/hiqdev/composer-config-plugin/commit/2d68985
379 | [49f229b]: https://github.com/hiqdev/composer-config-plugin/commit/49f229b
380 | [0.2.0]: https://github.com/hiqdev/composer-config-plugin/compare/0.1.0...0.2.0
381 | [e1bea13]: https://github.com/hiqdev/composer-config-plugin/commit/e1bea13
382 | [0.2.1]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.0...0.2.1
383 | [57e403a]: https://github.com/hiqdev/composer-config-plugin/commit/57e403a
384 | [33192bb]: https://github.com/hiqdev/composer-config-plugin/commit/33192bb
385 | [d32060d]: https://github.com/hiqdev/composer-config-plugin/commit/d32060d
386 | [2920c4e]: https://github.com/hiqdev/composer-config-plugin/commit/2920c4e
387 | [43c0d3c]: https://github.com/hiqdev/composer-config-plugin/commit/43c0d3c
388 | [8ec1461]: https://github.com/hiqdev/composer-config-plugin/commit/8ec1461
389 | [e89b1ab]: https://github.com/hiqdev/composer-config-plugin/commit/e89b1ab
390 | [94d957b]: https://github.com/hiqdev/composer-config-plugin/commit/94d957b
391 | [a379609]: https://github.com/hiqdev/composer-config-plugin/commit/a379609
392 | [4a317e4]: https://github.com/hiqdev/composer-config-plugin/commit/4a317e4
393 | [dc0397a]: https://github.com/hiqdev/composer-config-plugin/commit/dc0397a
394 | [66521da]: https://github.com/hiqdev/composer-config-plugin/commit/66521da
395 | [a490575]: https://github.com/hiqdev/composer-config-plugin/commit/a490575
396 | [d11c2bb]: https://github.com/hiqdev/composer-config-plugin/commit/d11c2bb
397 | [0.2.2]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.1...0.2.2
398 | [ed7f586]: https://github.com/hiqdev/composer-config-plugin/commit/ed7f586
399 | [06c9079]: https://github.com/hiqdev/composer-config-plugin/commit/06c9079
400 | [0.2.3]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.2...0.2.3
401 | [4889e11]: https://github.com/hiqdev/composer-config-plugin/commit/4889e11
402 | [b38c0f5]: https://github.com/hiqdev/composer-config-plugin/commit/b38c0f5
403 | [bea8462]: https://github.com/hiqdev/composer-config-plugin/commit/bea8462
404 | [a0f372d]: https://github.com/hiqdev/composer-config-plugin/commit/a0f372d
405 | [b411092]: https://github.com/hiqdev/composer-config-plugin/commit/b411092
406 | [42cf9ad]: https://github.com/hiqdev/composer-config-plugin/commit/42cf9ad
407 | [0.2.4]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.3...0.2.4
408 | [a08ff85]: https://github.com/hiqdev/composer-config-plugin/commit/a08ff85
409 | [f6b00f4]: https://github.com/hiqdev/composer-config-plugin/commit/f6b00f4
410 | [37dcf77]: https://github.com/hiqdev/composer-config-plugin/commit/37dcf77
411 | [3ddd313]: https://github.com/hiqdev/composer-config-plugin/commit/3ddd313
412 | [aaa59c6]: https://github.com/hiqdev/composer-config-plugin/commit/aaa59c6
413 | [0.2.5]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.4...0.2.5
414 | [67bf230]: https://github.com/hiqdev/composer-config-plugin/commit/67bf230
415 | [bea1b98]: https://github.com/hiqdev/composer-config-plugin/commit/bea1b98
416 | [078c488]: https://github.com/hiqdev/composer-config-plugin/commit/078c488
417 | [34cfa36]: https://github.com/hiqdev/composer-config-plugin/commit/34cfa36
418 | [3ec43a4]: https://github.com/hiqdev/composer-config-plugin/commit/3ec43a4
419 | [ed34c6e]: https://github.com/hiqdev/composer-config-plugin/commit/ed34c6e
420 | [faf6cec]: https://github.com/hiqdev/composer-config-plugin/commit/faf6cec
421 | [7e6e4fa]: https://github.com/hiqdev/composer-config-plugin/commit/7e6e4fa
422 | [8ba86d9]: https://github.com/hiqdev/composer-config-plugin/commit/8ba86d9
423 | [462c616]: https://github.com/hiqdev/composer-config-plugin/commit/462c616
424 | [7534700]: https://github.com/hiqdev/composer-config-plugin/commit/7534700
425 | [6d2c277]: https://github.com/hiqdev/composer-config-plugin/commit/6d2c277
426 | [22965f1]: https://github.com/hiqdev/composer-config-plugin/commit/22965f1
427 | [1d78abf]: https://github.com/hiqdev/composer-config-plugin/commit/1d78abf
428 | [e88f547]: https://github.com/hiqdev/composer-config-plugin/commit/e88f547
429 | [19b80be]: https://github.com/hiqdev/composer-config-plugin/commit/19b80be
430 | [3c7654c]: https://github.com/hiqdev/composer-config-plugin/commit/3c7654c
431 | [39fc269]: https://github.com/hiqdev/composer-config-plugin/commit/39fc269
432 | [03d7359]: https://github.com/hiqdev/composer-config-plugin/commit/03d7359
433 | [f73714d]: https://github.com/hiqdev/composer-config-plugin/commit/f73714d
434 | [3378133]: https://github.com/hiqdev/composer-config-plugin/commit/3378133
435 | [4e4f6b9]: https://github.com/hiqdev/composer-config-plugin/commit/4e4f6b9
436 | [8273a37]: https://github.com/hiqdev/composer-config-plugin/commit/8273a37
437 | [5f84f43]: https://github.com/hiqdev/composer-config-plugin/commit/5f84f43
438 | [1d52609]: https://github.com/hiqdev/composer-config-plugin/commit/1d52609
439 | [5ccb875]: https://github.com/hiqdev/composer-config-plugin/commit/5ccb875
440 | [eba7d87]: https://github.com/hiqdev/composer-config-plugin/commit/eba7d87
441 | [b8e8baf]: https://github.com/hiqdev/composer-config-plugin/commit/b8e8baf
442 | [117b250]: https://github.com/hiqdev/composer-config-plugin/commit/117b250
443 | [540be97]: https://github.com/hiqdev/composer-config-plugin/commit/540be97
444 | [1df0194]: https://github.com/hiqdev/composer-config-plugin/commit/1df0194
445 | [349da2d]: https://github.com/hiqdev/composer-config-plugin/commit/349da2d
446 | [b08f320]: https://github.com/hiqdev/composer-config-plugin/commit/b08f320
447 | [c2d1320]: https://github.com/hiqdev/composer-config-plugin/commit/c2d1320
448 | [f4fd70b]: https://github.com/hiqdev/composer-config-plugin/commit/f4fd70b
449 | [8a9d349]: https://github.com/hiqdev/composer-config-plugin/commit/8a9d349
450 | [c02b3cd]: https://github.com/hiqdev/composer-config-plugin/commit/c02b3cd
451 | [5596670]: https://github.com/hiqdev/composer-config-plugin/commit/5596670
452 | [77aa87a]: https://github.com/hiqdev/composer-config-plugin/commit/77aa87a
453 | [c3e0699]: https://github.com/hiqdev/composer-config-plugin/commit/c3e0699
454 | [05af3cc]: https://github.com/hiqdev/composer-config-plugin/commit/05af3cc
455 | [8304c24]: https://github.com/hiqdev/composer-config-plugin/commit/8304c24
456 | [14a42b0]: https://github.com/hiqdev/composer-config-plugin/commit/14a42b0
457 | [af29b9b]: https://github.com/hiqdev/composer-config-plugin/commit/af29b9b
458 | [b1a84e7]: https://github.com/hiqdev/composer-config-plugin/commit/b1a84e7
459 | [6796608]: https://github.com/hiqdev/composer-config-plugin/commit/6796608
460 | [6621a38]: https://github.com/hiqdev/composer-config-plugin/commit/6621a38
461 | [2e358df]: https://github.com/hiqdev/composer-config-plugin/commit/2e358df
462 | [167ae38]: https://github.com/hiqdev/composer-config-plugin/commit/167ae38
463 | [4c7e79d]: https://github.com/hiqdev/composer-config-plugin/commit/4c7e79d
464 | [fdc740a]: https://github.com/hiqdev/composer-config-plugin/commit/fdc740a
465 | [2b9795d]: https://github.com/hiqdev/composer-config-plugin/commit/2b9795d
466 | [05fff11]: https://github.com/hiqdev/composer-config-plugin/commit/05fff11
467 | [35823f1]: https://github.com/hiqdev/composer-config-plugin/commit/35823f1
468 | [32105a5]: https://github.com/hiqdev/composer-config-plugin/commit/32105a5
469 | [efcb091]: https://github.com/hiqdev/composer-config-plugin/commit/efcb091
470 | [597227a]: https://github.com/hiqdev/composer-config-plugin/commit/597227a
471 | [9f61a78]: https://github.com/hiqdev/composer-config-plugin/commit/9f61a78
472 | [83bc091]: https://github.com/hiqdev/composer-config-plugin/commit/83bc091
473 | [0c8c821]: https://github.com/hiqdev/composer-config-plugin/commit/0c8c821
474 | [959c971]: https://github.com/hiqdev/composer-config-plugin/commit/959c971
475 | [faab5ed]: https://github.com/hiqdev/composer-config-plugin/commit/faab5ed
476 | [49f65f7]: https://github.com/hiqdev/composer-config-plugin/commit/49f65f7
477 | [bf49430]: https://github.com/hiqdev/composer-config-plugin/commit/bf49430
478 | [e3e4f78]: https://github.com/hiqdev/composer-config-plugin/commit/e3e4f78
479 | [f4ef5d2]: https://github.com/hiqdev/composer-config-plugin/commit/f4ef5d2
480 | [1d807d0]: https://github.com/hiqdev/composer-config-plugin/commit/1d807d0
481 | [2543887]: https://github.com/hiqdev/composer-config-plugin/commit/2543887
482 | [5cbfdac]: https://github.com/hiqdev/composer-config-plugin/commit/5cbfdac
483 | [99c5696]: https://github.com/hiqdev/composer-config-plugin/commit/99c5696
484 | [0.3.0]: https://github.com/hiqdev/composer-config-plugin/compare/0.2.5...0.3.0
485 | [c18a233]: https://github.com/hiqdev/composer-config-plugin/commit/c18a233
486 | [c84e82e]: https://github.com/hiqdev/composer-config-plugin/commit/c84e82e
487 | [7d445fa]: https://github.com/hiqdev/composer-config-plugin/commit/7d445fa
488 | [4a6b89c]: https://github.com/hiqdev/composer-config-plugin/commit/4a6b89c
489 | [217fcbe]: https://github.com/hiqdev/composer-config-plugin/commit/217fcbe
490 | [4d68359]: https://github.com/hiqdev/composer-config-plugin/commit/4d68359
491 | [1db8b15]: https://github.com/hiqdev/composer-config-plugin/commit/1db8b15
492 | [341d3ad]: https://github.com/hiqdev/composer-config-plugin/commit/341d3ad
493 | [fc0df4c]: https://github.com/hiqdev/composer-config-plugin/commit/fc0df4c
494 | [892eb6b]: https://github.com/hiqdev/composer-config-plugin/commit/892eb6b
495 | [2a84e31]: https://github.com/hiqdev/composer-config-plugin/commit/2a84e31
496 | [0ebcdea]: https://github.com/hiqdev/composer-config-plugin/commit/0ebcdea
497 | [3fd5c38]: https://github.com/hiqdev/composer-config-plugin/commit/3fd5c38
498 | [d038a30]: https://github.com/hiqdev/composer-config-plugin/commit/d038a30
499 | [7fa31d1]: https://github.com/hiqdev/composer-config-plugin/commit/7fa31d1
500 | [d238de7]: https://github.com/hiqdev/composer-config-plugin/commit/d238de7
501 | [e2e8c7b]: https://github.com/hiqdev/composer-config-plugin/commit/e2e8c7b
502 | [3babef6]: https://github.com/hiqdev/composer-config-plugin/commit/3babef6
503 | [266138a]: https://github.com/hiqdev/composer-config-plugin/commit/266138a
504 | [3e18cbe]: https://github.com/hiqdev/composer-config-plugin/commit/3e18cbe
505 | [fb5a5d8]: https://github.com/hiqdev/composer-config-plugin/commit/fb5a5d8
506 | [b5fe4d5]: https://github.com/hiqdev/composer-config-plugin/commit/b5fe4d5
507 | [ef8a42c]: https://github.com/hiqdev/composer-config-plugin/commit/ef8a42c
508 | [a0401ea]: https://github.com/hiqdev/composer-config-plugin/commit/a0401ea
509 | [3d9bb59]: https://github.com/hiqdev/composer-config-plugin/commit/3d9bb59
510 | [0d92a2d]: https://github.com/hiqdev/composer-config-plugin/commit/0d92a2d
511 | [7e7b36e]: https://github.com/hiqdev/composer-config-plugin/commit/7e7b36e
512 | [e06125e]: https://github.com/hiqdev/composer-config-plugin/commit/e06125e
513 | [6a4eb47]: https://github.com/hiqdev/composer-config-plugin/commit/6a4eb47
514 | [8a6a588]: https://github.com/hiqdev/composer-config-plugin/commit/8a6a588
515 | [f1b4ff1]: https://github.com/hiqdev/composer-config-plugin/commit/f1b4ff1
516 | [7317438]: https://github.com/hiqdev/composer-config-plugin/commit/7317438
517 | [b1c9639]: https://github.com/hiqdev/composer-config-plugin/commit/b1c9639
518 | [42f3c4e]: https://github.com/hiqdev/composer-config-plugin/commit/42f3c4e
519 | [910c127]: https://github.com/hiqdev/composer-config-plugin/commit/910c127
520 | [1d6dd28]: https://github.com/hiqdev/composer-config-plugin/commit/1d6dd28
521 | [77a8eac]: https://github.com/hiqdev/composer-config-plugin/commit/77a8eac
522 | [b36d5ad]: https://github.com/hiqdev/composer-config-plugin/commit/b36d5ad
523 | [594aaab]: https://github.com/hiqdev/composer-config-plugin/commit/594aaab
524 | [820a9e6]: https://github.com/hiqdev/composer-config-plugin/commit/820a9e6
525 | [4f8d841]: https://github.com/hiqdev/composer-config-plugin/commit/4f8d841
526 | [0.4.0]: https://github.com/hiqdev/composer-config-plugin/compare/0.3.0...0.4.0
527 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiqdev/composer-config-plugin/d092c526f864565fcab47411fb384b47aab39298/logo.png
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ./tests/unit/
6 |
7 |
8 |
9 |
10 | ./src/
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/Builder.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class Builder
22 | {
23 | /**
24 | * @var string path to output assembled configs
25 | */
26 | protected $outputDir;
27 |
28 | /**
29 | * @var array collected variables
30 | */
31 | protected $vars = [];
32 |
33 | /**
34 | * @var array configurations
35 | */
36 | protected $configs = [];
37 |
38 | const OUTPUT_DIR_SUFFIX = '-output';
39 |
40 | public function __construct($outputDir = null)
41 | {
42 | $this->setOutputDir($outputDir);
43 | }
44 |
45 | public function createAlternative($name): Builder
46 | {
47 | $dir = $this->outputDir . DIRECTORY_SEPARATOR . $name;
48 | $alt = new static($dir);
49 | foreach (['aliases', 'packages'] as $key) {
50 | $alt->configs[$key] = $this->getConfig($key)->clone($alt);
51 | }
52 |
53 | return $alt;
54 | }
55 |
56 | public function setOutputDir($outputDir)
57 | {
58 | $this->outputDir = $outputDir
59 | ? static::buildAbsPath($this->getBaseDir(), $outputDir)
60 | : static::findOutputDir();
61 | }
62 |
63 | public function getBaseDir(): string
64 | {
65 | return dirname(__DIR__, 4);
66 | }
67 |
68 | public function getOutputDir(): string
69 | {
70 | return $this->outputDir;
71 | }
72 |
73 | public static function rebuild($outputDir = null)
74 | {
75 | $builder = new self($outputDir);
76 | $files = $builder->getConfig('__files')->load();
77 | $builder->buildUserConfigs($files->getValues());
78 | }
79 |
80 | public function rebuildUserConfigs()
81 | {
82 | $this->getConfig('__files')->load();
83 | }
84 |
85 | /**
86 | * Returns default output dir.
87 | * @param string $baseDir path to project base dir
88 | * @return string
89 | */
90 | public static function findOutputDir(string $baseDir = null): string
91 | {
92 | $baseDir = $baseDir ?: static::findBaseDir();
93 | $path = $baseDir . DIRECTORY_SEPARATOR . 'composer.json';
94 | $data = @json_decode(file_get_contents($path), true);
95 | $dir = $data['extra'][Package::EXTRA_OUTPUT_DIR_OPTION_NAME] ?? null;
96 |
97 | return $dir ? static::buildAbsPath($baseDir, $dir) : static::defaultOutputDir($baseDir);
98 | }
99 |
100 | public static function findBaseDir(): string
101 | {
102 | return dirname(__DIR__, 4);
103 | }
104 |
105 | /**
106 | * Returns default output dir.
107 | * @param string $vendor path to vendor dir
108 | * @return string
109 | */
110 | public static function defaultOutputDir($baseDir = null): string
111 | {
112 | if ($baseDir) {
113 | $dir = $baseDir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'hiqdev' . DIRECTORY_SEPARATOR . basename(dirname(__DIR__));
114 | } else {
115 | $dir = \dirname(__DIR__);
116 | }
117 |
118 | return $dir . static::OUTPUT_DIR_SUFFIX;
119 | }
120 |
121 | /**
122 | * Returns full path to assembled config file.
123 | * @param string $filename name of config
124 | * @param string $baseDir path to base dir
125 | * @return string absolute path
126 | */
127 | public static function path($filename, $baseDir = null)
128 | {
129 | return static::buildAbsPath(static::findOutputDir($baseDir), $filename . '.php');
130 | }
131 |
132 | public static function buildAbsPath(string $dir, string $file): string
133 | {
134 | return strncmp($file, DIRECTORY_SEPARATOR, 1) === 0 ? $file : $dir . DIRECTORY_SEPARATOR . $file;
135 | }
136 |
137 | /**
138 | * Builds all (user and system) configs by given files list.
139 | * @param null|array $files files to process: config name => list of files
140 | */
141 | public function buildAllConfigs(array $files)
142 | {
143 | $this->buildUserConfigs($files);
144 | $this->buildSystemConfigs($files);
145 | }
146 |
147 | /**
148 | * Builds configs by given files list.
149 | * @param null|array $files files to process: config name => list of files
150 | */
151 | public function buildUserConfigs(array $files): array
152 | {
153 | $resolver = new Resolver($files);
154 | $files = $resolver->get();
155 | foreach ($files as $name => $paths) {
156 | $this->getConfig($name)->load($paths)->build()->write();
157 | }
158 |
159 | return $files;
160 | }
161 |
162 | public function buildSystemConfigs(array $files)
163 | {
164 | $this->getConfig('__files')->setValues($files);
165 | foreach (['__rebuild', '__files', 'aliases', 'packages'] as $name) {
166 | $this->getConfig($name)->build()->write();
167 | }
168 | }
169 |
170 | public function getOutputPath($name)
171 | {
172 | return $this->outputDir . DIRECTORY_SEPARATOR . $name . '.php';
173 | }
174 |
175 | protected function createConfig($name)
176 | {
177 | $config = ConfigFactory::create($this, $name);
178 | $this->configs[$name] = $config;
179 |
180 | return $config;
181 | }
182 |
183 | public function getConfig(string $name)
184 | {
185 | if (!isset($this->configs[$name])) {
186 | $this->configs[$name] = $this->createConfig($name);
187 | }
188 |
189 | return $this->configs[$name];
190 | }
191 |
192 | public function getVar($name, $key)
193 | {
194 | $config = $this->configs[$name] ?? null;
195 | if (empty($config)) {
196 | return null;
197 | }
198 |
199 | return $config->getValues()[$key] ?? null;
200 | }
201 |
202 | public function getVars()
203 | {
204 | $vars = [];
205 | foreach ($this->configs as $name => $config) {
206 | $vars[$name] = $config->getValues();
207 | }
208 |
209 | return $vars;
210 | }
211 |
212 | public function mergeAliases(array $aliases)
213 | {
214 | $this->getConfig('aliases')->mergeValues($aliases);
215 | }
216 |
217 | public function setPackage(string $name, array $data)
218 | {
219 | $this->getConfig('packages')->setValue($name, $data);
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/src/Package.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | class Package
24 | {
25 | const EXTRA_FILES_OPTION_NAME = 'config-plugin';
26 | const EXTRA_DEV_FILES_OPTION_NAME = 'config-plugin-dev';
27 | const EXTRA_OUTPUT_DIR_OPTION_NAME = 'config-plugin-output-dir';
28 | const EXTRA_ALTERNATIVES_OPTION_NAME = 'config-plugin-alternatives';
29 |
30 | private $options = ['output-dir', 'alternatives'];
31 |
32 | protected $package;
33 |
34 | /**
35 | * @var array composer.json raw data array
36 | */
37 | protected $data;
38 |
39 | /**
40 | * @var string absolute path to the root base directory
41 | */
42 | protected $baseDir;
43 |
44 | /**
45 | * @var string absolute path to vendor directory
46 | */
47 | protected $vendorDir;
48 |
49 | /**
50 | * @var Filesystem utility
51 | */
52 | protected $filesystem;
53 |
54 | private $composer;
55 |
56 | public function __construct(PackageInterface $package, Composer $composer)
57 | {
58 | $this->package = $package;
59 | $this->composer = $composer;
60 | }
61 |
62 | /**
63 | * Collects package aliases.
64 | * @return array collected aliases
65 | */
66 | public function collectAliases(): array
67 | {
68 | $aliases = array_merge(
69 | $this->prepareAliases('psr-0'),
70 | $this->prepareAliases('psr-4')
71 | );
72 | if ($this->isRoot()) {
73 | $aliases = array_merge($aliases,
74 | $this->prepareAliases('psr-0', true),
75 | $this->prepareAliases('psr-4', true)
76 | );
77 | }
78 |
79 | return $aliases;
80 | }
81 |
82 | /**
83 | * Prepare aliases.
84 | * @param string 'psr-0' or 'psr-4'
85 | * @param bool $dev
86 | * @return array
87 | */
88 | protected function prepareAliases($psr, $dev = false)
89 | {
90 | $autoload = $dev ? $this->getDevAutoload() : $this->getAutoload();
91 | if (empty($autoload[$psr])) {
92 | return [];
93 | }
94 |
95 | $aliases = [];
96 | foreach ($autoload[$psr] as $name => $path) {
97 | if (is_array($path)) {
98 | // ignore psr-4 autoload specifications with multiple search paths
99 | // we can not convert them into aliases as they are ambiguous
100 | continue;
101 | }
102 | $name = str_replace('\\', '/', trim($name, '\\'));
103 | $path = $this->preparePath($path);
104 | if ('psr-0' === $psr) {
105 | $path .= '/' . $name;
106 | }
107 | $aliases["@$name"] = $path;
108 | }
109 |
110 | return $aliases;
111 | }
112 |
113 | /**
114 | * @return string package pretty name, like: vendor/name
115 | */
116 | public function getPrettyName(): string
117 | {
118 | return $this->package->getPrettyName();
119 | }
120 |
121 | /**
122 | * @return string package version, like: 3.0.16.0, 9999999-dev
123 | */
124 | public function getVersion(): string
125 | {
126 | return $this->package->getVersion();
127 | }
128 |
129 | /**
130 | * @return string package human friendly version, like: 5.x-dev d9aed42, 2.1.1, dev-master f6561bf
131 | */
132 | public function getFullPrettyVersion(): string
133 | {
134 | return $this->package->getFullPrettyVersion();
135 | }
136 |
137 | /**
138 | * @return string package CVS revision, like: 3a4654ac9655f32888efc82fb7edf0da517d8995
139 | */
140 | public function getSourceReference(): ?string
141 | {
142 | return $this->package->getSourceReference();
143 | }
144 |
145 | /**
146 | * @return string package dist revision, like: 3a4654ac9655f32888efc82fb7edf0da517d8995
147 | */
148 | public function getDistReference(): ?string
149 | {
150 | return $this->package->getDistReference();
151 | }
152 |
153 | /**
154 | * @return bool is package complete
155 | */
156 | public function isComplete(): bool
157 | {
158 | return $this->package instanceof CompletePackageInterface;
159 | }
160 |
161 | /**
162 | * @return bool is this a root package
163 | */
164 | public function isRoot(): bool
165 | {
166 | return $this->package instanceof RootPackageInterface;
167 | }
168 |
169 | /**
170 | * @return string package type, like: package, library
171 | */
172 | public function getType(): string
173 | {
174 | return $this->getRawValue('type') ?? $this->package->getType();
175 | }
176 |
177 | /**
178 | * @return array autoload configuration array
179 | */
180 | public function getAutoload(): array
181 | {
182 | return $this->getRawValue('autoload') ?? $this->package->getAutoload();
183 | }
184 |
185 | /**
186 | * @return array autoload-dev configuration array
187 | */
188 | public function getDevAutoload(): array
189 | {
190 | return $this->getRawValue('autoload-dev') ?? $this->package->getDevAutoload();
191 | }
192 |
193 | /**
194 | * @return array requre configuration array
195 | */
196 | public function getRequires(): array
197 | {
198 | return $this->getRawValue('require') ?? $this->package->getRequires();
199 | }
200 |
201 | /**
202 | * @return array requre-dev configuration array
203 | */
204 | public function getDevRequires(): array
205 | {
206 | return $this->getRawValue('require-dev') ?? $this->package->getDevRequires();
207 | }
208 |
209 | /**
210 | * @return array files array
211 | */
212 | public function getFiles(): array
213 | {
214 | return $this->getExtraValue(self::EXTRA_FILES_OPTION_NAME, []);
215 | }
216 |
217 | /**
218 | * @return array dev-files array
219 | */
220 | public function getDevFiles(): array
221 | {
222 | return $this->getExtraValue(self::EXTRA_DEV_FILES_OPTION_NAME, []);
223 | }
224 |
225 | /**
226 | * @return array output-dir option
227 | */
228 | public function getOutputDir(): ?string
229 | {
230 | return $this->getExtraValue(self::EXTRA_OUTPUT_DIR_OPTION_NAME);
231 | }
232 |
233 | /**
234 | * @return mixed alternatives array or path to config
235 | */
236 | public function getAlternatives()
237 | {
238 | return $this->getExtraValue(self::EXTRA_ALTERNATIVES_OPTION_NAME);
239 | }
240 |
241 | /**
242 | * @return array alternatives array
243 | */
244 | public function getExtraValue($key, $default = null)
245 | {
246 | return $this->getExtra()[$key] ?? $default;
247 | }
248 |
249 | /**
250 | * @return array extra configuration array
251 | */
252 | public function getExtra(): array
253 | {
254 | return $this->getRawValue('extra') ?? $this->package->getExtra();
255 | }
256 |
257 | /**
258 | * @param string $name option name
259 | * @return mixed raw value from composer.json if available
260 | */
261 | public function getRawValue(string $name)
262 | {
263 | if ($this->data === null) {
264 | $this->data = $this->readRawData();
265 | }
266 |
267 | return $this->data[$name] ?? null;
268 | }
269 |
270 | /**
271 | * @return mixed all raw data from composer.json if available
272 | */
273 | public function getRawData(): array
274 | {
275 | if ($this->data === null) {
276 | $this->data = $this->readRawData();
277 | }
278 |
279 | return $this->data;
280 | }
281 |
282 | /**
283 | * @return array composer.json contents as array
284 | */
285 | protected function readRawData(): array
286 | {
287 | $path = $this->preparePath('composer.json');
288 | if (file_exists($path)) {
289 | return json_decode(file_get_contents($path), true);
290 | }
291 |
292 | return [];
293 | }
294 |
295 | /**
296 | * Builds path inside of a package.
297 | * @param string $file
298 | * @return string absolute paths will stay untouched
299 | */
300 | public function preparePath(string $file): string
301 | {
302 | if (0 === strncmp($file, '$', 1)) {
303 | return $file;
304 | }
305 |
306 | $skippable = 0 === strncmp($file, '?', 1) ? '?' : '';
307 | if ($skippable) {
308 | $file = substr($file, 1);
309 | }
310 |
311 | if (!$this->getFilesystem()->isAbsolutePath($file)) {
312 | $prefix = $this->isRoot()
313 | ? $this->getBaseDir()
314 | : $this->getVendorDir() . '/' . $this->getPrettyName();
315 | $file = $prefix . '/' . $file;
316 | }
317 |
318 | return $skippable . $this->getFilesystem()->normalizePath($file);
319 | }
320 |
321 | /**
322 | * Get absolute path to package base dir.
323 | * @return string
324 | */
325 | public function getBaseDir()
326 | {
327 | if (null === $this->baseDir) {
328 | $this->baseDir = dirname($this->getVendorDir());
329 | }
330 |
331 | return $this->baseDir;
332 | }
333 |
334 | /**
335 | * Get absolute path to composer vendor dir.
336 | * @return string
337 | */
338 | public function getVendorDir()
339 | {
340 | if (null === $this->vendorDir) {
341 | $dir = $this->composer->getConfig()->get('vendor-dir');
342 | $this->vendorDir = $this->getFilesystem()->normalizePath($dir);
343 | }
344 |
345 | return $this->vendorDir;
346 | }
347 |
348 | /**
349 | * Getter for filesystem utility.
350 | * @return Filesystem
351 | */
352 | public function getFilesystem()
353 | {
354 | if (null === $this->filesystem) {
355 | $this->filesystem = new Filesystem();
356 | }
357 |
358 | return $this->filesystem;
359 | }
360 | }
361 |
--------------------------------------------------------------------------------
/src/Plugin.php:
--------------------------------------------------------------------------------
1 |
27 | */
28 | class Plugin implements PluginInterface, EventSubscriberInterface
29 | {
30 | /**
31 | * @var Package[] the array of active composer packages
32 | */
33 | protected $packages;
34 |
35 | private $alternatives = [];
36 |
37 | private $outputDir;
38 |
39 | private $rootPackage;
40 |
41 | /**
42 | * @var array config name => list of files
43 | */
44 | protected $files = [
45 | 'dotenv' => [],
46 | 'defines' => [],
47 | 'params' => [],
48 | ];
49 |
50 | protected $colors = ['red', 'green', 'yellow', 'cyan', 'magenta', 'blue'];
51 |
52 | /**
53 | * @var array package name => configs as listed in `composer.json`
54 | */
55 | protected $originalFiles = [];
56 |
57 | /**
58 | * @var Builder
59 | */
60 | protected $builder;
61 |
62 | /**
63 | * @var Composer instance
64 | */
65 | protected $composer;
66 |
67 | /**
68 | * @var IOInterface
69 | */
70 | public $io;
71 |
72 | /**
73 | * Initializes the plugin object with the passed $composer and $io.
74 | * @param Composer $composer
75 | * @param IOInterface $io
76 | */
77 | public function activate(Composer $composer, IOInterface $io)
78 | {
79 | $this->composer = $composer;
80 | $this->io = $io;
81 | }
82 |
83 | /**
84 | * Returns list of events the plugin is subscribed to.
85 | * @return array list of events
86 | */
87 | public static function getSubscribedEvents()
88 | {
89 | return [
90 | ScriptEvents::POST_AUTOLOAD_DUMP => [
91 | ['onPostAutoloadDump', 0],
92 | ],
93 | ];
94 | }
95 |
96 | /**
97 | * This is the main function.
98 | * @param Event $event
99 | */
100 | public function onPostAutoloadDump(Event $event)
101 | {
102 | $this->io->overwriteError('Assembling config files');
103 |
104 | $this->builder = new Builder();
105 |
106 | $this->initAutoload();
107 | $this->scanPackages();
108 | $this->reorderFiles();
109 | $this->showDepsTree();
110 |
111 | $this->builder->setOutputDir($this->outputDir);
112 | $this->builder->buildAllConfigs($this->files);
113 |
114 | $saveFiles = $this->files;
115 | $saveEnv = $_ENV;
116 | foreach ($this->alternatives as $name => $files) {
117 | $this->files = $saveFiles;
118 | $_ENV = $saveEnv;
119 | $builder = $this->builder->createAlternative($name);
120 | $this->addFiles($this->rootPackage, $files);
121 | $builder->buildAllConfigs($this->files);
122 | }
123 | }
124 |
125 | protected function initAutoload()
126 | {
127 | $dir = dirname(dirname(dirname(__DIR__)));
128 | require_once "$dir/autoload.php";
129 | }
130 |
131 | protected function scanPackages()
132 | {
133 | foreach ($this->getPackages() as $package) {
134 | if ($package->isComplete()) {
135 | $this->processPackage($package);
136 | }
137 | }
138 | }
139 |
140 | protected function reorderFiles(): void
141 | {
142 | foreach (array_keys($this->files) as $name) {
143 | $this->files[$name] = $this->getAllFiles($name);
144 | }
145 | foreach ($this->files as $name => $files) {
146 | $this->files[$name] = $this->orderFiles($files);
147 | }
148 | }
149 |
150 | protected function getAllFiles(string $name, array $stack = []): array
151 | {
152 | if (empty($this->files[$name])) {
153 | return[];
154 | }
155 | $res = [];
156 | foreach ($this->files[$name] as $file) {
157 | if (strncmp($file, '$', 1) === 0) {
158 | if (!in_array($name, $stack, true)) {
159 | $res = array_merge($res, $this->getAllFiles(substr($file, 1), array_merge($stack, [$name])));
160 | }
161 | } else {
162 | $res[] = $file;
163 | }
164 | }
165 |
166 | return $res;
167 | }
168 |
169 | protected function orderFiles(array $files): array
170 | {
171 | if (empty($files)) {
172 | return [];
173 | }
174 | $keys = array_combine($files, $files);
175 | $res = [];
176 | foreach ($this->orderedFiles as $file) {
177 | if (isset($keys[$file])) {
178 | $res[$file] = $file;
179 | }
180 | }
181 |
182 | return array_values($res);
183 | }
184 |
185 | /**
186 | * Scans the given package and collects packages data.
187 | * @param Package $package
188 | */
189 | protected function processPackage(Package $package)
190 | {
191 | $files = $package->getFiles();
192 | $this->originalFiles[$package->getPrettyName()] = $files;
193 |
194 | if (!empty($files)) {
195 | $this->addFiles($package, $files);
196 | }
197 | if ($package->isRoot()) {
198 | $this->rootPackage = $package;
199 | $this->loadDotEnv($package);
200 | $devFiles = $package->getDevFiles();
201 | if (!empty($devFiles)) {
202 | $this->addFiles($package, $devFiles);
203 | }
204 | $this->outputDir = $package->getOutputDir();
205 | $alternatives = $package->getAlternatives();
206 | if (is_string($alternatives)) {
207 | $this->alternatives = $this->readConfig($package, $alternatives);
208 | } elseif (is_array($alternatives)) {
209 | $this->alternatives = $alternatives;
210 | } elseif (!empty($alternatives)) {
211 | throw new BadConfigurationException('alternatives must be array or path to configuration file');
212 | }
213 | }
214 |
215 | $aliases = $package->collectAliases();
216 |
217 | $this->builder->mergeAliases($aliases);
218 | $this->builder->setPackage($package->getPrettyName(), array_filter([
219 | 'name' => $package->getPrettyName(),
220 | 'version' => $package->getVersion(),
221 | 'reference' => $package->getSourceReference() ?: $package->getDistReference(),
222 | 'aliases' => $aliases,
223 | ]));
224 | }
225 |
226 | private function readConfig($package, $file): array
227 | {
228 | $path = $package->preparePath($file);
229 | if (!file_exists($path)) {
230 | throw new FailedReadException("failed read file: $file");
231 | }
232 | $reader = ReaderFactory::get($this->builder, $path);
233 |
234 | return $reader->read($path);
235 |
236 | }
237 |
238 | protected function loadDotEnv(Package $package)
239 | {
240 | $path = $package->preparePath('.env');
241 | if (file_exists($path) && class_exists('Dotenv\Dotenv')) {
242 | $this->addFile($package, 'dotenv', $path);
243 | }
244 | }
245 |
246 | /**
247 | * Adds given files to the list of files to be processed.
248 | * Prepares `defines` in reversed order (outer package first) because
249 | * constants cannot be redefined.
250 | * @param Package $package
251 | * @param array $files
252 | */
253 | protected function addFiles(Package $package, array $files)
254 | {
255 | foreach ($files as $name => $paths) {
256 | $paths = (array) $paths;
257 | if ('defines' === $name) {
258 | $paths = array_reverse($paths);
259 | }
260 | foreach ($paths as $path) {
261 | $this->addFile($package, $name, $path);
262 | }
263 | }
264 | }
265 |
266 | protected $orderedFiles = [];
267 |
268 | protected function addFile(Package $package, string $name, string $path)
269 | {
270 | $path = $package->preparePath($path);
271 | if (!isset($this->files[$name])) {
272 | $this->files[$name] = [];
273 | }
274 | if (in_array($path, $this->files[$name], true)) {
275 | return;
276 | }
277 | if ('defines' === $name) {
278 | array_unshift($this->orderedFiles, $path);
279 | array_unshift($this->files[$name], $path);
280 | } else {
281 | array_push($this->orderedFiles, $path);
282 | array_push($this->files[$name], $path);
283 | }
284 | }
285 |
286 | /**
287 | * Sets [[packages]].
288 | * @param Package[] $packages
289 | */
290 | public function setPackages(array $packages)
291 | {
292 | $this->packages = $packages;
293 | }
294 |
295 | /**
296 | * Gets [[packages]].
297 | * @return Package[]
298 | */
299 | public function getPackages()
300 | {
301 | if (null === $this->packages) {
302 | $this->packages = $this->findPackages();
303 | }
304 |
305 | return $this->packages;
306 | }
307 |
308 | /**
309 | * Plain list of all project dependencies (including nested) as provided by composer.
310 | * The list is unordered (chaotic, can be different after every update).
311 | */
312 | protected $plainList = [];
313 |
314 | /**
315 | * Ordered list of package in form: package => depth
316 | * For order description @see findPackages.
317 | */
318 | protected $orderedList = [];
319 |
320 | /**
321 | * Returns ordered list of packages:
322 | * - listed earlier in the composer.json will get earlier in the list
323 | * - childs before parents.
324 | * @return Package[]
325 | */
326 | public function findPackages()
327 | {
328 | $root = new Package($this->composer->getPackage(), $this->composer);
329 | $this->plainList[$root->getPrettyName()] = $root;
330 | foreach ($this->composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages() as $package) {
331 | $this->plainList[$package->getPrettyName()] = new Package($package, $this->composer);
332 | }
333 | $this->orderedList = [];
334 | $this->iteratePackage($root, true);
335 |
336 | $res = [];
337 | foreach (array_keys($this->orderedList) as $name) {
338 | $res[] = $this->plainList[$name];
339 | }
340 |
341 | return $res;
342 | }
343 |
344 | /**
345 | * Iterates through package dependencies.
346 | * @param Package $package to iterate
347 | * @param bool $includingDev process development dependencies, defaults to not process
348 | */
349 | protected function iteratePackage(Package $package, $includingDev = false)
350 | {
351 | $name = $package->getPrettyName();
352 |
353 | /// prevent infinite loop in case of circular dependencies
354 | static $processed = [];
355 | if (isset($processed[$name])) {
356 | return;
357 | } else {
358 | $processed[$name] = 1;
359 | }
360 |
361 | /// package depth in dependency hierarchy
362 | static $depth = 0;
363 | ++$depth;
364 |
365 | $this->iterateDependencies($package);
366 | if ($includingDev) {
367 | $this->iterateDependencies($package, true);
368 | }
369 | if (!isset($this->orderedList[$name])) {
370 | $this->orderedList[$name] = $depth;
371 | }
372 |
373 | --$depth;
374 | }
375 |
376 | /**
377 | * Iterates dependencies of the given package.
378 | * @param Package $package
379 | * @param bool $dev which dependencies to iterate: true - dev, default - general
380 | */
381 | protected function iterateDependencies(Package $package, $dev = false)
382 | {
383 | $deps = $dev ? $package->getDevRequires() : $package->getRequires();
384 | foreach (array_keys($deps) as $target) {
385 | if (isset($this->plainList[$target]) && empty($this->orderedList[$target])) {
386 | $this->iteratePackage($this->plainList[$target]);
387 | }
388 | }
389 | }
390 |
391 | protected function showDepsTree()
392 | {
393 | if (!$this->io->isVerbose()) {
394 | return;
395 | }
396 |
397 | foreach (array_reverse($this->orderedList) as $name => $depth) {
398 | $deps = $this->originalFiles[$name];
399 | $color = $this->colors[$depth % count($this->colors)];
400 | $indent = str_repeat(' ', $depth - 1);
401 | $package = $this->plainList[$name];
402 | $showdeps = $deps ? '[' . implode(',', array_keys($deps)) . ']>' : '';
403 | $this->io->write(sprintf('%s - %s> %s %s', $indent, $color, $name, $package->getFullPrettyVersion(), $showdeps));
404 | }
405 | }
406 | }
407 |
--------------------------------------------------------------------------------
/src/configs/Config.php:
--------------------------------------------------------------------------------
1 |
23 | */
24 | class Config
25 | {
26 | const UNIX_DS = '/';
27 | const BASE_DIR_MARKER = '<<>>';
28 |
29 | /**
30 | * @var string config name
31 | */
32 | protected $name;
33 |
34 | /**
35 | * @var array sources - paths to config source files
36 | */
37 | protected $sources = [];
38 |
39 | /**
40 | * @var array config value
41 | */
42 | protected $values = [];
43 |
44 | /**
45 | * @var Builder
46 | */
47 | protected $builder;
48 |
49 | public function __construct(Builder $builder, string $name)
50 | {
51 | $this->builder = $builder;
52 | $this->name = $name;
53 | }
54 |
55 | public function clone(Builder $builder)
56 | {
57 | $config = new Config($builder, $this->name);
58 | $config->sources = $this->sources;
59 | $config->values = $this->values;
60 |
61 | return $config;
62 | }
63 |
64 | public function getBuilder(): Builder
65 | {
66 | return $this->builder;
67 | }
68 |
69 | public function getName(): string
70 | {
71 | return $this->name;
72 | }
73 |
74 | public function getValues(): array
75 | {
76 | return $this->values;
77 | }
78 |
79 | public function load(array $paths = []): self
80 | {
81 | $this->sources = $this->loadFiles($paths);
82 |
83 | return $this;
84 | }
85 |
86 | protected function loadFiles(array $paths): array
87 | {
88 | switch (count($paths)) {
89 | case 0:
90 | return [];
91 | case 1:
92 | return [$this->loadFile(reset($paths))];
93 | }
94 |
95 | $configs = [];
96 | foreach ($paths as $path) {
97 | $cs = $this->loadFiles($this->glob($path));
98 | foreach ($cs as $config) {
99 | if (!empty($config)) {
100 | $configs[] = $config;
101 | }
102 | }
103 | }
104 |
105 | return $configs;
106 | }
107 |
108 | protected function glob(string $path): array
109 | {
110 | if (strpos($path, '*') === FALSE) {
111 | return [$path];
112 | }
113 |
114 | return glob($path);
115 | }
116 |
117 | /**
118 | * Reads config file.
119 | * @param string $path
120 | * @return array configuration read from file
121 | */
122 | protected function loadFile($path): array
123 | {
124 | $reader = ReaderFactory::get($this->builder, $path);
125 |
126 | return $reader->read($path);
127 | }
128 |
129 | /**
130 | * Merges given configs and writes at given name.
131 | * @return Config
132 | */
133 | public function build(): self
134 | {
135 | $this->values = $this->calcValues($this->sources);
136 |
137 | return $this;
138 | }
139 |
140 | public function write(): self
141 | {
142 | $this->writeFile($this->getOutputPath(), $this->values);
143 |
144 | return $this;
145 | }
146 |
147 | protected function calcValues(array $sources): array
148 | {
149 | $values = call_user_func_array([Helper::class, 'mergeConfig'], $sources);
150 | $values = Helper::fixConfig($values);
151 |
152 | return $this->substituteOutputDirs($values);
153 | }
154 |
155 | protected function writeFile(string $path, array $data): void
156 | {
157 | $this->writePhpFile($path, $data);
158 | }
159 |
160 | /**
161 | * Writes complete PHP config file by full path.
162 | * @param string $path
163 | * @param string|array $data
164 | * @param bool $withEnv
165 | * @param bool $withDefines
166 | * @throws FailedWriteException
167 | * @throws ReflectionException
168 | */
169 | protected function writePhpFile(string $path, $data): void
170 | {
171 | $depth = $this->findDepth();
172 | $baseDir = $depth>0 ? "dirname(__DIR__, $depth)" : '__DIR__';
173 | static::putFile($path, $this->replaceMarkers(implode("\n\n", array_filter([
174 | 'header' => ' "\$baseDir = $baseDir;",
176 | 'BASEDIR' => "defined('COMPOSER_CONFIG_PLUGIN_BASEDIR') or define('COMPOSER_CONFIG_PLUGIN_BASEDIR', \$baseDir);",
177 | 'dotenv' => $this->withEnv() ? "\$_ENV = array_merge((array) require __DIR__ . '/dotenv.php', (array) \$_ENV);" : '',
178 | 'defines' => $this->withDefines() ? $this->builder->getConfig('defines')->buildRequires() : '',
179 | 'params' => $this->withParams() ? "\$params = require __DIR__ . '/params.php';" : '',
180 | 'content' => is_array($data) ? $this->renderVars($data) : $data,
181 | ]))) . "\n");
182 | }
183 |
184 | private function withEnv(): bool
185 | {
186 | return !in_array(static::class, [System::class, DotEnv::class], true);
187 | }
188 |
189 | private function withDefines(): bool
190 | {
191 | return !in_array(static::class, [System::class, DotEnv::class, Defines::class], true);
192 | }
193 |
194 | private function withParams(): bool
195 | {
196 | return !in_array(static::class, [System::class, DotEnv::class, Defines::class, Params::class], true);
197 | }
198 |
199 | private function findDepth()
200 | {
201 | $outDir = dirname(self::normalizePath($this->getOutputPath()));
202 | $diff = substr($outDir, strlen($this->getBaseDir()));
203 |
204 | return substr_count($diff, self::UNIX_DS);
205 | }
206 |
207 | /**
208 | * @param array $vars array to be exported
209 | * @return string
210 | * @throws ReflectionException
211 | */
212 | protected function renderVars(array $vars): string
213 | {
214 | return 'return ' . Helper::exportVar($vars) . ';';
215 | }
216 |
217 | protected function replaceMarkers(string $content): string
218 | {
219 | $content = str_replace("'" . static::BASE_DIR_MARKER, "\$baseDir . '", $content);
220 |
221 | return str_replace("'?" . static::BASE_DIR_MARKER, "'?' . \$baseDir . '", $content);
222 | }
223 |
224 | /**
225 | * Writes file if content changed.
226 | * @param string $path
227 | * @param string $content
228 | * @throws FailedWriteException
229 | */
230 | protected static function putFile($path, $content): void
231 | {
232 | if (file_exists($path) && $content === file_get_contents($path)) {
233 | return;
234 | }
235 | $dirname = dirname($path);
236 | if (!file_exists($dirname) && !mkdir($dirname, 0777, true) && !is_dir($dirname)) {
237 | throw new FailedWriteException(sprintf('Directory "%s" was not created', $dirname));
238 | }
239 | if (false === file_put_contents($path, $content)) {
240 | throw new FailedWriteException("Failed write file $path");
241 | }
242 | }
243 |
244 | /**
245 | * Substitute output paths in given data array recursively with marker.
246 | * @param array $data
247 | * @return array
248 | */
249 | public function substituteOutputDirs(array $data): array
250 | {
251 | $dir = static::normalizePath($this->getBaseDir());
252 |
253 | return static::substitutePaths($data, $dir, static::BASE_DIR_MARKER);
254 | }
255 |
256 | /**
257 | * Normalizes given path with given directory separator.
258 | * Default forced to Unix directory separator for substitutePaths to work properly in Windows.
259 | * @param string $path path to be normalized
260 | * @param string $ds directory separator
261 | * @return string
262 | */
263 | public static function normalizePath($path, $ds = self::UNIX_DS): string
264 | {
265 | return rtrim(strtr($path, '/\\', $ds . $ds), $ds);
266 | }
267 |
268 | /**
269 | * Substitute all paths in given array recursively with alias if applicable.
270 | * @param array $data
271 | * @param string $dir
272 | * @param string $alias
273 | * @return array
274 | */
275 | public static function substitutePaths($data, $dir, $alias): array
276 | {
277 | foreach ($data as &$value) {
278 | if (is_string($value)) {
279 | $value = static::substitutePath($value, $dir, $alias);
280 | } elseif (is_array($value)) {
281 | $value = static::substitutePaths($value, $dir, $alias);
282 | }
283 | }
284 |
285 | return $data;
286 | }
287 |
288 | /**
289 | * Substitute path with alias if applicable.
290 | * @param string $path
291 | * @param string $dir
292 | * @param string $alias
293 | * @return string
294 | */
295 | protected static function substitutePath($path, $dir, $alias): string
296 | {
297 | $end = $dir . self::UNIX_DS;
298 | $skippable = 0 === strncmp($path, '?', 1) ? '?' : '';
299 | if ($skippable) {
300 | $path = substr($path, 1);
301 | }
302 | if ($path === $dir) {
303 | $result = $alias;
304 | } elseif (strpos($path, $end) === 0) {
305 | $result = $alias . substr($path, strlen($end) - 1);
306 | } else {
307 | $result = $path;
308 | }
309 |
310 | return $skippable . $result;
311 | }
312 |
313 | public function getBaseDir(): string
314 | {
315 | return dirname(__DIR__, 5);
316 | }
317 |
318 | public function getOutputDir(): string
319 | {
320 | return $this->builder->getOutputDir();
321 | }
322 |
323 | public function getOutputPath(string $name = null): string
324 | {
325 | return $this->builder->getOutputPath($name ?: $this->name);
326 | }
327 | }
328 |
--------------------------------------------------------------------------------
/src/configs/ConfigFactory.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class ConfigFactory
22 | {
23 | private static $knownTypes = [
24 | '__rebuild' => Rebuild::class,
25 | '__files' => System::class,
26 | 'aliases' => System::class,
27 | 'packages' => System::class,
28 | 'dotenv' => DotEnv::class,
29 | 'params' => Params::class,
30 | 'defines' => Defines::class,
31 | ];
32 |
33 | /**
34 | * @param Builder $builder
35 | * @param string $name
36 | * @return Config
37 | */
38 | public static function create(Builder $builder, string $name): Config
39 | {
40 | $class = static::$knownTypes[$name] ?? Config::class;
41 |
42 | return new $class($builder, $name);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/configs/Defines.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class Defines extends Config
19 | {
20 | protected function loadFile($path): array
21 | {
22 | parent::loadFile($path);
23 | if (pathinfo($path, PATHINFO_EXTENSION) !== 'php') {
24 | return [];
25 | }
26 |
27 | return [$path];
28 | }
29 |
30 | public function buildRequires(): string
31 | {
32 | $res = [];
33 | foreach ($this->values as $path) {
34 | $res[] = "require_once '$path';";
35 | }
36 |
37 | return implode("\n", $res);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/configs/DotEnv.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class DotEnv extends Config
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/src/configs/Params.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class Params extends Config
19 | {
20 | protected function calcValues(array $sources): array
21 | {
22 | return $this->pushEnvVars(parent::calcValues($sources));
23 | }
24 |
25 | protected function pushEnvVars($vars): array
26 | {
27 | $env = $this->builder->getConfig('dotenv')->getValues();
28 | if (!empty($vars)) {
29 | foreach ($vars as $key => &$value) {
30 | if (is_array($value)) {
31 | foreach (array_keys($value) as $subkey) {
32 | $envKey = $this->getEnvKey($key . '_' . $subkey);
33 | if (isset($env[$envKey])) {
34 | $value[$subkey] = $env[$envKey];
35 | }
36 | }
37 | } else {
38 | $envKey = $this->getEnvKey($key);
39 | if (isset($env[$envKey])) {
40 | $vars[$key] = $env[$envKey];
41 | }
42 | }
43 | }
44 | }
45 |
46 | return $vars;
47 | }
48 |
49 | private function getEnvKey(string $key): string
50 | {
51 | return strtoupper(strtr($key, '.-', '__'));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/configs/Rebuild.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class Rebuild extends Config
19 | {
20 | protected function writeFile(string $path, array $data): void
21 | {
22 | static::putFile($path, file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . '__rebuild.php'));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/configs/System.php:
--------------------------------------------------------------------------------
1 |
18 | */
19 | class System extends Config
20 | {
21 | public function setValue(string $name, $value): Config
22 | {
23 | $this->values[$name] = $value;
24 |
25 | return $this;
26 | }
27 |
28 | public function setValues(array $values): Config
29 | {
30 | $this->values = $values;
31 |
32 | return $this;
33 | }
34 |
35 | public function mergeValues(array $values): Config
36 | {
37 | $this->values = array_merge($this->values, $values);
38 |
39 | return $this;
40 | }
41 |
42 | public function load(array $paths = []): Config
43 | {
44 | $path = $this->getOutputPath();
45 | if (!file_exists($path)) {
46 | return $this;
47 | }
48 |
49 | $this->values = array_merge($this->loadFile($path), $this->values);
50 |
51 | return $this;
52 | }
53 |
54 | public function build(): Config
55 | {
56 | $this->values = $this->substituteOutputDirs($this->values);
57 |
58 | return $this;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/configs/__rebuild.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 |
17 | */
18 | class BadConfigurationException extends Exception
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/src/exceptions/CircularDependencyException.php:
--------------------------------------------------------------------------------
1 |
16 | */
17 | class CircularDependencyException extends Exception
18 | {
19 | }
20 |
--------------------------------------------------------------------------------
/src/exceptions/Exception.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class Exception extends \Exception
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/src/exceptions/FailedReadException.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class FailedReadException extends Exception
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/src/exceptions/FailedWriteException.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class FailedWriteException extends Exception
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/src/exceptions/UnsupportedFileTypeException.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class UnsupportedFileTypeException extends FailedReadException
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/src/readers/AbstractReader.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | abstract class AbstractReader
22 | {
23 | /**
24 | * @var Builder
25 | */
26 | protected $builder;
27 |
28 | public function __construct(Builder $builder)
29 | {
30 | $this->builder = $builder;
31 | }
32 |
33 | public function getBuilder(): Builder
34 | {
35 | return $this->builder;
36 | }
37 |
38 | public function read($path)
39 | {
40 | $skippable = 0 === strncmp($path, '?', 1) ? '?' : '';
41 | if ($skippable) {
42 | $path = substr($path, 1);
43 | }
44 |
45 | if (is_readable($path)) {
46 | $res = $this->readRaw($path);
47 |
48 | return is_array($res) ? $res : [];
49 | }
50 |
51 | if (empty($skippable)) {
52 | throw new FailedReadException("failed read file: $path");
53 | }
54 |
55 | return [];
56 | }
57 |
58 | public function getFileContents($path)
59 | {
60 | $res = file_get_contents($path);
61 | if (false === $res) {
62 | throw new FailedReadException("failed read file: $path");
63 | }
64 |
65 | return $res;
66 | }
67 |
68 | abstract public function readRaw($path);
69 | }
70 |
--------------------------------------------------------------------------------
/src/readers/EnvReader.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class EnvReader extends AbstractReader
22 | {
23 | public function readRaw($path)
24 | {
25 | if (!class_exists(Dotenv::class)) {
26 | throw new UnsupportedFileTypeException('for .env support require `vlucas/phpdotenv` in your composer.json');
27 | }
28 | $info = pathinfo($path);
29 | $this->loadDotenv($info['dirname'], $info['basename']);
30 |
31 | return $_ENV;
32 | }
33 |
34 | /**
35 | * Creates and loads Dotenv object.
36 | * Supports all 2, 3 and 4 version of `phpdotenv`
37 | * @param mixed $dir
38 | * @param mixed $file
39 | * @return Dotenv\Dotenv
40 | */
41 | private function loadDotenv($dir, $file)
42 | {
43 | if (method_exists(Dotenv::class, 'createMutable')) {
44 | Dotenv::createMutable($dir, $file)->load();
45 | } elseif (method_exists(Dotenv::class, 'create')) {
46 | Dotenv::create($dir, $file)->overload();
47 | } else {
48 | (new Dotenv($dir, $file))->overload();
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/readers/JsonReader.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class JsonReader extends AbstractReader
19 | {
20 | public function readRaw($path)
21 | {
22 | return json_decode($this->getFileContents($path), true);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/readers/PhpReader.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class PhpReader extends AbstractReader
19 | {
20 | public function readRaw($__path)
21 | {
22 | /// Expose variables to be used in configs
23 | extract($this->builder->getVars());
24 |
25 | return require $__path;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/readers/ReaderFactory.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class ReaderFactory
22 | {
23 | private static $loaders;
24 |
25 | protected static $knownReaders = [
26 | 'env' => EnvReader::class,
27 | 'php' => PhpReader::class,
28 | 'json' => JsonReader::class,
29 | 'yaml' => YamlReader::class,
30 | 'yml' => YamlReader::class,
31 | ];
32 |
33 | public static function get(Builder $builder, $path)
34 | {
35 | $type = static::detectType($path);
36 | $class = static::findClass($type);
37 |
38 | #return static::create($builder, $type);
39 |
40 | $uniqid = $class . ':' . spl_object_hash($builder);
41 | if (empty(static::$loaders[$uniqid])) {
42 | static::$loaders[$uniqid] = static::create($builder, $type);
43 | }
44 |
45 | return static::$loaders[$uniqid];
46 | }
47 |
48 | public static function detectType($path)
49 | {
50 | if (strncmp(basename($path), '.env.', 5) === 0) {
51 | return 'env';
52 | }
53 |
54 | return pathinfo($path, PATHINFO_EXTENSION);
55 | }
56 |
57 | public static function findClass($type)
58 | {
59 | if (empty(static::$knownReaders[$type])) {
60 | throw new UnsupportedFileTypeException("unsupported file type: $type");
61 | }
62 |
63 | return static::$knownReaders[$type];
64 | }
65 |
66 | public static function create(Builder $builder, $type)
67 | {
68 | $class = static::findClass($type);
69 |
70 | return new $class($builder);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/readers/YamlReader.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class YamlReader extends AbstractReader
22 | {
23 | public function readRaw($path)
24 | {
25 | if (!class_exists(Yaml::class)) {
26 | throw new UnsupportedFileTypeException("for YAML support require `symfony/yaml` in your composer.json (reading $path)");
27 | }
28 |
29 | return Yaml::parse($this->getFileContents($path));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/utils/ClosureEncoder.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class ClosureEncoder implements Encoder
22 | {
23 | /**
24 | * {@inheritdoc}
25 | */
26 | public function getDefaultOptions()
27 | {
28 | return [];
29 | }
30 |
31 | /**
32 | * {@inheritdoc}
33 | */
34 | public function supports($value)
35 | {
36 | return $value instanceof Closure;
37 | }
38 |
39 | /**
40 | * {@inheritdoc}
41 | */
42 | public function encode($value, $depth, array $options, callable $encode)
43 | {
44 | return (new ReflectionClosure($value))->getCode();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/utils/Helper.php:
--------------------------------------------------------------------------------
1 |
19 | */
20 | class Helper
21 | {
22 | /**
23 | * Merges two or more arrays into one recursively.
24 | * Based on Yii2 yii\helpers\BaseArrayHelper::merge.
25 | * @return array the merged array
26 | */
27 | public static function mergeConfig(): array
28 | {
29 | $args = \func_get_args();
30 | $res = array_shift($args) ?: [];
31 | foreach ($args as $items) {
32 | if (!\is_array($items)) {
33 | continue;
34 | }
35 | foreach ($items as $k => $v) {
36 | if ($v instanceof \yii\helpers\UnsetArrayValue || $v instanceof \Yiisoft\Arrays\UnsetArrayValue) {
37 | unset($res[$k]);
38 | } elseif ($v instanceof \yii\helpers\ReplaceArrayValue || $v instanceof \Yiisoft\Arrays\ReplaceArrayValue) {
39 | $res[$k] = $v->value;
40 | } elseif (\is_int($k)) {
41 | /// XXX skip repeated values
42 | if (\in_array($v, $res, true)) {
43 | continue;
44 | }
45 | if (isset($res[$k])) {
46 | $res[] = $v;
47 | } else {
48 | $res[$k] = $v;
49 | }
50 | } elseif (\is_array($v) && isset($res[$k]) && \is_array($res[$k])) {
51 | $res[$k] = self::mergeConfig($res[$k], $v);
52 | } else {
53 | $res[$k] = $v;
54 | }
55 | }
56 | }
57 |
58 | return $res;
59 | }
60 |
61 | public static function fixConfig(array $config): array
62 | {
63 | $remove = false;
64 | foreach ($config as $key => &$value) {
65 | if (is_array($value)) {
66 | $value = static::fixConfig($value);
67 | } elseif ($value instanceof RemoveArrayKeys) {
68 | $remove = true;
69 | unset($config[$key]);
70 | }
71 | }
72 | if ($remove) {
73 | return array_values($config);
74 | }
75 |
76 | return $config;
77 | }
78 |
79 | public static function exportDefines(array $defines): string
80 | {
81 | $res = '';
82 | foreach ($defines as $key => $value) {
83 | $var = static::exportVar($value);
84 | $res .= "defined('$key') or define('$key', $var);\n";
85 | }
86 |
87 | return $res;
88 | }
89 |
90 | /**
91 | * Returns PHP-executable string representation of given value.
92 | * Uses Riimu/Kit-PHPEncoder based `var_export` alternative.
93 | * And Opis/Closure to dump closures as PHP code.
94 | * @param mixed $value
95 | * @return string
96 | * @throws \ReflectionException
97 | */
98 | public static function exportVar($value): string
99 | {
100 | return static::getEncoder()->encode($value);
101 | }
102 |
103 | private static $encoder;
104 |
105 | private static function getEncoder()
106 | {
107 | if (static::$encoder === null) {
108 | static::$encoder = static::createEncoder();
109 | }
110 |
111 | return static::$encoder;
112 | }
113 |
114 | private static function createEncoder()
115 | {
116 | $encoder = new PHPEncoder([
117 | 'object.format' => 'serialize',
118 | ]);
119 | $encoder->addEncoder(new ClosureEncoder(), true);
120 |
121 | return $encoder;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/utils/RemoveArrayKeys.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class RemoveArrayKeys
11 | {
12 | }
13 |
--------------------------------------------------------------------------------
/src/utils/Resolver.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class Resolver
22 | {
23 | protected $order = [];
24 |
25 | protected $deps = [];
26 |
27 | protected $following = [];
28 |
29 | public function __construct(array $files)
30 | {
31 | $this->files = $files;
32 |
33 | $this->collectDeps();
34 | foreach (array_keys($this->files) as $name) {
35 | $this->followDeps($name);
36 | }
37 | }
38 |
39 | public function get()
40 | {
41 | $result = [];
42 | foreach ($this->order as $name) {
43 | $result[$name] = $this->resolveDeps($this->files[$name]);
44 | }
45 |
46 | return $result;
47 | }
48 |
49 | protected function resolveDeps(array $paths)
50 | {
51 | foreach ($paths as &$path) {
52 | $dep = $this->isDep($path);
53 | if ($dep) {
54 | $path = Builder::path($dep);
55 | }
56 | }
57 |
58 | return $paths;
59 | }
60 |
61 | protected function followDeps($name)
62 | {
63 | if (isset($this->order[$name])) {
64 | return;
65 | }
66 | if (isset($this->following[$name])) {
67 | throw new CircularDependencyException($name . ' ' . implode(',', $this->following));
68 | }
69 | $this->following[$name] = $name;
70 | if (isset($this->deps[$name])) {
71 | foreach ($this->deps[$name] as $dep) {
72 | $this->followDeps($dep);
73 | }
74 | }
75 | $this->order[$name] = $name;
76 | unset($this->following[$name]);
77 | }
78 |
79 | protected function collectDeps()
80 | {
81 | foreach ($this->files as $name => $paths) {
82 | foreach ($paths as $path) {
83 | $dep = $this->isDep($path);
84 | if ($dep) {
85 | if (!isset($this->deps[$name])) {
86 | $this->deps[$name] = [];
87 | }
88 | $this->deps[$name][$dep] = $dep;
89 | }
90 | }
91 | }
92 | }
93 |
94 | protected function isDep($path)
95 | {
96 | return 0 === strncmp($path, '$', 1) ? substr($path, 1) : false;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/tests/_bootstrap.php:
--------------------------------------------------------------------------------
1 | 42];
14 | $closure = static function () use ($params) {
15 | return $params['test'];
16 | };
17 |
18 | $exportedClosure = Helper::exportVar($closure);
19 |
20 | $this->assertSameWithoutLE("static function () use (\$params) {\n return \$params['test'];\n }", $exportedClosure);
21 | }
22 |
23 | private function assertSameWithoutLE($expected, $actual, string $message = ''): void
24 | {
25 | $expected = preg_replace('/\R/', "\n", $expected);
26 | $actual = preg_replace('/\R/', "\n", $actual);
27 | $this->assertSame($expected, $actual, $message);
28 | }
29 |
30 | public function testFixRemoveArrayKeys()
31 | {
32 | $config = [
33 | 'a' => '1',
34 | 'b' => '2',
35 | 'c' => [
36 | 'd' => 4,
37 | 'remove' => new RemoveArrayKeys(),
38 | 'e' => 5,
39 | ],
40 | ];
41 |
42 | $fixed = $config;
43 | unset($fixed['c']['remove']);
44 | $fixed['c'] = array_values($fixed['c']);
45 |
46 | $this->assertEquals($fixed, Helper::fixConfig($config));
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/unit/PluginTest.php:
--------------------------------------------------------------------------------
1 | composer = new Composer();
32 | $this->composer->setConfig(new Config(true, getcwd()));
33 | $this->io = $this->createMock('Composer\IO\IOInterface');
34 | $this->event = $this->getMockBuilder('Composer\Script\Event')
35 | ->setConstructorArgs(['test', $this->composer, $this->io])
36 | ->getMock();
37 |
38 | $this->object = new Plugin();
39 | $this->object->setPackages($this->packages);
40 | $this->object->activate($this->composer, $this->io);
41 | }
42 |
43 | public function testGetPackages()
44 | {
45 | $this->assertSame($this->packages, $this->object->getPackages());
46 | }
47 |
48 | public function testGetSubscribedEvents()
49 | {
50 | $this->assertInternalType('array', $this->object->getSubscribedEvents());
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/unit/configs/ConfigFactoryTest.php:
--------------------------------------------------------------------------------
1 | builder = new Builder();
30 |
31 | $this->checkCreate('common', Config::class);
32 | $this->checkCreate('defines', Defines::class);
33 | $this->checkCreate('params', Params::class);
34 | $this->checkCreate('__files', System::class);
35 | }
36 |
37 | public function checkCreate(string $name, string $class)
38 | {
39 | $config = ConfigFactory::create($this->builder, $name);
40 | $this->assertInstanceOf($class, $config);
41 | $this->assertSame($this->builder, $config->getBuilder());
42 | $this->assertSame($name, $config->getName());
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/unit/readers/ReaderFactoryTest.php:
--------------------------------------------------------------------------------
1 | builder = new Builder();
30 |
31 | $env = $this->checkGet('.env', EnvReader::class);
32 | $json = $this->checkGet('.json', JsonReader::class);
33 | $yml = $this->checkGet('.yml', YamlReader::class);
34 | $yaml = $this->checkGet('.yaml', YamlReader::class);
35 | $php = $this->checkGet('.php', PhpReader::class);
36 | $php2 = $this->checkGet('.php', PhpReader::class);
37 |
38 | $this->assertSame($php, $php2);
39 | $this->assertSame($yml, $yaml);
40 | }
41 |
42 | public function checkGet(string $name, string $class)
43 | {
44 | $reader = ReaderFactory::get($this->builder, $name);
45 | $this->assertInstanceOf($class, $reader);
46 | $this->assertSame($this->builder, $reader->getBuilder());
47 |
48 | return $reader;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/version:
--------------------------------------------------------------------------------
1 | composer-config-plugin dev-0.4.0-e3392b6 2020-03-08 20:51:09 +0200 e3392b6fae3dc3200d85edb359fcef5739558536
2 |
--------------------------------------------------------------------------------