Laravel Zero

Script e Server Automation

di

Alessandro Cappellozza

Perché

Uno sviluppatore laravel che vuole crearsi uno strumento di deploy o di manutenzione senza dover imparare altri framework specifici, è un riuso delle conoscenze applicate però ad un altro ambito.

Deploy più comodo e compatto.

  • Riuso dell'esperienza
  • Riuso del codice
  • Leggero
  • Componenti specifici
  • Deployabile facilmente

Laravel Zero - Alessandro Cappellozza

Campo Applicativo

  • Un tool pensato per sviluppatori Laravel.
  • Per automazione locale durante lo sviluppo.
  • Per automazione e manutenzione server.
  • Sviluppo generico di un tool a linea di comando.

Laravel Zero - Alessandro Cappellozza

Installazione

I metodi di installazione sono quelli classici di Laravel solo con il loro cli:

# Con un comando globale
composer global require "laravel-zero/installer"
laravel-zero new command-cli

# Via composer project
composer create-project --prefer-dist laravel-zero/laravel-zero command-cli

Nota: A fine installazione verrà richiesto il rename.

Laravel Zero - Alessandro Cappellozza

Architettura

Un Laravel ridotto ai minimi, viene rimossa tutta la parte http e tenuta solo la parte strutturale legata ai comandi e le utility/helper.

Segue le versioni principali al momento siamo alla 7.x

# Structure
app
	Commands
	Providers
boostrap
config
	app.php
	commands.php
[stubs]
tests

# Files
box.json
command-cli
composer.json
phpunit.xml

Laravel Zero - Alessandro Cappellozza

Exception Handler

<?php

// ....

$app->singleton(
  Illuminate\Contracts\Debug\ExceptionHandler::class,
  App\Exceptions\Handler::class
);

Laravel Zero - Alessandro Cappellozza

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler;
use Throwable;

class MyHandler extends Handler
{
    protected $dontReport = [
    ];

    /**
     * Report or log an exception.
     *
     * @param  \Throwable  $exception
     * @return void
     *
     * @throws \Exception
     */
    public function report(Throwable $exception)
    {
        parent::report($exception);
    }
}

Orientamento al Comando

Il nome del comando non è più artisan ma il nome che abbiamo scelto noi.

 

In più ci sono dei comandi per la distribuzione.

php command-cli

  Command-cli  unreleased

  USAGE: command-cli <command> [options] [arguments]

  inspiring    Display an inspiring quote
  test         Run the application tests

  app:build    Build a single file executable
  app:install  Install optional components
  app:rename   Set the application name

  make:command Create a new command

  stub:publish Publish all stubs

Laravel Zero - Alessandro Cappellozza

Comando

La struttura è identica a quella di Laravel se non per la registrazione che può essere automatica e per la schedulazione che è incorporata.

<?php

namespace DummyNamespace;

use Illuminate\Console\Scheduling\Schedule;
use LaravelZero\Framework\Commands\Command;

class ExampleCommand extends Command
{
    protected $signature = 'dummy:command';

    protected $description = 'Command description';

    public function handle()
    {
      $this->task("Installing Laravel", function () {
          return true;
      });
    }

    public function schedule(Schedule $schedule): void
    {
        $schedule->command(static::class)->everyMinute();
    }
}

Laravel Zero - Alessandro Cappellozza

Configurazione: config/app.php

<?php

return [

    'name' => 'Command-cli',

    'version' => app('git.version'),

    'env' => 'development',

    'providers' => [
        App\Providers\AppServiceProvider::class,
    ],

];

....

git rev-list --tags --max-count=1

Laravel Zero - Alessandro Cappellozza

Configurazione: config/commands.php

<?php

return [

    'default' => SummaryCommand::class,

    'paths' => [app_path('Commands')],

    'add' => [
        // ..
    ],

    'hidden' => [

    ],

    'remove' => [
        // ..
    ],
];

Laravel Zero - Alessandro Cappellozza

  • phpunit

  • tinker

Tinker non è presente di default, va installato a parte con un package.

Toolling

composer require intonate/tinker-zero

vi app/confdig.php

...
'providers' => [

    Intonate\TinkerZero\TinkerZeroServiceProvider::class,

],
...

