Skip to content

Commit 4f7c4c9

Browse files
committed
Use shared project config dependency
1 parent 7aeb94f commit 4f7c4c9

7 files changed

Lines changed: 342 additions & 137 deletions

File tree

de.peeeq.wurstscript/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ dependencies {
110110
implementation 'org.xerial:sqlite-jdbc:3.46.1.3'
111111
implementation 'com.github.inwc3:jmpq3:e28f6999c0'
112112
implementation 'com.github.inwc3:wc3libs:a69318d921'
113+
implementation 'com.github.wurstscript:wurst-project-config:2c7ccd1a5f'
113114
implementation('com.github.wurstscript:wurstsetup:393cf5ea39') {
114115
exclude group: 'org.eclipse.jgit', module: 'org.eclipse.jgit'
115116
exclude group: 'org.eclipse.jgit', module: 'org.eclipse.jgit.ssh.apache'

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/WurstBuildConfig.java

Lines changed: 57 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
import config.WurstProjectConfigData;
44
import de.peeeq.wurstscript.WLogger;
55
import net.moonlightflower.wc3libs.port.GameVersion;
6+
import org.wurstscript.projectconfig.Wc3PatchTarget;
67

78
import java.io.IOException;
89
import java.lang.reflect.Method;
9-
import java.nio.file.Files;
1010
import java.nio.file.Path;
11-
import java.util.ArrayList;
1211
import java.util.List;
13-
import java.util.Locale;
1412
import java.util.Optional;
1513

1614
import static de.peeeq.wurstio.languageserver.ProjectConfigBuilder.FILE_NAME;
@@ -24,181 +22,133 @@ public enum ScriptMode {
2422

2523
public enum Wc3Patch {
2624
REFORGED,
25+
CLASSIC,
2726
PRE_129
2827
}
2928

30-
private final Optional<ScriptMode> scriptMode;
31-
private final Optional<Wc3Patch> wc3Patch;
29+
private final org.wurstscript.projectconfig.WurstBuildConfig sharedConfig;
3230

33-
private WurstBuildConfig(Optional<ScriptMode> scriptMode, Optional<Wc3Patch> wc3Patch) {
34-
this.scriptMode = scriptMode;
35-
this.wc3Patch = wc3Patch;
31+
private WurstBuildConfig(org.wurstscript.projectconfig.WurstBuildConfig sharedConfig) {
32+
this.sharedConfig = sharedConfig == null ? org.wurstscript.projectconfig.WurstBuildConfig.empty() : sharedConfig;
3633
}
3734

3835
public static WurstBuildConfig empty() {
39-
return new WurstBuildConfig(Optional.empty(), Optional.empty());
36+
return new WurstBuildConfig(org.wurstscript.projectconfig.WurstBuildConfig.empty());
4037
}
4138

4239
public static WurstBuildConfig fromWorkspaceRoot(WFile workspaceRoot) {
40+
if (workspaceRoot == null) {
41+
return empty();
42+
}
4343
return fromBuildFile(Path.of(workspaceRoot.toString(), FILE_NAME));
4444
}
4545

4646
public static WurstBuildConfig fromProject(WurstProjectConfigData projectConfig, WFile workspaceRoot) {
4747
WurstBuildConfig fileConfig = fromWorkspaceRoot(workspaceRoot);
48-
Optional<ScriptMode> scriptMode = readEnumGetter(projectConfig, "getScriptMode", ScriptMode::valueOf)
49-
.or(fileConfig::scriptMode);
50-
Optional<Wc3Patch> wc3Patch = readEnumGetter(projectConfig, "getWc3Patch", WurstBuildConfig::parsePatchName)
51-
.or(fileConfig::wc3Patch);
52-
return new WurstBuildConfig(scriptMode, wc3Patch);
48+
if (projectConfig == null) {
49+
return fileConfig;
50+
}
51+
Optional<org.wurstscript.projectconfig.ScriptMode> scriptMode = readStringGetter(projectConfig, "getScriptMode")
52+
.flatMap(WurstBuildConfig::parseSharedScriptMode)
53+
.or(fileConfig.sharedConfig::scriptMode);
54+
Optional<Wc3PatchTarget> wc3Patch = readStringGetter(projectConfig, "getWc3Patch")
55+
.flatMap(Wc3PatchTarget::parse)
56+
.or(fileConfig.sharedConfig::wc3Patch);
57+
return new WurstBuildConfig(new org.wurstscript.projectconfig.WurstBuildConfig(scriptMode, wc3Patch));
5358
}
5459

5560
static WurstBuildConfig fromBuildFile(Path buildFile) {
56-
if (!Files.exists(buildFile)) {
57-
return empty();
58-
}
59-
Optional<ScriptMode> scriptMode = Optional.empty();
60-
Optional<Wc3Patch> wc3Patch = Optional.empty();
6161
try {
62-
for (String rawLine : Files.readAllLines(buildFile)) {
63-
String line = stripComment(rawLine).trim();
64-
if (line.isEmpty() || Character.isWhitespace(rawLine.charAt(0))) {
65-
continue;
66-
}
67-
int colon = line.indexOf(':');
68-
if (colon < 0) {
69-
continue;
70-
}
71-
String key = line.substring(0, colon).trim();
72-
String value = normalizeScalar(line.substring(colon + 1).trim());
73-
if (key.equals("scriptMode")) {
74-
scriptMode = parseScriptMode(value);
75-
} else if (key.equals("wc3Patch")) {
76-
wc3Patch = parsePatch(value);
77-
}
78-
}
62+
return new WurstBuildConfig(org.wurstscript.projectconfig.WurstBuildConfig.fromBuildFile(buildFile));
7963
} catch (IOException e) {
8064
WLogger.warning("Could not read " + buildFile + " for build settings", e);
65+
return empty();
8166
}
82-
return new WurstBuildConfig(scriptMode, wc3Patch);
8367
}
8468

8569
public Optional<ScriptMode> scriptMode() {
86-
return scriptMode;
70+
return sharedConfig.scriptMode().map(mode -> ScriptMode.valueOf(mode.name()));
8771
}
8872

8973
public Optional<Wc3Patch> wc3Patch() {
90-
return wc3Patch;
74+
return sharedConfig.wc3Patch().map(WurstBuildConfig::patchKind);
75+
}
76+
77+
public Optional<String> wc3PatchName() {
78+
return sharedConfig.wc3Patch().map(Wc3PatchTarget::name);
79+
}
80+
81+
public Optional<GameVersion> configuredGameVersion() {
82+
return sharedConfig.wc3Patch()
83+
.map(Wc3PatchTarget::gameVersion)
84+
.map(GameVersion::new);
9185
}
9286

9387
public Wc3Patch wc3PatchOrReforged() {
94-
return wc3Patch.orElse(Wc3Patch.REFORGED);
88+
return wc3Patch().orElse(Wc3Patch.REFORGED);
9589
}
9690

9791
public GameVersion fallbackGameVersion() {
98-
if (wc3PatchOrReforged() == Wc3Patch.PRE_129) {
99-
return new GameVersion("1.28");
100-
}
101-
return GameVersion.VERSION_1_32;
92+
return configuredGameVersion().orElse(GameVersion.VERSION_1_32);
10293
}
10394

10495
public List<String> applyToCompileArgs(List<String> compileArgs) {
105-
if (!scriptMode.isPresent()) {
106-
return compileArgs;
107-
}
108-
List<String> result = new ArrayList<>();
109-
for (String arg : compileArgs) {
110-
if (!"-lua".equals(arg)) {
111-
result.add(arg);
112-
}
113-
}
114-
if (scriptMode.get() == ScriptMode.LUA) {
115-
result.add("-lua");
116-
}
117-
return result;
96+
return sharedConfig.applyToCompileArgs(compileArgs);
11897
}
11998

12099
public boolean shouldUseReforgedLaunchArgs(Optional<GameVersion> detectedVersion) {
121-
return detectedVersion
122-
.map(version -> version.compareTo(GameVersion.VERSION_1_32) >= 0)
123-
.orElse(wc3PatchOrReforged() == Wc3Patch.REFORGED);
100+
return sharedConfig.shouldUseReforgedLaunchArgs(versionString(detectedVersion));
124101
}
125102

126103
public boolean shouldUseClassicWindowArg(Optional<GameVersion> detectedVersion) {
127-
return detectedVersion
128-
.map(version -> version.compareTo(GameVersion.VERSION_1_31) < 0)
129-
.orElse(wc3PatchOrReforged() == Wc3Patch.PRE_129);
104+
return sharedConfig.shouldUseClassicWindowArg(versionString(detectedVersion));
130105
}
131106

132107
public boolean shouldCopyRunMapToWarcraftMapDir(Optional<GameVersion> detectedVersion) {
133-
return detectedVersion
134-
.map(version -> version.compareTo(GameVersion.VERSION_1_32) < 0)
135-
.orElse(wc3PatchOrReforged() == Wc3Patch.PRE_129);
108+
return sharedConfig.shouldCopyRunMapToWarcraftMapDir(versionString(detectedVersion));
136109
}
137110

138111
public boolean shouldUseInstallDirForMaps(Optional<GameVersion> detectedVersion) {
139-
return detectedVersion.orElseGet(this::fallbackGameVersion)
140-
.compareTo(new GameVersion("1.27.9")) <= 0;
112+
Optional<GameVersion> effectiveVersion = detectedVersion == null ? Optional.empty() : detectedVersion;
113+
return effectiveVersion.or(this::configuredGameVersion)
114+
.map(version -> version.compareTo(new GameVersion("1.27.9")) <= 0)
115+
.orElse(false);
141116
}
142117

143-
private static String stripComment(String line) {
144-
int commentStart = line.indexOf('#');
145-
return commentStart >= 0 ? line.substring(0, commentStart) : line;
146-
}
147-
148-
private static String normalizeScalar(String value) {
149-
String result = value;
150-
if ((result.startsWith("\"") && result.endsWith("\""))
151-
|| (result.startsWith("'") && result.endsWith("'"))) {
152-
result = result.substring(1, result.length() - 1);
153-
}
154-
return result.trim();
118+
private static Optional<String> versionString(Optional<GameVersion> version) {
119+
return version == null ? Optional.empty() : version.map(GameVersion::toString);
155120
}
156121

157-
private static Optional<ScriptMode> parseScriptMode(String value) {
158-
String normalized = value.toUpperCase(Locale.ROOT);
122+
private static Optional<org.wurstscript.projectconfig.ScriptMode> parseSharedScriptMode(String value) {
159123
try {
160-
return Optional.of(ScriptMode.valueOf(normalized));
161-
} catch (IllegalArgumentException e) {
162-
WLogger.warning("Ignoring unknown scriptMode in wurst.build: " + value);
124+
return Optional.of(org.wurstscript.projectconfig.ScriptMode.valueOf(value.trim().toUpperCase()));
125+
} catch (IllegalArgumentException | NullPointerException e) {
163126
return Optional.empty();
164127
}
165128
}
166129

167-
private static Optional<Wc3Patch> parsePatch(String value) {
168-
try {
169-
return Optional.of(parsePatchName(value));
170-
} catch (IllegalArgumentException e) {
171-
WLogger.warning("Ignoring unknown wc3Patch in wurst.build: " + value);
172-
return Optional.empty();
130+
private static Wc3Patch patchKind(Wc3PatchTarget target) {
131+
if (target.kind() == Wc3PatchTarget.Kind.PRE_129) {
132+
return Wc3Patch.PRE_129;
173133
}
174-
}
175-
176-
private static Wc3Patch parsePatchName(String value) {
177-
String normalized = value.toUpperCase(Locale.ROOT)
178-
.replace(".", "_")
179-
.replace("-", "_");
180-
if (normalized.equals("PRE1_29")) {
181-
normalized = "PRE_129";
134+
if (target.kind() == Wc3PatchTarget.Kind.CLASSIC) {
135+
return Wc3Patch.CLASSIC;
182136
}
183-
return Wc3Patch.valueOf(normalized);
184-
}
185-
186-
private interface EnumParser<T> {
187-
T parse(String value);
137+
return Wc3Patch.REFORGED;
188138
}
189139

190-
private static <T> Optional<T> readEnumGetter(WurstProjectConfigData projectConfig, String getterName, EnumParser<T> parser) {
140+
private static Optional<String> readStringGetter(WurstProjectConfigData projectConfig, String getterName) {
191141
try {
192142
Method getter = projectConfig.getClass().getMethod(getterName);
193143
Object value = getter.invoke(projectConfig);
194144
if (value == null) {
195145
return Optional.empty();
196146
}
197-
return Optional.of(parser.parse(value.toString()));
147+
return Optional.of(value.toString());
198148
} catch (NoSuchMethodException ignored) {
199149
return Optional.empty();
200150
} catch (Exception e) {
201-
WLogger.warning("Could not read " + getterName + " from wurst.build config", e);
151+
WLogger.debug("Could not read " + getterName + " from wurst.build config: " + e);
202152
return Optional.empty();
203153
}
204154
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/MapRequest.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import de.peeeq.wurstio.languageserver.ModelManager;
1111
import de.peeeq.wurstio.languageserver.ProjectConfigBuilder;
1212
import de.peeeq.wurstio.languageserver.WFile;
13+
import de.peeeq.wurstio.languageserver.WurstBuildConfig;
1314
import de.peeeq.wurstio.languageserver.WurstLanguageServer;
1415
import de.peeeq.wurstio.map.importer.ImportFile;
1516
import de.peeeq.wurstio.mpq.MpqEditor;
@@ -62,6 +63,7 @@ public abstract class MapRequest extends UserRequest<Object> {
6263
protected final WFile workspaceRoot;
6364
protected final RunArgs runArgs;
6465
protected final Optional<String> wc3Path;
66+
protected final WurstBuildConfig buildConfig;
6567
protected final W3InstallationData w3data;
6668
protected final TimeTaker timeTaker;
6769

@@ -104,8 +106,9 @@ public MapRequest(WurstLanguageServer langServer, Optional<File> map, List<Strin
104106
this.workspaceRoot = workspaceRoot;
105107
this.runArgs = new RunArgs(compileArgs);
106108
this.wc3Path = wc3Path;
109+
this.buildConfig = WurstBuildConfig.fromWorkspaceRoot(workspaceRoot);
107110
if (gameExePath.isPresent() && StringUtils.isNotBlank(gameExePath.get())) {
108-
this.w3data = new W3InstallationData(Optional.of(new File(gameExePath.get())), Optional.empty());
111+
this.w3data = new W3InstallationData(Optional.of(new File(gameExePath.get())), buildConfig.configuredGameVersion());
109112
} else {
110113
this.w3data = getBestW3InstallationData();
111114
}
@@ -929,21 +932,30 @@ protected File renameJhcrOutput(File buildDir) throws IOException {
929932
}
930933

931934
private W3InstallationData getBestW3InstallationData() throws RequestFailedException {
935+
Optional<GameVersion> configuredVersion = buildConfig.configuredGameVersion();
936+
boolean needsGameExe = this instanceof RunMap && !runArgs.isHotReload();
937+
if (configuredVersion.isPresent()) {
938+
WLogger.info("Using wurst.build wc3Patch " + buildConfig.wc3PatchName().orElse(configuredVersion.get().toString())
939+
+ " (" + configuredVersion.get() + ").");
940+
}
932941
if (Orient.isLinuxSystem()) {
933942
// no Warcraft installation supported on Linux
934-
return new W3InstallationData(Optional.empty(), Optional.empty());
943+
return new W3InstallationData(Optional.empty(), configuredVersion);
944+
}
945+
if (!needsGameExe && configuredVersion.isPresent()) {
946+
return new W3InstallationData(Optional.empty(), configuredVersion);
935947
}
936948
if (wc3Path.isPresent() && StringUtils.isNotBlank(wc3Path.get())) {
937949
W3InstallationData w3data = new W3InstallationData(langServer, new File(wc3Path.get()),
938-
this instanceof RunMap && !runArgs.isHotReload());
939-
if (w3data.getWc3PatchVersion().isEmpty()) {
950+
needsGameExe, configuredVersion);
951+
if (w3data.getWc3PatchVersion().isEmpty() && !configuredVersion.isPresent()) {
940952
WLogger.warning("Could not determine Warcraft III version at specified path: " + wc3Path
941-
+ ". Falling back to wurst.build patch target.");
953+
+ ". Falling back to default launch behavior.");
942954
}
943955

944956
return w3data;
945957
} else {
946-
return new W3InstallationData(langServer, this instanceof RunMap && !runArgs.isHotReload());
958+
return new W3InstallationData(langServer, needsGameExe, configuredVersion);
947959
}
948960
}
949961

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/RunMap.java

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import config.WurstProjectConfig;
66
import config.WurstProjectConfigData;
77
import de.peeeq.wurstio.gui.WurstGuiImpl;
8-
import de.peeeq.wurstio.languageserver.WurstBuildConfig;
98
import de.peeeq.wurstio.languageserver.ModelManager;
109
import de.peeeq.wurstio.languageserver.WFile;
1110
import de.peeeq.wurstio.languageserver.WurstLanguageServer;
@@ -41,7 +40,6 @@
4140
public class RunMap extends MapRequest {
4241

4342
private @Nullable File customTarget = null;
44-
private @Nullable WurstBuildConfig buildConfig = null;
4543

4644

4745
public RunMap(WurstLanguageServer langServer, WFile workspaceRoot, Optional<String> wc3Path, Optional<File> map,
@@ -68,8 +66,6 @@ public Object execute(ModelManager modelManager) throws IOException {
6866
throw new RequestFailedException(MessageType.Error, FILE_NAME + " file doesn't exist or is invalid. " +
6967
"Please install your project using grill or the wurst setup tool.");
7068
}
71-
buildConfig = WurstBuildConfig.fromProject(projectConfig, workspaceRoot);
72-
7369
// TODO use normal compiler for this, avoid code duplication
7470
WurstGui gui = new WurstGuiImpl(getWorkspaceAbsolute());
7571
try {
@@ -140,7 +136,6 @@ private void startGame(WurstGui gui, CompilationResult result) throws Exception
140136
gui.sendProgress("Starting Warcraft 3...");
141137

142138
File mapCopy = cachedMapFile.get();
143-
WurstBuildConfig buildConfig = getBuildConfig();
144139
Optional<GameVersion> detectedGameVersion = w3data.getWc3PatchVersion();
145140
if (buildConfig.shouldCopyRunMapToWarcraftMapDir(detectedGameVersion)) {
146141
mapCopy = copyToWarcraftMapDir(cachedMapFile.get());
@@ -325,7 +320,7 @@ private Optional<String> findMapDocumentPath(String testMapName, File myDocument
325320
}
326321
}
327322

328-
if (getBuildConfig().shouldUseInstallDirForMaps(w3data.getWc3PatchVersion())) {
323+
if (buildConfig.shouldUseInstallDirForMaps(w3data.getWc3PatchVersion())) {
329324
// 1.27 and lower compat
330325
WLogger.info("Version 1.27 or lower detected, changing file location");
331326
documentPath = wc3Path;
@@ -341,12 +336,4 @@ private Optional<String> findMapDocumentPath(String testMapName, File myDocument
341336
}
342337
return documentPath;
343338
}
344-
345-
private WurstBuildConfig getBuildConfig() {
346-
if (buildConfig == null) {
347-
buildConfig = WurstBuildConfig.fromWorkspaceRoot(workspaceRoot);
348-
}
349-
return buildConfig;
350-
}
351-
352339
}

0 commit comments

Comments
 (0)