diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 672edae..d2aeae7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,25 +1,27 @@ --- name: Bug report about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - +title: "" +labels: "" +assignees: "" --- +Please provide the following info. You may run `artisan bundle:version` to dump all relevant package versions. + - Bundle: #.#.# - Bun: #.#.# - Laravel: #.#.# - PHP: #.#.# -- Operating System: e.g. macOS 14.2.1 +- Operating System: e.g. macOS 14.2.1 **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Run `npm install ...` -2. Add import component to template '....' +2. Add import component to template '....' 3. Use the import in the following code '...' 4. See error diff --git a/.github/workflows/browser-tests.yml b/.github/workflows/browser-tests.yml index b5229fa..fef0443 100644 --- a/.github/workflows/browser-tests.yml +++ b/.github/workflows/browser-tests.yml @@ -1,6 +1,7 @@ name: browser-tests on: + workflow_dispatch: pull_request: branches: [development, main] workflow_run: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9804e30..0f6a373 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,7 @@ name: tests on: + workflow_dispatch: pull_request: branches: [development, main] workflow_run: diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 4a35787..82276a6 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -174,6 +174,14 @@ You may configure what paths are scanned by publishing the Bundle config file an `artisan bundle:clear` Clear all bundled scripts. +### bundle:version + +`artisan bundle:version` Dumps Bundle's version & it's dependencies (Bun & optionally LightningCSS & Sass). + +### bundle:install + +`artisan bundle:install` Prompts you through installing Bun & optional CSS loader dependencies. + ## Testing fake When writing Unit or Feature tests in your application you don't need Bundle to process & serve your imports. diff --git a/docs/css-loading.md b/docs/css-loading.md index 5f5b5a9..b08fd71 100644 --- a/docs/css-loading.md +++ b/docs/css-loading.md @@ -14,9 +14,11 @@ We provide a custom CSS loader plugin that just works™. Built on top of [Light You'll need to install Lightning CSS as a dependency. ```bash -npm install lightningcss --save-dev +php artisan bundle:install ``` +You will be prompted to select a CSS loading method. Choose `CSS`. + Afterwards you may use `x-import` to load css files directly. Bundle transpiles it and injects it on your page with zero effort. ```html @@ -44,9 +46,11 @@ npm install lightningcss --save-dev You can use Bundle to compile [Sass](https://sass-lang.com/) on the fly. You'll need to install both Sass & Lightning CSS in your project. Bundle takes care of the rest. ```bash -npm install sass lightningcss --save-dev +php artisan bundle:install ``` +You will be prompted to select a CSS loading method. Choose `Sass`. + {: .note } > Due to a unresolved issue Bun is not able to auto-install LightningCSS & Sass on the fly. When this issue is fixed you won't have to install these dependencies yourself. Bun will automatically install them when needed 💅 diff --git a/docs/index.md b/docs/index.md index b17645e..a303c68 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,7 +26,7 @@ composer require leuverink/bundle ``` ```bash -npm install bun --save-dev +php artisan bundle:install ``` This is all you need to start using Bundle! diff --git a/src/Commands/Install.php b/src/Commands/Install.php new file mode 100644 index 0000000..bcf988b --- /dev/null +++ b/src/Commands/Install.php @@ -0,0 +1,118 @@ +callSilent('bundle:clear'); + + $this->printAscii(); + $this->printIntro(); + + $this->promptToInstallBun(); + $this->promptToInstallCssLoading(); + + $this->install(); + + $this->call('bundle:version'); + + $this->printOutro(); + + return static::SUCCESS; + } + + protected function printAscii() + { + note(<<< TEXT + ____ __ __ _ __ ____ __ ______ + / __ ) / / / // | / // __ \ / / / ____/ + / __ |/ / / // |/ // / / // / / __/ + / /_/ // /_/ // /| // /_/ // /___ / /___ + /_____/ \____//_/ |_//_____//_____//_____/ + + TEXT); + } + + protected function printIntro() + { + intro(PHP_EOL . ' Thank you for installing Bundle! This wizard will set everything up for you. ' . PHP_EOL); + } + + protected function promptToInstallBun() + { + $confirmed = confirm( + default: true, + label: 'Do you want to install Bun?', + hint: 'Bun needs to be installed in order to use Bundle. Skip this if you\'ve installed it manually.' + ); + + if ($confirmed) { + $this->installCommands[] = 'npm install bun@^1 --save-dev'; + } + } + + protected function promptToInstallCssLoading() + { + $choice = select( + label: 'Would you like to use CSS loading?', + options: [ + 'css' => 'CSS (installs LightningCSS)', + 'sass' => 'Sass (installs Sass & LightningCSS)', + 'none' => 'None', + ], + default: 'css', + ); + + match ($choice) { + 'css' => $this->installCommands[] = 'npm install lightningcss --save-dev', + 'sass' => $this->installCommands = array_merge($this->installCommands, [ + 'npm install lightningcss --save-dev', + 'npm install sass --save-dev', + ]), + default => null, + }; + } + + protected function install() + { + if (empty($this->installCommands)) { + warning('Nothing to install.'); + + return; + } + + progress( + label: 'Installing dependencies.', + steps: $this->installCommands, + callback: function ($command, $progress) { + $progress->hint($command); + + Process::run($command); + }, + hint: 'This may take some time.', + ); + } + + protected function printOutro() + { + outro(PHP_EOL . " You're all set! Check out https://laravel-bundle.dev/ to get started! " . PHP_EOL); + } +} diff --git a/src/Commands/Version.php b/src/Commands/Version.php new file mode 100644 index 0000000..0018eef --- /dev/null +++ b/src/Commands/Version.php @@ -0,0 +1,43 @@ +components->twoColumnDetail(' Back-end'); + $this->components->twoColumnDetail('Bundle', $this->composerPackageVersion('leuverink/bundle')); + $this->components->twoColumnDetail('Laravel', phpversion()); + $this->components->twoColumnDetail('PHP', $this->laravel->version()); + + $this->newLine(); + $this->components->twoColumnDetail(' Front-end'); + $this->components->twoColumnDetail('Bun', $this->npmPackageVersion('bun')); + $this->components->twoColumnDetail('LightningCSS', $this->npmPackageVersion('lightningcss')); + $this->components->twoColumnDetail('Sass', $this->npmPackageVersion('sass')); + + return static::SUCCESS; + } + + protected function composerPackageVersion(string $name): string + { + $packageInfo = json_decode(Process::run("composer show {$name} --format=json")->output()); + $versions = data_get($packageInfo, 'versions', ['Not installed']); + + return head($versions); + } + + protected function npmPackageVersion(string $name): string + { + $packageInfo = json_decode(Process::run("npm list {$name} --json")->output()); + + return data_get($packageInfo, "dependencies.{$name}.version", 'Not installed'); + } +} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index e23c3c4..2f46fce 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -10,6 +10,8 @@ use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Route; use Leuverink\Bundle\Bundlers\Bun\Bun; +use Leuverink\Bundle\Commands\Install; +use Leuverink\Bundle\Commands\Version; use Leuverink\Bundle\Components\Import; use Illuminate\Foundation\Http\Events\RequestHandled; use Illuminate\Support\ServiceProvider as BaseServiceProvider; @@ -64,6 +66,8 @@ protected function injectCore() protected function registerCommands() { + $this->commands(Install::class); + $this->commands(Version::class); $this->commands(Build::class); $this->commands(Clear::class); } diff --git a/tests/Feature/Commands/InstallCommandTest.php b/tests/Feature/Commands/InstallCommandTest.php new file mode 100644 index 0000000..1336930 --- /dev/null +++ b/tests/Feature/Commands/InstallCommandTest.php @@ -0,0 +1,82 @@ +artisan('bundle:install') + ->expectsQuestion('Do you want to install Bun?', true) + ->expectsQuestion('Would you like to use CSS loading?', 'none') + ->assertSuccessful(); + +it('installs Bun when selected', function () { + $this->artisan('bundle:install') + ->expectsQuestion('Do you want to install Bun?', true) + ->expectsQuestion('Would you like to use CSS loading?', 'none') + ->assertSuccessful(); + + Process::assertRan('npm install bun@^1 --save-dev'); +}); + +it('doesnt install Bun when not selected', function () { + $this->artisan('bundle:install') + ->expectsQuestion('Do you want to install Bun?', false) + ->expectsQuestion('Would you like to use CSS loading?', 'none') + ->assertSuccessful(); + + Process::assertDidntRun('npm install bun@^1 --save-dev'); +}); + +it('installs LightningCSS when selected', function () { + $this->artisan('bundle:install') + ->expectsQuestion('Do you want to install Bun?', false) + ->expectsQuestion('Would you like to use CSS loading?', 'css') + ->assertSuccessful(); + + Process::assertRan('npm install lightningcss --save-dev'); +}); + +it('doesnt install LightningCSS when not selected', function () { + $this->artisan('bundle:install') + ->expectsQuestion('Do you want to install Bun?', false) + ->expectsQuestion('Would you like to use CSS loading?', 'none') + ->assertSuccessful(); + + Process::assertDidntRun('npm install lightningcss --save-dev'); +}); + +it('installs Sass when selected', function () { + $this->artisan('bundle:install') + ->expectsQuestion('Do you want to install Bun?', false) + ->expectsQuestion('Would you like to use CSS loading?', 'sass') + ->assertSuccessful(); + + Process::assertRan('npm install lightningcss --save-dev'); + Process::assertRan('npm install sass --save-dev'); +}); + +it('doesnt install Sass when not selected', function () { + $this->artisan('bundle:install') + ->expectsQuestion('Do you want to install Bun?', false) + ->expectsQuestion('Would you like to use CSS loading?', 'none') + ->assertSuccessful(); + + Process::assertDidntRun('npm install lightningcss --save-dev'); + Process::assertDidntRun('npm install sass --save-dev'); +}); + +it('doesnt install anything when nothing selected', function () { + $this->artisan('bundle:install') + ->expectsQuestion('Do you want to install Bun?', false) + ->expectsQuestion('Would you like to use CSS loading?', 'none') + ->assertSuccessful(); + + // Assert for absence of npm install commands + Process::assertDidntRun(function (PendingProcess $process) { + return str($process->command)->startsWith('npm install'); + }); +}); diff --git a/tests/Feature/Commands/VersionCommandTest.php b/tests/Feature/Commands/VersionCommandTest.php new file mode 100644 index 0000000..ee73a40 --- /dev/null +++ b/tests/Feature/Commands/VersionCommandTest.php @@ -0,0 +1,11 @@ +artisan('bundle:version') + ->expectsOutputToContain('Bundle') + ->expectsOutputToContain('Laravel') + ->expectsOutputToContain('PHP') + ->expectsOutputToContain('Bun') + ->expectsOutputToContain('LightningCSS') + ->expectsOutputToContain('Sass') + ->assertSuccessful(); diff --git a/workbench/node_modules/.bin/bun b/workbench/node_modules/.bin/bun deleted file mode 120000 index 3610914..0000000 --- a/workbench/node_modules/.bin/bun +++ /dev/null @@ -1 +0,0 @@ -../bun/bin/bun \ No newline at end of file diff --git a/workbench/node_modules/.bin/bunx b/workbench/node_modules/.bin/bunx deleted file mode 120000 index 3610914..0000000 --- a/workbench/node_modules/.bin/bunx +++ /dev/null @@ -1 +0,0 @@ -../bun/bin/bun \ No newline at end of file diff --git a/workbench/package-lock.json b/workbench/package-lock.json index 78d1b81..020f48b 100644 --- a/workbench/package-lock.json +++ b/workbench/package-lock.json @@ -5,22 +5,22 @@ "packages": { "": { "devDependencies": { - "@alpinejs/persist": "^3.13.3", - "alpinejs": "^3.13.3", - "bun": "^1.0.33", - "lodash": "^4.17.21" + "@alpinejs/persist": "^3.14", + "alpinejs": "^3.14", + "bun": "^1.1.10", + "lodash": "^4.17" } }, "node_modules/@alpinejs/persist": { - "version": "3.13.5", - "resolved": "https://registry.npmjs.org/@alpinejs/persist/-/persist-3.13.5.tgz", - "integrity": "sha512-nmULi5Kp/v5/h4FtGpqyzzMPlulc2fmQ+Olhk0NwTcBKSCZDg6OtXgS998rnHpcWO0jsjCmvXn/Pul2av7D8lA==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@alpinejs/persist/-/persist-3.14.0.tgz", + "integrity": "sha512-yv4CKzoTW+jmLeZMuRr/iuEJyviIvA6BKQ1PvonzdIzmHyQtL8psCwy1vtHC6eV/H7cBEaCnnedqOjMZopQb5w==", "dev": true }, "node_modules/@oven/bun-darwin-aarch64": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.0.33.tgz", - "integrity": "sha512-Hd7ZxKETiDB3CQi4JzetyIPRLYyxmW5OTO/hTPVnpIoaRYwAEF2ymxiTQGTxlp88lStcuECyOBbaNuGvrww0kA==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.1.10.tgz", + "integrity": "sha512-5x6QGEzTurmCPZM3OLosIJE0QynhKfKZZ6uSVl7C36mNPFAZfTXjK64LgbM+4P9Kr0PyEQnZweLlScl+HaEJcw==", "cpu": [ "arm64" ], @@ -31,9 +31,9 @@ ] }, "node_modules/@oven/bun-darwin-x64": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.0.33.tgz", - "integrity": "sha512-X5AIltSEoS8c2Tmw49+yPLyJ0iPm1wwgktL0/GWwZllCFCR/kWH/C8wS8VYMIDh/84cSzuDepXVOMbse0TygNg==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.1.10.tgz", + "integrity": "sha512-DYbp2koaATwWikMIyeWLq2LhLZtvxzr4WuFIBe4+KwoWLGXJEC8uK9QsTwis/tCLPH45ov9DMwDmBA31oX+0iA==", "cpu": [ "x64" ], @@ -44,9 +44,9 @@ ] }, "node_modules/@oven/bun-darwin-x64-baseline": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.0.33.tgz", - "integrity": "sha512-Jf1zVsyleXgJAnvr1jOi/dY+bs6eZ5RV6MGucBK/YOSmdDrrh2xTgjM1qABfTO4DnzDgWHigNSUwI+EpQqroFA==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.1.10.tgz", + "integrity": "sha512-a/P612tHH86gpBiITwHmrpFMLT9Z/v6VxBKpPK+FgejIgLDGvzfIOxbNtBeGygWbZaAFDQfRRQJFGpVHvjwGQA==", "cpu": [ "x64" ], @@ -57,9 +57,9 @@ ] }, "node_modules/@oven/bun-linux-aarch64": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.0.33.tgz", - "integrity": "sha512-EfbW2qi2vOt/4AgLc/H/SCa1l5rwr7KEnZj1IAuiwRkR91SPAdKi8xcxmYq8S37clGhKfENaWiLuT9KCScO3gQ==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.1.10.tgz", + "integrity": "sha512-iR7TRUWtVtrPe+iZu1ISQNbz7M6HxMRtn4PCr/a6dswuPkIhvXxTJUD6WTpHnHxsgioS5GHG9eonu03PTeBY0Q==", "cpu": [ "arm64" ], @@ -70,9 +70,9 @@ ] }, "node_modules/@oven/bun-linux-x64": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.0.33.tgz", - "integrity": "sha512-336/bqGulWgvzQWPd0Mq6l12w0JX/+ptsNTHMuizj/bhbx8JuKOmXjbNowGRNv6wGOXERmadxe3PAChQqtq4qQ==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.1.10.tgz", + "integrity": "sha512-pUgLdu/5Yn+hV8aIwZE0x2H/t2QQRIPWUibnUdDLglnNtGjaqNUyST9iVN5TD7NdMk1p342GDc9rouA8VxAHHA==", "cpu": [ "x64" ], @@ -83,9 +83,9 @@ ] }, "node_modules/@oven/bun-linux-x64-baseline": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.0.33.tgz", - "integrity": "sha512-OIT0Fjgki4FOPgxz1Jq6/0MmDO5W+IXG8uhOc1+m6Qf77C6VlNPxD3cuXwWqFKa0Fvza/mJEsw+TUb0H5Z61aQ==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.1.10.tgz", + "integrity": "sha512-TjBH/KIyI/4Ms3PJYRm2QEgI7HOyV5fXdwqwB/40SCPXND6wq0u4voHDIINc9rdHDRXpmO8RPUFWsKNuN3Mf5w==", "cpu": [ "x64" ], @@ -95,6 +95,32 @@ "linux" ] }, + "node_modules/@oven/bun-windows-x64": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.1.10.tgz", + "integrity": "sha512-+KiITh1xyrDGoRXM3HLHyO9iweaMZ9T41KP4cbov92D78SKxR5jpq1LDLPhWK668a0aNX/r9PGePkPNt4yg/HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oven/bun-windows-x64-baseline": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.1.10.tgz", + "integrity": "sha512-+q2pDLq9VCXYJ89pcT5AevXUTGdDoqgq+scE3qlKLclSxtSR25K18C61D9rpqgiueC6jLrxIN13w5qOi4B3LfQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@vue/reactivity": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", @@ -111,18 +137,18 @@ "dev": true }, "node_modules/alpinejs": { - "version": "3.13.5", - "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.5.tgz", - "integrity": "sha512-1d2XeNGN+Zn7j4mUAKXtAgdc4/rLeadyTMWeJGXF5DzwawPBxwTiBhFFm6w/Ei8eJxUZeyNWWSD9zknfdz1kEw==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.0.tgz", + "integrity": "sha512-YCWF95PMJqePe9ll6KMyDt/nLhh2R7RhqBf4loEmLzIskcHque4Br/9UgAa6cw13H0Cm3FM9e1hzDwP5z5wlDA==", "dev": true, "dependencies": { "@vue/reactivity": "~3.1.1" } }, "node_modules/bun": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/bun/-/bun-1.0.33.tgz", - "integrity": "sha512-WTh8AST6fKRwnbVjQYxvYYeh1Q1PiDD/XdlV/qnkv6RRsLZodSZ3PWttya9PiUOLymBaCWP16PpfptGhFrpoQQ==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/bun/-/bun-1.1.10.tgz", + "integrity": "sha512-qOJXrQZSzJ5DbJMt47GZGWtUSmIkbwD7fPSN/XS/T46D4cTTnPK46QDHlyC8VD+Anvs6uKNwuwKIyB31kUdHmQ==", "cpu": [ "arm64", "x64" @@ -131,19 +157,22 @@ "hasInstallScript": true, "os": [ "darwin", - "linux" + "linux", + "win32" ], "bin": { - "bun": "bin/bun", - "bunx": "bin/bun" + "bun": "bin/bun.exe", + "bunx": "bin/bun.exe" }, "optionalDependencies": { - "@oven/bun-darwin-aarch64": "1.0.33", - "@oven/bun-darwin-x64": "1.0.33", - "@oven/bun-darwin-x64-baseline": "1.0.33", - "@oven/bun-linux-aarch64": "1.0.33", - "@oven/bun-linux-x64": "1.0.33", - "@oven/bun-linux-x64-baseline": "1.0.33" + "@oven/bun-darwin-aarch64": "1.1.10", + "@oven/bun-darwin-x64": "1.1.10", + "@oven/bun-darwin-x64-baseline": "1.1.10", + "@oven/bun-linux-aarch64": "1.1.10", + "@oven/bun-linux-x64": "1.1.10", + "@oven/bun-linux-x64-baseline": "1.1.10", + "@oven/bun-windows-x64": "1.1.10", + "@oven/bun-windows-x64-baseline": "1.1.10" } }, "node_modules/lodash": { diff --git a/workbench/package.json b/workbench/package.json index 2bd0e65..f278b6c 100644 --- a/workbench/package.json +++ b/workbench/package.json @@ -5,9 +5,9 @@ "IE 11" ], "devDependencies": { - "bun": "^1.0.33", - "lodash": "^4.17.21", - "alpinejs": "^3.13.3", - "@alpinejs/persist": "^3.13.3" + "bun": "^1.1.10", + "lodash": "^4.17", + "alpinejs": "^3.14", + "@alpinejs/persist": "^3.14" } }