@Override
    public void run(Namespace namespace, Liquibase liquibase) throws Exception {
        final String tag = namespace.getString("tag");
        final Integer count = namespace.getInt("count");
        final Date date = namespace.get("date");
        final boolean dryRun = namespace.getBoolean("dry-run") != null && namespace.getBoolean("dry-run");
        final String context = getContext(namespace);
        if (Stream.of(tag, count, date).filter(Objects::nonNull).count() != 1) {
            throw new IllegalArgumentException("Must specify either a count, a tag, or a date.");
        }

        if (count != null) {
            if (dryRun) {
                liquibase.rollback(count, context, new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
            } else {
                liquibase.rollback(count, context);
            }
        } else if (tag != null) {
            if (dryRun) {
                liquibase.rollback(tag, context, new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
            } else {
                liquibase.rollback(tag, context);
            }
        } else {
            if (dryRun) {
                liquibase.rollback(date, context, new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
            } else {
                liquibase.rollback(date, context);
            }
        }
    }
@Test
    void testRollbackToTag() throws Exception {
        // Migrate the first DDL change to the database
        migrateCommand.run(null, new Namespace(Map.of("count", 1)), conf);

        // Tag it
        final DbTagCommand<TestMigrationConfiguration> tagCommand = new DbTagCommand<>(
            new TestMigrationDatabaseConfiguration(), TestMigrationConfiguration.class, migrationsFileName);
        tagCommand.run(null, new Namespace(Map.of("tag-name", List.of("v1"))), conf);

        try (Handle handle = dbi.open()) {
            assertThat(MigrationTestSupport.columnExists(handle, "PERSONS", "EMAIL"))
                .isFalse();
        }

        // Migrate the second change
        migrateCommand.run(null, new Namespace(Map.of()), conf);

        try (Handle handle = dbi.open()) {
            assertThat(MigrationTestSupport.columnExists(handle, "PERSONS", "EMAIL"))
                .isTrue();
        }

        // Rollback to the first change
        rollbackCommand.run(null, new Namespace(Map.of("tag", "v1")), conf);

        try (Handle handle = dbi.open()) {
            assertThat(MigrationTestSupport.columnExists(handle, "PERSONS", "EMAIL"))
                .isFalse();
        }
    }