Skip to content

Commit 631a2af

Browse files
committed
Actually make a sane message board
```java plugin.queueMessage(ForgeGradleMessages.WELCOME); ```
1 parent 0db58d1 commit 631a2af

File tree

6 files changed

+197
-94
lines changed

6 files changed

+197
-94
lines changed

src/main/java/net/minecraftforge/gradle/internal/Constants.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ If you are on an older version (1.20.4 and older), you will need the
5555
'net.minecraftforge.obfuscation' plugin. Many of these come with our provided
5656
MDK, so this should not be an issue for you.
5757
58+
For more details on this release, see https://docs.minecraftforge.net/en/fg-7.0/""";
59+
60+
static final String WELCOME_CONDITION = """
5861
This message will not display again until the next major beta update, ForgeGradle
5962
7.1, or the below file is deleted:
60-
{}
61-
62-
For more details on this release, see https://docs.minecraftforge.net/en/fg-7.0/""";
63+
{}""";
6364

6465
static final String MAGIC = """
6566
This build is using ForgeGradle Magic. ForgeGradle Magic employs automatic
@@ -70,9 +71,6 @@ If you are on an older version (1.20.4 and older), you will need the
7071
Gradle property:
7172
net.minecraftforge.gradle.magic=false
7273
73-
This message will not display again unless the below file is deleted:
74-
{}
75-
7674
For more information, see https://docs.minecraftforge.net/en/fg-7.0/magic/""";
7775
}
7876
}

src/main/java/net/minecraftforge/gradle/internal/ForgeGradleFlowAction.java

Lines changed: 55 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@
55
package net.minecraftforge.gradle.internal;
66

77
import net.minecraftforge.gradleutils.shared.EnhancedFlowAction;
8+
import org.gradle.api.Project;
89
import org.gradle.api.file.DirectoryProperty;
910
import org.gradle.api.provider.Property;
10-
import org.gradle.api.provider.ProviderFactory;
11+
import org.gradle.api.provider.SetProperty;
12+
import org.jetbrains.annotations.Nullable;
1113

1214
import javax.inject.Inject;
15+
import java.io.File;
1316
import java.io.IOException;
1417
import java.nio.file.Files;
15-
import java.util.Locale;
18+
import java.text.MessageFormat;
19+
import java.util.ArrayList;
1620

1721
import static net.minecraftforge.gradle.internal.ForgeGradlePlugin.LOGGER;
1822

@@ -23,83 +27,74 @@ protected Parameters() {
2327
}
2428
}
2529

