Skip to content

Commit

Permalink
Merge pull request #4 from fidum/dont-append-namespace-to-json-keys
Browse files Browse the repository at this point in the history
Handle namespaced json files
  • Loading branch information
dmason30 authored Oct 9, 2023
2 parents 2e648cf + 41711d1 commit f61529d
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 10 deletions.
10 changes: 10 additions & 0 deletions src/Contracts/Factories/LanguageNamespaceKeyFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Fidum\LaravelTranslationLinter\Contracts\Factories;

use Symfony\Component\Finder\SplFileInfo;

interface LanguageNamespaceKeyFactory
{
public function getNamespaceHintedKey(SplFileInfo $file, string $locale, string $namespaceHint, string $key): string;
}
27 changes: 27 additions & 0 deletions src/Factories/LanguageNamespaceKeyFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Fidum\LaravelTranslationLinter\Factories;

use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageNamespaceKeyFactory as LanguageNamespaceKeyFactoryContract;
use Fidum\LaravelTranslationLinter\Managers\LanguageFileReaderManager;
use Symfony\Component\Finder\SplFileInfo;

class LanguageNamespaceKeyFactory implements LanguageNamespaceKeyFactoryContract
{
public function __construct(protected LanguageFileReaderManager $manager) {}

public function getNamespaceHintedKey(SplFileInfo $file, string $locale, string $namespaceHint, string $key): string
{
$extension = $file->getExtension();

if ($this->manager->isEnabled($extension)) {
$reader = $this->manager->driver($extension);

if ($reader instanceof LanguageNamespaceKeyFactoryContract) {
return $reader->getNamespaceHintedKey($file, $locale, $namespaceHint, $key);
}
}

return $key;
}
}
5 changes: 5 additions & 0 deletions src/LaravelTranslationLinterServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Fidum\LaravelTranslationLinter\Contracts\Collections\UnusedFieldCollection as UnusedFieldCollectionContract;
use Fidum\LaravelTranslationLinter\Contracts\Collections\UnusedFilterCollection as UnusedFilterCollectionContract;
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageKeyFactory as LanguageKeyFactoryContract;
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageNamespaceKeyFactory as LanguageNamespaceKeyFactoryContract;
use Fidum\LaravelTranslationLinter\Contracts\Finders\ApplicationFileFinder as ApplicationFileFinderContract;
use Fidum\LaravelTranslationLinter\Contracts\Finders\LanguageFileFinder as LanguageFileFinderContract;
use Fidum\LaravelTranslationLinter\Contracts\Finders\LanguageNamespaceFinder as LanguageNamespaceFinderContract;
Expand All @@ -18,6 +19,7 @@
use Fidum\LaravelTranslationLinter\Contracts\Readers\ApplicationFileReader as ApplicationFileReaderContract;
use Fidum\LaravelTranslationLinter\Contracts\Readers\LanguageFileReader as LanguageFileReaderContract;
use Fidum\LaravelTranslationLinter\Factories\LanguageKeyFactory;
use Fidum\LaravelTranslationLinter\Factories\LanguageNamespaceKeyFactory;
use Fidum\LaravelTranslationLinter\Finders\ApplicationFileFinder;
use Fidum\LaravelTranslationLinter\Finders\LanguageFileFinder;
use Fidum\LaravelTranslationLinter\Finders\LanguageNamespaceFinder;
Expand Down Expand Up @@ -74,6 +76,8 @@ public function registeringPackage()

$this->app->bind(LanguageNamespaceFinderContract::class, LanguageNamespaceFinder::class);

$this->app->bind(LanguageNamespaceKeyFactoryContract::class, LanguageNamespaceKeyFactory::class);

$this->app->bind(ResultObjectCollectionContract::class, ResultObjectCollection::class);

