Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate config to DTOs #1800

Merged
merged 20 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
php: [8.3, 8.2, 8.1]
php: [8.3, 8.2]
laravel: [11.*, 10.*]
stability: [prefer-lowest, prefer-stable]
carbon: [^2.63]
Expand All @@ -26,9 +26,6 @@ jobs:
testbench: 8.*
- laravel: 11.*
testbench: 9.*
exclude:
- laravel: 11.*
php: 8.1

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

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ composer.lock
vendor
.phpunit.result.cache
.php-cs-fixer.cache
.phpunit.cache
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
}
],
"require": {
"php": "^8.1",
"php": "^8.2",
"ext-zip": "^1.14.0",
"illuminate/console": "^10.10.0|^11.0",
"illuminate/contracts": "^10.10.0|^11.0",
Expand Down
2 changes: 1 addition & 1 deletion docs/sending-notifications/customizing-the-notifiable.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class BackupNotifiable extends Notifiable
{
public function routeNotificationForAnotherNotificationChannel()
{
return config('backup.notifications.another_notification_channel.property');
return $this->config()->notifications->another_notification_channel->property;
}
}

Expand Down
15 changes: 5 additions & 10 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ parameters:
count: 1
path: src/BackupDestination/BackupCollection.php

-
message: "#^Unable to resolve the template type TKey in call to function collect$#"
count: 1
path: src/BackupDestination/BackupDestinationFactory.php

-
message: "#^Unable to resolve the template type TValue in call to function collect$#"
count: 1
path: src/BackupDestination/BackupDestinationFactory.php

-
message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\Collection\\<int,int\\>\\:\\:map\\(\\) expects callable\\(int, int\\)\\: string, Closure\\(string\\)\\: non\\-falsy\\-string given\\.$#"
count: 1
Expand Down Expand Up @@ -54,3 +44,8 @@ parameters:
message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\Collection\\<int,Spatie\\\\Backup\\\\BackupDestination\\\\Backup\\>\\:\\:each\\(\\) expects callable\\(Spatie\\\\Backup\\\\BackupDestination\\\\Backup, int\\)\\: mixed, Closure\\(Spatie\\\\Backup\\\\BackupDestination\\\\BackupCollection\\)\\: void given\\.$#"
count: 1
path: src/Tasks/Cleanup/Strategies/DefaultStrategy.php

-
message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\Collection\\<\\(int\\|string\\),Spatie\\\\Backup\\\\Config\\\\MonitoredBackupConfig\\>\\:\\:flatMap\\(\\) expects callable\\(Spatie\\\\Backup\\\\Config\\\\MonitoredBackupConfig, int\\|string\\)\\: \\(array\\<int, Spatie\\\\Backup\\\\Tasks\\\\Monitor\\\\BackupDestinationStatus\\>\\|Illuminate\\\\Support\\\\Collection\\<int, Spatie\\\\Backup\\\\Tasks\\\\Monitor\\\\BackupDestinationStatus\\>\\), Closure\\(array\\)\\: Illuminate\\\\Support\\\\Collection\\<int, Spatie\\\\Backup\\\\Tasks\\\\Monitor\\\\BackupDestinationStatus\\> given\\.$#"
count: 1
path: src/Tasks/Monitor/BackupDestinationStatusFactory.php
1 change: 1 addition & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ parameters:
tmpDir: build/phpstan
checkOctaneCompatibility: true
checkModelProperties: true
treatPhpDocTypesAsCertain: false

ignoreErrors:
- '#Unsafe usage of new static#'
22 changes: 16 additions & 6 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" backupStaticAttributes="false" colors="true" verbose="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage>
<include>
<directory suffix=".php">src/</directory>
</include>
</coverage>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="vendor/autoload.php"
backupGlobals="false"
colors="true"
processIsolation="false"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
cacheDirectory=".phpunit.cache"
backupStaticProperties="false"
>
<testsuites>
<testsuite name="Spatie Test Suite">
<directory>tests</directory>
Expand All @@ -13,4 +18,9 @@
<php>
<env name="APP_NAME" value="mysite"/>
</php>
<source>
<include>
<directory suffix=".php">src/</directory>
</include>
</source>
</phpunit>
2 changes: 2 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector;
use Rector\TypeDeclaration\Rector\Closure\AddClosureVoidReturnTypeWhereNoReturnRector;

return RectorConfig::configure()
->withPaths(['config', 'resources', 'src'])
Expand All @@ -33,4 +34,5 @@
PostIncDecToPreIncDecRector::class,
NullableCompareToNullRector::class,
AddArrowFunctionReturnTypeRector::class,
AddClosureVoidReturnTypeWhereNoReturnRector::class,
]);
2 changes: 1 addition & 1 deletion src/BackupDestination/BackupCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static function createFromFiles(?FileSystem $disk, array $files): self
{
return (new static($files))
->filter(fn (string $path) => (new File())->isZipFile($disk, $path))
->map(fn (string $path) => new Backup($disk, $path))
->map(fn (string $path): \Spatie\Backup\BackupDestination\Backup => new Backup($disk, $path))
->sortByDesc(fn (Backup $backup) => $backup->date()->timestamp)
->values();
}
Expand Down
8 changes: 4 additions & 4 deletions src/BackupDestination/BackupDestinationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
namespace Spatie\Backup\BackupDestination;

