diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 59d30ad..1f57189 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -1,6 +1,10 @@ name: Fix Code Styling -on: [ push ] +on: + push: + branches: + - main + - '*.x' jobs: lint: @@ -18,7 +22,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: "8.4" + php-version: 8.4 extensions: json, dom, curl, libxml, mbstring coverage: none diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9d757ca..9afcbe1 100755 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,16 +17,10 @@ jobs: strategy: fail-fast: false matrix: - php: [ 8.1, 8.2, 8.3, 8.4 ] + php: [ 8.2, 8.3, 8.4 ] laravel: [ '10.*', '11.*', '12.*' ] dependency-version: [ prefer-lowest, prefer-stable ] - exclude: - - laravel: 11.* - php: 8.1 - - laravel: 12.* - php: 8.1 - name: P${{ matrix.php }} / L${{ matrix.laravel }} / ${{ matrix.dependency-version }} steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index cacb65c..848d9d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 1.1.0 - 2025-11-27 + +### Added +- PHP 8.4 support + +### Changed +- Default config now uses Vite instead of Laravel Mix (`vite.config.js`, `build/manifest.json`, `build/assets`) +- Modernized codebase with strict PHP typing (return types, parameter types, property types) + +### Removed +- PHP 8.1 support (EOL November 2024) + ## 0.2.3 - 2022-02-15 - Added: Support for Laravel 9 diff --git a/composer.json b/composer.json index 6682e73..3bb30ff 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "illuminate/support": "^10.0|^11.0|^12.0", "illuminate/filesystem": "^10.0|^11.0|^12.0", "illuminate/console": "^10.0|^11.0|^12.0" diff --git a/config/airdrop.php b/config/airdrop.php index aae79dc..8c2b22c 100644 --- a/config/airdrop.php +++ b/config/airdrop.php @@ -73,9 +73,9 @@ // this makes the most sense and doesn't need to be changed. resource_path(), - // Any time the webpack.mix.js file is changed, it could affect the + // Any time the vite.config.js file is changed, it could affect // the build steps, and therefore the built files. - base_path('webpack.mix.js'), + base_path('vite.config.js'), // Depending on your package manager, you'll want to uncomment one // of the following lines. Whenever JS packages are updated or @@ -120,14 +120,11 @@ * Files or folders that should be included. */ 'include' => [ - // The mix-manifest file tells Laravel how to get your versioned assets. - public_path('mix-manifest.json'), + // The Vite manifest file tells Laravel how to get your versioned assets. + public_path('build/manifest.json'), - // Compiled CSS. - public_path('css'), - - // Compiled JS. - public_path('js'), + // Compiled assets from Vite. + public_path('build/assets'), ], /* diff --git a/src/AirdropServiceProvider.php b/src/AirdropServiceProvider.php index c5112b9..757b319 100644 --- a/src/AirdropServiceProvider.php +++ b/src/AirdropServiceProvider.php @@ -15,7 +15,7 @@ class AirdropServiceProvider extends ServiceProvider { - public function boot() + public function boot(): void { if ($this->app->runningInConsole()) { $this->commands([ @@ -32,7 +32,7 @@ public function boot() ], 'config'); } - public function register() + public function register(): void { $this->mergeConfigFrom(__DIR__ . '/../config/airdrop.php', 'airdrop'); } diff --git a/src/Commands/Debug.php b/src/Commands/Debug.php index 3d21dd9..2ad86b9 100644 --- a/src/Commands/Debug.php +++ b/src/Commands/Debug.php @@ -7,8 +7,8 @@ namespace AaronFrancis\Airdrop\Commands; use AaronFrancis\Airdrop\HashGenerator; -use Arr; use Illuminate\Console\Command; +use Illuminate\Support\Arr; class Debug extends Command { @@ -16,7 +16,7 @@ class Debug extends Command protected $description = 'Output the array of all triggers, or a specific trigger.'; - public function handle() + public function handle(): void { $output = HashGenerator::make()->asArray(); diff --git a/src/Commands/Download.php b/src/Commands/Download.php index cb40dee..bfab4bb 100644 --- a/src/Commands/Download.php +++ b/src/Commands/Download.php @@ -17,7 +17,7 @@ class Download extends Command protected $description = 'Run as a part of your deploy pipeline *before* assets are built.'; - public function handle() + public function handle(): void { config([ 'airdrop.verbose' => $this->option('verbose') diff --git a/src/Commands/Hash.php b/src/Commands/Hash.php index 06ca031..70fb100 100644 --- a/src/Commands/Hash.php +++ b/src/Commands/Hash.php @@ -15,7 +15,7 @@ class Hash extends Command protected $description = 'Output the calculated hash.'; - public function handle() + public function handle(): void { $hash = HashGenerator::make()->generate(); diff --git a/src/Commands/Install.php b/src/Commands/Install.php index a518a2e..6ff3e83 100644 --- a/src/Commands/Install.php +++ b/src/Commands/Install.php @@ -12,18 +12,8 @@ class Install extends Command { - /** - * The name and signature of the console command. - * - * @var string - */ protected $signature = 'airdrop:install'; - /** - * The console command description. - * - * @var string - */ protected $description = 'Install the Airdrop config file into your app.'; public function __construct() @@ -35,10 +25,7 @@ public function __construct() } } - /** - * @throws Exception - */ - public function handle() + public function handle(): void { Artisan::call('vendor:publish', [ '--provider' => AirdropServiceProvider::class diff --git a/src/Commands/Upload.php b/src/Commands/Upload.php index 2f64767..937642c 100644 --- a/src/Commands/Upload.php +++ b/src/Commands/Upload.php @@ -13,7 +13,7 @@ class Upload extends Command protected $description = 'Run as a part of your deploy pipeline *after* assets are built.'; - public function handle() + public function handle(): void { config([ 'airdrop.verbose' => $this->option('verbose') diff --git a/src/Concerns/MakesDrivers.php b/src/Concerns/MakesDrivers.php index 67ef961..5d1a8c6 100644 --- a/src/Concerns/MakesDrivers.php +++ b/src/Concerns/MakesDrivers.php @@ -13,12 +13,7 @@ trait MakesDrivers { - /** - * @return BaseDriver - * - * @throws Exception - */ - public function makeDriver() + public function makeDriver(): BaseDriver { $config = $this->getDriverConfig(); @@ -30,10 +25,7 @@ public function makeDriver() return $class->setConfig($config)->setCurrentHash(HashGenerator::make()->generate()); } - /** - * @return string|null - */ - public function getDriverConfig() + public function getDriverConfig(): ?array { $driver = config('airdrop.driver') ?? 'DRIVER_NOT_SET'; $drivers = config('airdrop.drivers'); @@ -41,10 +33,7 @@ public function getDriverConfig() return Arr::get($drivers, $driver); } - /** - * @throws Exception - */ - protected function ensureDriverExtendsBase($driver) + protected function ensureDriverExtendsBase(mixed $driver): void { if (!is_subclass_of($driver, BaseDriver::class)) { throw new Exception('Airdrop drivers must extend ' . json_encode(BaseDriver::class)); diff --git a/src/Contracts/TriggerContract.php b/src/Contracts/TriggerContract.php index 30972cf..1d13c0c 100644 --- a/src/Contracts/TriggerContract.php +++ b/src/Contracts/TriggerContract.php @@ -11,9 +11,6 @@ interface TriggerContract /** * Return any state that should be considered when determining * whether or not your build process needs to run again. - * - * @param array $config - * @return array */ - public function triggerBuildWhenChanged($config = []); + public function triggerBuildWhenChanged(array $config = []): array; } diff --git a/src/Drivers/BaseDriver.php b/src/Drivers/BaseDriver.php index a68a864..84a0f0e 100644 --- a/src/Drivers/BaseDriver.php +++ b/src/Drivers/BaseDriver.php @@ -8,42 +8,32 @@ abstract class BaseDriver { - /** - * Config for this specific driver. - * - * @var array - */ - protected $config; - - /** - * Current hash based on all inputs. - * - * @var string - */ - protected $hash; - - public function setConfig($config) + protected array $config = []; + + protected string $hash = ''; + + public function setConfig(array $config): static { $this->config = $config; return $this; } - public function setCurrentHash($hash) + public function setCurrentHash(string $hash): static { $this->hash = $hash; return $this; } - public function output($line) + public function output(string $line): void { if (config('airdrop.verbose')) { echo "[Airdrop] $line\n"; } } - abstract public function download(); + abstract public function download(): void; - abstract public function upload(); + abstract public function upload(): void; } diff --git a/src/Drivers/FilesystemDriver.php b/src/Drivers/FilesystemDriver.php index 6ab9947..3f2894f 100644 --- a/src/Drivers/FilesystemDriver.php +++ b/src/Drivers/FilesystemDriver.php @@ -16,10 +16,7 @@ class FilesystemDriver extends BaseDriver { - /** - * Called after building, to stash the files somewhere. - */ - public function upload() + public function upload(): void { // Remove the skip file that `restore` might have created. File::delete($this->skipFilePath()); @@ -41,11 +38,7 @@ public function upload() $this->uploadToRemoteStorage($zipPath); } - /** - * Called before building files, to see if we can skip that - * altogether and just download them. - */ - public function download() + public function download(): void { if ($this->extract()) { $this->output('Assets downloaded and extracted.'); @@ -61,10 +54,7 @@ public function download() } } - /** - * @throws Exception - */ - public function makeZip($path) + public function makeZip(string $path): void { $zip = new ZipArchive; @@ -85,7 +75,7 @@ public function makeZip($path) $zip->close(); } - public function extract() + public function extract(): bool { if (!$this->exists()) { return false; @@ -118,7 +108,7 @@ public function extract() return true; } - public function files() + public function files(): \Illuminate\Support\Collection { $include = config('airdrop.outputs.include') ?? []; $exclude = config('airdrop.outputs.exclude') ?? []; @@ -129,44 +119,27 @@ public function files() ->selected(); } - /** - * @return \Illuminate\Contracts\Filesystem\Filesystem - */ - public function disk() + public function disk(): \Illuminate\Contracts\Filesystem\Filesystem { return Storage::disk($this->config['disk']); } - /** - * @return bool - */ - public function exists() + public function exists(): bool { return $this->disk()->exists($this->remoteStashPath() . $this->stashedPackageFilename()); } - /** - * @return string - */ - protected function skipFilePath() + protected function skipFilePath(): string { return Arr::get($this->config, 'skip_file'); } - /** - * @return string - */ - protected function stashedPackageFilename() + protected function stashedPackageFilename(): string { return "airdrop-{$this->hash}.zip"; } - /** - * @param string $zipPath - * - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException - */ - protected function downloadFromRemoteStorage($zipPath) + protected function downloadFromRemoteStorage(string $zipPath): void { // Download the file to local disk as a stream. File::put( @@ -175,10 +148,7 @@ protected function downloadFromRemoteStorage($zipPath) ); } - /** - * @param string $zipPath - */ - protected function uploadToRemoteStorage($zipPath) + protected function uploadToRemoteStorage(string $zipPath): void { $this->output('Uploading to remote disk at ' . $this->remoteStashPath() . $this->stashedPackageFilename()); @@ -192,20 +162,14 @@ protected function uploadToRemoteStorage($zipPath) File::delete($zipPath); } - /** - * @return string - */ - protected function remoteStashPath() + protected function remoteStashPath(): string { $dir = Arr::get($this->config, 'remote_directory'); - return $dir ? Str::finish($dir, '/') : $dir; + return $dir ? Str::finish($dir, '/') : ''; } - /** - * @return string - */ - protected function localStashPath() + protected function localStashPath(): string { $tmp = Arr::get($this->config, 'local_tmp_directory'); diff --git a/src/Drivers/GithubActionsDriver.php b/src/Drivers/GithubActionsDriver.php index 1d0e783..dfd6fff 100644 --- a/src/Drivers/GithubActionsDriver.php +++ b/src/Drivers/GithubActionsDriver.php @@ -8,19 +8,19 @@ class GithubActionsDriver extends FilesystemDriver { - public function exists() + public function exists(): bool { return file_exists($this->localStashPath() . $this->stashedPackageFilename()); } - protected function downloadFromRemoteStorage($zipPath) + protected function downloadFromRemoteStorage(string $zipPath): void { // For GitHub actions there is no downloading required. // The file will be placed in the appropriate location // by the Cache step of the workflow. } - protected function uploadToRemoteStorage($zipPath) + protected function uploadToRemoteStorage(string $zipPath): void { // No upload is required either. GitHub will take the // zip from the tmp directory and cache it for us for diff --git a/src/FileSelection.php b/src/FileSelection.php index 95ce100..c72446a 100644 --- a/src/FileSelection.php +++ b/src/FileSelection.php @@ -15,86 +15,52 @@ class FileSelection { - /** - * @var \Illuminate\Support\Collection - */ - protected $includeFilesAndDirectories; - - /** - * @var \Illuminate\Support\Collection - */ - protected $excludeFilesAndDirectories; - - /** - * @var array - */ - protected $excludeNames = []; - - /** - * @var bool - */ - protected $shouldFollowLinks = false; - - /** - * @param array $include - * @param array $exclude - * @return FileSelection - */ - public static function create($include = [], $exclude = []) + protected \Illuminate\Support\Collection $includeFilesAndDirectories; + + protected \Illuminate\Support\Collection $excludeFilesAndDirectories; + + protected array $excludeNames = []; + + protected bool $shouldFollowLinks = false; + + public static function create(array $include = [], array $exclude = []): static { return new static($include, $exclude); } - /** - * @param array $include - * @param array $exclude - */ - public function __construct($include = [], $exclude = []) + public function __construct(array $include = [], array $exclude = []) { $this->includeFilesAndDirectories = collect($include); $this->excludeFilesAndDirectories = collect($exclude); } - /** - * @param array $patterns - * @return FileSelection - */ - public function excludeNames($patterns) + public function excludeNames(array $patterns): static { $this->excludeNames = $patterns; return $this; } - /** - * Do not included the given files and directories. - * - * @param array|string $excludeFilesAndDirectories - * @return FileSelection - */ - public function excludeFilesFrom($excludeFilesAndDirectories) + public function excludeFilesFrom(array|string $excludeFilesAndDirectories): static { $this->excludeFilesAndDirectories = $this->excludeFilesAndDirectories->merge($this->sanitize($excludeFilesAndDirectories)); return $this; } - public function shouldFollowLinks(bool $shouldFollowLinks) + public function shouldFollowLinks(bool $shouldFollowLinks): static { $this->shouldFollowLinks = $shouldFollowLinks; return $this; } - public function selected() + public function selected(): \Illuminate\Support\Collection { return collect($this->yieldSelectedFiles())->diff($this->excludeFilesAndDirectories); } - /** - * @return \Generator|string[] - */ - protected function yieldSelectedFiles() + protected function yieldSelectedFiles(): \Generator|array { if ($this->includeFilesAndDirectories->isEmpty()) { return []; @@ -129,7 +95,7 @@ protected function yieldSelectedFiles() } } - protected function includedFiles() + protected function includedFiles(): array { return $this->includeFilesAndDirectories ->each(function ($path) { @@ -143,7 +109,7 @@ protected function includedFiles() ->toArray(); } - protected function includedDirectories() + protected function includedDirectories(): array { return $this->includeFilesAndDirectories ->each(function ($path) { @@ -168,11 +134,7 @@ protected function shouldExclude(string $path): bool return false; } - /** - * @param string|array $paths - * @return \Illuminate\Support\Collection - */ - protected function sanitize($paths) + protected function sanitize(array|string $paths): \Illuminate\Support\Collection { return collect($paths) ->reject(function ($path) { diff --git a/src/HashGenerator.php b/src/HashGenerator.php index 8abf36e..1d069ac 100644 --- a/src/HashGenerator.php +++ b/src/HashGenerator.php @@ -11,9 +11,9 @@ class HashGenerator { - protected $triggers = []; + protected array $triggers = []; - public static function make() + public static function make(): static { return new static; } @@ -31,22 +31,12 @@ public function __construct() } } - /** - * @return string - * - * @throws Exception - */ - public function generate() + public function generate(): string { return md5(json_encode($this->asArray())); } - /** - * @return array - * - * @throws Exception - */ - public function asArray() + public function asArray(): array { $contents = []; @@ -64,10 +54,7 @@ public function asArray() return $contents; } - /** - * @throws Exception - */ - protected function ensureContractImplemented($class) + protected function ensureContractImplemented(string $class): void { if (!array_key_exists(TriggerContract::class, class_implements($class))) { throw new Exception('Airdrop triggers must implement contract ' . json_encode(TriggerContract::class)); diff --git a/src/Triggers/ConfigTrigger.php b/src/Triggers/ConfigTrigger.php index 2371d14..e48e702 100644 --- a/src/Triggers/ConfigTrigger.php +++ b/src/Triggers/ConfigTrigger.php @@ -10,14 +10,7 @@ class ConfigTrigger implements TriggerContract { - /** - * Return any state that should be considered when determining - * whether or not your build process needs to run again. - * - * @param array $config - * @return array - */ - public function triggerBuildWhenChanged($config = []) + public function triggerBuildWhenChanged(array $config = []): array { return $config; } diff --git a/src/Triggers/FileTrigger.php b/src/Triggers/FileTrigger.php index f500e4d..2fcc023 100644 --- a/src/Triggers/FileTrigger.php +++ b/src/Triggers/FileTrigger.php @@ -8,20 +8,12 @@ use AaronFrancis\Airdrop\Contracts\TriggerContract; use AaronFrancis\Airdrop\FileSelection; -use Generator; use Illuminate\Support\Arr; use Illuminate\Support\Facades\File; class FileTrigger implements TriggerContract { - /** - * Return any state that should be considered when determining - * whether or not your build process needs to run again. - * - * @param array $config - * @return array - */ - public function triggerBuildWhenChanged($config = []) + public function triggerBuildWhenChanged(array $config = []): array { $include = Arr::get($config, 'include', []); $exclude = Arr::get($config, 'exclude', []); @@ -44,10 +36,7 @@ public function triggerBuildWhenChanged($config = []) ->toArray(); } - /** - * @return Generator - */ - protected function files($include, $exclude, $excludeNames) + protected function files(array $include, array $exclude, array $excludeNames): \Illuminate\Support\Collection { return FileSelection::create($include, $exclude) ->excludeNames($excludeNames)