Skip to content

Commit 7c90c16

Browse files
authored
Merge pull request #54 from tonysm/tm/l11
Laravel 11 Support
2 parents 50e8622 + 6585240 commit 7c90c16

File tree

5 files changed

+107
-150
lines changed

5 files changed

+107
-150
lines changed

.github/workflows/run-tests.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ jobs:
1414
matrix:
1515
os: [ubuntu-latest, macos-latest, windows-latest]
1616
php: [8.1, 8.2]
17-
laravel: [9.45.*, 10.*]
17+
laravel: [10.*, 11.x]
1818
stability: [prefer-lowest, prefer-stable]
1919
include:
20-
- laravel: 9.45.*
21-
testbench: 7.17.*
2220
- laravel: 10.*
2321
testbench: 8.*
22+
collision: ^6.0
23+
- laravel: 11.*
24+
testbench: 9.*
25+
collision: ^8.1
2426

2527
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
2628

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
.php_cs
33
.php_cs.cache
44
.phpunit.result.cache
5+
.phpunit.cache
56
build
67
composer.lock
78
coverage

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@
1616
}
1717
],
1818
"require": {
19-
"php": "^8.1",
20-
"illuminate/contracts": "^9.0|^10.0",
21-
"illuminate/support": "^9.0|^10.0",
19+
"php": "^8.1|^8.2",
20+
"illuminate/contracts": "^10.0|^11.0",
21+
"illuminate/support": "^10.0|^11.0",
2222
"spatie/laravel-package-tools": "^1.9"
2323
},
2424
"require-dev": {
2525
"guzzlehttp/guzzle": "^7.4",
2626
"laravel/pint": "^1.10",
27-
"nunomaduro/collision": "^5.10|^6.0",
27+
"nunomaduro/collision": "^6.0|^8.1",
2828
"orchestra/testbench": "^7.17|^8.0",
2929
"phpstan/extension-installer": "^1.1",
3030
"phpstan/phpstan-deprecation-rules": "^1.0",
3131
"phpstan/phpstan-phpunit": "^1.0",
32-
"phpunit/phpunit": "^9.5"
32+
"phpunit/phpunit": "^10.5"
3333
},
3434
"bin": [
3535
"bin/importmap"

phpunit.xml.dist

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,30 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
54
backupGlobals="false"
6-
backupStaticAttributes="false"
75
bootstrap="vendor/autoload.php"
86
colors="true"
9-
convertErrorsToExceptions="true"
10-
convertNoticesToExceptions="true"
11-
convertWarningsToExceptions="true"
127
processIsolation="false"
138
stopOnFailure="false"
149
executionOrder="random"
1510
failOnWarning="true"
1611
failOnRisky="true"
1712
failOnEmptyTestSuite="true"
1813
beStrictAboutOutputDuringTests="true"
19-
verbose="true"
14+
cacheDirectory=".phpunit.cache"
15+
backupStaticProperties="false"
2016
>
2117
<testsuites>
22-
<testsuite name="Tonysm Test Suite">
18+
<testsuite name="Importmap Test Suite">
2319
<directory>tests</directory>
2420
</testsuite>
2521
</testsuites>
26-
<coverage>
22+
<logging>
23+
<junit outputFile="build/report.junit.xml" />
24+
</logging>
25+
<source>
2726
<include>
2827
<directory suffix=".php">./src</directory>
2928
</include>
30-
<report>
31-
<html outputDirectory="build/coverage"/>
32-
<text outputFile="build/coverage.txt"/>
33-
<clover outputFile="build/logs/clover.xml"/>
34-
</report>
35-
</coverage>
36-
<logging>
37-
<junit outputFile="build/report.junit.xml"/>
38-
</logging>
29+
</source>
3930
</phpunit>

src/Commands/InstallCommand.php

Lines changed: 86 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
namespace Tonysm\ImportmapLaravel\Commands;
44

55
use Illuminate\Console\Command;
6-
use Illuminate\Support\Facades\Artisan;
7-
use Illuminate\Support\Facades\Event;
86
use Illuminate\Support\Facades\File;
7+
use Illuminate\Support\Facades\Process;
98
use Illuminate\Support\Str;
109
use Symfony\Component\Console\Attribute\AsCommand;
11-
use Symfony\Component\Console\Terminal;
10+
use Symfony\Component\Process\PhpExecutableFinder;
1211
use Tonysm\ImportmapLaravel\Actions\FixJsImportPaths;
1312
use Tonysm\ImportmapLaravel\Actions\ReplaceOrAppendTags;
14-
use Tonysm\ImportmapLaravel\Events\FailedToFixImportStatement;
1513

1614
#[AsCommand('importmap:install')]
1715
class InstallCommand extends Command
@@ -20,12 +18,8 @@ class InstallCommand extends Command
2018

2119
public $description = 'Installs the package.';
2220

23-
public $afterMessages = [];
24-
2521
public function handle(): int
2622
{
27-
$this->displayHeader('Installing Importmap Laravel', '<bg=blue;fg=black> INFO </>');
28-
2923
File::ensureDirectoryExists(resource_path('js'));
3024

3125
$this->convertLocalImportsFromUsingDots();
@@ -34,112 +28,83 @@ public function handle(): int
3428
$this->updateAppLayouts();
3529
$this->deleteNpmRelatedFiles();
3630
$this->configureIgnoredFolder();
37-
38-
$this->displayAfterNotes();
31+
$this->runStorageLinkCommand();
3932

4033
$this->newLine();
41-
$this->line(' <fg=white>Done!</>');
34+
$this->components->info('Importmap Laravel was installed succesfully.');
4235

4336
return self::SUCCESS;
4437
}
4538

4639
private function deleteNpmRelatedFiles(): void
4740
{
48-
$this->displayTask('removing NPM related files', function () {
49-
$files = [
50-
'package.json',
51-
'package-lock.json',
52-
'webpack.mix.js',
53-
'postcss.config.js',
54-
'vite.config.js',
55-
];
56-
57-
collect($files)
58-
->map(fn ($file) => base_path($file))
59-
->filter(fn ($file) => File::exists($file))
60-
->each(fn ($file) => File::delete($file));
61-
62-
return self::SUCCESS;
63-
});
41+
$files = [
42+
'package.json',
43+
'package-lock.json',
44+
'webpack.mix.js',
45+
'postcss.config.js',
46+
'vite.config.js',
47+
];
48+
49+
collect($files)
50+
->map(fn ($file) => base_path($file))
51+
->filter(fn ($file) => File::exists($file))
52+
->each(fn ($file) => File::delete($file));
6453
}
6554

6655
private function publishImportmapFiles(): void
6756
{
68-
$this->displayTask('publishing the `routes/importmap.php` file', function () {
69-
File::copy(dirname(__DIR__, 2).implode(DIRECTORY_SEPARATOR, ['', 'stubs', 'routes', 'importmap.php']), base_path(implode(DIRECTORY_SEPARATOR, ['routes', 'importmap.php'])));
70-
File::copy(dirname(__DIR__, 2).implode(DIRECTORY_SEPARATOR, ['', 'stubs', 'jsconfig.json']), base_path('jsconfig.json'));
71-
72-
return self::SUCCESS;
73-
});
57+
File::copy(dirname(__DIR__, 2).implode(DIRECTORY_SEPARATOR, ['', 'stubs', 'routes', 'importmap.php']), base_path(implode(DIRECTORY_SEPARATOR, ['routes', 'importmap.php'])));
58+
File::copy(dirname(__DIR__, 2).implode(DIRECTORY_SEPARATOR, ['', 'stubs', 'jsconfig.json']), base_path('jsconfig.json'));
7459
}
7560

7661
private function convertLocalImportsFromUsingDots(): void
7762
{
78-
Event::listen(function (FailedToFixImportStatement $event) {
79-
$this->afterMessages[] = sprintf(
80-
'Failed to fix import statement (%s) in file (%).',
81-
$event->importStatement,
82-
str_replace(base_path(), '', $event->file->getPath()),
83-
);
84-
});
85-
86-
$this->displayTask('converting js imports', function () {
87-
$root = rtrim(resource_path('js'), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
88-
89-
(new FixJsImportPaths($root))();
90-
91-
return self::SUCCESS;
92-
});
63+
(new FixJsImportPaths(rtrim(resource_path('js'), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR))();
9364
}
9465

9566
private function importDependenciesFromNpm(): void
9667
{
97-
$this->displayTask('pinning dependencies from NPM', function () {
98-
if (! File::exists($packageJsonFile = base_path('package.json'))) {
99-
$this->afterMessages[] = '<fg=white>* Pinning was skipped because of missing package.json</>';
100-
101-
return self::INVALID;
102-
}
103-
104-
$this->afterMessages[] = '<fg=white>* Some dev dependencies could\'ve been skipped...</>';
68+
if (! File::exists($packageJsonFile = base_path('package.json'))) {
69+
return;
70+
}
10571

106-
$filteredOutDependencies = [
107-
'@tailwindcss/forms',
108-
'@tailwindcss/typography',
109-
'autoprefixer',
110-
'laravel-vite-plugin',
111-
'postcss',
112-
'tailwindcss',
113-
'vite',
114-
];
72+
$filteredOutDependencies = [
73+
'@tailwindcss/forms',
74+
'@tailwindcss/typography',
75+
'autoprefixer',
76+
'laravel-vite-plugin',
77+
'postcss',
78+
'tailwindcss',
79+
'vite',
80+
];
11581

116-
$packageJson = json_decode(File::get($packageJsonFile), true);
82+
$packageJson = json_decode(File::get($packageJsonFile), true);
11783

118-
$dependencies = collect(array_replace($packageJson['dependencies'] ?? [], $packageJson['devDependencies'] ?? []))
119-
->filter(fn ($_version, $package) => ! in_array($package, $filteredOutDependencies))
120-
// Axios has an issue with importmaps, so we'll hardcode the version for now...
121-
->map(fn ($version, $package) => $package === 'axios' ? 'axios@0.27' : "\"{$package}@{$version}\"")
122-
->join(' ');
84+
$dependencies = collect(array_replace($packageJson['dependencies'] ?? [], $packageJson['devDependencies'] ?? []))
85+
->filter(fn ($_version, $package) => ! in_array($package, $filteredOutDependencies))
86+
// Axios has an issue with importmaps, so we'll hardcode the version for now...
87+
->map(fn ($version, $package) => $package === 'axios' ? 'axios@0.27' : "\"{$package}@{$version}\"");
12388

124-
if (trim($dependencies) === '') {
125-
return self::SUCCESS;
126-
}
89+
if (trim($dependencies->join('')) === '') {
90+
return;
91+
}
12792

128-
return Artisan::call("importmap:pin {$dependencies}");
93+
Process::forever()->run(array_merge([
94+
$this->phpBinary(),
95+
'artisan',
96+
'importmap:pin',
97+
], $dependencies->all()), function ($_type, $output) {
98+
$this->output->write($output);
12999
});
130100
}
131101

132102
private function updateAppLayouts(): void
133103
{
134-
$this->displayTask('Updating layout files', function () {
135-
$this->existingLayoutFiles()
136-
->each(fn ($file) => File::put(
137-
$file,
138-
(new ReplaceOrAppendTags())(File::get($file)),
139-
));
140-
141-
return self::SUCCESS;
142-
});
104+
$this->existingLayoutFiles()->each(fn ($file) => File::put(
105+
$file,
106+
(new ReplaceOrAppendTags())(File::get($file)),
107+
));
143108
}
144109

145110
private function existingLayoutFiles()
@@ -149,55 +114,53 @@ private function existingLayoutFiles()
149114
->filter(fn ($file) => File::exists($file));
150115
}
151116

152-
private function displayHeader($text, $prefix)
153-
{
154-
$this->newLine();
155-
$this->line(sprintf(' %s <fg=white>%s</> ', $prefix, $text));
156-
$this->newLine();
157-
}
158-
159-
private function displayTask($description, $task)
160-
{
161-
$width = (new Terminal())->getWidth();
162-
$dots = max(str_repeat('<fg=gray>.</>', $width - strlen($description) - 13), 0);
163-
$this->output->write(sprintf(' <fg=white>%s</> %s ', $description, $dots));
164-
$output = $task();
165-
166-
if ($output === self::SUCCESS) {
167-
$this->output->write('<info>DONE</info>');
168-
} elseif ($output === self::FAILURE) {
169-
$this->output->write('<error>FAIL</error>');
170-
} elseif ($output === self::INVALID) {
171-
$this->output->write('<fg=yellow>WARN</>');
172-
}
173-
174-
$this->newLine();
175-
}
176-
177117
private function configureIgnoredFolder()
178118
{
179119
if (Str::contains(File::get(base_path('.gitignore')), 'public/js')) {
180120
return;
181121
}
182122

183-
$this->displayTask('dumping & ignoring `public/js` folder', function () {
184-
File::append(
185-
base_path('.gitignore'),
186-
"\n/public/js\n"
187-
);
188-
189-
return self::SUCCESS;
190-
});
123+
File::append(base_path('.gitignore'), "\n/public/js\n");
191124
}
192125

193-
private function displayAfterNotes()
126+
private function runStorageLinkCommand()
194127
{
195-
if (count($this->afterMessages) > 0) {
196-
$this->displayHeader('After Notes & Next Steps', '<bg=yellow;fg=black> NOTES </>');
197-
198-
foreach ($this->afterMessages as $message) {
199-
$this->line(' '.$message);
128+
if ($this->components->confirm('To be able to serve your assets in development, the resource/js folder will be symlinked to your public/js. Would you like to do that now?', true)) {
129+
if ($this->usingSail() && ! env('LARAVEL_SAIL')) {
130+
Process::forever()->run([
131+
'./vendor/bin/sail',
132+
'up',
133+
'-d',
134+
], function ($_type, $output) {
135+
$this->output->write($output);
136+
});
137+
138+
Process::forever()->run([
139+
'./vendor/bin/sail',
140+
'artisan',
141+
'storage:link',
142+
], function ($_type, $output) {
143+
$this->output->write($output);
144+
});
145+
} else {
146+
Process::forever()->run([
147+
$this->phpBinary(),
148+
'artisan',
149+
'storage:link',
150+
], function ($_type, $output) {
151+
$this->output->write($output);
152+
});
200153
}
201154
}
202155
}
156+
157+
private function usingSail(): bool
158+
{
159+
return file_exists(base_path('docker-compose.yml')) && str_contains(file_get_contents(base_path('composer.json')), 'laravel/sail');
160+
}
161+
162+
private function phpBinary()
163+
{
164+
return (new PhpExecutableFinder())->find(false) ?: 'php';
165+
}
203166
}

0 commit comments

Comments
 (0)