use Illuminate\Support\Collection;
use Spatie\Backup\Config\Config;

class BackupDestinationFactory
{
/**
* @param array<string, mixed> $config
* @return Collection<int, BackupDestination>
*/
public static function createFromArray(array $config): Collection
public static function createFromArray(Config $config): Collection
{
return collect($config['destination']['disks'])
->map(fn ($filesystemName) => BackupDestination::create($filesystemName, $config['name']));
return collect($config->backup->destination->disks)
->map(fn (string $filesystemName) => BackupDestination::create($filesystemName, $config->backup->name));
}
}
7 changes: 6 additions & 1 deletion src/BackupServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Spatie\Backup\Commands\CleanupCommand;
use Spatie\Backup\Commands\ListCommand;
use Spatie\Backup\Commands\MonitorCommand;
use Spatie\Backup\Config\Config;
use Spatie\Backup\Events\BackupZipWasCreated;
use Spatie\Backup\Helpers\ConsoleOutput;
use Spatie\Backup\Listeners\EncryptBackupArchive;
Expand Down Expand Up @@ -50,12 +51,16 @@ public function packageRegistered(): void
$this->app->bind(CleanupStrategy::class, config('backup.cleanup.strategy'));

$this->registerDiscordChannel();

$this->app->scoped(Config::class, function (): \Spatie\Backup\Config\Config {
return Config::fromArray(config('backup'));
});
}

