Skip to content

Commit

Permalink
feat: Add mode option to InfoCmd.
Browse files Browse the repository at this point in the history
Closes #419 and #420.
  • Loading branch information
michael-simons committed Feb 21, 2022
1 parent 970c84c commit ad644a5
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 9 deletions.
19 changes: 19 additions & 0 deletions docs/usage.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,25 @@ Commands:

If no values are given to either `location` or `packages` we check for a directory structure of `neo4j/migrations` inside
the current working directory and use that as a default for `location` if such a structure exists.

The `info` command takes a `mode` option as an optional argument:

----
Usage: neo4j-migrations info [mode=<mode>]
Retrieves all applied and pending informations, prints them and exits.
mode=<mode> Controls how the information should be computed. Valid
options are COMPARE, LOCAL, REMOTE with COMPARE being the
default. COMPARE will always compare locally discovered
and remotely applied migrations, while the other options
just check what's there.
----

This means that we by default compare what has been discovered locally with what has been applied in the database:
We check for missing or superfluous migrations and also compare checksums.
At times, you might want to have just a quick look at what is in the database, without configuring a local filesystem.
Use `mode=remote` in that case: We just look at what is in the database and assume everything is applied.
Use `mode=local` to print out what has been discovered locally with the current settings and would be applied to an empty database.

=== Safe passwords in CI/CD usage

There are 4 ways to specify the password:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import ac.simons.neo4j.migrations.core.MigrationChain;
import ac.simons.neo4j.migrations.core.Migrations;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParentCommand;

/**
Expand All @@ -32,6 +33,14 @@ final class InfoCommand extends ConnectedCommand {
@ParentCommand
private MigrationsCli parent;

@Option(names = "mode",
defaultValue = "COMPARE",
description =
"Controls how the information should be computed. Valid options are ${COMPLETION-CANDIDATES} with ${DEFAULT-VALUE} being the default. "
+ "${DEFAULT-VALUE} will always compare locally discovered and remotely applied migrations, while the other options just check what's there."
)
private MigrationChain.ChainBuilderMode mode = MigrationChain.ChainBuilderMode.COMPARE;

@Override
public MigrationsCli getParent() {
return parent;
Expand All @@ -40,7 +49,7 @@ public MigrationsCli getParent() {
@Override
Integer withMigrations(Migrations migrations) {

MigrationChain migrationChain = migrations.info();
MigrationChain migrationChain = migrations.info(mode);
MigrationsCli.LOGGER.info(migrationChain::prettyPrint);
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.io.UncheckedIOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -90,6 +91,7 @@ private static void configureLogging() {
public static void main(String... args) {

CommandLine commandLine = new CommandLine(new MigrationsCli());
commandLine.setCaseInsensitiveEnumValuesAllowed(true);
CommandLine generateCompletionCmd = commandLine.getSubcommands().get("generate-completion");
generateCompletionCmd.getCommandSpec().usageMessage().hidden(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.mockito.Mockito.when;

import ac.simons.neo4j.migrations.core.MigrationChain;
import ac.simons.neo4j.migrations.core.MigrationChain.ChainBuilderMode;
import ac.simons.neo4j.migrations.core.Migrations;

import org.junit.jupiter.api.Test;
Expand All @@ -36,12 +37,12 @@ void shouldLog() {
Migrations migrations = mock(Migrations.class);
MigrationChain info = mock(MigrationChain.class);
when(info.prettyPrint()).thenReturn("<<info>>");
when(migrations.info()).thenReturn(info);
when(migrations.info(ChainBuilderMode.COMPARE)).thenReturn(info);

InfoCommand cmd = new InfoCommand();
cmd.withMigrations(migrations);

verify(migrations).info();
verify(migrations).info(ChainBuilderMode.COMPARE);
verify(info).prettyPrint();

verifyNoMoreInteractions(migrations, info);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ MigrationChain buildChain(MigrationContext context, List<Migration> discoveredMi
private Map<MigrationVersion, Element> buildChain0(MigrationContext context, List<Migration> discoveredMigrations, boolean detailedCauses, ChainBuilderMode infoCmd) {

Map<MigrationVersion, Element> appliedMigrations =
infoCmd == ChainBuilderMode.USE_LOCAL_ONLY ? Collections.emptyMap() : getChainOfAppliedMigrations(context);
if (infoCmd == ChainBuilderMode.USE_REMOTE_ONLY) {
infoCmd == ChainBuilderMode.LOCAL ? Collections.emptyMap() : getChainOfAppliedMigrations(context);
if (infoCmd == ChainBuilderMode.REMOTE) {
// Only looking at remote, assume everything is applied
return Collections.unmodifiableMap(appliedMigrations);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ enum ChainBuilderMode {
* Build a chain only based on locally discovered migrations and assume all migrations are pending. No validation
* will be performed.
*/
USE_LOCAL_ONLY,
LOCAL,
/**
* Build a chain only based on remotely applied migrations and assume all migrations are applied. No validation
* will be performed.
*/
USE_REMOTE_ONLY
REMOTE
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void localOnlyInfoShouldWork() {

assertThat(lengthOfMigrations(driver, null)).isEqualTo(5);

MigrationChain migrationChain = migrations.info(ChainBuilderMode.USE_LOCAL_ONLY);
MigrationChain migrationChain = migrations.info(ChainBuilderMode.LOCAL);
assertThat(migrationChain.getElements())
.isNotEmpty()
.allMatch(element -> element.getState() == MigrationState.PENDING);
Expand All @@ -108,7 +108,7 @@ void remoteOnlyInfoShouldWork() {
assertThat(lengthOfMigrations(driver, null)).isEqualTo(5);

migrations = new Migrations(MigrationsConfig.defaultConfig(), driver);
MigrationChain migrationChain = migrations.info(ChainBuilderMode.USE_REMOTE_ONLY);
MigrationChain migrationChain = migrations.info(ChainBuilderMode.REMOTE);
assertThat(migrationChain.getElements())
.isNotEmpty()
.allMatch(element -> element.getState() == MigrationState.APPLIED);
Expand Down

0 comments on commit ad644a5

Please sign in to comment.