Skip to content

Commit 7eaf0a5

Browse files
authored
ore: init plugin deployment (#56)
1 parent 53a5f8e commit 7eaf0a5

29 files changed

+2166
-1
lines changed

gradle/libs.versions.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ indra-licenserSpotless = { module = "net.kyori:indra-licenser-spotless", version
2121
# plugin-development
2222
pluginMeta = { module = "org.spongepowered:plugin-meta", version = "0.8.0"}
2323

24+
# ore
25+
apacheHttp-client = { module = "org.apache.httpcomponents.client5:httpclient5", version = "5.1.3"}
26+
2427
[plugins]
2528
gradlePluginPublish = { id = "com.gradle.plugin-publish", version.ref = "pluginPublish" }
2629
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }

ore/build.gradle.kts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
plugins {
2+
groovy
3+
}
4+
5+
tasks.withType(GroovyCompile::class).configureEach {
6+
options.compilerArgs.add("-Xlint:all")
7+
}
8+
9+
dependencies {
10+
api(libs.mammoth)
11+
implementation(localGroovy())
12+
implementation(libs.gson)
13+
implementation(libs.apacheHttp.client)
14+
}
15+
16+
sourceSets.main {
17+
multirelease {
18+
alternateVersions(9)
19+
}
20+
}
21+
22+
indraPluginPublishing {
23+
plugin(
24+
"ore",
25+
"org.spongepowered.gradle.ore.OreDeploymentPlugin",
26+
"Ore Deployment",
27+
"Deploy Sponge plugins to the Ore plugin repository",
28+
listOf("ore", "publishing", "sponge", "minecraft", "plugin")
29+
)
30+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* This file is part of spongegradle-ore, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) SpongePowered <https://www.spongepowered.org>
5+
* Copyright (c) contributors
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package org.spongepowered.gradle.ore;
26+
27+
import net.kyori.mammoth.ProjectPlugin;
28+
import org.gradle.api.Project;
29+
import org.gradle.api.plugins.ExtensionContainer;
30+
import org.gradle.api.plugins.HelpTasksPlugin;
31+
import org.gradle.api.plugins.PluginContainer;
32+
import org.gradle.api.provider.Provider;
33+
import org.gradle.api.publish.plugins.PublishingPlugin;
34+
import org.gradle.api.tasks.TaskContainer;
35+
import org.jetbrains.annotations.NotNull;
36+
import org.spongepowered.gradle.ore.internal.OreDeploymentExtensionImpl;
37+
import org.spongepowered.gradle.ore.internal.OreSessionService;
38+
import org.spongepowered.gradle.ore.task.OreTask;
39+
import org.spongepowered.gradle.ore.task.PublishToOreTask;
40+
import org.spongepowered.gradle.ore.task.ViewOrePermissions;
41+
42+
import java.time.Duration;
43+
44+
public class OreDeploymentPlugin implements ProjectPlugin {
45+
46+
private static final String ORE_DEPLOYMENT_EXTENSION = "oreDeployment";
47+
private static final String PUBLISH_TO_ORE_TASK = "publishToOre";
48+
49+
private static final String ORE_GROUP = "ore";
50+
51+
@Override
52+
public void apply(
53+
final @NotNull Project project,
54+
final @NotNull PluginContainer plugins,
55+
final @NotNull ExtensionContainer extensions,
56+
final @NotNull TaskContainer tasks
57+
) {
58+
final OreDeploymentExtension extension = extensions.create(OreDeploymentExtension.class, ORE_DEPLOYMENT_EXTENSION, OreDeploymentExtensionImpl.class);
59+
60+
final Provider<OreSessionService> ore = project.getGradle().getSharedServices().registerIfAbsent(
61+
"oreSessions",
62+
OreSessionService.class,
63+
params -> {
64+
params.getParameters().getSessionDuration().set(Duration.ofHours(3));
65+
}
66+
);
67+
68+
tasks.withType(OreTask.class).configureEach(task -> {
69+
task.getOreSessions().set(ore);
70+
task.getOreEndpoint().set(extension.oreEndpoint());
71+
task.getOreApiKey().set(extension.apiKey());
72+
});
73+
74+
this.registerPublicationTasks(extension, tasks);
75+
this.registerDefaultPublication(project, extension);
76+
77+
tasks.register("orePermissions", ViewOrePermissions.class, task -> {
78+
task.setGroup(HelpTasksPlugin.HELP_GROUP);
79+
});
80+
}
81+
82+
private void registerPublicationTasks(final OreDeploymentExtension extension, final TaskContainer tasks) {
83+
tasks.register(PUBLISH_TO_ORE_TASK, task -> {
84+
task.dependsOn(tasks.withType(PublishToOreTask.class));
85+
task.setGroup(PublishingPlugin.PUBLISH_TASK_GROUP);
86+
});
87+
88+
extension.publications().all(publication -> {
89+
tasks.register(publishTaskName(publication.getName()), PublishToOreTask.class, task -> {
90+
task.getPublication().set(publication);
91+
task.setGroup(PublishingPlugin.PUBLISH_TASK_GROUP);
92+
});
93+
});
94+
}
95+
96+
private void registerDefaultPublication(final Project project, final OreDeploymentExtension extension) {
97+
SpongeGradleConfigurationSource.configureSpongeGradle(project, extension);
98+
}
99+
100+
private String publishTaskName(final String publicationName) {
101+
final String capitalized;
102+
if (publicationName.length() > 0 && Character.isLowerCase(publicationName.codePointAt(0))) {
103+
final StringBuilder builder = new StringBuilder(publicationName.length());
104+
capitalized = builder.appendCodePoint(Character.toUpperCase(publicationName.codePointAt(0)))
105+
.append(publicationName, builder.length(), publicationName.length())
106+
.toString();
107+
} else {
108+
capitalized = publicationName;
109+
}
110+
return "publish" + capitalized + "PublicationToOre";
111+
}
112+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* This file is part of spongegradle-ore, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) SpongePowered <https://www.spongepowered.org>
5+
* Copyright (c) contributors
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package org.spongepowered.gradle.ore
26+
27+
import groovy.transform.PackageScope
28+
import org.gradle.api.Project
29+
30+
@PackageScope
31+
class SpongeGradleConfigurationSource {
32+
33+
private SpongeGradleConfigurationSource() {
34+
}
35+
36+
static def configureSpongeGradle(Project project, OreDeploymentExtension extension) {
37+
project.plugins.withId('org.spongepowered.gradle.plugin') {
38+
def first = true
39+
project.sponge.plugins.whenObjectAdded { plugin ->
40+
if (first) {
41+
first = false
42+
extension.defaultPublication {
43+
projectId.set(plugin.name)
44+
publishArtifacts.from(project.tasks.named('jar').map { it.outputs })
45+
}
46+
}
47+
}
48+
}
49+
}
50+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* This file is part of spongegradle-ore, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) SpongePowered <https://www.spongepowered.org>
5+
* Copyright (c) contributors
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package org.spongepowered.gradle.ore;
26+
27+
import static java.util.Objects.requireNonNull;
28+
29+
import org.gradle.api.Action;
30+
import org.gradle.api.NamedDomainObjectContainer;
31+
import org.gradle.api.provider.Property;
32+
import org.jetbrains.annotations.NotNull;
33+
import org.spongepowered.gradle.ore.internal.OrePublicationImpl;
34+
35+
/**
36+
* Properties to configure all ore deployment tasks.
37+
*
38+
* <p>These options can be overridden per-task if needed.</p>
39+
*
40+
* @since 2.1.0
41+
*/
42+
public interface OreDeploymentExtension {
43+
44+
/**
45+
* The Ore host to publish to.
46+
*
47+
* <p>Default: {@code https://ore.spongepowered.org/}</p>
48+
*
49+
* @return a property supplying the ore endpoint.
50+
* @since 2.1.0
51+
*/
52+
@NotNull Property<String> oreEndpoint();
53+
54+
/**
55+
* Set the ore host to publish to.
56+
*
57+
* @param endpoint the ore endpoint
58+
* @since 2.1.0
59+
* @see #oreEndpoint()
60+
*/
61+
default void oreEndpoint(final @NotNull String endpoint) {
62+
this.oreEndpoint().set(endpoint);
63+
}
64+
65+
/**
66+
* Get the API key to use for authentication.
67+
*
68+
* <p>This should be a v2 API key with {@code create_version} permissions.</p>
69+
*
70+
* <p>For security reasons, this property should be set to the value of a gradle property
71+
* or environment variable rather than the literal API key.</p>
72+
*
73+
* <p>Default: the value of the environment variable {@code ORE_TOKEN}.</p>
74+
*
75+
* @return the API key property
76+
* @since 2.1.0
77+
*/
78+
@NotNull Property<String> apiKey();
79+
80+
/**
81+
* Set the API key to use for authentication.
82+
*
83+
* @param apiKey the api key
84+
* @since 2.1.0
85+
* @see #apiKey()
86+
*/
87+
default void apiKey(final @NotNull String apiKey) {
88+
this.apiKey().set(apiKey);
89+
}
90+
91+
/**
92+
* Configure the default publication, creating it if necessary.
93+
*
94+
* <p>This publication will be automatically configured when SpongeGradle is present.</p>
95+
*
96+
* @param configureAction the action to configure
97+
* @since 2.1.0
98+
*/
99+
default void defaultPublication(final @NotNull Action<? super OrePublication> configureAction) {
100+
if (this.publications().getNames().contains(OrePublicationImpl.DEFAULT_NAME)) {
101+
this.publications().named(OrePublicationImpl.DEFAULT_NAME).configure(configureAction);
102+
} else {
103+
this.publications().register(OrePublicationImpl.DEFAULT_NAME, configureAction);
104+
}
105+
}
106+
107+
/**
108+
* Get publications for this project.
109+
*
110+
* @return publications collection
111+
* @since 2.1.0
112+
*/
113+
@NotNull NamedDomainObjectContainer<OrePublication> publications();
114+
115+
/**
116+
* Configure the publications on this project.
117+
*
118+
* @param configureAction the configure action
119+
* @since 2.1.0
120+
*/
121+
default void publications(final @NotNull Action<NamedDomainObjectContainer<OrePublication>> configureAction) {
122+
requireNonNull(configureAction, "configureAction").execute(this.publications());
123+
}
124+
125+
}

0 commit comments

Comments
 (0)