Gradle: support configuring tests, fix test deobfuscation

This commit is contained in:
Alexey Andreev 2023-01-25 10:55:38 +01:00
parent 0629e6af31
commit e3da484f79
32 changed files with 394 additions and 33 deletions

View File

@ -56,7 +56,7 @@ val generateLibJs by tasks.register<JavaExec>("generateLibJs") {
mainClass.set("org.teavm.tooling.deobfuscate.js.Compiler")
args(
"org.teavm.tooling.deobfuscate.js.DeobfuscatorLib",
"\$teavm_deobfuscator",
"deobfuscator",
File(buildDir, "teavm-lib").absolutePath,
"deobfuscator-lib.js",
)

View File

@ -21,17 +21,23 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import javax.inject.Inject;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Provider;
import org.teavm.gradle.api.TeaVMBaseExtension;
import org.teavm.gradle.api.TeaVMLibraries;
import org.teavm.gradle.api.TeaVMTests;
import org.teavm.gradle.config.ArtifactCoordinates;
public class TeaVMBaseExtensionImpl implements TeaVMBaseExtension {
class TeaVMBaseExtensionImpl implements TeaVMBaseExtension {
protected Project project;
private Provider<Properties> properties;
private TeaVMTestsImpl tests;
@Inject
public TeaVMBaseExtensionImpl(Project project) {
TeaVMBaseExtensionImpl(Project project, ObjectFactory objectFactory) {
this.project = project;
properties = project.provider(() -> {
var result = new Properties();
@ -44,6 +50,8 @@ public class TeaVMBaseExtensionImpl implements TeaVMBaseExtension {
}
return result;
});
tests = new TeaVMTestsImpl(objectFactory);
tests.configure(this);
}
private void append(Properties target, File source) throws IOException {
@ -102,4 +110,14 @@ public class TeaVMBaseExtensionImpl implements TeaVMBaseExtension {
return project.getProviders().gradleProperty("teavm." + name).getOrElse(null);
});
}
@Override
public TeaVMTests getTests() {
return tests;
}
@Override
public void tests(Action<TeaVMTests> config) {
config.execute(tests);
}
}

View File

@ -16,21 +16,26 @@
package org.teavm.gradle;
import java.io.File;
import javax.inject.Inject;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.model.ObjectFactory;
import org.teavm.gradle.api.OptimizationLevel;
import org.teavm.gradle.api.TeaVMCConfiguration;
import org.teavm.gradle.api.TeaVMCommonConfiguration;
import org.teavm.gradle.api.TeaVMExtension;
import org.teavm.gradle.api.TeaVMJSConfiguration;
import org.teavm.gradle.api.TeaVMWasiConfiguration;
import org.teavm.gradle.api.TeaVMWasmConfiguration;
public class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtension {
class TeaVMExtensionImpl extends TeaVMBaseExtensionImpl implements TeaVMExtension {
private TeaVMJSConfiguration js;
private TeaVMWasmConfiguration wasm;
private TeaVMWasiConfiguration wasi;
private TeaVMCConfiguration c;
private TeaVMCommonConfiguration all;
@Inject
public TeaVMExtensionImpl(Project project, ObjectFactory objectFactory) {
super(project);
TeaVMExtensionImpl(Project project, ObjectFactory objectFactory) {
super(project, objectFactory);
js = objectFactory.newInstance(TeaVMJSConfiguration.class);
wasm = objectFactory.newInstance(TeaVMWasmConfiguration.class);
wasi = objectFactory.newInstance(TeaVMWasiConfiguration.class);

View File

@ -0,0 +1,55 @@
/*
* Copyright 2023 Alexey Andreev.
*
* 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 org.teavm.gradle;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Property;
import org.teavm.gradle.api.TeaVMJSTests;
import org.teavm.gradle.api.TeaVMWebTestRunner;
class TeaVMJSTestsImpl implements TeaVMJSTests {
private Property<Boolean> enabled;
private Property<TeaVMWebTestRunner> runner;
private Property<Boolean> decodeStack;
TeaVMJSTestsImpl(ObjectFactory objectFactory) {
enabled = objectFactory.property(Boolean.class);
runner = objectFactory.property(TeaVMWebTestRunner.class);
decodeStack = objectFactory.property(Boolean.class);
}
@Override
public Property<Boolean> getEnabled() {
return enabled;
}
@Override
public Property<TeaVMWebTestRunner> getRunner() {
return runner;
}
@Override
public Property<Boolean> getDecodeStack() {
return decodeStack;
}
void configure(TeaVMBaseExtensionImpl extension) {
enabled.convention(extension.property("tests.js.enabled").map(Boolean::parseBoolean).orElse(false));
runner.convention(extension.property("tests.js.runner").map(s -> TeaVMWebTestRunner.valueOf(s.toUpperCase()))
.orElse(TeaVMWebTestRunner.CHROME));
decodeStack.convention(extension.property("tests.js.decodeStack").map(Boolean::parseBoolean).orElse(true));
}
}

View File

@ -20,6 +20,7 @@ import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.plugins.JavaPlugin;
import org.teavm.gradle.api.TeaVMBaseExtension;
import org.teavm.gradle.config.ArtifactCoordinates;
public class TeaVMLibraryPlugin implements Plugin<Project> {
@ -32,9 +33,10 @@ public class TeaVMLibraryPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
var extension = objectFactory.newInstance(TeaVMBaseExtensionImpl.class);
var extension = new TeaVMBaseExtensionImpl(project, objectFactory);
project.getExtensions().add(TeaVMBaseExtension.class, TeaVMPlugin.EXTENSION_NAME, extension);
project.getDependencies().add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, ArtifactCoordinates.JUNIT);
project.getDependencies().add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, ArtifactCoordinates.CLASSLIB);
project.getDependencies().add(JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME, ArtifactCoordinates.CLASSLIB);
TeaVMTestConfigurator.configure(project, extension.getTests());
}
}

View File

@ -27,7 +27,14 @@ import org.gradle.api.plugins.WarPlugin;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.bundling.War;
import org.teavm.gradle.api.TeaVMConfiguration;
import org.teavm.gradle.api.TeaVMExtension;
import org.teavm.gradle.config.ArtifactCoordinates;
import org.teavm.gradle.tasks.GenerateCTask;
import org.teavm.gradle.tasks.GenerateJavaScriptTask;
import org.teavm.gradle.tasks.GenerateWasiTask;
import org.teavm.gradle.tasks.GenerateWasmTask;
import org.teavm.gradle.tasks.TeaVMTask;
public class TeaVMPlugin implements Plugin<Project> {
public static final String EXTENSION_NAME = "teavm";
@ -53,10 +60,11 @@ public class TeaVMPlugin implements Plugin<Project> {
registerTasks(project);
addDependencies(project);
setupWarTask(project);
TeaVMTestConfigurator.configure(project, project.getExtensions().getByType(TeaVMExtension.class).getTests());
}
private void registerExtension(Project project) {
var extension = objectFactory.newInstance(TeaVMExtensionImpl.class);
var extension = new TeaVMExtensionImpl(project, objectFactory);
project.getExtensions().add(TeaVMExtension.class, EXTENSION_NAME, extension);
}
@ -83,6 +91,7 @@ public class TeaVMPlugin implements Plugin<Project> {
sourceSet.setCompileClasspath(sourceSet.getCompileClasspath().plus(main)
.plus(project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME)));
sourceSet.java(java -> { });
project.getDependencies().add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, sourceSet.getOutput());
}
private void registerTasks(Project project) {
@ -145,6 +154,7 @@ public class TeaVMPlugin implements Plugin<Project> {
private void addDependencies(Project project) {
project.getDependencies().add(CONFIGURATION_NAME, ArtifactCoordinates.CLASSLIB);
project.getDependencies().add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, ArtifactCoordinates.JUNIT);
project.getDependencies().add(JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME, ArtifactCoordinates.CLASSLIB);
}
private void setupWarTask(Project project) {

View File

@ -0,0 +1,60 @@
/*
* Copyright 2023 Alexey Andreev.
*
* 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 org.teavm.gradle;
import java.io.File;
import org.gradle.api.Project;
import org.gradle.api.tasks.testing.Test;
import org.teavm.gradle.api.TeaVMTests;
import org.teavm.gradle.api.TeaVMWebTestRunner;
class TeaVMTestConfigurator {
private TeaVMTestConfigurator() {
}
static void configure(Project project, TeaVMTests tests) {
project.getTasks().withType(Test.class).configureEach(test -> {
test.getSystemProperties().putIfAbsent("teavm.junit.target",
new File(project.getBuildDir(), "tests/teavm"));
test.getSystemProperties().putIfAbsent("teavm.junit.threads", "1");
test.getSystemProperties().putIfAbsent("teavm.junit.js.enabled",
tests.getJs().getEnabled().get());
test.getSystemProperties().putIfAbsent("teavm.junit.js.runner",
tests.getJs().getRunner().map(TeaVMTestConfigurator::runnerToString).get());
test.getSystemProperties().putIfAbsent("teavm.junit.js.decodeStack",
tests.getJs().getDecodeStack().get());
test.getSystemProperties().putIfAbsent("teavm.junit.wasm.enabled",
tests.getWasm().getEnabled().get());
test.getSystemProperties().putIfAbsent("teavm.junit.wasm.runner",
tests.getWasm().getRunner().map(TeaVMTestConfigurator::runnerToString).get());
});
}
private static String runnerToString(TeaVMWebTestRunner runner) {
switch (runner) {
case CHROME:
return "browser-chrome";
case FIREFOX:
return "browser-firefox";
case CUSTOM_BROWSER:
return "browser";
default:
return "none";
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2023 Alexey Andreev.
*
* 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 org.teavm.gradle;
import org.gradle.api.Action;
import org.gradle.api.model.ObjectFactory;
import org.teavm.gradle.api.TeaVMJSTests;
import org.teavm.gradle.api.TeaVMTests;
import org.teavm.gradle.api.TeaVMWasmTests;
class TeaVMTestsImpl implements TeaVMTests {
private TeaVMJSTestsImpl js;
private TeaVMWasmTestsImpl wasm;
TeaVMTestsImpl(ObjectFactory objectFactory) {
js = new TeaVMJSTestsImpl(objectFactory);
wasm = new TeaVMWasmTestsImpl(objectFactory);
}
@Override
public TeaVMJSTests getJs() {
return js;
}
@Override
public void js(Action<TeaVMJSTests> config) {
config.execute(js);
}
@Override
public TeaVMWasmTests getWasm() {
return wasm;
}
@Override
public void wasm(Action<TeaVMWasmTests> config) {
config.execute(wasm);
}
void configure(TeaVMBaseExtensionImpl extension) {
js.configure(extension);
wasm.configure(extension);
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2023 Alexey Andreev.
*
* 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 org.teavm.gradle;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Property;
import org.teavm.gradle.api.TeaVMWasmTests;
import org.teavm.gradle.api.TeaVMWebTestRunner;
class TeaVMWasmTestsImpl implements TeaVMWasmTests {
private Property<Boolean> enabled;
private Property<TeaVMWebTestRunner> runner;
TeaVMWasmTestsImpl(ObjectFactory objectFactory) {
enabled = objectFactory.property(Boolean.class);
runner = objectFactory.property(TeaVMWebTestRunner.class);
}
@Override
public Property<Boolean> getEnabled() {
return enabled;
}
@Override
public Property<TeaVMWebTestRunner> getRunner() {
return runner;
}
void configure(TeaVMBaseExtensionImpl extension) {
enabled.convention(extension.property("tests.wasm.enabled").map(Boolean::parseBoolean).orElse(false));
runner.convention(extension.property("tests.wasm.runner").map(s -> TeaVMWebTestRunner.valueOf(s.toUpperCase()))
.orElse(TeaVMWebTestRunner.CHROME));
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
public enum OptimizationLevel {
NONE,

View File

@ -13,12 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.Action;
import org.gradle.api.provider.Provider;
public interface TeaVMBaseExtension {
TeaVMLibraries getLibs();
Provider<String> property(String name);
TeaVMTests getTests();
void tests(Action<TeaVMTests> config);
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.provider.Property;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import java.io.File;
import org.gradle.api.provider.ListProperty;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.provider.Property;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.Action;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.provider.Property;

View File

@ -0,0 +1,26 @@
/*
* Copyright 2023 Alexey Andreev.
*
* 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 org.teavm.gradle.api;
import org.gradle.api.provider.Property;
public interface TeaVMJSTests {
Property<Boolean> getEnabled();
Property<TeaVMWebTestRunner> getRunner();
Property<Boolean> getDecodeStack();
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.artifacts.Dependency;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.provider.Property;

View File

@ -0,0 +1,28 @@
/*
* Copyright 2023 Alexey Andreev.
*
* 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 org.teavm.gradle.api;
import org.gradle.api.Action;
public interface TeaVMTests {
TeaVMJSTests getJs();
void js(Action<TeaVMJSTests> config);
TeaVMWasmTests getWasm();
void wasm(Action<TeaVMWasmTests> config);
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
public interface TeaVMWasiConfiguration extends TeaVMWasmBaseConfiguration, TeaVMConfiguration {
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.provider.Property;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
public interface TeaVMWasmConfiguration extends TeaVMWebConfiguration, TeaVMWasmBaseConfiguration {
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2023 Alexey Andreev.
*
* 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 org.teavm.gradle.api;
import org.gradle.api.provider.Property;
public interface TeaVMWasmTests {
Property<Boolean> getEnabled();
Property<TeaVMWebTestRunner> getRunner();
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.api;
import org.gradle.api.provider.Property;

View File

@ -0,0 +1,23 @@
/*
* Copyright 2023 Alexey Andreev.
*
* 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 org.teavm.gradle.api;
public enum TeaVMWebTestRunner {
CUSTOM_BROWSER,
CHROME,
FIREFOX,
NONE
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.tasks;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.tasks;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.tasks;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.tasks;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 Alexey Andreev.
* Copyright 2023 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.tasks;
import org.gradle.api.logging.Logger;
import org.teavm.tooling.TeaVMToolLog;
public class GradleTeaVMToolLog implements TeaVMToolLog {
class GradleTeaVMToolLog implements TeaVMToolLog {
private Logger log;
public GradleTeaVMToolLog(Logger log) {
GradleTeaVMToolLog(Logger log) {
this.log = log;
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.gradle;
package org.teavm.gradle.tasks;
import java.io.File;
import java.io.IOException;
@ -33,6 +33,7 @@ import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import org.teavm.gradle.api.OptimizationLevel;
import org.teavm.tooling.TeaVMProblemRenderer;
import org.teavm.tooling.builder.BuildException;
import org.teavm.tooling.builder.BuildStrategy;