php command-cli tinker

Laravel Zero - Alessandro Cappellozza

Logging

Anche se installato a parte è il classico log di laravel basato su monolog.

php command-cli app:install log

use Log;

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);
vi conf/logging.php
<?php

use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;

return [
    'default' => env('LOG_CHANNEL', 'stack'),
    'channels' => [
        'stack' => [ ],
        'single' => [
            'driver' => 'single',
            'path' => storage_path('logs/laravel.log'),
            'level' => 'debug',        
        ],
        'daily' => [ ],
        'slack' => [ ],
        'papertrail' => [ ],
        'stderr' => [ ],
        'syslog' => [ ],
        'errorlog' => [ ],
        'null' => [ ],
    ],

];

Laravel Zero - Alessandro Cappellozza

Storage

Basato sempre su flysystem di Phplegue, il concetto di storage è differente.

$touch conf/filesystems.php
$vi conf/filesystems.php

<?php

return [
    'default' => 'local',
    'disks' => [
        'local' => [
            'driver' => 'local',
            'root' => getcwd(),
        ],
    ],
];
<?php

function userHome($path = null)
{
    $user = posix_getpwuid(posix_getuid());

    if ($path == null) {
        return $user['dir'];
    }

    return "{$user['dir']}/{$path}";
}

Consigliabile usare la cartella home dell'utente.

 

NB: Su Win l'estensione Posix non c'è

Laravel Zero - Alessandro Cappellozza

Database

Sono presenti tutti i tool classici come migrazioni, seeder, eloquent e facade.

 

Ma vanno installati a parte.

 

Può essere interessante se si vuole integrarlo con Lravel e/o portarsi un db embedded (sqlite).

php command-cli app:install database

<?php

use DB;

DB::table('users')->insert(
    ['email' => 'enunomaduro@gmail.com']
);

$users = DB::table('users')->get();

Laravel Zero - Alessandro Cappellozza

Queue

Va installato a parte ma non è documentato, va integrato a mano sistemando i default.

php command-cli app:install queue

<?php

return [

    'default' => env('QUEUE_CONNECTION', 'database'),


    'connections' => [

        'sync' => [
            'driver' => 'sync',
        ],

        'database' => [ ],

        'beanstalkd' => [ ],

        'sqs' => [ ],

        'redis' => [ ],
    ],

    'failed' => [ ],
];

Laravel Zero - Alessandro Cappellozza

Http/Dusk

Presente e aggiornato con l'ultimo facade di Laravel.

 

Disponibile anche Dusk che in teoria servirebbe per i test qui si usa per scopi diversi come la documentazione/log errori.

php command-cli app:install http

<?php

use Illuminate\Support\Facades\Http;

Http::get($url);
Http::post($url, $data);

php command-cli app:install console-dusk

<?php

....

class VisitLaravelZeroCommand extends Command
{
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->browse(function ($browser) {
            $browser->visit('http://laravel-zero.com')
                ->assertSee('Collision');
        });
    }
}

Laravel Zero - Alessandro Cappellozza

Env

Funziona esattamente come quello standard e verrà cercato nella stessa directory del nostro tool.

 

Potrebbe essere più comodo installarla nella home utente.

php command-cli app:install dotenv

vi .env

...

API_URL=https://example.com/api


<?php

$apikey = env('A_B_C');

Laravel Zero - Alessandro Cappellozza

Menu

Logo

Possibilità di creare interattività con l'utente per installer.

Abbellimenti per migliorare l'esperienza d'uso:

<<EYE SUGAR>>

Laravel Zero - Alessandro Cappellozza

Componente Embed Installabile Documentato
Filesystem X - X
DB - X X
Logging - X X
Env - X X
Queue - X -
Tinker - X X
Dusk - X X
Http - X X

Recap Componenti

Su https://github.com/laravel-zero/framework/tree/master/src/Components

Laravel Zero - Alessandro Cappellozza

Build

php command-cli app:build <<NOME>>
# Verrà chiesta la versione


php command-cli app:build --build-version=1.0.0
# Per la vuild non interattiva

Viene creato un file auto-contenuto: .phar Una specie di archivio con dentro tutto il necessario per funzionare.

 

