diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..7fb0d41 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,41 @@ +name: Tests + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Run test suite + run: composer test diff --git a/composer.json b/composer.json index d7081fb..a67bfe6 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,6 @@ "name": "naingaunglwin-dev/dotenv", "description": "Simple and lightweight php dotenv library", "minimum-stability": "dev", - "version": "2.0.0", "prefer-stable": true, "license": "MIT", "authors": [ @@ -22,5 +21,8 @@ }, "require-dev": { "phpunit/phpunit": "^11.5" + }, + "scripts": { + "test": "vendor/bin/phpunit tests" } } diff --git a/src/Loader/BaseLoader.php b/src/Loader/BaseLoader.php index de27465..1ae6ba9 100644 --- a/src/Loader/BaseLoader.php +++ b/src/Loader/BaseLoader.php @@ -2,6 +2,7 @@ namespace NAL\Dotenv\Loader; +use NAL\Dotenv\Exceptions\UnableToOpenFileException; use NAL\Dotenv\Parser\ParserInterface; use NAL\Dotenv\PathResolver; @@ -54,7 +55,15 @@ protected function getDefaultFile(): string */ protected function resolveFiles(): array { - return array_map(fn ($file) => $this->resolver->resolve($file), $this->files); + return array_map(function ($file) { + $file = $this->resolver->resolve($file); + + if (!is_file($file) || !is_readable($file)) { + throw new UnableToOpenFileException($file); + } + + return $file; + }, $this->files); } /** diff --git a/src/Loader/DotenvLoader.php b/src/Loader/DotenvLoader.php index dd84624..3dd6c79 100644 --- a/src/Loader/DotenvLoader.php +++ b/src/Loader/DotenvLoader.php @@ -43,7 +43,7 @@ public function load(): array $handle = @fopen($file, 'r'); if ($handle === false) { - throw new UnableToOpenFileException($file); + throw new UnableToOpenFileException($file); // @codeCoverageIgnore } $contents = fread($handle, filesize($file)); diff --git a/src/Loader/JsonLoader.php b/src/Loader/JsonLoader.php index a8c6f96..b2e84af 100644 --- a/src/Loader/JsonLoader.php +++ b/src/Loader/JsonLoader.php @@ -46,7 +46,7 @@ public function load(): array $handle = @fopen($file, 'r'); if ($handle === false) { - throw new UnableToOpenFileException($file); + throw new UnableToOpenFileException($file); // @codeCoverageIgnore } $content = fread($handle, filesize($file)); diff --git a/src/PathResolver.php b/src/PathResolver.php index b359b53..90f2af8 100644 --- a/src/PathResolver.php +++ b/src/PathResolver.php @@ -107,6 +107,10 @@ public static function isAbsolute(string $path): bool */ public static function normalize(string $path): string { + if (self::isAbsolute($path)) { + return str_replace(['/', '\\'], self::DS, $path); + } + return trim(str_replace(['/', '\\'], self::DS, $path), self::DS); } } diff --git a/tests/EnvTest.php b/tests/EnvTest.php index fc30c7e..f63772d 100644 --- a/tests/EnvTest.php +++ b/tests/EnvTest.php @@ -146,6 +146,15 @@ public function testThrowExceptionIfEnvFileNotFound() $env->load(); } + public function testEnvFileLoadWithCustomPath() + { + $file = $this->createEnvFile('.env', "FOO=bar\n"); + + $env = Env::create(loader: new DotenvLoader('.env', resolver: new PathResolver($this->dir))); + + $this->assertSame('bar', $env->get('FOO')); + } + public function testThrowExceptionEnvLoadWithGuessLoaderForUnregisteredFileType() { $file = $this->createEnvFile('env.txt', "APP_TEST=true");