From fd7bf608149192edc2609865977575aa81304037 Mon Sep 17 00:00:00 2001 From: Maarten Tolhuijs Date: Sat, 20 Jul 2019 20:57:26 +0200 Subject: [PATCH] Adds intentioned package implementation, test and readme updates --- CHANGELOG.md | 2 +- README.md | 61 +++++++++++++++++++++++++++++++++++---- composer.json | 2 +- config/config.php | 8 ----- phpunit.xml.dist | 5 +++- src/Commands/EnvScan.php | 39 ++++++++++++------------- src/LaravelEnvScanner.php | 45 +++++++++++++++-------------- tests/EnvScanTest.php | 60 ++++++++++++++++++++++++++++++++++++++ tests/ExampleTest.php | 14 --------- 9 files changed, 163 insertions(+), 73 deletions(-) delete mode 100644 config/config.php create mode 100644 tests/EnvScanTest.php delete mode 100644 tests/ExampleTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index a8b411d..467f690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,6 @@ All notable changes to `laravel-env-scanner` will be documented in this file -## 1.0.0 - 201X-XX-XX +## 1.0.0 - 2019-07-20 - initial release diff --git a/README.md b/README.md index 4bbdddc..ba956ce 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,29 @@ -# Very short description of the package +# Laravel environmental variable scanner [![Latest Version on Packagist](https://img.shields.io/packagist/v/mtolhuys/laravel-env-scanner.svg?style=flat-square)](https://packagist.org/packages/mtolhuys/laravel-env-scanner) [![Build Status](https://img.shields.io/travis/mtolhuys/laravel-env-scanner/master.svg?style=flat-square)](https://travis-ci.org/mtolhuys/laravel-env-scanner) [![Quality Score](https://img.shields.io/scrutinizer/g/mtolhuys/laravel-env-scanner.svg?style=flat-square)](https://scrutinizer-ci.com/g/mtolhuys/laravel-env-scanner) [![Total Downloads](https://img.shields.io/packagist/dt/mtolhuys/laravel-env-scanner.svg?style=flat-square)](https://packagist.org/packages/mtolhuys/laravel-env-scanner) -This is where your description should go. Try and limit it to a paragraph or two, and maybe throw in a mention of what PSRs you support to avoid any confusion with users and contributors. +This package comes with a `LaravelEnvScanner` class and artisan command which you can use to scan any folder in your app for potential .env related problems. + +Example output of the command: + +```bash +$ php artisan env:scan +Scanning: laravel-app/config... ++--------------+----------------+---------------------------+-------------------+ +| Files (1) | Has value (4) | Depending on default (1) | No value (2) | ++--------------+----------------+---------------------------+-------------------+ +| database.php | DB_CONNECTION | - | - | +| - | - | - | DATABASE_URL | +| - | DB_DATABASE | - | - | +| - | - | DB_FOREIGN_KEYS | - | +| - | - | - | DATABASE_URL | +| - | DB_HOST | - | - | +| - | DB_PORT | - | - | ++--------------+----------------+---------------------------+-------------------+ +``` ## Installation @@ -16,9 +34,41 @@ composer require mtolhuys/laravel-env-scanner ``` ## Usage +You can call the artisan command to start the scan: + +```bash +php artisan env:scan +``` + +Optionally you could specify a directory to run from: + +```bash +php artisan env:scan -d app/Http/Controllers +``` -``` php -// Usage description here +Additionally you can use the `LaravelEnvScanner` from anywhere you want: +```php +(new LaravelEnvScanner(__DIR__))->scan()->results; + +// Or + +$this->scanner = new LaravelEnvScanner(__DIR__); +$this->scanner->scan(); +$this->scanner->results; + +// Example results +[ + "files" => 1 + "empty" => 0 + "has_value" => 1 + "depending_on_default" => 0 + "data" => [ + 0 => [ + "filename" => "database.php" + "has_value" => "DB_HOST" + "depending_on_default" => "-" + "empty" => "-" +] ``` ### Testing @@ -37,12 +87,13 @@ Please see [CONTRIBUTING](CONTRIBUTING.md) for details. ### Security -If you discover any security related issues, please email mtolhuys@hotmail.com instead of using the issue tracker. +If you discover any security related issues, please email mtolhuys@protonmail.com instead of using the issue tracker. ## Credits - [Maarten Tolhuijs](https://github.com/mtolhuys) - [All Contributors](../../contributors) +- [Beyond Code](https://github.com/beyondcode) For the [boilerplate](https://laravelpackageboilerplate.com/) and having me come up with the idea for this package. ## License diff --git a/composer.json b/composer.json index e6847c6..6120e47 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "illuminate/support": "5.8.*" }, "require-dev": { - "orchestra/testbench": "3.8.*", + "orchestra/testbench": "^3.5", "phpunit/phpunit": "^7.0" }, "autoload": { diff --git a/config/config.php b/config/config.php deleted file mode 100644 index 48d0ee9..0000000 --- a/config/config.php +++ /dev/null @@ -1,8 +0,0 @@ - - + + + + diff --git a/src/Commands/EnvScan.php b/src/Commands/EnvScan.php index e54cd05..1d7f1a6 100644 --- a/src/Commands/EnvScan.php +++ b/src/Commands/EnvScan.php @@ -15,8 +15,7 @@ class EnvScan extends Command */ protected $signature = ' env:scan - { --a|app : Include app folder } - { --t|table : Show results data in a table } + { --d|dir= : Specify directory to scan (defaults to your config folder) } '; private $scanner; @@ -26,7 +25,7 @@ class EnvScan extends Command * * @var string */ - protected $description = 'Check all environmental variables used in config folder'; + protected $description = 'Check environmental variables used in your app'; /** * Execute the console command. @@ -37,27 +36,25 @@ class EnvScan extends Command public function handle() { $this->scanner = new LaravelEnvScanner( - $this->option('app') + $this->option('dir') ); - $this->scanner->scan(); + if (! file_exists($this->scanner->dir)) { + $this->error("{$this->scanner->dir} does not exist"); + exit(); + } - $this->showResults(); - } + $this->output->write( + "Scanning: {$this->scanner->dir}...\n" + ); - private function showResults() - { - if ($this->option('table')) { - $this->table([ - 'File', - "Has value ({$this->scanner->results['has_value']})", - "Depending on default ({$this->scanner->results['depending_on_default']})", - "No value ({$this->scanner->results['empty']})", - ], $this->scanner->results['data']); - } else { - $this->info("{$this->scanner->results['has_value']} have a value"); - $this->line("{$this->scanner->results['depending_on_default']} are depending on default"); - $this->warn("{$this->scanner->results['empty']} have no value"); - } + $this->scanner->scan(); + + $this->table([ + "Files ({$this->scanner->results['files']})", + "Has value ({$this->scanner->results['has_value']})", + "Depending on default ({$this->scanner->results['depending_on_default']})", + "No value ({$this->scanner->results['empty']})", + ], $this->scanner->results['data']); } } diff --git a/src/LaravelEnvScanner.php b/src/LaravelEnvScanner.php index 01122f2..fe3791d 100644 --- a/src/LaravelEnvScanner.php +++ b/src/LaravelEnvScanner.php @@ -14,6 +14,7 @@ class LaravelEnvScanner * @var array */ public $results = [ + 'files' => 0, 'empty' => 0, 'has_value' => 0, 'depending_on_default' => 0, @@ -28,16 +29,16 @@ class LaravelEnvScanner private $currentFile; /** - * If true - * combine all config files with files in app folder + * Root directory to start recursive search for env()'s from + * Defaults to config_path() * - * @var bool + * @var string $dir */ - private $includeAppFolder; + public $dir; - public function __construct($includeAppFolder = false) + public function __construct(string $dir = null) { - $this->includeAppFolder = $includeAppFolder; + $this->dir = $dir ?? config_path(); } /** @@ -48,19 +49,11 @@ public function __construct($includeAppFolder = false) */ public function scan() { - $files = $this->recursiveGlob(config_path(), '/.*?.php/'); - - if ($this->includeAppFolder) { - $files = array_merge( - $this->recursiveGlob(app_path(), '/.*?.php/'), $files - ); - } + $files = $this->recursiveDirSearch($this->dir, '/.*?.php/'); foreach ($files as $file) { $values = array_filter( - preg_split( - "#[\n]+#", shell_exec("tr -d '\n' < $file | grep -oP 'env\(\K[^)]+'") - ) + preg_split("#[\n]+#", shell_exec("tr -d '\n' < $file | grep -oP 'env\(\K[^)]+'")) ); foreach ($values as $value) { @@ -71,6 +64,8 @@ public function scan() $this->storeResult($file, $result); } } + + return $this; } /** @@ -105,10 +100,10 @@ private function storeResult(string $file, $result) } $this->results['data'][] = [ - 'File' => $this->getFilename($file), - 'Has value' => $result->hasValue ? $result->envVar : '-', - 'Depending on default' => !$result->hasValue && $result->hasDefault ? $result->envVar : '-', - 'No value' => !$result->hasValue && !$result->hasDefault ? $result->envVar : '-', + 'filename' => $this->getFilename($file), + 'has_value' => $result->hasValue ? $result->envVar : '-', + 'depending_on_default' => !$result->hasValue && $result->hasDefault ? $result->envVar : '-', + 'empty' => !$result->hasValue && !$result->hasDefault ? $result->envVar : '-', ]; } @@ -117,14 +112,20 @@ private function getFilename(string $file) $basename = basename($file); if ($this->currentFile === $basename) { - return ''; + return '-'; } + $this->results['files']++; + return $this->currentFile = $basename; } - private function recursiveGlob(string $folder, string $pattern): array + private function recursiveDirSearch(string $folder, string $pattern): array { + if (! file_exists($folder)) { + return []; + } + $files = new RegexIterator( new RecursiveIteratorIterator( new RecursiveDirectoryIterator($folder) diff --git a/tests/EnvScanTest.php b/tests/EnvScanTest.php new file mode 100644 index 0000000..b3d8f21 --- /dev/null +++ b/tests/EnvScanTest.php @@ -0,0 +1,60 @@ +scanner = new LaravelEnvScanner(__DIR__); + + $this->scanner->scan(); + } + + /** @test + * @throws \Exception + */ + public function it_checks_if_example_env_scan_results_are_correct() + { + $this->assertTrue($this->scanner->results['files'] === 1); + $this->assertTrue($this->scanner->results['has_value'] === 1); + $this->assertTrue($this->scanner->results['depending_on_default'] === 1); + $this->assertTrue($this->scanner->results['empty'] === 1); + $this->assertTrue($this->scanner->results['data'][0]['filename'] === basename(__FILE__)); + + foreach ($this->scanner->results['data'] as $result) { + if ($result['has_value'] !== '-') { + $this->assertTrue($result['has_value'] === 'FILLED'); + $this->assertTrue($result['depending_on_default'] === '-'); + $this->assertTrue($result['empty'] === '-'); + } else if ($result['depending_on_default'] !== '-') { + $this->assertTrue($result['depending_on_default'] === 'DEPENDS'); + $this->assertTrue($result['has_value'] === '-'); + $this->assertTrue($result['empty'] === '-'); + } else if ($result['empty'] !== '-') { + $this->assertTrue($result['empty'] === 'EMPTY'); + $this->assertTrue($result['depending_on_default'] === '-'); + $this->assertTrue($result['has_value'] === '-'); + + } + } + } +} diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php deleted file mode 100644 index c489f50..0000000 --- a/tests/ExampleTest.php +++ /dev/null @@ -1,14 +0,0 @@ -assertTrue(true); - } -}