La build è interattiva se senza parametri se no è possibile farla girare senza input.

Laravel Zero - Alessandro Cappellozza

Phar

Phar archives are similar in concept to Java JAR archives, but are tailored to the needs and to the flexibility of PHP applications. A Phar archive is used to distribute a complete PHP application or library in a single file. A Phar archive application is used exactly like any other PHP application:


$ php coolapplication.phar

$ mv coolapplication.phar /bin/coolapplication

$ coolapplication --options

da php.net

Laravel Zero - Alessandro Cappellozza

Humbug/Box

{
    "chmod": "0755",
    "directories": [
        "app",
        "bootstrap",
        "config",
        "vendor"
    ],
    "files": [
        "composer.json"
    ],
    "exclude-composer-files": false,
    "compression": "GZ",
    "compactors": [
        "KevinGH\\Box\\Compactor\\Php",
        "KevinGH\\Box\\Compactor\\Json"
    ]
}

Tutti i parametri sono disponibili sul file box.json in root del progetto. Fare riferimento a:

https://github.com/humbug/box

Laravel Zero - Alessandro Cappellozza

Embed di risorse

{
    "chmod": "0755",
    "directories": [
        "app",
        "bootstrap",
        "config",
        "vendor",
        "<<mydir>>"
    ],
    "files": [
        "composer.json"
    ],
    "exclude-composer-files": false,
    "compression": "GZ",
    "compactors": [
        "KevinGH\\Box\\Compactor\\Php",
        "KevinGH\\Box\\Compactor\\Json"
    ]
}

La cartella sarà presente e accessibile tramite Storage facade o altri helper ma sarà di sola lettura.

 

Si fa sempre riferimento a box.json per la configurazione e l'elenco delle cartelle da importare.

Laravel Zero - Alessandro Cappellozza

Autoupdate: Installazione

php command-cli app:install self-update

# vi config/updater.php

use LaravelZero\Framework\Components\Updater\Strategy\GithubStrategy;

return [

    /*
    |--------------------------------------------------------------------------
    | Self-updater Strategy
    |--------------------------------------------------------------------------
    |
    | Here you may specify which update strategy class you wish to use when
    | updating your application via the "self-update" command. This must
    | be a class that implements the StrategyInterface from Humbug.
    |
    */

    'strategy' => GithubStrategy::class,

];

Laravel Zero - Alessandro Cappellozza

Autoupdate: Strategy (1/2)

namespace LaravelZero\Framework\Components\Updater\Strategy;

use Phar;

final class GithubStrategy extends 
		\Humbug\SelfUpdate\Strategy\GithubStrategy implements StrategyInterface
{
    /**
     * Returns the Download Url.
     *
     * @param array $package
     *
     * @return string
     */
    protected function getDownloadUrl(array $package): string
    {
        $downloadUrl = parent::getDownloadUrl($package);

        $downloadUrl = str_replace('releases/download', 'raw', $downloadUrl);

        return $downloadUrl.'/builds/'.basename(Phar::running());
    }
}

Laravel Zero - Alessandro Cappellozza

Autoupdate: Strategy (2/2)

 
  const API_URL = 'https://packagist.org/p/%s.json';

  protected function getApiUrl()
  {
    return sprintf(self::API_URL, $this->getPackageName());
  }

  ....
    
    protected function getDownloadUrl(array $package)
    {
        $baseUrl = preg_replace(
            '{\.git$}',
            '',
            $package['packages'][$this->getPackageName()][$this->remoteVersion]['source']['url']
        );
        $downloadUrl = sprintf(
            '%s/releases/download/%s/%s',
            $baseUrl,
            $this->remoteVersion,
            $this->getPharName()
        );
        return $downloadUrl;
    }
 

Laravel Zero - Alessandro Cappellozza

Ringraziamenti/Riferimenti

Disegni: https://undraw.co/

alessandro.cappellozza@gmail.com

https://github.com/eppak

https://github.com/eppak/laradock-cli

Email

Github

Sorgenti

Laravel Zero - Alessandro Cappellozza

Alessandro Cappellozza

A cura di

Laravel Zero

By Alessandro Cappellozza

Laravel Zero

  • 626