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

orchestral / workbench / 12245788578

09 Dec 2024 10:53PM UTC coverage: 91.356% (-2.8%) from 94.118%
12245788578

push

github

crynobone
Merge branch '7.x' into 8.x

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

14 of 14 new or added lines in 1 file covered. (100.0%)

30 existing lines in 2 files now uncovered.

539 of 590 relevant lines covered (91.36%)

13.57 hits per line

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

92.68
/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\Contracts\Console\PromptsForMissingInput;
8
use Illuminate\Filesystem\Filesystem;
9
use Illuminate\Support\Collection;
10
use Orchestra\Testbench\Foundation\Console\Actions\GeneratesFile;
11
use Orchestra\Workbench\Workbench;
12
use Symfony\Component\Console\Attribute\AsCommand;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Input\InputOption;
15
use Symfony\Component\Console\Output\OutputInterface;
16

17
use function Laravel\Prompts\confirm;
18
use function Laravel\Prompts\select;
19
use function Orchestra\Testbench\join_paths;
20
use function Orchestra\Testbench\package_path;
21

22
#[AsCommand(name: 'workbench:install', description: 'Setup Workbench for package development')]
23
class InstallCommand extends Command implements PromptsForMissingInput
24
{
25
    use Concerns\InteractsWithFiles;
26

27
    /**
28
     * The `testbench.yaml` default configuration file.
29
     */
30
    public static ?string $configurationBaseFile = null;
31

32
    /**
33
     * Determine if Package also uses Testbench Dusk.
34
     */
35
    protected ?bool $hasTestbenchDusk = null;
36

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

43
        parent::initialize($input, $output);
21✔
44
    }
45

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

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

68
        $workingPath = package_path();
21✔
69

70
        $this->copyTestbenchConfigurationFile($filesystem, $workingPath);
21✔
71
        $this->copyTestbenchDotEnvFile($filesystem, $workingPath);
21✔
72

73
        $this->replaceDefaultLaravelSkeletonInTestbenchConfigurationFile($filesystem, $workingPath);
21✔
74

75
        $this->call('workbench:create-sqlite-db', ['--force' => true]);
21✔
76

77
        return Command::SUCCESS;
21✔
78
    }
79

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

89
        $to = join_paths($workingPath, 'testbench.yaml');
21✔
90

91
        (new GeneratesFile(
21✔
92
            filesystem: $filesystem,
21✔
93
            components: $this->components,
21✔
94
            force: (bool) $this->option('force'),
21✔
95
        ))->handle($from, $to);
21✔
96
    }
97

98
    /**
99
     * Copy the ".env" file.
100
     */
101
    protected function copyTestbenchDotEnvFile(Filesystem $filesystem, string $workingPath): void
102
    {
103
        $workbenchWorkingPath = join_paths($workingPath, 'workbench');
21✔
104

105
        $from = $this->laravel->basePath('.env.example');
21✔
106

107
        if (! $filesystem->isFile($this->laravel->basePath('.env.example'))) {
21✔
UNCOV
108
            return;
×
109
        }
110

111
        /** @var \Illuminate\Support\Collection<int, string> $choices */
112
        $choices = Collection::make($this->environmentFiles())
21✔
113
            ->reject(static fn ($file) => $filesystem->isFile(join_paths($workbenchWorkingPath, $file)))
21✔
114
            ->values();
21✔
115

116
        if (! $this->option('force') && $choices->isEmpty()) {
21✔
117
            $this->components->twoColumnDetail(
1✔
118
                'File [.env] already exists', '<fg=yellow;options=bold>SKIPPED</>'
1✔
119
            );
1✔
120

121
            return;
1✔
122
        }
123

124
        /** @var string $targetEnvironmentFile */
125
        $targetEnvironmentFile = select(
20✔
126
            label: "Export '.env' file as?",
20✔
127
            options: $choices->prepend('Skip exporting .env'), // @phpstan-ignore argument.type
20✔
128
            default: 'Skip exporting .env'
20✔
129
        );
20✔
130

131
        if ($targetEnvironmentFile === 'Skip exporting .env') {
20✔
132
            return;
5✔
133
        }
134

135
        $filesystem->ensureDirectoryExists($workbenchWorkingPath);
15✔
136

137
        $this->generateSeparateEnvironmentFileForTestbenchDusk($filesystem, $workbenchWorkingPath, $targetEnvironmentFile);
15✔
138

139
        (new GeneratesFile(
15✔
140
            filesystem: $filesystem,
15✔
141
            components: $this->components,
15✔
142
            force: (bool) $this->option('force'),
15✔
143
        ))->handle(
15✔
144
            $from,
15✔
145
            join_paths($workbenchWorkingPath, $targetEnvironmentFile)
15✔
146
        );
15✔
147

148
        (new GeneratesFile(
15✔
149
            filesystem: $filesystem,
15✔
150
            force: (bool) $this->option('force'),
15✔
151
        ))->handle(
15✔
152
            (string) Workbench::stubFile('gitignore'),
15✔
153
            join_paths($workbenchWorkingPath, '.gitignore')
15✔
154
        );
15✔
155
    }
