Skip to content

Commit

Permalink
Line Space Preservation (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
msamgan authored Oct 7, 2024
1 parent 507922b commit 3ebb69d
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 70 deletions.
43 changes: 43 additions & 0 deletions src/Actions/AddKeys.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Msamgan\LaravelEnvKeysChecker\Actions;

use Illuminate\Support\Collection;

class AddKeys
{
public function handle(Collection $missingKeys): void
{
$missingKeys->each(function ($missingKey) {
$filePath = base_path($missingKey['envFile']);
$envContent = file($filePath);

$lineDiff = count($envContent) - $missingKey['line'];
if ($lineDiff < 0) {
$envContent = $this->appendEmptyLines(file: $filePath, numberOfLines: abs($lineDiff));
}

array_splice(
$envContent, $missingKey['line'] - 1, 0, $missingKey['key'] . '=""' . PHP_EOL
);

if ($missingKey['is_next_line_empty']) {
array_splice($envContent, $missingKey['line'], 0, PHP_EOL);
}

file_put_contents($filePath, $envContent);
});
}

private function appendEmptyLines(string $file, int $numberOfLines = 1): array
{
$envContent = file($file);
$lastLine = count($envContent);

for ($i = 0; $i < $numberOfLines; $i++) {
array_splice($envContent, $lastLine, 0, PHP_EOL);
}

return $envContent;
}
}
32 changes: 32 additions & 0 deletions src/Actions/CheckKeys.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Msamgan\LaravelEnvKeysChecker\Actions;

use Illuminate\Support\Collection;

class CheckKeys
{
public function handle(array $keyData, array $envFiles, Collection $missingKeys): void
{
collect($envFiles)->each(function ($envFile) use ($keyData, $missingKeys) {
$envContent = file($envFile);
$keyExists = false;

foreach ($envContent as $line) {
if (str_starts_with($line, $keyData['key'])) {
$keyExists = true;
break;
}
}

if (! $keyExists) {
$missingKeys->push([
'line' => $keyData['line'],
'key' => $keyData['key'],
'is_next_line_empty' => $keyData['is_next_line_empty'],
'envFile' => basename($envFile),
]);
}
});
}
}
36 changes: 36 additions & 0 deletions src/Actions/GetKeys.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Msamgan\LaravelEnvKeysChecker\Actions;

use Illuminate\Support\Collection;

class GetKeys
{
public function handle(array|string $files): Collection
{
$ignoredKeys = config('env-keys-checker.ignore_keys', []);

$files = is_array($files)
? collect($files)
: collect([$files]);

return $files
->map(function ($file) use ($ignoredKeys) {
return collect(file($file))->map(function ($line, $index) use ($file) {
[$key] = explode('=', $line);

return [
'key' => $key,
'line' => $index + 1,
'is_next_line_empty' => isset(file($file)[$index + 1]) && file($file)[$index + 1] === "\n",
];
})->filter(function ($item) {
return $item['key'] !== "\n" && ! str_starts_with($item['key'], '#');
})->filter(function ($keyData) use ($ignoredKeys) {
return ! in_array($keyData['key'], $ignoredKeys);
});
})
->flatten(1)
->unique('key');
}
}
87 changes: 17 additions & 70 deletions src/Commands/LaravelEnvKeysCheckerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
namespace Msamgan\LaravelEnvKeysChecker\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Collection;

use function Laravel\Prompts\confirm;
use function Laravel\Prompts\table;

use Msamgan\LaravelEnvKeysChecker\Actions\AddKeys;
use Msamgan\LaravelEnvKeysChecker\Actions\CheckKeys;
use Msamgan\LaravelEnvKeysChecker\Actions\GetKeys;

class LaravelEnvKeysCheckerCommand extends Command
{
public $signature = 'env:keys-check {--auto-add=}';

public $description = 'Check if all keys in .env file are present across all .env files. Like .env, .env.example, .env.testing, etc.';

public function handle(): int
public function handle(GetKeys $getKeys, CheckKeys $checkKeys, AddKeys $addKeys): int
{
$envFiles = glob(base_path('.env*'));

Expand All @@ -40,11 +43,11 @@ public function handle(): int
return ! in_array(basename($file), $ignoredFiles);
})->toArray();

$keys = $this->getAllKeys($envFiles);
$keys = $getKeys->handle(files: $envFiles);

$missingKeys = collect();
$keys->each(function ($keyData) use ($envFiles, $missingKeys) {
$this->checkForKeyInFile($keyData, $envFiles, $missingKeys);
$keys->each(function ($keyData) use ($envFiles, $missingKeys, $checkKeys) {
$checkKeys->handle(keyData: $keyData, envFiles: $envFiles, missingKeys: $missingKeys);
});

if ($missingKeys->isEmpty()) {
Expand All @@ -55,87 +58,31 @@ public function handle(): int

table(
headers: ['Line', 'Key', 'Is missing in'],
rows: $missingKeys,
rows: $missingKeys->map(function ($missingKey) {
return [
$missingKey['line'],
$missingKey['key'],
$missingKey['envFile'],
];
})->toArray()
);

if ($autoAddStrategy === 'ask') {
$confirmation = confirm('Do you want to add the missing keys to the .env files?');

if ($confirmation) {
$this->addKeysToFile($missingKeys, $envFiles);
$addKeys->handle(missingKeys: $missingKeys);
}

return self::SUCCESS;
}

if ($autoAddStrategy === 'auto') {
$this->addKeysToFile($missingKeys, $envFiles);
$addKeys->handle(missingKeys: $missingKeys);

return self::SUCCESS;
}

return self::FAILURE;
}

private function getAllKeys($files): Collection
{
$ignoredKeys = config('env-keys-checker.ignore_keys', []);

$files = is_array($files)
? collect($files)
: collect([$files]);

return $files
->map(function ($file) use ($ignoredKeys) {
return collect(file($file))->map(function ($line, $index) {
[$key] = explode('=', $line);

return [
'key' => $key,
'line' => $index + 1,
];
})->filter(function ($item) {
return $item['key'] !== "\n" && ! str_starts_with($item['key'], '#');
})->filter(function ($keyData) use ($ignoredKeys) {
return ! in_array($keyData['key'], $ignoredKeys);
});
})
->flatten(1)
->unique('key');
}

private function checkForKeyInFile($keyData, $envFiles, $missingKeys): void
{
collect($envFiles)->each(function ($envFile) use ($keyData, $missingKeys) {
$envContent = file($envFile);
$keyExists = false;

foreach ($envContent as $line) {
if (str_starts_with($line, $keyData['key'])) {
$keyExists = true;
break;
}
}

if (! $keyExists) {
$missingKeys->push([
'line' => $keyData['line'],
'key' => $keyData['key'],
'envFile' => basename($envFile),
]);
}
});
}

private function addKeysToFile($missingKeys, array $envFiles): void
{
$missingKeys->each(function ($missingKey) {
$filePath = base_path($missingKey['envFile']);
$envContent = file($filePath);
array_splice($envContent, $missingKey['line'] - 1, 0, $missingKey['key'] . '=""' . PHP_EOL);
file_put_contents($filePath, $envContent);
});

$this->info('=> Missing keys added to all .env files.');
}
}

0 comments on commit 3ebb69d

Please sign in to comment.