26-
static abstract class WelcomeMessage extends ForgeGradleFlowAction<WelcomeMessage.Parameters> {
27-
enum DisplayOption {
28-
ONCE, NEVER, ALWAYS
29-
}
30-
30+
static abstract class MessageBoard extends ForgeGradleFlowAction<MessageBoard.Parameters> {
3131
static abstract class Parameters extends ForgeGradleFlowAction.Parameters {
32-
final DirectoryProperty messagesDir;
33-
final Property<DisplayOption> displayOption;
34-
35-
protected abstract @Inject ProviderFactory getProviders();
32+
final SetProperty<ForgeGradleMessage.QueuedMessage> messages = this.getObjects().setProperty(ForgeGradleMessage.QueuedMessage.class);
3633

3734
@Inject
38-
public Parameters() {
39-
this.messagesDir = this.getObjects().directoryProperty();
40-
this.displayOption = this.getObjects().property(DisplayOption.class).convention(DisplayOption.ONCE).value(
41-
this.getProviders().gradleProperty("net.minecraftforge.gradle.messages.welcome")
42-
.orElse(this.getProviders().systemProperty("net.minecraftforge.gradle.messages.welcome"))
43-
.map(it -> DisplayOption.valueOf(it.toUpperCase(Locale.ROOT)))
44-
);
35+
public Parameters() { }
36+
37+
void queue(Project project, DirectoryProperty globalCaches, ForgeGradleMessage message) {
38+
this.messages.add(message.queue(project, globalCaches));
4539
}
4640
}
4741

4842
@Inject
49-
public WelcomeMessage() { }
43+
public MessageBoard() { }
5044

5145
@Override
52-
protected void run(Parameters parameters) throws IOException {
46+
protected void run(Parameters parameters) {
5347
// if build failed, don't bother
5448
if (parameters.getFailure().isPresent()) return;
5549

56-
// check for marker file
57-
var markerFile = parameters.messagesDir.file("7_0_BETA_WELCOME_1").get().getAsFile();
58-
if (markerFile.exists()) return;
59-
Files.createDirectories(markerFile.toPath().getParent());
60-
Files.createFile(markerFile.toPath());
61-
62-
LOGGER.lifecycle(Constants.Messages.WELCOME, markerFile.getAbsolutePath());
63-
}
64-
}
65-
66-
static abstract class MagicMessage extends ForgeGradleFlowAction<MagicMessage.Parameters> {
67-
enum DisplayOption {
68-
ONCE, NEVER, ALWAYS
69-
}
70-
71-
static abstract class Parameters extends ForgeGradleFlowAction.Parameters {
72-
final DirectoryProperty messagesDir;
73-
final Property<DisplayOption> displayOption;
50+
var pending = parameters.messages.get();
51+
var messages = new ArrayList<ForgeGradleMessage.QueuedMessage>(pending.size());
52+
@Nullable File markerFile = null;
53+
for (var queued : pending) {
54+
switch (queued.displayOption()) {
55+
case NEVER:
56+
continue;
57+
58+
case ONCE:
59+
// check for marker file
60+
markerFile = queued.markerFile().get().getAsFile();
61+
if (markerFile.exists()) continue;
62+
63+
try {
64+
Files.createDirectories(markerFile.toPath().getParent());
65+
Files.createFile(markerFile.toPath());
66+
} catch (IOException e) {
67+
parameters.problems().reportMessageBoardCacheBroken(e, markerFile, queued.message().getProperty());
68+
}
69+
70+
case ALWAYS:
71+
messages.add(queued);
72+
break;
73+
}
74+
}
7475

75-
protected abstract @Inject ProviderFactory getProviders();
76+
if (messages.isEmpty())
77+
return;
7678

77-
@Inject
78-
public Parameters() {
79-
this.messagesDir = this.getObjects().directoryProperty();
80-
this.displayOption = this.getObjects().property(DisplayOption.class).convention(DisplayOption.ONCE).value(
81-
this.getProviders().gradleProperty("net.minecraftforge.gradle.messages.magic")
82-
.orElse(this.getProviders().systemProperty("net.minecraftforge.gradle.messages.magic"))
83-
.map(it -> DisplayOption.valueOf(it.toUpperCase(Locale.ROOT)))
84-
);
79+
if (!LOGGER.isLifecycleEnabled()) {
80+
LOGGER.warn("WARNING: ForgeGradle messages cannot be displayed as the logger is not configured to display lifecycle messages.");
8581
}
86-
}
8782

88-
@Inject
89-
public MagicMessage() { }
83+
var count = messages.size();
84+
LOGGER.lifecycle("You have " + count + " new message" + (count == 1 ? "" : "s") + " from ForgeGradle.\n");
85+
for (var i = 0; i < count; i++) {
86+
var queued = messages.get(i);
9087

91-
@Override
92-
protected void run(Parameters parameters) throws IOException {
93-
// if build failed, don't bother
94-
if (parameters.getFailure().isPresent()) return;
88+
LOGGER.lifecycle("--- Message %d/%d ---".formatted(i + 1, count));
89+
LOGGER.lifecycle(MessageFormat.format(queued.message().getText(), queued));
9590

96-
// check for marker file
97-
var markerFile = parameters.messagesDir.file("7_0_BETA_MAGIC_1").get().getAsFile();
98-
if (markerFile.exists()) return;
99-
Files.createDirectories(markerFile.toPath().getParent());
100-
Files.createFile(markerFile.toPath());
91+
if (markerFile != null && queued.displayOption() == ForgeGradleMessage.DisplayOption.ONCE)
92+
LOGGER.lifecycle('\n' + queued.message().getCondition(), markerFile.getAbsolutePath());
10193

102-
LOGGER.lifecycle(Constants.Messages.MAGIC, markerFile.getAbsolutePath());
94+
LOGGER.lifecycle("--- End of Message ---");
95+
if (i != count - 1)
96+
LOGGER.lifecycle("");
97+
}
10398
}
10499
}
105100

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) Forge Development LLC and contributors
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
5+
package net.minecraftforge.gradle.internal;
6+
7+
import org.gradle.api.Project;
8+
import org.gradle.api.file.Directory;
9+
import org.gradle.api.file.DirectoryProperty;
10+
import org.gradle.api.file.RegularFile;
11+
import org.gradle.api.provider.Provider;
12+
13+
import java.util.Locale;
14+
15+
enum ForgeGradleMessage {
16+
WELCOME("7_0_BETA_WELCOME_1", Constants.Messages.WELCOME, Constants.Messages.WELCOME_CONDITION),
17+
MAGIC("7_0_BETA_MAGIC_1", Constants.Messages.MAGIC);
18+
19+
private static final String MESSAGES_DIR = "messages";
20+
21+
private final String marker;
22+
private final String property;
23+
private final String text;
24+
private final String condition;
25+
26+
ForgeGradleMessage(String marker, String text) {
27+
this(marker, text, """
28+
This message will not display again unless the below file is deleted:
29+
{}""");
30+
}
31+
32+
ForgeGradleMessage(String marker, String text, String condition) {
33+
var name = this.name().toLowerCase(Locale.ENGLISH);
34+
this.marker = marker;
35+
this.property = "net.minecraftforge.gradle.messages." + name;
36+
this.text = text;
37+
this.condition = condition;
38+
}
39+
40+
String getProperty() {
41+
return this.property;
42+
}
43+
44+
String getText() {
45+
return this.text;
46+
}
47+
48+
String getCondition() {
49+
return this.condition;
50+
}
51+
52+
QueuedMessage queue(Project project, DirectoryProperty globalCaches) {
53+
return new QueuedMessage(project, globalCaches, this);
54+
}
55+
56+
enum DisplayOption {
57+
ONCE, NEVER, ALWAYS
58+
}
59+
60+
static Provider<Directory> getMessagesDirectory(DirectoryProperty globalCaches) {
61+
return globalCaches.dir(MESSAGES_DIR);
62+
}
63+
64+
private Provider<RegularFile> getMarkerFile(DirectoryProperty globalCaches) {
65+
return getMessagesDirectory(globalCaches).map(d -> d.file(this.marker));
66+
}
67+
68+
private DisplayOption getDisplayOption(Project project) {
69+
return project.getProviders().gradleProperty(this.property)
70+
.orElse(project.getProviders().systemProperty(this.property))
71+
.map(it -> DisplayOption.valueOf(it.toUpperCase(Locale.ROOT)))
72+
.getOrElse(DisplayOption.ONCE);
73+
}
74+
75+
// NOTE: Has to be public so Gradle can reconstruct it for configuration cache.
76+
// Can't be accessed though since ForgeGradleMessage is package-private.
77+
public record QueuedMessage(
78+
ForgeGradleMessage message, Provider<RegularFile> markerFile, DisplayOption displayOption
79+
) implements Comparable<QueuedMessage> {
80+
@SuppressWarnings("ClassEscapesDefinedScope")
81+
public QueuedMessage(Project project, DirectoryProperty globalCaches, ForgeGradleMessage message) {
82+
this(message, message.getMarkerFile(globalCaches), message.getDisplayOption(project));
83+
}
84+
85+
@Override
86+
public int compareTo(ForgeGradleMessage.QueuedMessage that) {
87+
return this.message.compareTo(that.message);
88+
}
89+
}
90+
}

src/main/java/net/minecraftforge/gradle/internal/ForgeGradlePlugin.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@
66

77
import net.minecraftforge.gradleutils.shared.EnhancedPlugin;
88
import org.gradle.api.Project;
9+
import org.gradle.api.flow.FlowProviders;
10+
import org.gradle.api.flow.FlowScope;
911
import org.gradle.api.logging.Logger;
1012
import org.gradle.api.logging.Logging;
1113
import org.gradle.api.plugins.ExtensionAware;
14+
import org.jetbrains.annotations.Nullable;
1215

1316
import javax.inject.Inject;
17+
import java.util.function.BiConsumer;
18+
import java.util.function.Consumer;
1419

1520
abstract class ForgeGradlePlugin extends EnhancedPlugin<ExtensionAware> {
1621
static final String NAME = "forgegradle";
@@ -24,19 +29,39 @@ abstract class ForgeGradlePlugin extends EnhancedPlugin<ExtensionAware> {
2429
LOGGER.lifecycle("ForgeGradle 7 is an incubating plugin.");
2530
}
2631

32+
protected abstract @Inject FlowScope getFlowScope();
33+
34+
protected abstract @Inject FlowProviders getFlowProviders();
35+
2736
@Inject
2837
public ForgeGradlePlugin() {
2938
super(NAME, DISPLAY_NAME, "fgtools");
3039
}
3140

3241
@Override
3342
public void setup(ExtensionAware target) {
34-
if (target instanceof Project project && !problems.testFalse("net.minecraftforge.gradle.magic")) {
35-
LOGGER.info("Applying ForgeGradle Magic to {}", project);
36-
project.getPluginManager().apply(ForgeGradleMagicPlugin.class);
43+
if (target instanceof Project project) {
44+
this.getFlowScope().always(ForgeGradleFlowAction.MessageBoard.class, spec -> {
45+
spec.parameters(parameters -> {
46+
this.messageBoard = message -> parameters.queue(project, globalCaches(), message);
47+
parameters.getFailure().set(this.getFlowProviders().getBuildWorkResult().map(p -> p.getFailure().orElse(null)));
48+
});
49+
});
50+
51+
if (!problems.testFalse("net.minecraftforge.gradle.magic")) {
52+
LOGGER.info("Applying ForgeGradle Magic to {}", project);
53+
project.getPluginManager().apply(ForgeGradleMagicPlugin.class);
54+
}
3755
}
3856

3957
ForgeGradleExtensionImpl.register(this, target);
4058
MinecraftExtensionImpl.register(this, target);
4159
}
60+
61+
private @Nullable Consumer<ForgeGradleMessage> messageBoard;
62+
63+
void queueMessage(ForgeGradleMessage message) {
64+
if (messageBoard != null)
65+
messageBoard.accept(message);
66+
}
4267
}

src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
import javax.inject.Inject;
1616

17+
import java.io.File;
18+
1719
import static net.minecraftforge.gradle.internal.ForgeGradlePlugin.LOGGER;
1820

1921
/**
@@ -183,6 +185,7 @@ void reportForgeMavenNotDeclared() {
183185
//endregion
184186
//endregion
185187

188+
//region Access Transformers
186189
void reportAccessTransformersNotApplied(Throwable e) {
187190
this.report("access-transformers-not-applied", "AccessTransformers plugin not applied", spec -> spec
188191
.details("""
@@ -216,4 +219,18 @@ RuntimeException accessTransformersNotOnClasspath(Throwable e) {
216219
);
217220
}
218221
//endregion
222+
223+
//region Message Board
224+
void reportMessageBoardCacheBroken(Throwable e, File file, String property) {
225+
this.report("message-board-cache-broken", "ForgeGradle's message board cannot save data", spec -> spec
226+
.details("""
227+
ForgeGradle's message board cannot save data to its cache directory.
228+
This will prevent ForgeGradle from remembering that a message has been displayed.""")
229+
.severity(Severity.ERROR)
230+
.withException(e)
231+
.solution("Ensure read/write access for the following file: " + file)
232+
.solution("Disable the message by setting the following property: " + property + "=never")
233+
.solution(HELP_MESSAGE));
234+
}
235+
//endregion
219236
}

0 commit comments

Comments
 (0)