diff --git a/base/src/main/java/io/spine/base/Environment.java b/base/src/main/java/io/spine/base/Environment.java index 6c938b4a67..f1a1ffd077 100644 --- a/base/src/main/java/io/spine/base/Environment.java +++ b/base/src/main/java/io/spine/base/Environment.java @@ -21,37 +21,141 @@ package io.spine.base; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableList; +import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.spine.annotation.SPI; import org.checkerframework.checker.nullness.qual.Nullable; +import static com.google.common.base.Preconditions.checkNotNull; + /** * Provides information about the environment (current platform used, etc.). + * + *

Environment Type Detection

+ * + *

Current implementation allows to {@linkplain #is(EnvironmentType) check} whether a given + * environment is currently the active one and {@linkplain #type() get an instance of the current + * environment type}. Two environment types exist out of the box: + * + *

+ * + *

The framework users may define their custom settings depending on the current environment + * type: + * + *

+ *
+ * public final class Application {
+ *
+ *     private final EmailSender sender;
+ *
+ *     private Application() {
+ *         Environment environment = Environment.instance();
+ *         if(environment.is(Tests.type())) {
+ *             // Do not send out emails if in tests.
+ *             this.sender = new MockEmailSender();
+ *         } else {
+ *             this.sender = EmailSender.withConfig("email_gateway.yml");
+ *         }
+ *         //...
+ *     }
+ * }
+ * 
+ * + *

Custom environment types

+ * + * {@code Environment} allows to {@link #register(EnvironmentType) reguster custom types}. + * In this case the environment detection functionality iterates over all known types, starting + * with those registered by the framework user: + * + *
+ *
+ * public final class Application {
+ *
+ *     static {
+ *         Environment.instance()
+ *                    .register(StagingEnvironmentType.type())
+ *                    .register(LoadTestingType.type());
+ *     }
+ *
+ *     private final ConnectionPool pool;
+ *
+ *     private Application() {
+ *         Environment environment = Environment.instance();
+ *         if (environment.is(Tests.type()) {
+ *              // Single connection is enough for tests.
+ *             this.pool = new ConnectionPoolImpl(PoolCapacity.of(1));
+ *         } else {
+ *             if(environment.is(LoadTesting.type()) {
+ *                 this.pool =
+ *                         new ConnectionPoolImpl(PoolCapacity.fromConfig("load_tests.yml"));
+ *             } else {
+ *                 this.pool =
+ *                         new ConnectionPoolImpl(PoolCapacity.fromConfig("cloud_deployment.yml"));
+ *             }
+ *         }
+ *         //...
+ *     }
+ * }
+ * 
+ * + *

When registering custom types, please ensure their mutual exclusivity. + * If two or more environment types {@linkplain EnvironmentType#enabled() consider themselves + * enabled} at the same time, the behaviour of {@link #is(EnvironmentType)}} is undefined. + * + * @see EnvironmentType + * @see Tests + * @see Production */ @SPI -@SuppressWarnings("AccessOfSystemProperties") // OK as we need system properties for this class. public final class Environment { - private static final Environment INSTANCE = new Environment(); + private static final ImmutableList BASE_TYPES = + ImmutableList.of(Tests.type(), Production.type()); - /** - * The key name of the system property which tells if a code runs under a testing framework. - * - *

