├── CHANGELOG.md ├── LICENSE ├── README.md ├── composer.json ├── pint.json ├── resources └── views │ └── livewire │ └── outdated.blade.php ├── src ├── Livewire │ └── Outdated.php ├── OutdatedServiceProvider.php └── Recorders │ └── OutdatedRecorder.php ├── testbench.yaml └── workbench ├── .env.example ├── .gitignore ├── app ├── Models │ └── .gitkeep └── Providers │ └── WorkbenchServiceProvider.php ├── database ├── factories │ └── .gitkeep ├── migrations │ └── .gitkeep └── seeders │ └── DatabaseSeeder.php ├── resources └── views │ └── vendor │ └── pulse │ └── dashboard.blade.php └── routes ├── console.php └── web.php /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aarondfrancis/pulse-outdated/a1e163e9e601c1b572fa36d934c25e4b706e0b9b/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Hammerstone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Outdated Composer Dependencies card for Laravel Pulse 2 | 3 | This card will show you outdated Composer dependencies. 4 | 5 | ## Installation 6 | 7 | Require the package with Composer: 8 | 9 | ```shell 10 | composer require aaronfrancis/pulse-outdated 11 | ``` 12 | 13 | ## Register the recorder 14 | 15 | Right now, the Composer dependencies will only be checked once per day. To run the checks you must add the `OutdatedRecorder` to the `pulse.php` file. 16 | 17 | ```diff 18 | return [ 19 | // ... 20 | 21 | 'recorders' => [ 22 | + \AaronFrancis\Pulse\Outdated\Recorders\OutdatedRecorder::class => [], 23 | ] 24 | ] 25 | ``` 26 | 27 | You also need to be running [the `pulse:check` command](https://laravel.com/docs/10.x/pulse#dashboard-cards). 28 | 29 | ## Add to your dashboard 30 | 31 | To add the card to the Pulse dashboard, you must first [publish the vendor view](https://laravel.com/docs/10.x/pulse#dashboard-customization). 32 | 33 | Then, you can modify the `dashboard.blade.php` file: 34 | 35 | ```diff 36 | 37 | + 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | ``` 59 | 60 | That's it! 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aaronfrancis/pulse-outdated", 3 | "description": "A Laravel Pulse card to show outdated composer dependencies", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Aaron Francis", 9 | "email": "aarondfrancis@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": "^8.1", 14 | "illuminate/support": "*", 15 | "laravel/pulse": "^1.0.0@beta" 16 | }, 17 | "require-dev": { 18 | "orchestra/testbench": "^8.17", 19 | "mockery/mockery": "^1.5.0", 20 | "phpunit/phpunit": "^10" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "AaronFrancis\\Pulse\\Outdated\\": "src/" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "AaronFrancis\\Pulse\\Outdated\\Tests\\": "tests/", 30 | "Workbench\\App\\": "workbench/app/", 31 | "Workbench\\Database\\Factories\\": "workbench/database/factories/", 32 | "Workbench\\Database\\Seeders\\": "workbench/database/seeders/" 33 | } 34 | }, 35 | "extra": { 36 | "laravel": { 37 | "providers": [ 38 | "AaronFrancis\\Pulse\\Outdated\\OutdatedServiceProvider" 39 | ] 40 | } 41 | }, 42 | "scripts": { 43 | "post-autoload-dump": [ 44 | "@clear", 45 | "@prepare" 46 | ], 47 | "clear": "@php vendor/bin/testbench package:purge-skeleton --ansi", 48 | "prepare": "@php vendor/bin/testbench package:discover --ansi", 49 | "build": "@php vendor/bin/testbench workbench:build --ansi", 50 | "serve": [ 51 | "Composer\\Config::disableProcessTimeout", 52 | "@build", 53 | "@php vendor/bin/testbench serve" 54 | ], 55 | "test": [ 56 | "@php vendor/bin/phpunit" 57 | ] 58 | }, 59 | "prefer-stable": true, 60 | "minimum-stability": "dev" 61 | } 62 | -------------------------------------------------------------------------------- /pint.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "laravel", 3 | "rules": { 4 | "not_operator_with_successor_space": false, 5 | "cast_spaces": false, 6 | "heredoc_to_nowdoc": false, 7 | "phpdoc_summary": false, 8 | "concat_space": { 9 | "spacing": "one" 10 | }, 11 | "trailing_comma_in_multiline": false 12 | } 13 | } -------------------------------------------------------------------------------- /resources/views/livewire/outdated.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | @if (!count($packages)) 10 | 11 | @else 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | Package 22 | Installed 23 | Available 24 | 25 | 26 | 27 | @foreach ($packages as $package) 28 | 29 | 30 | 31 | 32 | {{ $package['name'] }} 33 | 34 |

