diff --git a/lib/src/main/java/com/diffplug/spotless/sql/HibernateStep.java b/lib/src/main/java/com/diffplug/spotless/sql/HibernateStep.java new file mode 100644 index 0000000000..cc181acdfd --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/sql/HibernateStep.java @@ -0,0 +1,86 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.sql; + +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.Objects; + +import com.diffplug.spotless.FormatterFunc; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.JarState; +import com.diffplug.spotless.Provisioner; + +/** Wraps up [BasicFormatterImpl](https://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/engine/jdbc/internal/BasicFormatterImpl.html) as a FormatterStep. */ +public class HibernateStep { + // prevent direct instantiation + private HibernateStep() {} + + private static final String DEFAULT_VERSION = "5.2.12.Final"; + static final String NAME = "hibernateSql"; + static final String MAVEN_COORDINATE = "org.hibernate:hibernate-core:"; + + public enum Kind { + BASIC("org.hibernate.engine.jdbc.internal.BasicFormatterImpl"), DDL("org.hibernate.engine.jdbc.internal.DDLFormatterImpl"); + + private final String className; + + Kind(String className) { + this.className = className; + } + } + + public static FormatterStep create(Provisioner provisioner, Kind kind) { + return create(defaultVersion(), provisioner, kind); + } + + public static FormatterStep create(String version, Provisioner provisioner, Kind kind) { + Objects.requireNonNull(version, "version"); + Objects.requireNonNull(provisioner, "provisioner"); + return FormatterStep.createLazy(NAME, + () -> new State(version, provisioner, kind.className), + State::createFormat); + } + + public static String defaultVersion() { + return DEFAULT_VERSION; + } + + static final class State implements Serializable { + private static final long serialVersionUID = 1L; + + final String formatterClassname; + final JarState jarState; + + State(String version, Provisioner provisioner, String formatterClassname) throws IOException { + this.jarState = JarState.from(MAVEN_COORDINATE + version, provisioner); + this.formatterClassname = formatterClassname; + } + + FormatterFunc createFormat() throws Exception { + ClassLoader classLoader = jarState.getClassLoader(); + + // this is how we actually do a format + Class formatterClazz = classLoader.loadClass(formatterClassname); + Object formatter = formatterClazz.newInstance(); + Method formatMethod = formatterClazz.getMethod("format", String.class); + return input -> { + return (String) formatMethod.invoke(formatter, input); + }; + } + } +} diff --git a/lib/src/main/java/com/diffplug/spotless/sql/package-info.java b/lib/src/main/java/com/diffplug/spotless/sql/package-info.java new file mode 100644 index 0000000000..77088bf36c --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/sql/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@ReturnValuesAreNonnullByDefault +package com.diffplug.spotless.sql; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.diffplug.spotless.annotations.ReturnValuesAreNonnullByDefault; diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java index 355c1a0075..15877034d9 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtension.java @@ -113,6 +113,11 @@ public void groovyGradle(Action closure) { configure(GroovyGradleExtension.NAME, GroovyGradleExtension.class, closure); } + /** Configures the special sql-specific extension for SQL files. */ + public void sql(Action closure) { + configure(SqlExtension.NAME, SqlExtension.class, closure); + } + /** Configures a custom extension. */ public void format(String name, Action closure) { requireNonNull(name, "name"); diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SqlExtension.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SqlExtension.java new file mode 100644 index 0000000000..59cf88c176 --- /dev/null +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SqlExtension.java @@ -0,0 +1,49 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.spotless; + +import com.diffplug.spotless.sql.HibernateStep; + +public class SqlExtension extends FormatExtension { + static final String NAME = "sql"; + + public SqlExtension(SpotlessExtension rootExtension) { + super(rootExtension); + } + + public void hibernateSql() { + hibernateSql(HibernateStep.defaultVersion()); + } + + public void hibernateSql(String version) { + hibernate(version, HibernateStep.Kind.BASIC); + } + + public void hibernateDdl() { + hibernateDdl(HibernateStep.defaultVersion()); + } + + public void hibernateDdl(String version) { + hibernate(version, HibernateStep.Kind.DDL); + } + + private void hibernate(String version, HibernateStep.Kind kind) { + this.addStep(HibernateStep.create( + version, + GradleProvisioner.fromProject(getProject()), + kind)); + } +} diff --git a/testlib/src/test/java/com/diffplug/spotless/sql/HibernateStepTest.java b/testlib/src/test/java/com/diffplug/spotless/sql/HibernateStepTest.java new file mode 100644 index 0000000000..0643db0e96 --- /dev/null +++ b/testlib/src/test/java/com/diffplug/spotless/sql/HibernateStepTest.java @@ -0,0 +1,69 @@ +/* + * Copyright 2016 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.spotless.sql; + +import java.io.IOException; + +import org.junit.Test; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.ResourceHarness; +import com.diffplug.spotless.SerializableEqualityTester; +import com.diffplug.spotless.SerializableEqualityTester.API; +import com.diffplug.spotless.StepHarness; +import com.diffplug.spotless.TestProvisioner; +import com.diffplug.spotless.sql.HibernateStep.Kind; + +public class HibernateStepTest extends ResourceHarness { + @Test + public void behaviorBasic() throws Exception { + FormatterStep step = HibernateStep.create(TestProvisioner.mavenCentral(), HibernateStep.Kind.BASIC); + StepHarness.forStep(step) + .testResource("sql/hibernate/basic.dirty", "sql/hibernate/basic.clean"); + } + + @Test + public void behaviorDdl() throws Exception { + FormatterStep step = HibernateStep.create(TestProvisioner.mavenCentral(), HibernateStep.Kind.DDL); + StepHarness.forStep(step) + .testResource("sql/hibernate/ddl.dirty", "sql/hibernate/ddl.clean"); + } + + @Test + public void equality() throws Exception { + new SerializableEqualityTester() { + String version = HibernateStep.defaultVersion(); + Kind kind = Kind.BASIC; + + @Override + protected void setupTest(API api) throws IOException { + // same version == same + api.areDifferentThan(); + // change the version, and it's different + version = "5.2.11.Final"; + api.areDifferentThan(); + // change the kind, and it's different + kind = Kind.DDL; + api.areDifferentThan(); + } + + @Override + protected FormatterStep create() { + return HibernateStep.create(version, TestProvisioner.mavenCentral(), kind); + } + }.testEquals(); + } +} diff --git a/testlib/src/test/resources/sql/hibernate/basic.clean b/testlib/src/test/resources/sql/hibernate/basic.clean new file mode 100644 index 0000000000..ee563c9651 --- /dev/null +++ b/testlib/src/test/resources/sql/hibernate/basic.clean @@ -0,0 +1,7 @@ +ALTER TABLE userinfo ALTER COLUMN id + drop DEFAULT; +ALTER TABLE userinfo + drop constraint userinfo_pkey cascade; +alter table userinfo + add primary key (user_id); +ALTER TABLE userinfo DROP COLUMN id \ No newline at end of file diff --git a/testlib/src/test/resources/sql/hibernate/basic.dirty b/testlib/src/test/resources/sql/hibernate/basic.dirty new file mode 100644 index 0000000000..905922a574 --- /dev/null +++ b/testlib/src/test/resources/sql/hibernate/basic.dirty @@ -0,0 +1,4 @@ +ALTER TABLE userinfo ALTER COLUMN id drop DEFAULT; +ALTER TABLE userinfo drop constraint userinfo_pkey cascade; +alter table userinfo add primary key (user_id); +ALTER TABLE userinfo DROP COLUMN id; diff --git a/testlib/src/test/resources/sql/hibernate/ddl.clean b/testlib/src/test/resources/sql/hibernate/ddl.clean new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testlib/src/test/resources/sql/hibernate/ddl.dirty b/testlib/src/test/resources/sql/hibernate/ddl.dirty new file mode 100644 index 0000000000..905922a574 --- /dev/null +++ b/testlib/src/test/resources/sql/hibernate/ddl.dirty @@ -0,0 +1,4 @@ +ALTER TABLE userinfo ALTER COLUMN id drop DEFAULT; +ALTER TABLE userinfo drop constraint userinfo_pkey cascade; +alter table userinfo add primary key (user_id); +ALTER TABLE userinfo DROP COLUMN id;