Passed
Push — dbal ( 396fa2...d36e46 )
by Greg
11:43
created

ComposerScripts::missingTests()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 3
nop 1
dl 0
loc 20
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2022 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Console;
21
22
use Composer\Script\Event;
23
use Fisharebest\Localization\Translation;
24
use League\Flysystem\Filesystem;
25
use League\Flysystem\FilesystemException;
26
use League\Flysystem\FilesystemReader;
27
use League\Flysystem\Local\LocalFilesystemAdapter;
28
use League\Flysystem\StorageAttributes;
29
30
use function basename;
31
use function count;
32
use function dirname;
33
use function file_put_contents;
34
use function glob;
35
use function str_contains;
36
use function var_export;
37
38
/**
39
 * Command-line utilities.
40
 */
41
class ComposerScripts
42
{
43
    // Location of our translation files.
44
    private const PO_FILE_PATTERN = 'resources/lang/*/*.po';
45
46
    // Path to the root folder.
47
    private const ROOT_DIR = __DIR__ . '/../../';
48
49
    /**
50
     * Rebuild the .POT, .PO and .PHP file.
51
     *
52
     * @param Event $event
53
     */
54
    public static function languageFiles(Event $event): void
55
    {
56
        require $event->getComposer()->getConfig()->get('vendor-dir') . '/autoload.php';
57
58
        $io = $event->getIO();
59
60
        $po_files = glob(self::PO_FILE_PATTERN) ?: [];
61
62
        foreach ($po_files as $po_file) {
63
            $translation  = new Translation($po_file);
64
            $translations = $translation->asArray();
65
            $io->write($po_file . ': ' . count($translations));
66
            $php_file = dirname($po_file) . '/' . basename($po_file, '.po') . '.php';
67
            $php_code = "<?php\n\nreturn " . var_export($translations, true) . ";\n";
68
69
            file_put_contents($php_file, $php_code);
70
        }
71
    }
72
73
    /**
74
     * Ensure every class has a corresponding test script.
75
     *
76
     * @param Event $event
77
     *
78
     * @throws FilesystemException
79
     */
80
    public static function missingTests(Event $event): void
81
    {
82
        require $event->getComposer()->getConfig()->get('vendor-dir') . '/autoload.php';
83
84
        $io = $event->getIO();
85
86
        $filesystem = new Filesystem(new LocalFilesystemAdapter(self::ROOT_DIR));
87
88
        $scripts = $filesystem->listContents('app', FilesystemReader::LIST_DEEP)
89
            ->filter(static fn (StorageAttributes $file): bool => $file->isFile())
90
            ->map(static fn (StorageAttributes $file): string => $file->path())
91
            ->filter(static fn (string $script): bool => !str_contains($script, 'Interface.php') && !str_contains($script, 'Abstract'));
92
93
        foreach ($scripts as $script) {
94
            $class = strtr($script, ['app/' => '', '.php' => '', '/' => '\\']);
95
            $test  = strtr($script, ['app/' => 'tests/app/', '.php' => 'Test.php']);
96
97
            if (!$filesystem->fileExists($test)) {
98
                $io->write('Creating test script for: ' . $class);
99
                $filesystem->write($test, self::testStub($class));
100
            }
101
        }
102
    }
103
104
    /**
105
     * Create an empty test script.
106
     *
107
     * @param string $class
108
     *
109
     * @return string
110
     */
111
    private static function testStub(string $class): string
112
    {
113
        $year       = date('Y');
114
        $namespace  = strtr(dirname(strtr($class, ['\\' => '/'])), ['/' => '\\']);
115
        $base_class = basename(strtr($class, ['\\' => '/']));
116
117
        if ($namespace === '.') {
118
            $namespace = 'Fisharebest\\Webtrees';
119
        } else {
120
            $namespace = 'Fisharebest\\Webtrees\\' . $namespace;
121
        }
122
123
        return <<<"end_of_file"
124
<?php
125
126
/**
127
 * webtrees: online genealogy
128
 * Copyright (C) {$year} webtrees development team
129
 * This program is free software: you can redistribute it and/or modify
130
 * it under the terms of the GNU General Public License as published by
131
 * the Free Software Foundation, either version 3 of the License, or
132
 * (at your option) any later version.
133
 * This program is distributed in the hope that it will be useful,
134
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
135
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
136
 * GNU General Public License for more details.
137
 * You should have received a copy of the GNU General Public License
138
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
139
 */
140
141
declare(strict_types=1);
142
143
namespace {$namespace};
144
145
use Fisharebest\\Webtrees\\TestCase;
146
147
/**
148
 * Test harness for the class {$base_class}
149
 *
150
 * @covers {$namespace}\\{$base_class}
151
 */
152
class {$base_class}Test extends TestCase
153
{
154
}
155
156
end_of_file;
157
    }
158
}
159