eniams/safe-migrations

当迁移不安全时发出警告

1.2.0 2023-10-31 09:19 UTC

This package is auto-updated.

Last update: 2024-09-23 23:24:59 UTC


README

⚠️ 当你的 自动生成 doctrine 迁移包含不安全的 SQL 语句时发出警告。

不安全的迁移是

  • 在零停机部署时必须小心进行的操作。
  • 对您自行定义的关键表进行的操作。
  • 可能锁定表(如 NOT NULL CONSTRAINT)或丢失数据(如删除或截断)的操作。
  • 可能危险的操作,如 DROPRENAME
  • 您定义的操作。

当检测到不安全的迁移时,在命令 doctrine:migrations:diff 中显示警告,并在迁移文件中添加注释。

image

image

不安全语句列表

  • CREATE INDEX
  • DROP
  • MODIFY
  • NOT NULL
  • RENAME
  • TRUNCATE

如果您的最后迁移中存在这些语句中的任何一个,都会触发警告,欢迎提交 PR 添加更多语句。

功能

入门

安装

您可以通过 composer 轻松安装 Safe Migrations Bundle

$ composer require eniams/safe-migrations --dev

然后,确保在 config\bundles.php 中注册了捆绑包。

Eniams\SafeMigrationsBundle\SafeMigrationsBundle::class => ['dev' => true],

配置

然后,您应该在配置中注册它(config/packages/dev/safe_migrations.yaml

# config/packages/safe-migrations.yaml
    safe_migrations:
      # required
      migrations_path: '%kernel.project_dir%/migrations'
      # optional
      critical_tables: # List of critical tables
        - 'user'
        - 'product'
        - # ...
      # optional
      excluded_statements: # List of operations that not need a warning
        - 'TRUNCATE'
        - # ...
排除一个语句

如果您想排除一个语句,您可以在配置文件中添加它。

# config/packages/safe-migrations.yaml
    safe_migrations:
      excluded_statements: # List of operations that not need a warning
        - 'TRUNCATE' # The statement TRUNCATE will not be flagged as unsafe
        - # ...
创建自己的语句

如果您想创建自定义语句,您可以通过添加一个实现 Eniams\SafeMigrationsBundle\Statement\StatementInterface 的新类来完成。

以下是一个示例
# config/services.yaml
services:
    _defaults:
        autoconfigure: true
<?php
namespace App\Statement\MyStatement;
use Eniams\SafeMigrationsBundle\Statement\StatementInterface;

class MyStatement implements StatementInterface
{
    protected string $migrationWarning;

    public function migrationWarning(): string
    {
        // The message that will be added in the migration file
        return $this->migrationWarning;
    }
    
    public function supports(string $migrationUpContent): bool
    {
        // The logic to determine if the statement is present in the `up` method of migration file.
        // The following code can be enough
        return str_contains(strtoupper($statement), $this->getStatement());
    }

    public function getStatement(): string;
    {
        return 'MY_STATEMENT';
    }
}
配置关键表

如果您想将表标记为关键,并在迁移包含对该表的更改时发出警告,只需按如下方式标记表

# config/packages/safe-migrations.yaml
    safe_migrations:
      critical_tables: # List of critical tables
        - 'user'
        - 'product'
        - # ...
装饰语句

如果您想包装语句以个性化警告消息或捕获语句的逻辑,可以使用 装饰器设计模式

请参阅以下示例,您还可以查看 如何使用 Symfony 装饰服务

<?php
namespace App\Statement;

use Eniams\SafeMigrationsBundle\Statement\AbstractStatement;

class CustomNotNullStatement extends AbstractStatement
{
    public function getStatement(): string
    {
        return 'NOT NULL';
    }

    public function migrationWarning(): string
    {
        return 'Your custom message';
    }
}
# config/services.yaml
    App\Warning\CustomNotNullStatement:
      decorates: 'eniams_safe_migrations.not_null.statement'
事件监听器

当创建不安全的迁移时,会触发一个名为 Eniams\SafeMigrationsBundle\Event\UnsafeMigrationEvent 的事件,您可以监听它并获取一个包含迁移名称和迁移文件内容的 UnsafeMigration

示例

<?php

namespace App\Listener;

use Eniams\SafeMigrationsBundle\Event\UnsafeMigrationEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MigrationRiskySubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            UnsafeMigrationEvent::class => 'onUnsafeMigration',
        ];
    }

    public function onUnsafeMigration(UnsafeMigrationEvent $event)
    {
        $unsafeMigration = $event->getUnsafeMigration();

        // Version20231030215756
        $unsafeMigration->getMigrationName();

        // Migration file
        $unsafeMigration->getMigrationFileContent();

        // Migration file with the warning.
        $unsafeMigration->getMigrationFileContentWithWarning();
    }
}
调试配置

您可以使用以下命令调试您设置的配置:$ bin/console eniams:debug-configuration

贡献

请阅读 CONTRIBUTING.md 以了解我们的行为准则以及向我们提交拉取请求的过程。

在编写您的修复/功能之后,您可以使用以下命令来确保一切仍然正常。

# Install dev dependencies
$ composer install

# Running tests and quality tools locally
$ make all

作者

  • Smaïne Milianni - ismail1432 - <smaine(dot)milianni@gmail(dot)com>
  • 昆汀·德奇普 - qdequippe - <quentin@dequippe(dot)tech>