Skip to content

Commit 1e9e66f

Browse files
committed
All wiring KMP application plugin to kmpApplication block instance without applying plugin
1 parent bc91512 commit 1e9e66f

File tree

1 file changed

+150
-150
lines changed

1 file changed

+150
-150
lines changed

unified-prototype/unified-plugin/plugin-kmp/src/main/java/org/gradle/api/experimental/kmp/StandaloneKmpApplicationPlugin.java

Lines changed: 150 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -20,191 +20,191 @@
2020
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest;
2121
import org.apache.commons.text.WordUtils;
2222

23-
import java.util.logging.Logger;
24-
2523
/**
2624
* Creates a declarative {@link KmpApplication} DSL model, applies the official KMP plugin,
2725
* and links the declarative model to the official plugin.
2826
*/
2927
@SuppressWarnings({"UnstableApiUsage", "CodeBlock2Expr"})
3028
public abstract class StandaloneKmpApplicationPlugin implements Plugin<Project> {
31-
private static final Logger LOGGER = Logger.getLogger(StandaloneKmpApplicationPlugin.class.getName());
32-
3329
public static final String KOTLIN_APPLICATION = "kotlinApplication";
3430

3531
@SoftwareType(name = KOTLIN_APPLICATION, modelPublicType = KmpApplication.class)
3632
public abstract KmpApplication getKmpApplication();
3733

3834
@Override
3935
public void apply(Project project) {
40-
KmpApplication dslModel = createDslModel(project);
36+
PluginWiring.wirePlugin(project, getKmpApplication());
37+
}
4138

42-
project.afterEvaluate(p -> linkDslModelToPlugin(p, dslModel));
39+
public static final class PluginWiring {
40+
private PluginWiring() { /* not instantiable */ }
4341

44-
// Apply the official KMP plugin
45-
project.getPlugins().apply("org.jetbrains.kotlin.multiplatform");
46-
project.getPlugins().apply(CliApplicationConventionsPlugin.class);
42+
public static void wirePlugin(Project project, KmpApplication initialDslModel) {
43+
KmpApplication dslModel = setupDslModel(project, initialDslModel);
4744

48-
linkDslModelToPluginLazy(project, dslModel);
49-
}
45+
project.afterEvaluate(p -> linkDslModelToPlugin(p, dslModel));
5046

51-
/**
52-
* Performs linking actions that must occur within an afterEvaluate block.
53-
*/
54-
private void linkDslModelToPlugin(Project project, KmpApplication dslModel) {
55-
KotlinMultiplatformExtension kotlin = project.getExtensions().getByType(KotlinMultiplatformExtension.class);
56-
57-
// Link common properties
58-
kotlin.getSourceSets().configureEach(sourceSet -> {
59-
sourceSet.languageSettings(languageSettings -> {
60-
ifPresent(dslModel.getLanguageVersion(), languageSettings::setLanguageVersion);
61-
ifPresent(dslModel.getLanguageVersion(), languageSettings::setApiVersion);
62-
});
63-
});
64-
65-
// Link Native targets
66-
dslModel.getTargetsContainer().withType(KmpApplicationNativeTarget.class).all(target -> {
67-
kotlin.macosArm64(target.getName(), kotlinTarget -> {
68-
kotlinTarget.binaries(nativeBinaries -> {
69-
nativeBinaries.executable(executable -> {
70-
executable.entryPoint(target.getEntryPoint().get());
71-
TaskProvider<AbstractExecTask<?>> runTask = executable.getRunTaskProvider();
72-
if (runTask != null) {
73-
dslModel.getRunTasks().add(runTask);
74-
}
75-
});
47+
// Apply the official KMP plugin
48+
project.getPlugins().apply("org.jetbrains.kotlin.multiplatform");
49+
project.getPlugins().apply(CliApplicationConventionsPlugin.class);
50+
51+
linkDslModelToPluginLazy(project, dslModel);
52+
}
53+
54+
private static KmpApplication setupDslModel(Project project, KmpApplication dslModel) {
55+
// In order for function extraction from the DependencyCollector on the library deps to work, configurations must exist
56+
// Matching the names of the getters on LibraryDependencies
57+
project.getConfigurations().dependencyScope("implementation").get();
58+
project.getConfigurations().dependencyScope("compileOnly").get();
59+
project.getConfigurations().dependencyScope("runtimeOnly").get();
60+
61+
// Set conventional custom test suit locations as src/<SUITE_NAME>
62+
dslModel.getTargetsContainer().withType(KmpApplicationJvmTarget.class).all(target -> {
63+
target.getTesting().getTestSuites().forEach((name, testSuite) -> {
64+
Directory srcRoot = project.getLayout().getProjectDirectory().dir("src/jvm" + WordUtils.capitalize(name));
65+
testSuite.getSourceRoot().convention(srcRoot);
7666
});
7767
});
78-
});
7968

80-
// Add common JVM testing dependencies if the JVM target is a part of this build
81-
if (null != kotlin.getSourceSets().findByName("jvmTest")) {
82-
KotlinPluginSupport.linkSourceSetToDependencies(project, kotlin.getSourceSets().getByName("jvmTest"), dslModel.getTargetsContainer().getByName("jvm").getTesting().getDependencies());
83-
project.getTasks().withType(KotlinJvmTest.class).forEach(Test::useJUnitPlatform);
69+
return dslModel;
8470
}
8571

86-
// Create all custom JVM test suites
87-
dslModel.getTargetsContainer().withType(KmpApplicationJvmTarget.class).all(target -> {
88-
kotlin.jvm(target.getName(), kotlinTarget -> {
89-
target.getTesting().getTestSuites().forEach((name, testSuite) -> {
90-
// Create a new compilation for the test suite
91-
String suiteCompilationName = "suite" + WordUtils.capitalize(name) + "Compilation";
92-
// Note: "register" won't work here, lazy APIs not working right on this container, just create
93-
KotlinJvmCompilation suiteCompilation = kotlinTarget.getCompilations().create(suiteCompilationName, compilation -> {
94-
compilation.associateWith(kotlin.jvm().compilations.getByName("test"));
95-
compilation.getDefaultSourceSet().getKotlin().srcDir(testSuite.getSourceRoot());
96-
97-
// Add testing dependencies specific to each JVM test suite
98-
KotlinPluginSupport.linkSourceSetToDependencies(
99-
project,
100-
compilation.getDefaultSourceSet(),
101-
testSuite.getDependencies()
102-
);
103-
// LOGGER.warning("Default source set for compilation: " + suiteCompilationName + " is: " + compilation.getDefaultSourceSet().getName() + " at: " + compilation.getDefaultSourceSet().getKotlin().getSrcDirs());
104-
});
72+
/**
73+
* Performs linking actions that must occur within an afterEvaluate block.
74+
*/
75+
private static void linkDslModelToPlugin(Project project, KmpApplication dslModel) {
76+
KotlinMultiplatformExtension kotlin = project.getExtensions().getByType(KotlinMultiplatformExtension.class);
77+
78+
// Link common properties
79+
kotlin.getSourceSets().configureEach(sourceSet -> {
80+
sourceSet.languageSettings(languageSettings -> {
81+
ifPresent(dslModel.getLanguageVersion(), languageSettings::setLanguageVersion);
82+
ifPresent(dslModel.getLanguageVersion(), languageSettings::setApiVersion);
83+
});
84+
});
10585

106-
// Create test task for the new compilation
107-
String suiteTestTaskName = "suite" + WordUtils.capitalize(name) + "Test";
108-
Provider<KotlinJvmTest> suiteTestTask = project.getTasks().register(suiteTestTaskName, KotlinJvmTest.class, task -> {
109-
task.setTargetName(suiteCompilation.getTarget().getName());
110-
task.useJUnitPlatform();
111-
task.dependsOn(suiteCompilation.getCompileTaskProvider());
112-
task.setTestClassesDirs(suiteCompilation.getCompileTaskProvider().get().getOutputs().getFiles());
113-
114-
ConfigurableFileCollection testRuntimeClasspath = project.getObjects().fileCollection();
115-
testRuntimeClasspath.from(suiteCompilation.getCompileTaskProvider().get().getOutputs().getFiles());
116-
testRuntimeClasspath.from(project.getConfigurations().named(suiteCompilation.getRuntimeDependencyConfigurationName()).get());
117-
task.setClasspath(testRuntimeClasspath);
86+
// Link Native targets
87+
dslModel.getTargetsContainer().withType(KmpApplicationNativeTarget.class).all(target -> {
88+
kotlin.macosArm64(target.getName(), kotlinTarget -> {
89+
kotlinTarget.binaries(nativeBinaries -> {
90+
nativeBinaries.executable(executable -> {
91+
executable.entryPoint(target.getEntryPoint().get());
92+
TaskProvider<AbstractExecTask<?>> runTask = executable.getRunTaskProvider();
93+
if (runTask != null) {
94+
dslModel.getRunTasks().add(runTask);
95+
}
96+
});
11897
});
98+
});
99+
});
119100

120-
// New tests are included in jvm tests
121-
project.getTasks().named("jvmTest").configure(task -> {
122-
task.dependsOn(suiteTestTask);
101+
// Add common JVM testing dependencies if the JVM target is a part of this build
102+
if (null != kotlin.getSourceSets().findByName("jvmTest")) {
103+
KotlinPluginSupport.linkSourceSetToDependencies(project, kotlin.getSourceSets().getByName("jvmTest"), dslModel.getTargetsContainer().getByName("jvm").getTesting().getDependencies());
104+
project.getTasks().withType(KotlinJvmTest.class).forEach(Test::useJUnitPlatform);
105+
}
106+
107+
// Create all custom JVM test suites
108+
dslModel.getTargetsContainer().withType(KmpApplicationJvmTarget.class).all(target -> {
109+
kotlin.jvm(target.getName(), kotlinTarget -> {
110+
target.getTesting().getTestSuites().forEach((name, testSuite) -> {
111+
// Create a new compilation for the test suite
112+
String suiteCompilationName = "suite" + WordUtils.capitalize(name) + "Compilation";
113+
// Note: "register" won't work here, lazy APIs not working right on this container, just create
114+
KotlinJvmCompilation suiteCompilation = kotlinTarget.getCompilations().create(suiteCompilationName, compilation -> {
115+
compilation.associateWith(kotlin.jvm().compilations.getByName("test"));
116+
compilation.getDefaultSourceSet().getKotlin().srcDir(testSuite.getSourceRoot());
117+
118+
// Add testing dependencies specific to each JVM test suite
119+
KotlinPluginSupport.linkSourceSetToDependencies(
120+
project,
121+
compilation.getDefaultSourceSet(),
122+
testSuite.getDependencies()
123+
);
124+
});
125+
126+
// Create test task for the new compilation
127+
String suiteTestTaskName = "suite" + WordUtils.capitalize(name) + "Test";
128+
Provider<KotlinJvmTest> suiteTestTask = project.getTasks().register(suiteTestTaskName, KotlinJvmTest.class, task -> {
129+
task.setTargetName(suiteCompilation.getTarget().getName());
130+
task.useJUnitPlatform();
131+
task.dependsOn(suiteCompilation.getCompileTaskProvider());
132+
task.setTestClassesDirs(suiteCompilation.getCompileTaskProvider().get().getOutputs().getFiles());
133+
134+
ConfigurableFileCollection testRuntimeClasspath = project.getObjects().fileCollection();
135+
testRuntimeClasspath.from(suiteCompilation.getCompileTaskProvider().get().getOutputs().getFiles());
136+
testRuntimeClasspath.from(project.getConfigurations().named(suiteCompilation.getRuntimeDependencyConfigurationName()).get());
137+
task.setClasspath(testRuntimeClasspath);
138+
});
139+
140+
// New tests are included in jvm tests
141+
project.getTasks().named("jvmTest").configure(task -> {
142+
task.dependsOn(suiteTestTask);
143+
});
123144
});
124145
});
125146
});
126-
});
127-
}
128-
129-
private KmpApplication createDslModel(Project project) {
130-
KmpApplication dslModel = getKmpApplication();
131-
132-
// In order for function extraction from the DependencyCollector on the library deps to work, configurations must exist
133-
// Matching the names of the getters on LibraryDependencies
134-
project.getConfigurations().dependencyScope("implementation").get();
135-
project.getConfigurations().dependencyScope("compileOnly").get();
136-
project.getConfigurations().dependencyScope("runtimeOnly").get();
147+
}
137148

138-
// Set conventional custom test suit locations as src/<SUITE_NAME>
139-
dslModel.getTargetsContainer().withType(KmpApplicationJvmTarget.class).all(target -> {
140-
target.getTesting().getTestSuites().forEach((name, testSuite) -> {
141-
Directory srcRoot = project.getLayout().getProjectDirectory().dir("src/jvm" + WordUtils.capitalize(name));
142-
testSuite.getSourceRoot().convention(srcRoot);
149+
/**
150+
* Performs linking actions that do not need to occur within an afterEvaluate block.
151+
*/
152+
@SuppressWarnings("deprecation")
153+
private static void linkDslModelToPluginLazy(Project project, KmpApplication dslModel) {
154+
KotlinMultiplatformExtension kotlin = project.getExtensions().getByType(KotlinMultiplatformExtension.class);
155+
156+
// Link common dependencies
157+
KotlinPluginSupport.linkSourceSetToDependencies(project, kotlin.getSourceSets().getByName("commonMain"), dslModel.getDependencies());
158+
159+
// Link JVM targets
160+
dslModel.getTargetsContainer().withType(KmpApplicationJvmTarget.class).all(target -> {
161+
kotlin.jvm(target.getName(), kotlinTarget -> {
162+
KotlinPluginSupport.linkSourceSetToDependencies(
163+
project,
164+
kotlinTarget.getCompilations().getByName("main").getDefaultSourceSet(),
165+
target.getDependencies()
166+
);
167+
kotlinTarget.getCompilations().configureEach(compilation -> {
168+
compilation.getCompilerOptions().getOptions().getJvmTarget().set(target.getJdkVersion().map(value -> JvmTarget.Companion.fromTarget(String.valueOf(value))));
169+
});
170+
kotlinTarget.mainRun(kotlinJvmRunDsl -> {
171+
kotlinJvmRunDsl.getMainClass().set(target.getMainClass());
172+
// The task is not registered until this block of code runs, but the block is deferred until some arbitrary point in time
173+
// So, wire up the task when this block runs
174+
dslModel.getRunTasks().add(project.getTasks().named(target.getName() + "Run"));
175+
return Unit.INSTANCE;
176+
});
177+
});
143178
});
144-
});
145-
146-
return dslModel;
147-
}
148179

149-
/**
150-
* Performs linking actions that do not need to occur within an afterEvaluate block.
151-
*/
152-
@SuppressWarnings("deprecation")
153-
private void linkDslModelToPluginLazy(Project project, KmpApplication dslModel) {
154-
KotlinMultiplatformExtension kotlin = project.getExtensions().getByType(KotlinMultiplatformExtension.class);
155-
156-
// Link common dependencies
157-
KotlinPluginSupport.linkSourceSetToDependencies(project, kotlin.getSourceSets().getByName("commonMain"), dslModel.getDependencies());
158-
159-
// Link JVM targets
160-
dslModel.getTargetsContainer().withType(KmpApplicationJvmTarget.class).all(target -> {
161-
kotlin.jvm(target.getName(), kotlinTarget -> {
162-
KotlinPluginSupport.linkSourceSetToDependencies(
163-
project,
164-
kotlinTarget.getCompilations().getByName("main").getDefaultSourceSet(),
165-
target.getDependencies()
166-
);
167-
kotlinTarget.getCompilations().configureEach(compilation -> {
168-
compilation.getCompilerOptions().getOptions().getJvmTarget().set(target.getJdkVersion().map(value -> JvmTarget.Companion.fromTarget(String.valueOf(value))));
169-
});
170-
kotlinTarget.mainRun(kotlinJvmRunDsl -> {
171-
kotlinJvmRunDsl.getMainClass().set(target.getMainClass());
172-
// The task is not registered until this block of code runs, but the block is deferred until some arbitrary point in time
173-
// So, wire up the task when this block runs
174-
dslModel.getRunTasks().add(project.getTasks().named(target.getName() + "Run"));
175-
return Unit.INSTANCE;
180+
// Link JS targets
181+
dslModel.getTargetsContainer().withType(KmpApplicationNodeJsTarget.class).all(target -> {
182+
kotlin.js(target.getName(), kotlinTarget -> {
183+
kotlinTarget.nodejs();
184+
KotlinPluginSupport.linkSourceSetToDependencies(
185+
project,
186+
kotlinTarget.getCompilations().getByName("main").getDefaultSourceSet(),
187+
target.getDependencies()
188+
);
176189
});
177190
});
178-
});
179-
180-
// Link JS targets
181-
dslModel.getTargetsContainer().withType(KmpApplicationNodeJsTarget.class).all(target -> {
182-
kotlin.js(target.getName(), kotlinTarget -> {
183-
kotlinTarget.nodejs();
184-
KotlinPluginSupport.linkSourceSetToDependencies(
185-
project,
186-
kotlinTarget.getCompilations().getByName("main").getDefaultSourceSet(),
187-
target.getDependencies()
188-
);
189-
});
190-
});
191-
192-
// Link Native targets
193-
dslModel.getTargetsContainer().withType(KmpApplicationNativeTarget.class).all(target -> {
194-
kotlin.macosArm64(target.getName(), kotlinTarget -> {
195-
KotlinPluginSupport.linkSourceSetToDependencies(
196-
project,
197-
kotlinTarget.getCompilations().getByName("main").getDefaultSourceSet(),
198-
target.getDependencies()
199-
);
191+
192+
// Link Native targets
193+
dslModel.getTargetsContainer().withType(KmpApplicationNativeTarget.class).all(target -> {
194+
kotlin.macosArm64(target.getName(), kotlinTarget -> {
195+
KotlinPluginSupport.linkSourceSetToDependencies(
196+
project,
197+
kotlinTarget.getCompilations().getByName("main").getDefaultSourceSet(),
198+
target.getDependencies()
199+
);
200+
});
200201
});
201-
});
202-
}
202+
}
203203

204-
private static <T> void ifPresent(Property<T> property, Action<T> action) {
205-
if (property.isPresent()) {
206-
action.execute(property.get());
204+
private static <T> void ifPresent(Property<T> property, Action<T> action) {
205+
if (property.isPresent()) {
206+
action.execute(property.get());
207+
}
207208
}
208209
}
209-
210210
}

0 commit comments

Comments
 (0)