• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

orchestral / workbench / 12383445206

17 Dec 2024 11:46PM UTC coverage: 93.076% (-0.1%) from 93.193%
12383445206

push

github

web-flow
[7.x] Fix `workbench:install` generating migrate-fresh command with incorrect options (#66)

* [7.x] Fix `workbench:install` generating `migrate-fresh` command with
incorrect options

fixes #65

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

---------

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

3 of 4 new or added lines in 1 file covered. (75.0%)

578 of 621 relevant lines covered (93.08%)

14.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.3
/src/Console/InstallCommand.php
1
<?php
2

3
namespace Orchestra\Workbench\Console;
4

5
use Composer\InstalledVersions;
6
use Illuminate\Console\Command;
7
use Illuminate\Filesystem\Filesystem;
8
use Illuminate\Support\Collection;
9
use Orchestra\Testbench\Foundation\Console\Actions\GeneratesFile;
10
use Orchestra\Workbench\Workbench;
11
use Symfony\Component\Console\Attribute\AsCommand;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15

16
use function Orchestra\Testbench\join_paths;
17
use function Orchestra\Testbench\package_path;
18

19
#[AsCommand(name: 'workbench:install', description: 'Setup Workbench for package development')]
20
class InstallCommand extends Command
21
{
22
    use Concerns\InteractsWithFiles;
23

24
    /**
25
     * The `testbench.yaml` default configuration file.
26
     */
27
    public static ?string $configurationBaseFile = null;
28

29
    /**
30
     * Determine if Package also uses Testbench Dusk.
31
     */
32
    protected ?bool $hasTestbenchDusk = null;
33

34
    /** {@inheritDoc} */
35
    #[\Override]
36
    protected function initialize(InputInterface $input, OutputInterface $output)
37
    {
38
        $this->hasTestbenchDusk = InstalledVersions::isInstalled('orchestra/testbench-dusk');
22✔
39

40
        parent::initialize($input, $output);
22✔
41
    }
42

43
    /**
44
     * Execute the console command.
45
     *
46
     * @return int
47
     */
48
    public function handle(Filesystem $filesystem)
49
    {
50
        if (! $this->option('skip-devtool')) {
22✔
51
            $devtool = match (true) {
22✔
52
                \is_bool($this->option('devtool')) => $this->option('devtool'),
22✔
53
                default => $this->components->confirm('Install Workbench DevTool?', true),
22✔
54
            };
22✔
55

56
            if ($devtool === true) {
22✔
57
                $this->call('workbench:devtool', [
4✔
58
                    '--force' => $this->option('force'),
4✔
59
                    '--no-install' => true,
4✔
60
                    '--basic' => $this->option('basic'),
4✔
61
                ]);
4✔
62
            }
63
        }
64

65
        $workingPath = package_path();
22✔
66

67
        $this->copyTestbenchConfigurationFile($filesystem, $workingPath);
22✔
68
        $this->copyTestbenchDotEnvFile($filesystem, $workingPath);
22✔
69

70
        $this->replaceDefaultLaravelSkeletonInTestbenchConfigurationFile($filesystem, $workingPath);
22✔
71

72
        $this->call('workbench:create-sqlite-db', ['--force' => true]);
22✔
73

74
        return Command::SUCCESS;
22✔
75
    }
76

77
    /**
78
     * Copy the "testbench.yaml" file.
79
     */
80
    protected function copyTestbenchConfigurationFile(Filesystem $filesystem, string $workingPath): void
81
    {
82
        $from = ! \is_null(static::$configurationBaseFile)
22✔
83
            ? (string) realpath(static::$configurationBaseFile)
×
84
            : (string) Workbench::stubFile($this->option('basic') === true ? 'config.basic' : 'config');
22✔
85

86
        $to = join_paths($workingPath, 'testbench.yaml');
22✔
87

88
        (new GeneratesFile(
22✔
89
            filesystem: $filesystem,
22✔
90
            components: $this->components,
22✔
91
            force: (bool) $this->option('force'),
22✔
92
        ))->handle($from, $to);
22✔
93

94
        $workbenchAppNamespacePrefix = Workbench::detectNamespace('app', force: true) ?? 'Workbench\App\\';
22✔
95
        $workbenchSeederNamespacePrefix = Workbench::detectNamespace('database/seeders', force: true) ?? 'Workbench\Database\Seeders\\';
22✔
96

97
        $serviceProvider = \sprintf('%sProviders\WorkbenchServiceProvider', $workbenchAppNamespacePrefix);
22✔
98
        $databaseSeeder = \sprintf('%sDatabaseSeeder', $workbenchSeederNamespacePrefix);
22✔
99

100
        $this->replaceInFile(
22✔
101
            $filesystem,
22✔
102
            [
22✔
103
                '{{WorkbenchAppNamespace}}',
22✔
104
                '{{ WorkbenchAppNamespace }}',
22✔
105
                '{{WorkbenchSeederNamespace}}',
22✔
106
                '{{ WorkbenchSeederNamespace }}',
22✔
107

108
                '{{WorkbenchServiceProvider}}',
22✔
109
                '{{ WorkbenchServiceProvider }}',
22✔
110
                'Workbench\App\Providers\WorkbenchServiceProvider',
22✔
111

112
                '{{WorkbenchDatabaseSeeder}}',
22✔
113
                '{{ WorkbenchDatabaseSeeder }}',
22✔
114
                'Workbench\Database\Seeders\DatabaseSeeder',
22✔
115

116
                '    - migrate-fresh',
22✔
117
            ],
22✔
118
            [
22✔
119
                $workbenchAppNamespacePrefix,
22✔
120
                $workbenchAppNamespacePrefix,
22✔
121
                $workbenchSeederNamespacePrefix,
22✔
122
                $workbenchSeederNamespacePrefix,
22✔
123

124
                $serviceProvider,
22✔
125
                $serviceProvider,
22✔
126
                $serviceProvider,
22✔
127

128
                $databaseSeeder,
22✔
129
                $databaseSeeder,
22✔
130
                $databaseSeeder,
22✔
131

132
                $databaseSeeder === 'Database\Seeders\DatabaseSeeder'
22✔
NEW
133
                    ? '    - migrate-fresh'
×
134
                    : '    - migrate-fresh:'.PHP_EOL.'        --seed: true',
22✔
135
            ],
22✔
136
            $to
22✔
137
        );
22✔
138
    }
139

140
    /**
141
     * Copy the ".env" file.
142
     */
143
    protected function copyTestbenchDotEnvFile(Filesystem $filesystem, string $workingPath): void
144
    {
145
        $workbenchWorkingPath = join_paths($workingPath, 'workbench');
22✔
146

147
        $from = $this->laravel->basePath('.env.example');
22✔
148

149
        if (! $filesystem->isFile($this->laravel->basePath('.env.example'))) {
22✔
150
            return;
×
151
        }
152

153
        $choices = Collection::make($this->environmentFiles())
22✔
154
            ->reject(static fn ($file) => $filesystem->isFile(join_paths($workbenchWorkingPath, $file)))
22✔
155
            ->values();
22✔
156

157
        if (! $this->option('force') && $choices->isEmpty()) {
22✔
158
            $this->components->twoColumnDetail(
1✔
159
                'File [.env] already exists', '<fg=yellow;options=bold>SKIPPED</>'
1✔
160
            );
1✔
161

162
            return;
1✔
163
        }
164

165
        /** @var string|null $targetEnvironmentFile */
166
        $targetEnvironmentFile = $this->input->isInteractive()
21✔
167
            ? $this->components->choice(
21✔
168
                "Export '.env' file as?",
21✔
169
                $choices->prepend('Skip exporting .env')->all()
21✔
170
            ) : null;
21✔
171

172
        if (\in_array($targetEnvironmentFile, [null, 'Skip exporting .env'])) {
21✔
173
            return;
6✔
174
        }
175

176
        $filesystem->ensureDirectoryExists($workbenchWorkingPath);
15✔
177

178
        $this->generateSeparateEnvironmentFileForTestbenchDusk($filesystem, $workbenchWorkingPath, $targetEnvironmentFile);
15✔
179

180
        (new GeneratesFile(
15✔
181
            filesystem: $filesystem,
15✔
182
            components: $this->components,
15✔
183
            force: (bool) $this->option('force'),
15✔
184
        ))->handle(
15✔
185
            $from,
15✔
186
            join_paths($workbenchWorkingPath, $targetEnvironmentFile)
15✔
187
        );
15✔
188

189
        (new GeneratesFile(
15✔
190
            filesystem: $filesystem,
15✔
191
            force: (bool) $this->option('force'),
15✔
192
        ))->handle(
15✔
193
            (string) Workbench::stubFile('gitignore'),
15✔
194
            join_paths($workbenchWorkingPath, '.gitignore')
15✔
195
        );
15✔
196
    }
197

198
    /**
199
     * Replace the default `laravel` skeleton for Testbench Dusk.
200
     *
201
     * @codeCoverageIgnore
202
     */
203
    protected function replaceDefaultLaravelSkeletonInTestbenchConfigurationFile(Filesystem $filesystem, string $workingPath): void
204
    {
205
        if ($this->hasTestbenchDusk === false) {
206
            return;
207
        }
208

209
        $this->replaceInFile($filesystem, ["laravel: '@testbench'"], ["laravel: '@testbench-dusk'"], join_paths($workingPath, 'testbench.yaml'));
210
    }
211

212
    /**
213
     * Generate separate `.env.dusk` equivalent for Testbench Dusk.
214
     *
215
     * @codeCoverageIgnore
216
     */
217
    protected function generateSeparateEnvironmentFileForTestbenchDusk(Filesystem $filesystem, string $workbenchWorkingPath, string $targetEnvironmentFile): void
218
    {
219
        if ($this->hasTestbenchDusk === false) {
220
            return;
221
        }
222

223
        if ($this->components->confirm('Create separate environment file for Testbench Dusk?', false)) {
224
            (new GeneratesFile(
225
                filesystem: $filesystem,
226
                components: $this->components,
227
                force: (bool) $this->option('force'),
228
            ))->handle(
229
                $this->laravel->basePath('.env.example'),
230
                join_paths($workbenchWorkingPath, str_replace('.env', '.env.dusk', $targetEnvironmentFile))
231
            );
232
        }
233
    }
234

235
    /**
236
     * Get possible environment files.
237
     *
238
     * @return array<int, string>
239
     */
240
    protected function environmentFiles(): array
241
    {
242
        return [
22✔
243
            '.env',
22✔
244
            '.env.example',
22✔
245
            '.env.dist',
22✔
246
        ];
22✔
247
    }
248

249
    /**
250
     * Get the console command options.
251
     *
252
     * @return array
253
     */
254
    protected function getOptions()
255
    {
256
        return [
22✔
257
            ['force', 'f', InputOption::VALUE_NONE, 'Overwrite any existing files'],
22✔
258
            ['devtool', null, InputOption::VALUE_NEGATABLE, 'Run DevTool installation'],
22✔
259
            ['basic', null, InputOption::VALUE_NONE, 'Skipped routes and discovers installation'],
22✔
260

261
            /** @deprecated */
262
            ['skip-devtool', null, InputOption::VALUE_NONE, 'Skipped DevTool installation (deprecated)'],
22✔
263
        ];
22✔
264
    }
265
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc