Skip to content

Commit f61529d

Browse files
authored
Merge pull request #4 from fidum/dont-append-namespace-to-json-keys
Handle namespaced json files
2 parents 2e648cf + 41711d1 commit f61529d

File tree

13 files changed

+150
-10
lines changed

13 files changed

+150
-10
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Fidum\LaravelTranslationLinter\Contracts\Factories;
4+
5+
use Symfony\Component\Finder\SplFileInfo;
6+
7+
interface LanguageNamespaceKeyFactory
8+
{
9+
public function getNamespaceHintedKey(SplFileInfo $file, string $locale, string $namespaceHint, string $key): string;
10+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Fidum\LaravelTranslationLinter\Factories;
4+
5+
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageNamespaceKeyFactory as LanguageNamespaceKeyFactoryContract;
6+
use Fidum\LaravelTranslationLinter\Managers\LanguageFileReaderManager;
7+
use Symfony\Component\Finder\SplFileInfo;
8+
9+
class LanguageNamespaceKeyFactory implements LanguageNamespaceKeyFactoryContract
10+
{
11+
public function __construct(protected LanguageFileReaderManager $manager) {}
12+
13+
public function getNamespaceHintedKey(SplFileInfo $file, string $locale, string $namespaceHint, string $key): string
14+
{
15+
$extension = $file->getExtension();
16+
17+
if ($this->manager->isEnabled($extension)) {
18+
$reader = $this->manager->driver($extension);
19+
20+
if ($reader instanceof LanguageNamespaceKeyFactoryContract) {
21+
return $reader->getNamespaceHintedKey($file, $locale, $namespaceHint, $key);
22+
}
23+
}
24+
25+
return $key;
26+
}
27+
}

src/LaravelTranslationLinterServiceProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Fidum\LaravelTranslationLinter\Contracts\Collections\UnusedFieldCollection as UnusedFieldCollectionContract;
1111
use Fidum\LaravelTranslationLinter\Contracts\Collections\UnusedFilterCollection as UnusedFilterCollectionContract;
1212
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageKeyFactory as LanguageKeyFactoryContract;
13+
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageNamespaceKeyFactory as LanguageNamespaceKeyFactoryContract;
1314
use Fidum\LaravelTranslationLinter\Contracts\Finders\ApplicationFileFinder as ApplicationFileFinderContract;
1415
use Fidum\LaravelTranslationLinter\Contracts\Finders\LanguageFileFinder as LanguageFileFinderContract;
1516
use Fidum\LaravelTranslationLinter\Contracts\Finders\LanguageNamespaceFinder as LanguageNamespaceFinderContract;
@@ -18,6 +19,7 @@
1819
use Fidum\LaravelTranslationLinter\Contracts\Readers\ApplicationFileReader as ApplicationFileReaderContract;
1920
use Fidum\LaravelTranslationLinter\Contracts\Readers\LanguageFileReader as LanguageFileReaderContract;
2021
use Fidum\LaravelTranslationLinter\Factories\LanguageKeyFactory;
22+
use Fidum\LaravelTranslationLinter\Factories\LanguageNamespaceKeyFactory;
2123
use Fidum\LaravelTranslationLinter\Finders\ApplicationFileFinder;
2224
use Fidum\LaravelTranslationLinter\Finders\LanguageFileFinder;
2325
use Fidum\LaravelTranslationLinter\Finders\LanguageNamespaceFinder;
@@ -74,6 +76,8 @@ public function registeringPackage()
7476

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

79+
$this->app->bind(LanguageNamespaceKeyFactoryContract::class, LanguageNamespaceKeyFactory::class);
80+
7781
$this->app->bind(ResultObjectCollectionContract::class, ResultObjectCollection::class);
7882

7983
$this->app->bind(UnusedFieldCollectionContract::class, function (Application $app) {
@@ -102,6 +106,7 @@ public function provides()
102106
LanguageFileReaderManager::class,
103107
LanguageKeyFactoryContract::class,
104108
LanguageNamespaceFinderContract::class,
109+
LanguageNamespaceKeyFactoryContract::class,
105110
ResultObjectCollectionContract::class,
106111
UnusedFieldCollectionContract::class,
107112
UnusedFilterCollectionContract::class,

src/Linters/UnusedTranslationLinter.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Fidum\LaravelTranslationLinter\Contracts\Collections\ResultObjectCollection;
66
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageKeyFactory;
7+
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageNamespaceKeyFactory;
78
use Fidum\LaravelTranslationLinter\Contracts\Finders\LanguageFileFinder;
89
use Fidum\LaravelTranslationLinter\Contracts\Finders\LanguageNamespaceFinder;
910
use Fidum\LaravelTranslationLinter\Contracts\Linters\UnusedTranslationLinter as UnusedTranslationLinterContract;
@@ -21,8 +22,9 @@ public function __construct(
2122
protected ApplicationFileReader $used,
2223
protected LanguageFileFinder $files,
2324
protected LanguageFileReader $translations,
24-
protected LanguageKeyFactory $factory,
25+
protected LanguageKeyFactory $languageKeyFactory,
2526
protected LanguageNamespaceFinder $namespaces,
27+
protected LanguageNamespaceKeyFactory $namespaceKeyFactory,
2628
protected ResultObjectCollection $results,
2729
protected array $locales,
2830
) {}
@@ -42,17 +44,23 @@ public function execute(): ResultObjectCollection
4244
$translations = $this->translations->getTranslations($file);
4345

4446
foreach ($translations as $field => $children) {
45-
$group = $this->factory->getLanguageKey($file, $locale, $field);
46-
4747
foreach (Arr::dot(Arr::wrap($children)) as $key => $value) {
48-
$groupedKey = Str::of($group)
48+
$fieldKey = Str::of($field)
4949
->when(is_string($key), fn (Stringable $str) => $str->append(".$key"))
5050
->toString();
5151

52-
$namespacedKey = Str::of($namespace)
53-
->whenNotEmpty(fn (Stringable $str) => $str->append('::'))
54-
->append($groupedKey)
55-
->toString();
52+
$groupedKey = $this->languageKeyFactory->getLanguageKey(
53+
file: $file,
54+
locale: $locale,
55+
key: $fieldKey
56+
);
57+
58+
$namespacedKey = $this->namespaceKeyFactory->getNamespaceHintedKey(
59+
file: $file,
60+
locale: $locale,
61+
namespaceHint: $namespace,
62+
key: $groupedKey
63+
);
5664

5765
if ($used->doesntContain($namespacedKey)) {
5866
$this->results->push(new ResultObject(

src/Readers/PhpFileReader.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
namespace Fidum\LaravelTranslationLinter\Readers;
44

55
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageKeyFactory as LanguageKeyFactoryContract;
6+
use Fidum\LaravelTranslationLinter\Contracts\Factories\LanguageNamespaceKeyFactory as LanguageNamespaceKeyFactoryContract;
67
use Fidum\LaravelTranslationLinter\Contracts\Readers\LanguageFileReader as LanguageFileReaderContract;
78
use Illuminate\Support\Str;
9+
use Illuminate\Support\Stringable;
810
use InvalidArgumentException;
911
use Symfony\Component\Finder\SplFileInfo;
1012

11-
class PhpFileReader implements LanguageFileReaderContract, LanguageKeyFactoryContract
13+
class PhpFileReader implements LanguageFileReaderContract, LanguageKeyFactoryContract, LanguageNamespaceKeyFactoryContract
1214
{
1315
public function getLanguageKey(SplFileInfo $file, string $locale, string $key): string
1416
{
@@ -21,6 +23,14 @@ public function getLanguageKey(SplFileInfo $file, string $locale, string $key):
2123
->toString();
2224
}
2325

26+
public function getNamespaceHintedKey(SplFileInfo $file, string $locale, string $namespaceHint, string $key): string
27+
{
28+
return Str::of($namespaceHint)
29+
->whenNotEmpty(fn (Stringable $str) => $str->append('::'))
30+
->append($key)
31+
->toString();
32+
}
33+
2434
public function getTranslations(SplFileInfo $file): array
2535
{
2636
$translations = include $file->getPathname();

tests/.pest/snapshots/Commands/UnusedCommandTest/it_errors_with_default_no_filters.snap

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11

2-
ERROR 19 unused translations found.
2+
ERROR 22 unused translations found.
33

44
+--------+-----------+------------------------------------+------------------------------+
55
| Locale | Namespace | Key | Value |
66
+--------+-----------+------------------------------------+------------------------------+
7+
| en | example | Unused Vendor PHP Class | I am unused in php class |
8+
| en | example | Unused Vendor Blade File | I am unused in blade |
9+
| en | example | Unused Vendor Vue Component | I am unused in vue component |
710
| en | example | example.unused | I am unused in php class |
811
| en | example | example.blade.choice.unused | I am unused in blade |
912
| en | example | example.blade.lang.unused | I am unused in blade |
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
ERROR 36 unused translations found.
3+
4+
+--------+-----------+------------------------------------+----------------------------------------------------+
5+
| Locale | Namespace | Key | Value |
6+
+--------+-----------+------------------------------------+----------------------------------------------------+
7+
| en | example | Unused Vendor PHP Class | I am unused in php class |
8+
| en | example | Unused Vendor Blade File | I am unused in blade |
9+
| en | example | Unused Vendor Vue Component | I am unused in vue component |
10+
| en | example | example.unused | I am unused in php class |
11+
| en | example | example.blade.choice.unused | I am unused in blade |
12+
| en | example | example.blade.lang.unused | I am unused in blade |
13+
| en | example | example.vue.unused | I am unused in vue component |
14+
| en | example | folder/example.unused | I am unused in php class |
15+
| en | example | folder/example.blade.choice.unused | I am unused in blade |
16+
| en | example | folder/example.blade.lang.unused | I am unused in blade |
17+
| en | example | folder/example.vue.unused | I am unused in vue component |
18+
| en | | Unused PHP Class | I am unused in php class |
19+
| en | | Unused Blade File | I am unused in blade |
20+
| en | | Unused Vue Component | I am unused in vue component |
21+
| en | | example.unused | I am unused in php class |
22+
| en | | example.blade.choice.unused | I am unused in blade |
23+
| en | | example.blade.lang.unused | I am unused in blade |
24+
| en | | example.vue.unused | I am unused in vue component |
25+
| en | | folder/example.unused | I am unused in php class |
26+
| en | | folder/example.blade.choice.unused | I am unused in blade |
27+
| en | | folder/example.blade.lang.unused | I am unused in blade |
28+
| en | | folder/example.vue.unused | I am unused in vue component |
29+
| de | example | Unused Vendor PHP Class | Ich werde in einer PHP-Klasse nicht verwendet |
30+
| de | example | Unused Vendor Blade File | Ich werde in Blade nicht verwendet |
31+
| de | example | Unused Vendor Vue Component | Ich werde in einem Vue-Komponenten nicht verwendet |
32+
| de | | Unused PHP Class | Ich werde in einer PHP-Klasse nicht verwendet |
33+
| de | | Unused Blade File | Ich werde in Blade nicht verwendet |
34+
| de | | Unused Vue Component | Ich werde in einem Vue-Komponenten nicht verwendet |
35+
| de | | example.unused | Ich werde in einer PHP-Klasse nicht verwendet |
36+
| de | | example.blade.choice.unused | Ich werde in Blade nicht verwendet |
37+
| de | | example.blade.lang.unused | Ich werde in Blade nicht verwendet |
38+
| de | | example.vue.unused | Ich werde in einem Vue-Komponenten nicht verwendet |
39+
| de | | folder/example.unused | Ich werde in einer PHP-Klasse nicht verwendet |
40+
| de | | folder/example.blade.choice.unused | Ich werde in Blade nicht verwendet |
41+
| de | | folder/example.blade.lang.unused | Ich werde in Blade nicht verwendet |
42+
| de | | folder/example.vue.unused | Ich werde in einem Vue-Komponenten nicht verwendet |
43+
+--------+-----------+------------------------------------+----------------------------------------------------+

tests/Commands/UnusedCommandTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@
5555
->toMatchSnapshot();
5656
});
5757

58+
it('errors with multiple locales and no filters', function () {
59+
config()->set('translation-linter.lang.locales', ['en', 'de']);
60+
config()->set('translation-linter.unused.fields.namespace', true);
61+
config()->set('translation-linter.unused.filters', []);
62+
63+
withoutMockingConsoleOutput();
64+
expect(artisan('translation:unused'))
65+
->toBe(1)
66+
->and(Artisan::output())
67+
->toMatchSnapshot();
68+
});
69+
5870
it('outputs success message when no unused translations found', function () {
5971
config()->set('translation-linter.lang.locales', []);
6072
withoutMockingConsoleOutput();

workbench/app/ExampleJson.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ class ExampleJson
77
public function handle()
88
{
99
__('Used PHP Class');
10+
__('Used Vendor PHP Class');
1011
}
1112
}

workbench/resources/js/ExampleComponent.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@ const exampleC = computed(() => __(
1515
'Used Vue Component',
1616
{foo: 'bar'},
1717
))
18+
const exampleD = computed(() => __(
19+
'Used Vendor Vue Component',
20+
{foo: 'bar'},
21+
))
1822
</script>

0 commit comments

Comments
 (0)