$this->app->bind(UnusedFieldCollectionContract::class, function (Application $app) {
Expand Down Expand Up @@ -102,6 +106,7 @@ public function provides()
LanguageFileReaderManager::class,
LanguageKeyFactoryContract::class,
LanguageNamespaceFinderContract::class,
LanguageNamespaceKeyFactoryContract::class,
ResultObjectCollectionContract::class,
UnusedFieldCollectionContract::class,
UnusedFilterCollectionContract::class,
Expand Down
24 changes: 16 additions & 8 deletions src/Linters/UnusedTranslationLinter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Fidum\LaravelTranslationLinter\Contracts\Collections\ResultObjectCollection;
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageKeyFactory;
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageNamespaceKeyFactory;
use Fidum\LaravelTranslationLinter\Contracts\Finders\LanguageFileFinder;
use Fidum\LaravelTranslationLinter\Contracts\Finders\LanguageNamespaceFinder;
use Fidum\LaravelTranslationLinter\Contracts\Linters\UnusedTranslationLinter as UnusedTranslationLinterContract;
Expand All @@ -21,8 +22,9 @@ public function __construct(
protected ApplicationFileReader $used,
protected LanguageFileFinder $files,
protected LanguageFileReader $translations,
protected LanguageKeyFactory $factory,
protected LanguageKeyFactory $languageKeyFactory,
protected LanguageNamespaceFinder $namespaces,
protected LanguageNamespaceKeyFactory $namespaceKeyFactory,
protected ResultObjectCollection $results,
protected array $locales,
) {}
Expand All @@ -42,17 +44,23 @@ public function execute(): ResultObjectCollection
$translations = $this->translations->getTranslations($file);

foreach ($translations as $field => $children) {
$group = $this->factory->getLanguageKey($file, $locale, $field);

foreach (Arr::dot(Arr::wrap($children)) as $key => $value) {
$groupedKey = Str::of($group)
$fieldKey = Str::of($field)
->when(is_string($key), fn (Stringable $str) => $str->append(".$key"))
->toString();

$namespacedKey = Str::of($namespace)
->whenNotEmpty(fn (Stringable $str) => $str->append('::'))
->append($groupedKey)
->toString();
$groupedKey = $this->languageKeyFactory->getLanguageKey(
file: $file,
locale: $locale,
key: $fieldKey
);

$namespacedKey = $this->namespaceKeyFactory->getNamespaceHintedKey(
file: $file,
locale: $locale,
namespaceHint: $namespace,
key: $groupedKey
);

if ($used->doesntContain($namespacedKey)) {
$this->results->push(new ResultObject(
Expand Down
12 changes: 11 additions & 1 deletion src/Readers/PhpFileReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
namespace Fidum\LaravelTranslationLinter\Readers;

use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageKeyFactory as LanguageKeyFactoryContract;
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageNamespaceKeyFactory as LanguageNamespaceKeyFactoryContract;
use Fidum\LaravelTranslationLinter\Contracts\Readers\LanguageFileReader as LanguageFileReaderContract;
use Illuminate\Support\Str;
use Illuminate\Support\Stringable;
use InvalidArgumentException;
use Symfony\Component\Finder\SplFileInfo;

class PhpFileReader implements LanguageFileReaderContract, LanguageKeyFactoryContract
class PhpFileReader implements LanguageFileReaderContract, LanguageKeyFactoryContract, LanguageNamespaceKeyFactoryContract
{
public function getLanguageKey(SplFileInfo $file, string $locale, string $key): string
{
Expand All @@ -21,6 +23,14 @@ public function getLanguageKey(SplFileInfo $file, string $locale, string $key):
->toString();
}

public function getNamespaceHintedKey(SplFileInfo $file, string $locale, string $namespaceHint, string $key): string
{
return Str::of($namespaceHint)
->whenNotEmpty(fn (Stringable $str) => $str->append('::'))
->append($key)
->toString();
}

public function getTranslations(SplFileInfo $file): array
{
$translations = include $file->getPathname();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@

ERROR 19 unused translations found.
ERROR 22 unused translations found.

+--------+-----------+------------------------------------+------------------------------+
| Locale | Namespace | Key | Value |
+--------+-----------+------------------------------------+------------------------------+
| en | example | Unused Vendor PHP Class | I am unused in php class |
| en | example | Unused Vendor Blade File | I am unused in blade |
| en | example | Unused Vendor Vue Component | I am unused in vue component |
| en | example | example.unused | I am unused in php class |
| en | example | example.blade.choice.unused | I am unused in blade |
| en | example | example.blade.lang.unused | I am unused in blade |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

ERROR 36 unused translations found.

+--------+-----------+------------------------------------+----------------------------------------------------+
| Locale | Namespace | Key | Value |
+--------+-----------+------------------------------------+----------------------------------------------------+
| en | example | Unused Vendor PHP Class | I am unused in php class |
| en | example | Unused Vendor Blade File | I am unused in blade |
| en | example | Unused Vendor Vue Component | I am unused in vue component |
| en | example | example.unused | I am unused in php class |
| en | example | example.blade.choice.unused | I am unused in blade |
| en | example | example.blade.lang.unused | I am unused in blade |
| en | example | example.vue.unused | I am unused in vue component |
| en | example | folder/example.unused | I am unused in php class |
| en | example | folder/example.blade.choice.unused | I am unused in blade |
| en | example | folder/example.blade.lang.unused | I am unused in blade |
| en | example | folder/example.vue.unused | I am unused in vue component |
| en | | Unused PHP Class | I am unused in php class |
| en | | Unused Blade File | I am unused in blade |
| en | | Unused Vue Component | I am unused in vue component |
| en | | example.unused | I am unused in php class |
| en | | example.blade.choice.unused | I am unused in blade |
| en | | example.blade.lang.unused | I am unused in blade |
| en | | example.vue.unused | I am unused in vue component |
| en | | folder/example.unused | I am unused in php class |
| en | | folder/example.blade.choice.unused | I am unused in blade |
| en | | folder/example.blade.lang.unused | I am unused in blade |
| en | | folder/example.vue.unused | I am unused in vue component |
| de | example | Unused Vendor PHP Class | Ich werde in einer PHP-Klasse nicht verwendet |
| de | example | Unused Vendor Blade File | Ich werde in Blade nicht verwendet |
| de | example | Unused Vendor Vue Component | Ich werde in einem Vue-Komponenten nicht verwendet |
| de | | Unused PHP Class | Ich werde in einer PHP-Klasse nicht verwendet |
| de | | Unused Blade File | Ich werde in Blade nicht verwendet |
| de | | Unused Vue Component | Ich werde in einem Vue-Komponenten nicht verwendet |
| de | | example.unused | Ich werde in einer PHP-Klasse nicht verwendet |
| de | | example.blade.choice.unused | Ich werde in Blade nicht verwendet |
| de | | example.blade.lang.unused | Ich werde in Blade nicht verwendet |
| de | | example.vue.unused | Ich werde in einem Vue-Komponenten nicht verwendet |
| de | | folder/example.unused | Ich werde in einer PHP-Klasse nicht verwendet |
| de | | folder/example.blade.choice.unused | Ich werde in Blade nicht verwendet |
| de | | folder/example.blade.lang.unused | Ich werde in Blade nicht verwendet |
| de | | folder/example.vue.unused | Ich werde in einem Vue-Komponenten nicht verwendet |
+--------+-----------+------------------------------------+----------------------------------------------------+
12 changes: 12 additions & 0 deletions tests/Commands/UnusedCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@
->toMatchSnapshot();
});

it('errors with multiple locales and no filters', function () {
config()->set('translation-linter.lang.locales', ['en', 'de']);
config()->set('translation-linter.unused.fields.namespace', true);
config()->set('translation-linter.unused.filters', []);

withoutMockingConsoleOutput();
expect(artisan('translation:unused'))
->toBe(1)
->and(Artisan::output())
->toMatchSnapshot();
});

it('outputs success message when no unused translations found', function () {
config()->set('translation-linter.lang.locales', []);
withoutMockingConsoleOutput();
Expand Down
1 change: 1 addition & 0 deletions workbench/app/ExampleJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ class ExampleJson
public function handle()
{
__('Used PHP Class');
__('Used Vendor PHP Class');
}
}
4 changes: 4 additions & 0 deletions workbench/resources/js/ExampleComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@ const exampleC = computed(() => __(
'Used Vue Component',
{foo: 'bar'},
))
const exampleD = computed(() => __(
'Used Vendor Vue Component',
{foo: 'bar'},
))
</script>
1 change: 1 addition & 0 deletions workbench/resources/views/welcome.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
)

{{ __('Used Blade File') }}
{{ __('Used Vendor Blade File') }}

@if(true)
@choice('example.blade.choice.used', 1)
Expand Down
8 changes: 8 additions & 0 deletions workbench/vendor/example/lang/de.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Used Vendor PHP Class": "Ich werde in einer PHP-Klasse verwendet",
"Unused Vendor PHP Class": "Ich werde in einer PHP-Klasse nicht verwendet",
"Used Vendor Blade File": "Ich werde in Blade verwendet",
"Unused Vendor Blade File": "Ich werde in Blade nicht verwendet",
"Used Vendor Vue Component": "Ich werde in einem Vue-Komponenten verwendet",
"Unused Vendor Vue Component": "Ich werde in einem Vue-Komponenten nicht verwendet"
}
8 changes: 8 additions & 0 deletions workbench/vendor/example/lang/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Used Vendor PHP Class": "I am used in php class",
"Unused Vendor PHP Class": "I am unused in php class",
"Used Vendor Blade File": "I am used in blade",
"Unused Vendor Blade File": "I am unused in blade",
"Used Vendor Vue Component": "I am used in vue component",
"Unused Vendor Vue Component": "I am unused in vue component"
}

0 comments on commit f61529d

Please sign in to comment.