156

157
    /**
158
     * Replace the default `laravel` skeleton for Testbench Dusk.
159
     *
160
     * @codeCoverageIgnore
161
     */
162
    protected function replaceDefaultLaravelSkeletonInTestbenchConfigurationFile(Filesystem $filesystem, string $workingPath): void
163
    {
164
        if ($this->hasTestbenchDusk === false) {
165
            return;
166
        }
167

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

171
    /**
172
     * Generate separate `.env.dusk` equivalent for Testbench Dusk.
173
     *
174
     * @codeCoverageIgnore
175
     */
176
    protected function generateSeparateEnvironmentFileForTestbenchDusk(Filesystem $filesystem, string $workbenchWorkingPath, string $targetEnvironmentFile): void
177
    {
178
        if ($this->hasTestbenchDusk === false) {
179
            return;
180
        }
181

182
        if ($this->components->confirm('Create separate environment file for Testbench Dusk?', false)) {
183
            (new GeneratesFile(
184
                filesystem: $filesystem,
185
                components: $this->components,
186
                force: (bool) $this->option('force'),
187
            ))->handle(
188
                $this->laravel->basePath('.env.example'),
189
                join_paths($workbenchWorkingPath, str_replace('.env', '.env.dusk', $targetEnvironmentFile))
190
            );
191
        }
192
    }
193

194
    /**
195
     * Get possible environment files.
196
     *
197
     * @return array<int, string>
198
     */
199
    protected function environmentFiles(): array
200
    {
201
        return [
21✔
202
            '.env',
21✔
203
            '.env.example',
21✔
204
            '.env.dist',
21✔
205
        ];
21✔
206
    }
207

208
    /**
209
     * Prompt the user for any missing arguments.
210
     *
211
     * @return void
212
     */
213
    protected function promptForMissingArguments(InputInterface $input, OutputInterface $output)
214
    {
215
        $devtool = null;
21✔
216

217
        if ($input->getOption('skip-devtool') === true) {
21✔
UNCOV
218
            $devtool = false;
×
219
        } elseif (\is_null($input->getOption('devtool'))) {
21✔
UNCOV
220
            $devtool = confirm('Run Workbench DevTool installation?', true);
×
221
        }
222

223
        if (! \is_null($devtool)) {
21✔
UNCOV
224
            $input->setOption('devtool', $devtool);
×
225
        }
226
    }
227

228
    /**
229
     * Get the console command options.
230
     *
231
     * @return array
232
     */
233
    protected function getOptions()
234
    {
235
        return [
21✔
236
            ['force', 'f', InputOption::VALUE_NONE, 'Overwrite any existing files'],
21✔
237
            ['devtool', null, InputOption::VALUE_NEGATABLE, 'Run DevTool installation'],
21✔
238
            ['basic', null, InputOption::VALUE_NONE, 'Skipped routes and discovers installation'],
21✔
239

240
            /** @deprecated */
241
            ['skip-devtool', null, InputOption::VALUE_NONE, 'Skipped DevTool installation (deprecated)'],
21✔
242
        ];
21✔
243
    }
244
}
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