If your testing framework is not among the supported by {@link #isTests()}, - * set this property to {@code true} before running tests. - */ - public static final String ENV_KEY_TESTS = "io.spine.tests"; + private static final Environment INSTANCE = new Environment(); - /** If set, tells if the code runs from a testing framework. */ - private @Nullable Boolean tests; + private ImmutableList knownEnvTypes; + private @Nullable EnvironmentType currentEnvType; - /** Prevents instantiation of this singleton class from outside. */ private Environment() { + this.knownEnvTypes = BASE_TYPES; } /** Creates a new instance with the copy of the state of the passed environment. */ private Environment(Environment copy) { - this.tests = copy.tests; + this.knownEnvTypes = copy.knownEnvTypes; + this.currentEnvType = copy.currentEnvType; + } + + /** + * Remembers the specified environment type, allowing {@linkplain #is(EnvironmentType) to + * determine whether it's enabled} later. + * + *

Note that the default types are still present. + * When trying to determine which environment type is enabled, the user-defined types are + * checked first, in the first-registered to last-registered order. + * + * @param environmentType + * a user-defined environment type + * @return this instance of {@code Environment} + * @see Tests + * @see Production + */ + @CanIgnoreReturnValue + public Environment register(EnvironmentType environmentType) { + if (!knownEnvTypes.contains(environmentType)) { + knownEnvTypes = ImmutableList + .builder() + .add(environmentType) + .addAll(INSTANCE.knownEnvTypes) + .build(); + } + return this; } /** Returns the singleton instance. */ @@ -69,60 +173,58 @@ public Environment createCopy() { } /** - * Restores the state from the instance created by {@link #createCopy()}. + * Determines whether the current environment is the same as the specified one. * - *

Call this method when cleaning up tests that modify {@code Environment}. + *

If {@linkplain #register(EnvironmentType) custom env types have been defined}, + * goes through them in the latest-registered to earliest-registered order. + * Then, checks {@link Tests} and {@link Production}. + * + * @return the current environment type. */ - @VisibleForTesting - public void restoreFrom(Environment copy) { - // Make sure this matches the set of fields copied in the copy constructor. - this.tests = copy.tests; + @SuppressWarnings("ConstantConditions"/* no NPE is ensured by the `ensureTypeIsSet` call. */) + public boolean is(EnvironmentType type) { + ensureTypeIsSet(); + return currentEnvType.equals(type); } /** - * Verifies if the code currently runs under a unit testing framework. + * Returns the current environment type. * - *

The method returns {@code true} if the following packages are discovered - * in the stacktrace: - *

+ *

If {@linkplain #register(EnvironmentType) custom env types have been defined}, + * goes through them in the latest-registered to earliest-registered order. + * Then, checks {@link Tests} and {@link Production}. * - * @return {@code true} if the code runs under a testing framework, {@code false} otherwise + * @return the current environment type */ - @SuppressWarnings({ - "DynamicRegexReplaceableByCompiledPattern", // OK as we cache the result - "DuplicateStringLiteralInspection" // used in another context - }) - public boolean isTests() { - // If we cached the value before, return it. - if (tests != null) { - return tests; - } + public EnvironmentType type() { + ensureTypeIsSet(); + return currentEnvType; + } - // Check the environment variable. We may run under unknown testing framework or - // tests may require production-like mode, which they simulate by setting - // the property to `false`. - String testProp = System.getProperty(ENV_KEY_TESTS); - if (testProp != null) { - testProp = testProp.replaceAll("\"' ", ""); - this.tests = (String.valueOf(true) - .equalsIgnoreCase(testProp) - || "1".equals(testProp)); - return this.tests; + private void ensureTypeIsSet() { + if (currentEnvType == null) { + determineCurrentType(); } + } - // Check stacktrace for known frameworks. - String stacktrace = Throwables.getStackTraceAsString(new RuntimeException("")); - if (stacktrace.contains("org.junit") - || stacktrace.contains("org.testng")) { - this.tests = true; - return true; + private void determineCurrentType() { + for (EnvironmentType type : knownEnvTypes) { + if (type.enabled()) { + this.currentEnvType = type; + return; + } } + } - this.tests = false; - return false; + /** + * Verifies if the code currently runs under a unit testing framework. + * + * @see Tests + * @deprecated use {@code Environment.instance().is(Tests.type)} + */ + @Deprecated + public boolean isTests() { + return is(Tests.type()); } /** @@ -131,39 +233,69 @@ public boolean isTests() { *

This method is opposite to {@link #isTests()} * * @return {@code true} if the code runs in the production mode, {@code false} otherwise + * @see Production + * @deprecated use {@code Environment.instance().is(Production.type())} */ + @Deprecated public boolean isProduction() { return !isTests(); } + /** + * Restores the state from the instance created by {@link #createCopy()}. + * + *

Call this method when cleaning up tests that modify {@code Environment}. + */ + @VisibleForTesting + public void restoreFrom(Environment copy) { + // Make sure this matches the set of fields copied in the copy constructor. + this.knownEnvTypes = copy.knownEnvTypes; + this.currentEnvType = copy.currentEnvType; + } + + /** + * Forces the specified environment type to be the current one. + */ + @VisibleForTesting + public void setTo(EnvironmentType type) { + this.currentEnvType = checkNotNull(type); + } + /** * Turns the test mode on. * *

This method is opposite to {@link #setToProduction()}. + * + * @deprecated use {@link #setTo(EnvironmentType)} */ + @Deprecated @VisibleForTesting public void setToTests() { - this.tests = true; - System.setProperty(ENV_KEY_TESTS, String.valueOf(true)); + this.currentEnvType = Tests.type(); + Tests.enable(); } /** * Turns the production mode on. * *

This method is opposite to {@link #setToTests()}. + * + * @deprecated use {@link #setTo(EnvironmentType)} */ + @Deprecated @VisibleForTesting public void setToProduction() { - this.tests = false; - System.setProperty(ENV_KEY_TESTS, String.valueOf(false)); + this.currentEnvType = Production.type(); + Tests.clearTestingEnvVariable(); } /** - * Resets the instance and clears the {@link #ENV_KEY_TESTS} variable. + * Resets the instance and clears the {@link Tests#ENV_KEY_TESTS} variable. */ @VisibleForTesting public void reset() { - this.tests = null; - System.clearProperty(ENV_KEY_TESTS); + this.currentEnvType = null; + this.knownEnvTypes = BASE_TYPES; + Tests.clearTestingEnvVariable(); } } diff --git a/base/src/main/java/io/spine/base/EnvironmentType.java b/base/src/main/java/io/spine/base/EnvironmentType.java new file mode 100644 index 0000000000..561b34a230 --- /dev/null +++ b/base/src/main/java/io/spine/base/EnvironmentType.java @@ -0,0 +1,67 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.base; + +import com.google.common.base.Objects; + +/** + * A type of environment. + * + *

Some examples may be {@code STAGING} or {@code LOCAL} environments. + * + * @implNote developers are encouraged to make their environment types singletons, such + * that their API is consistent with the env types provided by the {@code base} library: + * {@link Production}, {@link Tests}. + */ +public abstract class EnvironmentType { + + /** + * Returns {@code true} if the underlying system is currently in this environment type. + * + *

For example, if an application is deployed to a fleet of virtual machines, an environment + * variable may be set for every virtual machine. Application developer may use this type of + * knowledge to determine the current environment. + */ + protected abstract boolean enabled(); + + /** + * @inheritDoc + * + *

By default, environments types are compared based on their classes. + */ + @Override + public boolean equals(Object obj) { + return this.getClass() + .equals(obj.getClass()); + } + + /** + * @inheritDoc + * + *

By default, adheres to the {@code equals} and {@code hashCode} contract, assuming that + * the implementation of the {@code equals} is the {@linkplain EnvironmentType#equals(Object) + * default one}. + */ + @Override + public int hashCode() { + return Objects.hashCode(getClass()); + } +} diff --git a/base/src/main/java/io/spine/base/Production.java b/base/src/main/java/io/spine/base/Production.java new file mode 100644 index 0000000000..9f3ea652e9 --- /dev/null +++ b/base/src/main/java/io/spine/base/Production.java @@ -0,0 +1,59 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.base; + +import com.google.errorprone.annotations.Immutable; + +/** + * A non-testing environment. + * + *

If the system is not in the {@link Tests} environment, it is in the production environment. + */ +@Immutable +public final class Production extends EnvironmentType { + + @Override + protected boolean enabled() { + return !Tests.type() + .enabled(); + } + + /** + * Returns the singleton instance. + */ + public static Production type() { + return Singleton.INSTANCE.production; + } + + private enum Singleton { + + INSTANCE; + + @SuppressWarnings({ + "NonSerializableFieldInSerializableClass", + "PMD.SingularField" /* this field cannot be local */}) + private final Production production; + + Singleton() { + this.production = new Production(); + } + } +} diff --git a/base/src/main/java/io/spine/base/Tests.java b/base/src/main/java/io/spine/base/Tests.java new file mode 100644 index 0000000000..2d55191c64 --- /dev/null +++ b/base/src/main/java/io/spine/base/Tests.java @@ -0,0 +1,123 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.base; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableList; +import com.google.errorprone.annotations.Immutable; + +import java.util.regex.Pattern; + +/** + * Testing environment. + * + *

Detected by checking stack trace for mentions of the known testing frameworks. + * + *

This option is mutually exclusive with {@link Production}, i.e. one of them is always enabled. + */ +@Immutable +@SuppressWarnings("AccessOfSystemProperties" /* is necessary for this class to function */) +public final class Tests extends EnvironmentType { + + /** + * The key name of the system property which tells if a code runs under a testing framework. + * + *

If your testing framework is not among the {@link #KNOWN_TESTING_FRAMEWORKS}, set this + * property to {@code true} before running tests. + */ + @VisibleForTesting + static final String ENV_KEY_TESTS = "io.spine.tests"; + + @SuppressWarnings("DuplicateStringLiteralInspection" /* Used in another context. */) + private static final ImmutableList KNOWN_TESTING_FRAMEWORKS = + ImmutableList.of("org.junit", "org.testng"); + + private static final Pattern TEST_PROP_PATTERN = Pattern.compile("\"' "); + + /** + * Verifies if the code currently runs under a unit testing framework. + * + *

The method returns {@code true} if the following packages are discovered + * in the stacktrace: + *

+ * + * @return {@code true} if the code runs under a testing framework, {@code false} otherwise + * @implNote In addition to checking the stack trace, this method checks the + * environment variable value. If you wish to simulate not being in tests, the + * variable must be set to {@code false} explicitly. If your framework is not + * among the {@linkplain #KNOWN_TESTING_FRAMEWORKS known ones}, make sure to set + * the system property explicitly. + */ + @Override + protected boolean enabled() { + String testProp = System.getProperty(ENV_KEY_TESTS); + if (testProp != null) { + testProp = TEST_PROP_PATTERN.matcher(testProp) + .replaceAll(""); + return String.valueOf(true) + .equalsIgnoreCase(testProp) || "1".equals(testProp); + } + + String stacktrace = Throwables.getStackTraceAsString(new RuntimeException("")); + return KNOWN_TESTING_FRAMEWORKS.stream() + .anyMatch(stacktrace::contains); + } + + /** + * Clears the {@linkplain #ENV_KEY_TESTS environment variable used for test detection}. + */ + static void clearTestingEnvVariable() { + System.clearProperty(ENV_KEY_TESTS); + } + + /** + * Sets the {@linkplain #ENV_KEY_TESTS environment variable} such that the system is brought to + * the testing environment type. + */ + static void enable() { + System.setProperty(ENV_KEY_TESTS, String.valueOf(true)); + } + + /** + * Returns the singleton instance of this class. + */ + public static Tests type() { + return Singleton.INSTANCE.tests; + } + + private enum Singleton { + + INSTANCE; + + @SuppressWarnings({ + "NonSerializableFieldInSerializableClass", + "PMD.SingularField" /* this field cannot be local */}) + private final Tests tests; + + Singleton() { + this.tests = new Tests(); + } + } +} diff --git a/base/src/test/java/io/spine/base/EnvironmentTest.java b/base/src/test/java/io/spine/base/EnvironmentTest.java index 8e1d905ddc..9e6422eb88 100644 --- a/base/src/test/java/io/spine/base/EnvironmentTest.java +++ b/base/src/test/java/io/spine/base/EnvironmentTest.java @@ -26,11 +26,13 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static com.google.common.truth.Truth.assertThat; +import static io.spine.base.Tests.ENV_KEY_TESTS; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; @DisplayName("Environment utility class should") @SuppressWarnings("AccessOfSystemProperties") @@ -75,60 +77,92 @@ void setUp() { void cleanUp() { Environment.instance() .reset(); + System.clearProperty(ENV_KEY_TESTS); } @Test @DisplayName("tell that we are under tests if env. variable set to true") void environmentVarTrue() { + Tests tests = Tests.type(); Environment.instance() - .setToTests(); + .setTo(tests); - assertTrue(environment.isTests()); - assertFalse(environment.isProduction()); + assertThat(environment.is(Tests.type())).isTrue(); } @Test @DisplayName("tell that we are under tests if env. variable set to 1") void environmentVar1() { - System.setProperty(Environment.ENV_KEY_TESTS, "1"); + System.setProperty(ENV_KEY_TESTS, "1"); - assertTrue(environment.isTests()); - assertFalse(environment.isProduction()); + assertThat(environment.is(Tests.type())).isTrue(); } @Test @DisplayName("tell that we are under tests if run under known framework") void underTestFramework() { // As we run this from under JUnit... - assertTrue(environment.isTests()); - assertFalse(environment.isProduction()); + assertThat(environment.is(Tests.type())).isTrue(); } @Test @DisplayName("tell that we are not under tests if env set to something else") - void environmentVarUknownValue() { - System.setProperty(Environment.ENV_KEY_TESTS, "neitherTrueNor1"); + void environmentVarUnknownValue() { + System.setProperty(ENV_KEY_TESTS, "neitherTrueNor1"); - assertFalse(environment.isTests()); - assertTrue(environment.isProduction()); + assertThat(environment.is(Production.type())).isTrue(); + } + + @Test + @DisplayName("tell that we are under tests when a deprecated method is used") + void underTestFrameworkDeprecated() { + @SuppressWarnings("deprecation") + boolean isTests = environment.isTests(); + assertThat(isTests).isTrue(); + } + + @Test + @DisplayName("tell that we are under tests if explicitly set to tests using a deprecated method") + @SuppressWarnings("deprecation") + void explicitlySetTrue() { + environment.setToTests(); + + assertThat(environment.is(Tests.type())).isTrue(); + } + + @Test + @DisplayName("tell that we are not under tests when a deprecated method is used") + void inProductionUsingDeprecatedMethod() { + System.setProperty(ENV_KEY_TESTS, "neitherTrueNor1"); + + @SuppressWarnings("deprecation") + boolean isProduction = environment.isProduction(); + assertThat(isProduction).isTrue(); } @Test @DisplayName("turn tests mode on") void turnTestsOn() { - environment.setToTests(); + environment.setTo(Tests.type()); - assertTrue(environment.isTests()); - assertFalse(environment.isProduction()); + assertThat(environment.is(Tests.type())).isTrue(); } @Test @DisplayName("turn production mode on") void turnProductionOn() { + environment.setTo(Production.type()); + + assertThat(environment.is(Production.type())).isTrue(); + } + + @Test + @DisplayName("turn production mode on using a deprecated method") + @SuppressWarnings("deprecation") + void turnProductionOnUsingDeprecatedMethod() { environment.setToProduction(); - assertFalse(environment.isTests()); - assertTrue(environment.isProduction()); + assertThat(environment.is(Production.type())).isTrue(); } @Test @@ -136,6 +170,136 @@ void turnProductionOn() { void clearOnReset() { environment.reset(); - assertNull(System.getProperty(Environment.ENV_KEY_TESTS)); + assertNull(System.getProperty(ENV_KEY_TESTS)); + } + + @Nested + @DisplayName("when assigning custom environment types") + class CustomEnvTypes { + + @Test + @DisplayName("allow to provide user defined environment types") + void provideCustomTypes() { + register(Staging.type(), Local.type()); + + // Now that `Environment` knows about `LOCAL`, it should use it as fallback. + assertThat(environment.is(Local.type())).isTrue(); + } + + @Test + @DisplayName("fallback to the `TESTS` environment") + void fallBack() { + Environment.instance() + .register(Travis.type()); + assertThat(environment.is(Travis.type())).isFalse(); + assertThat(environment.is(Tests.type())).isTrue(); + } + } + + @Test + @DisplayName("detect the current environment correctly using the `type` method") + void determineUsingType() { + assertThat(environment.type()).isSameInstanceAs(Tests.type()); + } + + @Test + @DisplayName("detect the current custom environment in presence of custom types") + void determineUsingTypeInPresenceOfCustom() { + register(Local.type()); + + assertThat(environment.type()).isSameInstanceAs(Local.type()); + } + + private static void register(EnvironmentType... types) { + for (EnvironmentType type : types) { + Environment.instance() + .register(type); + } + } + + static final class Local extends EnvironmentType { + + private Local() { + } + + @Override + public boolean enabled() { + // `LOCAL` is the default custom env type. It should be used as a fallback. + return true; + } + + public static Local type() { + return Singleton.INSTANCE.local; + } + + private enum Singleton { + + INSTANCE; + + @SuppressWarnings("NonSerializableFieldInSerializableClass") + private final Local local; + + Singleton() { + this.local = new Local(); + } + } + } + + static final class Staging extends EnvironmentType { + + static final String STAGING_ENV_TYPE_KEY = "io.spine.base.EnvironmentTest.is_staging"; + + private Staging() { + } + + public static Staging type() { + return Singleton.INSTANCE.staging; + } + + @Override + public boolean enabled() { + return String.valueOf(true) + .equalsIgnoreCase(System.getProperty(STAGING_ENV_TYPE_KEY)); + } + + private enum Singleton { + + INSTANCE; + + @SuppressWarnings("NonSerializableFieldInSerializableClass") + private final Staging staging; + + Singleton() { + this.staging = new Staging(); + } + } + } + + @SuppressWarnings("unused" /* The only variant is used. */) + static final class Travis extends EnvironmentType { + + private Travis() { + } + + @Override + public boolean enabled() { + return false; + } + + public static Travis type() { + return Singleton.INSTANCE.travis; + } + + private enum Singleton { + + INSTANCE; + + @SuppressWarnings("NonSerializableFieldInSerializableClass") + private final Travis travis; + + Singleton() { + this.travis = new Travis(); + } + } } } diff --git a/base/src/test/java/io/spine/base/environment/EnvironmentTest.java b/base/src/test/java/io/spine/base/environment/EnvironmentTest.java new file mode 100644 index 0000000000..299e6d4ad9 --- /dev/null +++ b/base/src/test/java/io/spine/base/environment/EnvironmentTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.base.environment; + +import io.spine.base.Environment; +import io.spine.base.Tests; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static com.google.common.truth.Truth.assertThat; + +@DisplayName("Environment should") +class EnvironmentTest { + + @BeforeEach + void reset() { + Environment.instance() + .reset(); + } + + @Test + @DisplayName("allow a custom user type") + void allowCustomType() { + Environment.instance() + .register(Staging.type()); + + Staging.enable(); + assertThat(Environment.instance() + .is(Staging.type())).isTrue(); + } + + @Test + @DisplayName("fallback to the default type") + void fallbackToCustomType() { + Environment.instance().register(Staging.type()); + + Staging.disable(); + + assertThat(Environment.instance().is(Tests.type())).isTrue(); + } + +} diff --git a/base/src/test/java/io/spine/base/environment/Staging.java b/base/src/test/java/io/spine/base/environment/Staging.java new file mode 100644 index 0000000000..f436b35cdb --- /dev/null +++ b/base/src/test/java/io/spine/base/environment/Staging.java @@ -0,0 +1,64 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.base.environment; + +import io.spine.base.EnvironmentType; + +/** + * An environment type that mimics production but receives less traffic and is suitable for testing + * out new features. + * + *

This implementations relies on a static {@code boolean} flag for detection. + */ +public final class Staging extends EnvironmentType { + + @Override + protected boolean enabled() { + return Singleton.INSTANCE.enabled; + } + + public static Staging type() { + return Singleton.INSTANCE.staging; + } + + /** + * Brings the underlying system into the staging environment. + */ + static void enable() { + Singleton.INSTANCE.enabled = true; + } + + /** + * Brings the underlying system out of the staging environment. + */ + static void disable() { + Singleton.INSTANCE.enabled = false; + } + + public enum Singleton { + + INSTANCE; + + @SuppressWarnings("NonSerializableFieldInSerializableClass") + private final Staging staging = new Staging(); + private boolean enabled; + } +} diff --git a/base/src/test/java/io/spine/base/environment/package-info.java b/base/src/test/java/io/spine/base/environment/package-info.java new file mode 100644 index 0000000000..61e9fdfd99 --- /dev/null +++ b/base/src/test/java/io/spine/base/environment/package-info.java @@ -0,0 +1,32 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * This package contains tests for {@link io.spine.base.Environment} with custom + * {@linkplain io.spine.base.EnvironmentType environment types} using them how they would be used + * from a client API, i.e. from a package different from {@code io.spine.base}. + */ +@ParametersAreNonnullByDefault +@CheckReturnValue +package io.spine.base.environment; + +import com.google.errorprone.annotations.CheckReturnValue; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/license-report.md b/license-report.md index 8720bb716e..4bf6107acc 100644 --- a/license-report.md +++ b/license-report.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine:spine-base:1.5.12` +# Dependencies of `io.spine:spine-base:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -328,12 +328,12 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:52 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:28 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-errorprone-checks:1.5.12` +# Dependencies of `io.spine.tools:spine-errorprone-checks:1.5.13` ## Runtime 1. **Group:** com.github.ben-manes.caffeine **Name:** caffeine **Version:** 2.7.0 @@ -773,12 +773,12 @@ This report was generated on **Tue May 26 19:54:52 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:53 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:28 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-javadoc-filter:1.5.12` +# Dependencies of `io.spine.tools:spine-javadoc-filter:1.5.13` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1156,12 +1156,12 @@ This report was generated on **Tue May 26 19:54:53 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:54 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:29 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-javadoc-prettifier:1.5.12` +# Dependencies of `io.spine.tools:spine-javadoc-prettifier:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -1521,12 +1521,12 @@ This report was generated on **Tue May 26 19:54:54 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:54 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:29 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-model-compiler:1.5.12` +# Dependencies of `io.spine.tools:spine-model-compiler:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -1902,12 +1902,12 @@ This report was generated on **Tue May 26 19:54:54 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:55 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:30 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-mute-logging:1.5.12` +# Dependencies of `io.spine.tools:spine-mute-logging:1.5.13` ## Runtime 1. **Group:** com.google.auto.value **Name:** auto-value-annotations **Version:** 1.6.3 @@ -2281,12 +2281,12 @@ This report was generated on **Tue May 26 19:54:55 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:55 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:30 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-plugin-base:1.5.12` +# Dependencies of `io.spine.tools:spine-plugin-base:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -2646,12 +2646,12 @@ This report was generated on **Tue May 26 19:54:55 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:56 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:30 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-plugin-testlib:1.5.12` +# Dependencies of `io.spine.tools:spine-plugin-testlib:1.5.13` ## Runtime 1. **Group:** com.google.auto.value **Name:** auto-value-annotations **Version:** 1.6.3 @@ -3065,12 +3065,12 @@ This report was generated on **Tue May 26 19:54:56 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:56 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:31 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-proto-dart-plugin:1.5.12` +# Dependencies of `io.spine.tools:spine-proto-dart-plugin:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -3430,12 +3430,12 @@ This report was generated on **Tue May 26 19:54:56 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:56 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:31 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-proto-js-plugin:1.5.12` +# Dependencies of `io.spine.tools:spine-proto-js-plugin:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -3795,12 +3795,12 @@ This report was generated on **Tue May 26 19:54:56 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:57 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:31 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-protoc-api:1.5.12` +# Dependencies of `io.spine.tools:spine-protoc-api:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -4120,12 +4120,12 @@ This report was generated on **Tue May 26 19:54:57 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:57 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:31 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-protoc-plugin:1.5.12` +# Dependencies of `io.spine.tools:spine-protoc-plugin:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -4453,12 +4453,12 @@ This report was generated on **Tue May 26 19:54:57 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:58 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:32 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testlib:1.5.12` +# Dependencies of `io.spine:spine-testlib:1.5.13` ## Runtime 1. **Group:** com.google.auto.value **Name:** auto-value-annotations **Version:** 1.6.3 @@ -4832,12 +4832,12 @@ This report was generated on **Tue May 26 19:54:58 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:58 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:32 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-tool-base:1.5.12` +# Dependencies of `io.spine.tools:spine-tool-base:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -5165,12 +5165,12 @@ This report was generated on **Tue May 26 19:54:58 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:58 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Thu May 28 12:20:32 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-validation-generator:1.5.12` +# Dependencies of `io.spine.tools:spine-validation-generator:1.5.13` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -5498,4 +5498,4 @@ This report was generated on **Tue May 26 19:54:58 EEST 2020** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue May 26 19:54:59 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file +This report was generated on **Thu May 28 12:20:33 EEST 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/pom.xml b/pom.xml index f780e4d77d..9774fdb358 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject. io.spine spine-base -1.5.12 +1.5.13 2015 @@ -154,7 +154,7 @@ all modules and does not describe the project structure per-subproject. io.spine.tools spine-protoc-plugin - 1.5.12 + 1.5.13 test diff --git a/version.gradle.kts b/version.gradle.kts index 211c55daa5..8e3a0f75fd 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -25,7 +25,7 @@ * as we want to manage the versions in a single source. */ -val SPINE_VERSION = "1.5.12" +val SPINE_VERSION = "1.5.13" project.extra.apply { this["spineVersion"] = SPINE_VERSION