35 | 36 | {{ str($package['source'])->after('://') }} 37 | 38 |

39 |
40 | 41 | {{ $package['version'] }} 42 | 43 | 44 | {{ $package['latest'] }} 45 | 46 | 47 | @endforeach 48 | 49 |
50 |
51 | @endif 52 |
53 |
54 | -------------------------------------------------------------------------------- /src/Livewire/Outdated.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace AaronFrancis\Pulse\Outdated\Livewire; 7 | 8 | use Illuminate\Support\Facades\View; 9 | use Laravel\Pulse\Facades\Pulse; 10 | use Laravel\Pulse\Livewire\Card; 11 | use Livewire\Attributes\Lazy; 12 | 13 | class Outdated extends Card 14 | { 15 | #[Lazy] 16 | public function render() 17 | { 18 | // Get the data out of the Pulse data store. 19 | $packages = Pulse::values('composer_outdated', ['result'])->first(); 20 | 21 | $packages = $packages 22 | ? json_decode($packages->value, associative: true, flags: JSON_THROW_ON_ERROR)['installed'] 23 | : []; 24 | 25 | return View::make('outdated::livewire.outdated', [ 26 | 'packages' => $packages, 27 | ]); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/OutdatedServiceProvider.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace AaronFrancis\Pulse\Outdated; 7 | 8 | use AaronFrancis\Pulse\Outdated\Livewire\Outdated; 9 | use Illuminate\Foundation\Application; 10 | use Illuminate\Support\ServiceProvider; 11 | use Livewire\LivewireManager; 12 | 13 | class OutdatedServiceProvider extends ServiceProvider 14 | { 15 | public function boot(): void 16 | { 17 | $this->loadViewsFrom(__DIR__ . '/../resources/views', 'outdated'); 18 | 19 | $this->callAfterResolving('livewire', function (LivewireManager $livewire, Application $app) { 20 | $livewire->component('outdated', Outdated::class); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Recorders/OutdatedRecorder.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace AaronFrancis\Pulse\Outdated\Recorders; 7 | 8 | use Illuminate\Config\Repository; 9 | use Illuminate\Support\Facades\Process; 10 | use Laravel\Pulse\Events\SharedBeat; 11 | use Laravel\Pulse\Pulse; 12 | use RuntimeException; 13 | 14 | class OutdatedRecorder 15 | { 16 | /** 17 | * The events to listen for. 18 | * 19 | * @var class-string 20 | */ 21 | public string $listen = SharedBeat::class; 22 | 23 | /** 24 | * Create a new recorder instance. 25 | */ 26 | public function __construct( 27 | protected Pulse $pulse, 28 | protected Repository $config 29 | ) { 30 | // 31 | } 32 | 33 | public function record(SharedBeat $event): void 34 | { 35 | if ($event->time !== $event->time->startOfDay()) { 36 | return; 37 | } 38 | 39 | $result = Process::run('composer outdated -D -f json'); 40 | 41 | if ($result->failed()) { 42 | throw new RuntimeException('Composer outdated failed: ' . $result->errorOutput()); 43 | } 44 | 45 | json_decode($result->output(), flags: JSON_THROW_ON_ERROR); 46 | 47 | $this->pulse->set('composer_outdated', 'result', $result->output()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /testbench.yaml: -------------------------------------------------------------------------------- 1 | providers: 2 | - Livewire\LivewireServiceProvider 3 | - Laravel\Pulse\PulseServiceProvider 4 | - AaronFrancis\Pulse\Outdated\OutdatedServiceProvider 5 | - Workbench\App\Providers\WorkbenchServiceProvider 6 | 7 | migrations: 8 | - vendor/laravel/pulse/database/migrations 9 | 10 | seeders: 11 | - Workbench\Database\Seeders\DatabaseSeeder 12 | 13 | workbench: 14 | start: '/pulse' 15 | user: 'aarondfrancis@gmail.com' 16 | install: true 17 | discovers: 18 | web: true 19 | commands: false 20 | views: true 21 | build: 22 | - asset-publish 23 | - migrate-refresh 24 | assets: 25 | - laravel-assets 26 | sync: [] 27 | -------------------------------------------------------------------------------- /workbench/.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY=AckfSECXIvnK5r28GVIWUAxmbBSjTsmF 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | LOG_DEPRECATIONS_CHANNEL=null 9 | LOG_LEVEL=debug 10 | 11 | DB_CONNECTION=mysql 12 | DB_HOST=127.0.0.1 13 | DB_PORT=3306 14 | DB_DATABASE=laravel_pulse 15 | DB_USERNAME=root 16 | DB_PASSWORD= 17 | 18 | BROADCAST_DRIVER=log 19 | CACHE_DRIVER=file 20 | FILESYSTEM_DISK=local 21 | QUEUE_CONNECTION=sync 22 | SESSION_DRIVER=file 23 | SESSION_LIFETIME=120 24 | 25 | MEMCACHED_HOST=127.0.0.1 26 | 27 | REDIS_HOST=127.0.0.1 28 | REDIS_PASSWORD=null 29 | REDIS_PORT=6379 30 | 31 | MAIL_MAILER=smtp 32 | MAIL_HOST=mailpit 33 | MAIL_PORT=1025 34 | MAIL_USERNAME=null 35 | MAIL_PASSWORD=null 36 | MAIL_ENCRYPTION=null 37 | MAIL_FROM_ADDRESS="hello@example.com" 38 | MAIL_FROM_NAME="${APP_NAME}" 39 | 40 | AWS_ACCESS_KEY_ID= 41 | AWS_SECRET_ACCESS_KEY= 42 | AWS_DEFAULT_REGION=us-east-1 43 | AWS_BUCKET= 44 | AWS_USE_PATH_STYLE_ENDPOINT=false 45 | 46 | PUSHER_APP_ID= 47 | PUSHER_APP_KEY= 48 | PUSHER_APP_SECRET= 49 | PUSHER_HOST= 50 | PUSHER_PORT=443 51 | PUSHER_SCHEME=https 52 | PUSHER_APP_CLUSTER=mt1 53 | 54 | VITE_APP_NAME="${APP_NAME}" 55 | VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 56 | VITE_PUSHER_HOST="${PUSHER_HOST}" 57 | VITE_PUSHER_PORT="${PUSHER_PORT}" 58 | VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" 59 | VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 60 | -------------------------------------------------------------------------------- /workbench/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .env.dusk 3 | -------------------------------------------------------------------------------- /workbench/app/Models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aarondfrancis/pulse-outdated/a1e163e9e601c1b572fa36d934c25e4b706e0b9b/workbench/app/Models/.gitkeep -------------------------------------------------------------------------------- /workbench/app/Providers/WorkbenchServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 16 | OutdatedRecorder::class => [] 17 | ]]); 18 | } 19 | 20 | /** 21 | * Bootstrap services. 22 | */ 23 | public function boot(): void 24 | { 25 | // 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /workbench/database/factories/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aarondfrancis/pulse-outdated/a1e163e9e601c1b572fa36d934c25e4b706e0b9b/workbench/database/factories/.gitkeep -------------------------------------------------------------------------------- /workbench/database/migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aarondfrancis/pulse-outdated/a1e163e9e601c1b572fa36d934c25e4b706e0b9b/workbench/database/migrations/.gitkeep -------------------------------------------------------------------------------- /workbench/database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create([ 16 | 'name' => 'Aaron Francis', 17 | 'email' => 'aarondfrancis@gmail.com', 18 | ]); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /workbench/resources/views/vendor/pulse/dashboard.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /workbench/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | // })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /workbench/routes/web.php: -------------------------------------------------------------------------------- 1 |