瀏覽代碼

Add `scribe:config:diff` command

shalvah 2 年之前
父節點
當前提交
afc700b359
共有 5 個文件被更改,包括 186 次插入0 次删除
  1. 3 0
      phpunit.xml
  2. 35 0
      src/Commands/DiffConfig.php
  3. 2 0
      src/ScribeServiceProvider.php
  4. 75 0
      src/Tools/ConfigDiffer.php
  5. 71 0
      tests/Unit/ConfigDifferTest.php

+ 3 - 0
phpunit.xml

@@ -18,6 +18,8 @@
         </include>
         <exclude>
             <file>src/ScribeServiceProvider.php</file>
+            <file>src/Tools/ConfigDiffer.php</file>
+            <file>src/Commands/DiffConfig.php</file>
         </exclude>
     </coverage>
     <php>
@@ -38,6 +40,7 @@
         <testsuite name="Unit Tests 1">
             <file>tests/Unit/ExtractorTest.php</file>
             <file>tests/Unit/ExtractorPluginSystemTest.php</file>
+            <file>tests/Unit/ConfigDifferTest.php</file>
         </testsuite>
         <testsuite name="Unit Tests 2">
             <file>tests/Unit/ExtractedEndpointDataTest.php</file>

+ 35 - 0
src/Commands/DiffConfig.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace Knuckles\Scribe\Commands;
+
+use Illuminate\Console\Command;
+use Knuckles\Scribe\Tools\ConfigDiffer;
+
+class DiffConfig extends Command
+{
+    protected $signature = "scribe:config:diff";
+
+    protected $description = "Dump your changed config to the console. Use this when posting bug reports";
+
+    public function handle(): void
+    {
+        $usersConfig = config('scribe');
+        $defaultConfig = require __DIR__."/../../config/scribe.php";
+
+        $ignore = ['example_languages', 'routes', 'description', 'auth.extra_info', "intro_text", "groups"];
+        $asList = ['strategies.*', "examples.models_source"];
+        $differ = new ConfigDiffer($defaultConfig, $usersConfig, ignorePaths: $ignore, asList: $asList);
+
+        $diff = $differ->getDiff();
+
+        if (empty($diff)) {
+            $this->info("------ SAME AS DEFAULT CONFIG ------");
+            return;
+        }
+
+        foreach ($diff as $key => $item) {
+            $this->line("$key => $item");
+        }
+    }
+
+}

+ 2 - 0
src/ScribeServiceProvider.php

@@ -3,6 +3,7 @@
 namespace Knuckles\Scribe;
 
 use Illuminate\Support\ServiceProvider;
+use Knuckles\Scribe\Commands\DiffConfig;
 use Knuckles\Scribe\Commands\GenerateDocumentation;
 use Knuckles\Scribe\Commands\MakeStrategy;
 use Knuckles\Scribe\Commands\Upgrade;
@@ -85,6 +86,7 @@ class ScribeServiceProvider extends ServiceProvider
                 GenerateDocumentation::class,
                 MakeStrategy::class,
                 Upgrade::class,
+                DiffConfig::class,
             ]);
         }
     }

+ 75 - 0
src/Tools/ConfigDiffer.php

@@ -0,0 +1,75 @@
+<?php
+
+namespace Knuckles\Scribe\Tools;
+
+use Illuminate\Support\Str;
+
+class ConfigDiffer
+{
+
+    public function __construct(
+        protected array $defaultConfig,
+        protected array $usersConfig,
+        protected array $ignorePaths = [],
+        protected array $asList = [],
+    )
+    {
+    }
+
+    public function getDiff()
+    {
+        return $this->recursiveItemDiff($this->defaultConfig, $this->usersConfig);
+    }
+
+    protected function recursiveItemDiff($old, $new, $prefix = '')
+    {
+        $diff = [];
+
+        foreach ($new as $key => $value) {
+            $fullKey = $prefix.$key;
+            if (Str::is($this->ignorePaths, $fullKey)) continue;
+
+            $oldValue = data_get($old, $key);
+
+            if (is_array($value)) {
+                if (Str::is($this->asList, $fullKey)) {
+                    $listDiff = $this->diffList($oldValue, $value);
+                    if (!empty($listDiff)) {
+                        $diff[$fullKey] = $listDiff;
+                    }
+                } else {
+                    $diff = array_merge(
+                        $diff, $this->recursiveItemDiff($oldValue, $value, "$fullKey.")
+                    );
+                }
+            } else {
+                if ($oldValue !== $value) {
+                    $printedValue = json_encode($value, JSON_UNESCAPED_SLASHES);
+                    $diff[$prefix.$key] = $printedValue;
+                }
+            }
+        }
+
+        return $diff;
+    }
+
+    protected function diffList(mixed $oldValue, array $value)
+    {
+        if (!is_array($oldValue)) {
+            return "changed to a list";
+        }
+
+        $added = array_map(fn ($v) => "$v", array_diff($value, $oldValue));
+        $removed = array_map(fn ($v) => "$v", array_diff($oldValue, $value));
+
+        $diff = [];
+        if (!empty($added)) {
+            $diff[] = "added ".implode(", ", $added);
+        }
+        if (!empty($removed)) {
+            $diff[] = "removed ".implode(", ", $removed);
+        }
+
+        return empty($diff) ? "" : implode(": ", $diff);
+    }
+}

+ 71 - 0
tests/Unit/ConfigDifferTest.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Unit;
+
+use Knuckles\Scribe\Tools\ConfigDiffer;
+use PHPUnit\Framework\TestCase;
+
+class ConfigDifferTest extends TestCase
+{
+    /** @test */
+    public function returns_empty_when_there_are_no_changes()
+    {
+        $default = [
+            'title' => null,
+            'theme' => 'default',
+            'extra' => 'ignored',
+        ];
+        $user = [
+            'theme' => 'default',
+            'title' => null,
+        ];
+        $differ = new ConfigDiffer($default, $user);
+        $diff = $differ->getDiff();
+        $this->assertEquals([], $diff);
+    }
+
+    /** @test */
+    public function works()
+    {
+        $default = [
+            'title' => null,
+            'theme' => 'default',
+        ];
+        $user = [
+            'theme' => 'elements',
+            'title' => null,
+        ];
+        $differ = new ConfigDiffer($default, $user);
+        $diff = $differ->getDiff();
+        $this->assertEquals([
+            "theme" => '"elements"',
+        ], $diff);
+    }
+
+    /** @test */
+    public function ignores_specified_paths()
+    {
+        $default = [
+            'theme' => 'default',
+            'description' => '',
+            'test' => [
+                'array' => [ 'old-item' ],
+                'string' => null,
+            ],
+        ];
+        $user = [
+            'theme' => 'elements',
+            'description' => 'Details',
+            'test' => [
+                'string' => 'value',
+                'array' => [ 'new-item' ]
+            ],
+        ];
+        $differ = new ConfigDiffer($default, $user, ignorePaths: ['description', 'test.array']);
+        $diff = $differ->getDiff();
+        $this->assertEquals([
+            "theme" => '"elements"',
+            'test.string' => '"value"',
+        ], $diff);
+    }
+}