protected function registerDiscordChannel(): void
{
Notification::resolved(function (ChannelManager $service) {
$service->extend('discord', function ($app) {
$service->extend('discord', function ($app): \Spatie\Backup\Notifications\Channels\Discord\DiscordChannel {
return new DiscordChannel();
});
});
Expand Down
8 changes: 7 additions & 1 deletion src/Commands/BackupCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Exception;
use Illuminate\Contracts\Console\Isolatable;
use Spatie\Backup\Config\Config;
use Spatie\Backup\Events\BackupHasFailed;
use Spatie\Backup\Exceptions\BackupFailed;
use Spatie\Backup\Exceptions\InvalidCommand;
Expand All @@ -18,6 +19,11 @@ class BackupCommand extends BaseCommand implements Isolatable

protected $description = 'Run the backup.';

public function __construct(protected Config $config)
{
parent::__construct();
}

public function handle(): int
{
consoleOutput()->comment($this->currentTry > 1 ? sprintf('Attempt n°%d...', $this->currentTry) : 'Starting backup...');
Expand All @@ -31,7 +37,7 @@ public function handle(): int
try {
$this->guardAgainstInvalidOptions();

$backupJob = BackupJobFactory::createFromArray(config('backup'));
$backupJob = BackupJobFactory::createFromConfig($this->config);

if ($this->option('only-db')) {
$backupJob->dontBackupFilesystem();
Expand Down
11 changes: 6 additions & 5 deletions src/Commands/CleanupCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Exception;
use Illuminate\Contracts\Console\Isolatable;
use Spatie\Backup\BackupDestination\BackupDestinationFactory;
use Spatie\Backup\Config\Config;
use Spatie\Backup\Events\CleanupHasFailed;
use Spatie\Backup\Tasks\Cleanup\CleanupJob;
use Spatie\Backup\Tasks\Cleanup\CleanupStrategy;
Expand All @@ -20,8 +21,10 @@ class CleanupCommand extends BaseCommand implements Isolatable
/** @var string */
protected $description = 'Remove all backups older than specified number of days in config.';

public function __construct(protected CleanupStrategy $strategy)
{
public function __construct(
protected CleanupStrategy $strategy,
protected Config $config,
) {
parent::__construct();
}

Expand All @@ -34,9 +37,7 @@ public function handle(): int
$this->setTries('cleanup');

try {
$config = config('backup');

$backupDestinations = BackupDestinationFactory::createFromArray($config['backup']);
$backupDestinations = BackupDestinationFactory::createFromArray($this->config);

$cleanupJob = new CleanupJob($backupDestinations, $this->strategy, $disableNotifications);

Expand Down
18 changes: 10 additions & 8 deletions src/Commands/ListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Support\Collection;
use Spatie\Backup\BackupDestination\Backup;
use Spatie\Backup\Config\Config;
use Spatie\Backup\Helpers\Format;
use Spatie\Backup\Helpers\RightAlignedTableStyle;
use Spatie\Backup\Tasks\Monitor\BackupDestinationStatus;
Expand All @@ -17,13 +18,14 @@ class ListCommand extends BaseCommand
/** @var string */
protected $description = 'Display a list of all backups.';

public function handle(): int
public function __construct(protected Config $config)
{
if (config()->has('backup.monitorBackups')) {
$this->warn('Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.');
}
parent::__construct();
}

$statuses = BackupDestinationStatusFactory::createForMonitorConfig(config('backup.monitor_backups'));
public function handle(): int
{
$statuses = BackupDestinationStatusFactory::createForMonitorConfig($this->config->monitoredBackups);

$this->displayOverview($statuses)->displayFailures($statuses);

Expand All @@ -37,7 +39,7 @@ protected function displayOverview(Collection $backupDestinationStatuses): stati
{
$headers = ['Name', 'Disk', 'Reachable', 'Healthy', '# of backups', 'Newest backup', 'Used storage'];

$rows = $backupDestinationStatuses->map(function (BackupDestinationStatus $backupDestinationStatus) {
$rows = $backupDestinationStatuses->map(function (BackupDestinationStatus $backupDestinationStatus): array {
return $this->convertToRow($backupDestinationStatus);
});

Expand Down Expand Up @@ -81,10 +83,10 @@ public function convertToRow(BackupDestinationStatus $backupDestinationStatus):
protected function displayFailures(Collection $backupDestinationStatuses): static
{
$failed = $backupDestinationStatuses
->filter(function (BackupDestinationStatus $backupDestinationStatus) {
->filter(function (BackupDestinationStatus $backupDestinationStatus): bool {
return $backupDestinationStatus->getHealthCheckFailure() !== null;
})
->map(function (BackupDestinationStatus $backupDestinationStatus) {
->map(function (BackupDestinationStatus $backupDestinationStatus): array {
return [
$backupDestinationStatus->backupDestination()->backupName(),
$backupDestinationStatus->backupDestination()->diskName(),
Expand Down
12 changes: 7 additions & 5 deletions src/Commands/MonitorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Spatie\Backup\Commands;

use Illuminate\Contracts\Console\Isolatable;
use Spatie\Backup\Config\Config;
use Spatie\Backup\Events\HealthyBackupWasFound;
use Spatie\Backup\Events\UnhealthyBackupWasFound;
use Spatie\Backup\Tasks\Monitor\BackupDestinationStatusFactory;
Expand All @@ -15,15 +16,16 @@ class MonitorCommand extends BaseCommand implements Isolatable
/** @var string */
protected $description = 'Monitor the health of all backups.';

public function handle(): int
public function __construct(protected Config $config)
{
if (config()->has('backup.monitorBackups')) {
$this->warn('Warning! Your config file still uses the old monitorBackups key. Update it to monitor_backups.');
}
parent::__construct();
}

public function handle(): int
{
$hasError = false;

$statuses = BackupDestinationStatusFactory::createForMonitorConfig(config('backup.monitor_backups'));
$statuses = BackupDestinationStatusFactory::createForMonitorConfig($this->config->monitoredBackups);

foreach ($statuses as $backupDestinationStatus) {
$backupName = $backupDestinationStatus->backupDestination()->backupName();
Expand Down
51 changes: 51 additions & 0 deletions src/Config/BackupConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Spatie\Backup\Config;

use Spatie\Backup\Exceptions\InvalidConfig;
use Spatie\Backup\Support\Data;

class BackupConfig extends Data
{
protected function __construct(
public string $name,
public SourceConfig $source,
public ?string $databaseDumpCompressor,
public ?string $databaseDumpFileTimestampFormat,
public string $databaseDumpFilenameBase,
public string $databaseDumpFileExtension,
public DestinationConfig $destination,
public ?string $temporaryDirectory,
public ?string $password,
public string $encryption,
public int $tries,
public int $retryDelay,
public ?MonitoredBackupsConfig $monitoredBackups,
) {
if ($this->tries < 1) {
throw InvalidConfig::integerMustBePositive('tries');
}
}

/** @param array<mixed> $data */
public static function fromArray(array $data): self
{
$monitoredBackups = $data['monitored_backups'] ?? $data['monitorBackups'] ?? null;

return new self(
name: $data['name'],
source: SourceConfig::fromArray($data['source']),
databaseDumpCompressor: $data['database_dump_compressor'],
databaseDumpFileTimestampFormat: $data['database_dump_file_timestamp_format'],
databaseDumpFilenameBase: $data['database_dump_filename_base'],
databaseDumpFileExtension: $data['database_dump_file_extension'],
destination: DestinationConfig::fromArray($data['destination']),
temporaryDirectory: $data['temporary_directory'] ?? null,
password: $data['password'],
encryption: $data['encryption'],
tries: $data['tries'],
retryDelay: $data['retry_delay'],
monitoredBackups: $monitoredBackups ? MonitoredBackupsConfig::fromArray($monitoredBackups) : null,
);
}
}
Loading