From ba7253b7a5c70b488cfc1549e43502e33706c75b Mon Sep 17 00:00:00 2001 From: Dusan Malusev Date: Mon, 20 Jul 2020 14:45:38 +0200 Subject: [PATCH] Empty values (KEY=) is treated as null not as empty string, empty string should be KEY="". All other bugs are already fixed Signed-off-by: Dusan Malusev --- .gitignore | 3 + .idea/PhpMvc-DotEnv.iml | 47 ---- .idea/composerJson.xml | 10 - .idea/dictionaries/dusan.xml | 7 - .idea/misc.xml | 6 - .idea/modules.xml | 8 - .idea/php-test-framework.xml | 14 -- .idea/php.xml | 49 ----- .idea/vcs.xml | 6 - .idea/workspace.xml | 199 ----------------- .phpunit.result.cache | 1 - .vscode/launch.json | 22 -- .vscode/settings.json | 2 - composer.json | 13 +- composer.lock | 293 +++++++++++++++---------- phpunit.xml | 17 +- src/EnvParser.php | 117 +++++----- src/TypeChecker.php | 17 +- src/ValueType.php | 4 +- src/functions.php | 7 - tests/{EnvTest => }/.env | 4 +- tests/{EnvTest => }/.env-error | 0 tests/{EnvTest => }/.env.casts | 0 tests/.env.empty.value | 7 + tests/{EnvTest => }/.env.interpolation | 0 tests/{EnvTest => }/.env.space.error | 0 tests/EnvParserTest.php | 129 +++++++++++ tests/EnvTest/EnvParserTest.php | 109 --------- 28 files changed, 409 insertions(+), 682 deletions(-) delete mode 100644 .idea/PhpMvc-DotEnv.iml delete mode 100644 .idea/composerJson.xml delete mode 100644 .idea/dictionaries/dusan.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/php-test-framework.xml delete mode 100644 .idea/php.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml delete mode 100644 .phpunit.result.cache delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 src/functions.php rename tests/{EnvTest => }/.env (86%) rename tests/{EnvTest => }/.env-error (100%) rename tests/{EnvTest => }/.env.casts (100%) create mode 100644 tests/.env.empty.value rename tests/{EnvTest => }/.env.interpolation (100%) rename tests/{EnvTest => }/.env.space.error (100%) create mode 100644 tests/EnvParserTest.php delete mode 100644 tests/EnvTest/EnvParserTest.php diff --git a/.gitignore b/.gitignore index 48b8bf9..bd8dd8e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ vendor/ +.phpunit.result.cache +.idea/ +.vscode/ diff --git a/.idea/PhpMvc-DotEnv.iml b/.idea/PhpMvc-DotEnv.iml deleted file mode 100644 index 3d0afa3..0000000 --- a/.idea/PhpMvc-DotEnv.iml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/composerJson.xml b/.idea/composerJson.xml deleted file mode 100644 index 1b07430..0000000 --- a/.idea/composerJson.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/dictionaries/dusan.xml b/.idea/dictionaries/dusan.xml deleted file mode 100644 index a73c63c..0000000 --- a/.idea/dictionaries/dusan.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - dotenv - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 28a804d..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 814042c..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml deleted file mode 100644 index e47438f..0000000 --- a/.idea/php-test-framework.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml deleted file mode 100644 index 3de89bc..0000000 --- a/.idea/php.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 94b79ae..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - - - - - - - - - - - - $PROJECT_DIR$/composer.json - - - - - - - Dusan\\DotEnv\\ - Dusan\DotEnv\ - Dusan\DotEnv - - - BrosSquad\\DotEnv\\ - BrosSquad\DotEnv\ - BrosSquad\DotEnv - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1559597724028 - - - - - - - - - - - - preg_match('/^Nam/',$value) - PHP - CODE_FRAGMENT - - - preg_max - PHP - EXPRESSION - - - $value === 'Nam' - PHP - EXPRESSION - - - - \ No newline at end of file diff --git a/.phpunit.result.cache b/.phpunit.result.cache deleted file mode 100644 index 7a62be0..0000000 --- a/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -C:37:"PHPUnit\Runner\DefaultTestResultCache":414:{a:2:{s:7:"defects";a:1:{s:56:"BrosSquad\DotEnv\Tests\EnvParserTest::test_interpolation";i:3;}s:5:"times";a:4:{s:53:"BrosSquad\DotEnv\Tests\EnvParserTest::test_env_parser";d:0.003;s:57:"BrosSquad\DotEnv\Tests\EnvParserTest::test_env_with_error";d:0.001;s:80:"BrosSquad\DotEnv\Tests\EnvParserTest::test_env_with_space_error_in_variable_name";d:0;s:56:"BrosSquad\DotEnv\Tests\EnvParserTest::test_interpolation";d:0;}}} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 612eaac..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Listen for XDebug", - "type": "php", - "request": "launch", - "port": 9000 - }, - { - "name": "Launch currently open script", - "type": "php", - "request": "launch", - "program": "${file}", - "cwd": "${fileDirname}", - "port": 9000 - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7a73a41..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/composer.json b/composer.json index 1245ffc..fcd9171 100644 --- a/composer.json +++ b/composer.json @@ -8,17 +8,11 @@ } ], "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { "BrosSquad\\DotEnv\\": "src/" } }, "autoload-dev": { - "files": [ - "src/functions.php" - ], "psr-4": { "BrosSquad\\DotEnv\\Tests\\": "tests/" } @@ -26,11 +20,12 @@ "type": "library", "minimum-stability": "stable", "require": { - "dusan/php-mvc-file": "1.0", - "ext-mbstring": "*" + "php": ">=7.4", + "ext-mbstring": "*", + "dusan/php-mvc-file": "1.0" }, "require-dev": { - "phpunit/phpunit": "^8.1", + "phpunit/phpunit": "^8.5.8", "codedungeon/phpunit-result-printer": "^0.26.2" }, "license": "GPL-2.0", diff --git a/composer.lock b/composer.lock index e01017d..b42d8e6 100644 --- a/composer.lock +++ b/composer.lock @@ -81,16 +81,16 @@ }, { "name": "codedungeon/php-cli-colors", - "version": "1.10.7", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/mikeerickson/php-cli-colors.git", - "reference": "5649ef76ec0c9ed626e95bf40fdfaf4b8efcf79b" + "reference": "9f60ac692cc790755dad47b01c1d607fe5f43b94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mikeerickson/php-cli-colors/zipball/5649ef76ec0c9ed626e95bf40fdfaf4b8efcf79b", - "reference": "5649ef76ec0c9ed626e95bf40fdfaf4b8efcf79b", + "url": "https://api.github.com/repos/mikeerickson/php-cli-colors/zipball/9f60ac692cc790755dad47b01c1d607fe5f43b94", + "reference": "9f60ac692cc790755dad47b01c1d607fe5f43b94", "shasum": "" }, "require-dev": { @@ -121,7 +121,7 @@ "package", "php" ], - "time": "2018-05-17T01:34:14+00:00" + "time": "2019-12-29T22:29:29+00:00" }, { "name": "codedungeon/phpunit-result-printer", @@ -178,20 +178,20 @@ }, { "name": "doctrine/instantiator", - "version": "1.2.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "a2c590166b2133a4633738648b6b064edae0814a" + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", - "reference": "a2c590166b2133a4633738648b6b064edae0814a", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^6.0", @@ -230,7 +230,21 @@ "constructor", "instantiate" ], - "time": "2019-03-17T17:37:11+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-05-29T17:27:14+00:00" }, { "name": "hassankhan/config", @@ -291,20 +305,20 @@ }, { "name": "myclabs/deep-copy", - "version": "1.9.3", + "version": "1.10.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", - "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "replace": { "myclabs/deep-copy": "self.version" @@ -335,7 +349,13 @@ "object", "object graph" ], - "time": "2019-08-09T12:45:53+00:00" + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-06-29T13:22:24+00:00" }, { "name": "phar-io/manifest", @@ -441,28 +461,25 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "2.0.0", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~6" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -489,44 +506,42 @@ "reflection", "static analysis" ], - "time": "2018-08-07T13:53:10+00:00" + "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.2", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" + "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" + "ext-filter": "^7.1", + "php": "^7.2", + "phpdocumentor/reflection-common": "^2.0", + "phpdocumentor/type-resolver": "^1.0", + "webmozart/assert": "^1" }, "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" + "doctrine/instantiator": "^1", + "mockery/mockery": "^1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -537,38 +552,40 @@ { "name": "Mike van Riel", "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-09-12T14:27:41+00:00" + "time": "2020-02-22T12:28:44+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.0.1", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", "shasum": "" }, "require": { - "php": "^7.1", + "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "^7.1", - "mockery/mockery": "~1", - "phpunit/phpunit": "^7.0" + "ext-tokenizer": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-1.x": "1.x-dev" } }, "autoload": { @@ -587,37 +604,37 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2019-08-22T18:11:29+00:00" + "time": "2020-06-27T10:12:23+00:00" }, { "name": "phpspec/prophecy", - "version": "1.9.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" + "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", - "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", + "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" + "doctrine/instantiator": "^1.2", + "php": "^7.2", + "phpdocumentor/reflection-docblock": "^5.0", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev" + "dev-master": "1.11.x-dev" } }, "autoload": { @@ -650,20 +667,20 @@ "spy", "stub" ], - "time": "2019-10-03T11:07:50+00:00" + "time": "2020-07-08T12:44:21+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "7.0.8", + "version": "7.0.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa0d179a13284c7420fc281fc32750e6cc7c9e2f" + "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa0d179a13284c7420fc281fc32750e6cc7c9e2f", - "reference": "aa0d179a13284c7420fc281fc32750e6cc7c9e2f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf", + "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf", "shasum": "" }, "require": { @@ -713,7 +730,7 @@ "testing", "xunit" ], - "time": "2019-09-17T06:24:36+00:00" + "time": "2019-11-20T13:55:58+00:00" }, { "name": "phpunit/php-file-iterator", @@ -906,16 +923,16 @@ }, { "name": "phpunit/phpunit", - "version": "8.4.3", + "version": "8.5.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "67f9e35bffc0dd52d55d565ddbe4230454fd6a4e" + "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/67f9e35bffc0dd52d55d565ddbe4230454fd6a4e", - "reference": "67f9e35bffc0dd52d55d565ddbe4230454fd6a4e", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34c18baa6a44f1d1fbf0338907139e9dce95b997", + "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997", "shasum": "" }, "require": { @@ -959,7 +976,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "8.4-dev" + "dev-master": "8.5-dev" } }, "autoload": { @@ -985,7 +1002,17 @@ "testing", "xunit" ], - "time": "2019-11-06T09:42:23+00:00" + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-22T07:06:58+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -1154,16 +1181,16 @@ }, { "name": "sebastian/environment", - "version": "4.2.2", + "version": "4.2.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", - "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", "shasum": "" }, "require": { @@ -1203,7 +1230,7 @@ "environment", "hhvm" ], - "time": "2019-05-05T09:05:15+00:00" + "time": "2019-11-20T08:46:58+00:00" }, { "name": "sebastian/exporter", @@ -1604,16 +1631,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.12.0", + "version": "v1.18.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "550ebaac289296ce228a706d0867afc34687e3f4" + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", - "reference": "550ebaac289296ce228a706d0867afc34687e3f4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", "shasum": "" }, "require": { @@ -1625,7 +1652,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -1658,31 +1689,45 @@ "polyfill", "portable" ], - "time": "2019-08-06T08:03:45+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-14T12:35:20+00:00" }, { "name": "symfony/yaml", - "version": "v4.3.6", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "324cf4b19c345465fad14f3602050519e09e361d" + "reference": "c2d2cc66e892322cfcc03f8f12f8340dbd7a3f8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/324cf4b19c345465fad14f3602050519e09e361d", - "reference": "324cf4b19c345465fad14f3602050519e09e361d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/c2d2cc66e892322cfcc03f8f12f8340dbd7a3f8a", + "reference": "c2d2cc66e892322cfcc03f8f12f8340dbd7a3f8a", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.1.3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/console": "<3.4" }, "require-dev": { - "symfony/console": "~3.4|~4.0" + "symfony/console": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" @@ -1690,7 +1735,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -1717,27 +1762,41 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2019-10-30T12:58:49+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T08:37:50+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.3", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" + "reference": "75a63c33a8577608444246075ea0af0d052e452a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": "^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -1757,35 +1816,40 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2019-06-13T22:48:21+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" }, { "name": "webmozart/assert", - "version": "1.5.0", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0", + "php": "^5.3.3 || ^7.0 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -1807,7 +1871,7 @@ "check", "validate" ], - "time": "2019-08-24T08:43:50+00:00" + "time": "2020-07-08T17:02:28+00:00" } ], "aliases": [], @@ -1818,5 +1882,6 @@ "platform": { "ext-mbstring": "*" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/phpunit.xml b/phpunit.xml index bd1a2ec..0e7de36 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,11 +1,16 @@ - - - + - - tests + + ./tests - \ No newline at end of file + diff --git a/src/EnvParser.php b/src/EnvParser.php index 646552e..28e4c9f 100644 --- a/src/EnvParser.php +++ b/src/EnvParser.php @@ -1,15 +1,15 @@ - */ - private $typeCasters = [ - ]; - + private ?File $handler; /** * @var ValueType */ - private $typeChecker; + private ValueType $typeChecker; /** * Holder for parsed Environment Variables @@ -39,42 +32,40 @@ class EnvParser implements Tokens, EnvParserInterface * @internal * @var null|array */ - private $envs; + private ?array $envs; /** * Flag that doesn't allows the lexing and paring stages to happen twice * * @var bool */ - private $isParsed = false; + private bool $isParsed = false; /** * EnvParser constructor. * - * @param string $file + * @param string $file * - * @param array $typeCasters - * @param ValueType|null $typeChecker - * @param bool $emptyStringNull + * @param ValueType|null $typeChecker + * @param bool $emptyStringNull */ - public function __construct(string $file, ?array $typeCasters = null, ValueType $typeChecker = null, bool $emptyStringNull = true) - { + public function __construct( + string $file, + ValueType $typeChecker = null, + bool $emptyStringNull = true + ) { $this->handler = new File($file); - if ($this->handler === NULL) { + if ($this->handler === null) { throw new RuntimeException('File could not be opened'); } if (!$this->handler->isFile()) { - throw new RuntimeException($file . ' is not a file'); + throw new RuntimeException($file.' is not a file'); } if (!$this->handler->isReadable()) { - throw new RuntimeException($file . ' is not readable'); + throw new RuntimeException($file.' is not readable'); } - if($typeCasters !== null) { - $this->typeCasters = array_merge($this->typeCasters, $typeCasters); - } - if($typeChecker === null) - { + if ($typeChecker === null) { $typeChecker = new TypeChecker($emptyStringNull); } @@ -85,12 +76,13 @@ public function __construct(string $file, ?array $typeCasters = null, ValueType /** * {@inheritDoc} * - * @param bool $raw - * - * @return void * @throws DotEnvSyntaxError * @throws EnvVariableNotFound * @throws Exception + * + * @param bool $raw + * + * @return void */ public function parse(bool $raw = false): void { @@ -118,13 +110,15 @@ public function parse(bool $raw = false): void } /** - * @param string $startingChar - * @param int $column + * @throws DotEnvSyntaxError + * + * @param int $column + * + * @param string $startingChar * * @return string - * @throws DotEnvSyntaxError */ - private function extractName(string $startingChar, int & $column): string + private function extractName(string $startingChar, int &$column): string { $key = $startingChar; while (($c = $this->handler->fgetc()) !== self::EQUALS) { @@ -157,16 +151,19 @@ private function extractName(string $startingChar, int & $column): string /** * Parses the individual value from the .env file * - * @param array $envs - * @param bool $raw - * @param int $column + * @throws EnvVariableNotFound + * + * @param bool $raw + * @param int $column + * + * @param array $envs * * @return int|string|float|null - * @throws EnvVariableNotFound */ - private function extractValue(array $envs, bool $raw, int & $column) + private function extractValue(array $envs, bool $raw, int &$column) { $value = ''; + $shouldBeString = false; // Trimming the leading spaces of the value while (($c = $this->handler->fgetc()) === self::SPACE) { $column++; @@ -177,10 +174,13 @@ private function extractValue(array $envs, bool $raw, int & $column) // Handling Multiline values if ($c === self::MULTI_LINE_START) { + $shouldBeString = true; $this->handler->fseek($this->handler->ftell() + 1); while (($c = $this->handler->fgetc()) !== false && $c !== self::MULTI_LINE_STOP) { // Handle the interpolation - if (!$raw && $c === self::INTERPOLATION_INDICATOR && ($c = $this->handler->fgetc()) === self::INTERPOLATION_START) { + if (!$raw && + $c === self::INTERPOLATION_INDICATOR && + ($c = $this->handler->fgetc()) === self::INTERPOLATION_START) { $value .= $this->interpolation($envs); } else { $value .= $c; @@ -214,14 +214,15 @@ private function extractValue(array $envs, bool $raw, int & $column) $column++; } - return $this->typeChecker->detectValue($value); + return $this->typeChecker->detectValue($value, $shouldBeString); } /** - * @param array $envs + * @throws EnvVariableNotFound + * + * @param array $envs * * @return mixed - * @throws EnvVariableNotFound */ private function interpolation(array $envs) { @@ -230,7 +231,7 @@ private function interpolation(array $envs) $tmp .= $c; } if (!isset($envs[$tmp])) { - throw new EnvVariableNotFound($tmp . ' is not found'); + throw new EnvVariableNotFound($tmp.' is not found'); } return $envs[$tmp]; } @@ -238,8 +239,8 @@ private function interpolation(array $envs) /** * Loads ENVs into $_ENV Super global variable * - * @return void * @throws EnvNotParsed + * @return void */ public function loadIntoENV(): void { @@ -256,8 +257,8 @@ public function loadIntoENV(): void * Loads all ENVs using putenv() function * * @inheritDoc - * @return void * @throws EnvNotParsed + * @return void */ public function loadUsingPutEnv(): void { @@ -278,24 +279,26 @@ public function getEnvs(): array public function __destruct() { unset($this->handler); - $this->handler = NULL; + $this->handler = null; } /** - * @param string $envName - * @param string $value - * @param bool $shouldQuote - * @return int * @throws DotEnvSyntaxError * @throws EnvVariableNotFound + * + * @param bool $shouldQuote + * @param string $envName + * @param string $value + * + * @return int */ public function write(string $envName, string $value, bool $shouldQuote = false): int { - if(!$this->isParsed) { + if (!$this->isParsed) { $this->parse(); } - if($shouldQuote === true) { - $value = '"' . $value . '"'; + if ($shouldQuote === true) { + $value = '"'.$value.'"'; } $this->envs[$envName] = $value; diff --git a/src/TypeChecker.php b/src/TypeChecker.php index 9d00470..6e597fc 100644 --- a/src/TypeChecker.php +++ b/src/TypeChecker.php @@ -6,19 +6,25 @@ class TypeChecker implements ValueType { - private $emptyStringAsNull; + private bool $emptyStringAsNull; public function __construct(bool $emptyStringAsNull) { $this->emptyStringAsNull = $emptyStringAsNull; } - public function detectValue(string $value) + public function detectValue(string $value, bool $shouldBeString) { + if ($value === '' && $shouldBeString) { + return ''; + } + $toLower = strtolower($value); // Detecting NULL - if (strcmp('null', $toLower) === 0 || ($this->emptyStringAsNull === true && strcmp('', $toLower) === 0)) { + if (($value === '' && !$shouldBeString) || + strcmp('null', $toLower) === 0 || + ($this->emptyStringAsNull === true && strcmp('', $toLower) === 0)) { return null; } @@ -31,7 +37,6 @@ public function detectValue(string $value) $trimmed = ltrim($toLower, '0'); - $casted = (float)$toLower; if (($casted !== 0.0 || strcmp('.0', $trimmed) === 0) && preg_match('/^\d+\.\d+$/', $toLower) === 1) { @@ -63,7 +68,7 @@ private function checkForBoolean(string $value): ?int case 'false': return false; default: - return null; + return null; } } -} \ No newline at end of file +} diff --git a/src/ValueType.php b/src/ValueType.php index b6ea7a0..6b85c70 100644 --- a/src/ValueType.php +++ b/src/ValueType.php @@ -12,5 +12,5 @@ interface ValueType public const STRING = 'STRING'; public const BOOLEAN = 'BOOLEAN'; - public function detectValue(string $value); -} \ No newline at end of file + public function detectValue(string $value, bool $shouldBeString); +} diff --git a/src/functions.php b/src/functions.php deleted file mode 100644 index 0413e8c..0000000 --- a/src/functions.php +++ /dev/null @@ -1,7 +0,0 @@ -parse(true); + $array = $parser->getEnvs(); + self::assertIsArray($array); + self::assertArrayHasKey('APP_NAME', $array); + self::assertArrayHasKey('DB_NAME', $array); + self::assertArrayHasKey('MULTI_LINE', $array); + self::assertArrayHasKey('COMMENTS_AT_END_OF_VALUE', $array); + self::assertArrayHasKey('EMPTY_ENV', $array); + self::assertArrayHasKey('NAME_AND_VAlUE', $array); + self::assertEquals('Test', $array['APP_NAME']); + self::assertEquals('test', $array['DB_NAME']); + self::assertEquals('', $array['EMPTY_ENV']); + self::assertEquals(null, $array['NULL_ENV']); + self::assertEquals('Name', $array['COMMENTS_AT_END_OF_VALUE']); + self::assertEquals( + ' this + is multi line +', + $array['MULTI_LINE'] + ); + } catch (DotEnvSyntaxError $e) { + self::fail(sprintf('%s %d %d', $e->getMessage(), $e->getEnvLine(), $e->getColumn())); + } catch (Exception $e) { + self::fail($e->getMessage()); + } + } + + /** + * @throws DotEnvSyntaxError + * @throws EnvVariableNotFound + * @throws Exception + */ + public function test_env_with_error(): void + { + $this->expectException(DotEnvSyntaxError::class); + $parser = new EnvParser(__DIR__.'/.env-error'); + $parser->parse(); + } + + /** + * @throws DotEnvSyntaxError + * @throws EnvVariableNotFound + * @throws Exception + */ + public function test_env_with_space_error_in_variable_name(): void + { + $this->expectException(DotEnvSyntaxError::class); + $parser = new EnvParser(__DIR__.'/.env-error'); + $parser->parse(); + } + + public function test_interpolation(): void + { + $expected = 'Test is Interpolated'; + try { + $parser = new EnvParser(__DIR__.'/.env.interpolation'); + $parser->parse(); + $envs = $parser->getEnvs(); + self::assertIsArray($envs); + self::assertArrayHasKey('INTERPOLATION', $envs); + self::assertEquals($expected, $envs['INTERPOLATION']); + } catch (Exception $e) { + self::fail($e->getMessage()); + } + } + + public function test_casting(): void + { + try { + $parser = new EnvParser(__DIR__.'/.env.casts'); + $parser->parse(); + $envs = $parser->getEnvs(); + self::assertIsArray($envs); + + self::assertIsInt($envs['INTEGERS']); + self::assertIsInt($envs['INT_ZERO']); + self::assertIsBool($envs['BOOLEAN']); + self::assertIsString($envs['STR']); + self::assertIsFloat($envs['FLOATS']); + self::assertIsFloat($envs['FLOAT_ZERO']); + self::assertNull($envs['NULLABLE']); + self::assertNull($envs['UPPERNULL']); + self::assertEquals(123, $envs['INTEGERS']); + self::assertEquals(0, $envs['INT_ZERO']); + self::assertEquals(false, $envs['BOOLEAN']); + self::assertEquals(true, $envs['BOOLEAN_TRUE']); + self::assertEquals(1.65, $envs['FLOATS']); + self::assertEquals(0.0, $envs['FLOAT_ZERO']); + } catch (Exception $e) { + self::fail($e->getMessage()); + } + } + + public function test_empty_value(): void + { + try { + $parser = new EnvParser(__DIR__.'/.env.empty.value'); + $parser->parse(); + $envs = $parser->getEnvs(); + self::assertIsArray($envs); + self::assertArrayHasKey('APP_NAME', $envs); + self::assertArrayHasKey('DB_NAME', $envs); + self::assertArrayHasKey('TEST_EMPTY', $envs); + self::assertEquals('', $envs['TEST_EMPTY']); + } catch (Throwable $e) { + self::fail($e->getMessage()); + } + } +} diff --git a/tests/EnvTest/EnvParserTest.php b/tests/EnvTest/EnvParserTest.php deleted file mode 100644 index 4aa60ca..0000000 --- a/tests/EnvTest/EnvParserTest.php +++ /dev/null @@ -1,109 +0,0 @@ -parse(true); - $array = $parser->getEnvs(); - $this->assertIsArray($array); - $this->assertArrayHasKey('APP_NAME', $array); - $this->assertArrayHasKey('DB_NAME', $array); - $this->assertArrayHasKey('MULTI_LINE', $array); - $this->assertArrayHasKey('COMMENTS_AT_END_OF_VALUE', $array); - $this->assertArrayHasKey('EMPTY_ENV', $array); - $this->assertArrayHasKey('NAME_AND_VAlUE', $array); - $this->assertEquals('Test', $array['APP_NAME']); - $this->assertEquals('test', $array['DB_NAME']); - $this->assertEquals('', $array['EMPTY_ENV']); - $this->assertEquals('Name', $array['COMMENTS_AT_END_OF_VALUE']); - $this->assertEquals(' this - is multi line -', $array['MULTI_LINE']); - } catch (DotEnvSyntaxError $e) { - $this->fail(sprintf('%s %d %d', $e->getMessage(), $e->getEnvLine(), $e->getColumn())); - } catch (Exception $e) { - $this->fail($e->getMessage()); - } - } - - /** - * @throws DotEnvSyntaxError - * @throws EnvVariableNotFound - * @throws Exception - */ - public function test_env_with_error(): void - { - $this->expectException(DotEnvSyntaxError::class); - $parser = new EnvParser(__DIR__ . '/.env-error'); - $parser->parse(); - } - - /** - * @throws DotEnvSyntaxError - * @throws EnvVariableNotFound - * @throws Exception - */ - public function test_env_with_space_error_in_variable_name(): void - { - $this->expectException(DotEnvSyntaxError::class); - $parser = new EnvParser(__DIR__ . '/.env-error'); - $parser->parse(); - } - - public function test_interpolation(): void - { - $expected = 'Test is Interpolated'; - try { - $parser = new EnvParser(__DIR__ . '/.env.interpolation'); - $parser->parse(); - $envs = $parser->getEnvs(); - $this->assertIsArray($envs); - $this->assertArrayHasKey('INTERPOLATION', $envs); - $this->assertEquals($expected, $envs['INTERPOLATION']); - } catch (Exception $e) { - $this->fail($e->getMessage()); - } - } - - public function test_casting(): void - { - try { - $parser = new EnvParser(__DIR__ . '/.env.casts'); - $parser->parse(); - $envs = $parser->getEnvs(); - $this->assertIsArray($envs); - - $this->assertIsInt($envs['INTEGERS']); - $this->assertIsInt($envs['INT_ZERO']); - $this->assertIsBool($envs['BOOLEAN']); - $this->assertIsString($envs['STR']); - $this->assertIsFloat($envs['FLOATS']); - $this->assertIsFloat($envs['FLOAT_ZERO']); - $this->assertNull($envs['NULLABLE']); - $this->assertNull($envs['UPPERNULL']); - $this->assertEquals(123,$envs['INTEGERS']); - $this->assertEquals(0,$envs['INT_ZERO']); - $this->assertEquals(false,$envs['BOOLEAN']); - $this->assertEquals(true,$envs['BOOLEAN_TRUE']); - $this->assertEquals(1.65,$envs['FLOATS']); - $this->assertEquals(0.0,$envs['FLOAT_ZERO']); - } catch (Exception $e) { - $this->fail($e->getMessage()); - } - } -}