summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar NebelNidas2022-09-22 11:59:53 +0200
committerGravatar NebelNidas2023-10-09 11:51:28 +0200
commit47de69a821c6e089b01187e93f4f916aceeeea85 (patch)
treeb6e2ccab4e3e3896b9fc32b6f013c35f7ef0995d
parentBump version (diff)
downloadenigma-47de69a821c6e089b01187e93f4f916aceeeea85.tar.gz
enigma-47de69a821c6e089b01187e93f4f916aceeeea85.tar.xz
enigma-47de69a821c6e089b01187e93f4f916aceeeea85.zip
Add initial Mapping-IO export support
-rw-r--r--build.gradle2
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java45
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java23
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java25
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java126
-rw-r--r--gradlew.bat184
6 files changed, 304 insertions, 101 deletions
diff --git a/build.gradle b/build.gradle
index 08ccffe8..e2d5edd7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,6 +20,8 @@ subprojects {
20 implementation 'com.google.guava:guava:30.1.1-jre' 20 implementation 'com.google.guava:guava:30.1.1-jre'
21 implementation 'com.google.code.gson:gson:2.8.7' 21 implementation 'com.google.code.gson:gson:2.8.7'
22 22
23 implementation 'net.fabricmc:mapping-io:0.3.0'
24
23 testImplementation 'junit:junit:4.13.2' 25 testImplementation 'junit:junit:4.13.2'
24 testImplementation 'org.hamcrest:hamcrest:2.2' 26 testImplementation 'org.hamcrest:hamcrest:2.2'
25 } 27 }
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
index 91037b00..e7e75669 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -29,6 +29,8 @@ import javax.swing.JOptionPane;
29import javax.swing.SwingUtilities; 29import javax.swing.SwingUtilities;
30 30
31import com.google.common.collect.Lists; 31import com.google.common.collect.Lists;
32import net.fabricmc.mappingio.MappingWriter;
33import net.fabricmc.mappingio.tree.MemoryMappingTree;
32 34
33import cuchaz.enigma.Enigma; 35import cuchaz.enigma.Enigma;
34import cuchaz.enigma.EnigmaProfile; 36import cuchaz.enigma.EnigmaProfile;
@@ -77,6 +79,7 @@ import cuchaz.enigma.translation.mapping.EntryUtil;
77import cuchaz.enigma.translation.mapping.MappingDelta; 79import cuchaz.enigma.translation.mapping.MappingDelta;
78import cuchaz.enigma.translation.mapping.ResolutionStrategy; 80import cuchaz.enigma.translation.mapping.ResolutionStrategy;
79import cuchaz.enigma.translation.mapping.serde.MappingFormat; 81import cuchaz.enigma.translation.mapping.serde.MappingFormat;
82import cuchaz.enigma.translation.mapping.serde.MappingIoConverter;
80import cuchaz.enigma.translation.mapping.serde.MappingParseException; 83import cuchaz.enigma.translation.mapping.serde.MappingParseException;
81import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; 84import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
82import cuchaz.enigma.translation.mapping.tree.EntryTree; 85import cuchaz.enigma.translation.mapping.tree.EntryTree;
@@ -213,6 +216,48 @@ public class GuiController implements ClientPacketHandler {
213 }); 216 });
214 } 217 }
215 218
219 public CompletableFuture<Void> saveMappings(Path path, net.fabricmc.mappingio.format.MappingFormat format) {
220 if (project == null) {
221 return CompletableFuture.completedFuture(null);
222 }
223
224 return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> {
225 EntryRemapper mapper = project.getMapper();
226 MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters();
227
228 MappingDelta<EntryMapping> delta = mapper.takeMappingDelta();
229 boolean saveAll = !path.equals(loadedMappingPath);
230
231 switch (format) {
232 case ENIGMA:
233 loadedMappingFormat = MappingFormat.ENIGMA_DIRECTORY;
234 loadedMappingPath = path;
235 break;
236 case PROGUARD:
237 loadedMappingFormat = MappingFormat.PROGUARD;
238 loadedMappingPath = path;
239 break;
240 case SRG:
241 loadedMappingFormat = MappingFormat.SRG_FILE;
242 loadedMappingPath = path;
243 break;
244 case TINY:
245 loadedMappingFormat = MappingFormat.TINY_FILE;
246 loadedMappingPath = path;
247 break;
248 case TINY_2:
249 loadedMappingFormat = MappingFormat.TINY_V2;
250 loadedMappingPath = path;
251 break;
252 }
253
254 MemoryMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf());
255 MappingWriter writer = MappingWriter.create(path, format);
256 mappingTree.accept(writer);
257 writer.close();
258 });
259 }
260
216 public void closeMappings() { 261 public void closeMappings() {
217 if (project == null) { 262 if (project == null) {
218 return; 263 return;
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
index 1cfad504..1d4c1ca1 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
@@ -7,6 +7,7 @@ import java.io.IOException;
7import java.nio.file.Files; 7import java.nio.file.Files;
8import java.nio.file.Path; 8import java.nio.file.Path;
9import java.util.Arrays; 9import java.util.Arrays;
10import java.util.List;
10import java.util.Locale; 11import java.util.Locale;
11import java.util.Map; 12import java.util.Map;
12import java.util.stream.Collectors; 13import java.util.stream.Collectors;
@@ -439,6 +440,28 @@ public class MenuBar {
439 saveMappingsAsMenu.add(item); 440 saveMappingsAsMenu.add(item);
440 } 441 }
441 } 442 }
443
444 saveMappingsAsMenu.addSeparator();
445
446 List<net.fabricmc.mappingio.format.MappingFormat> writableMappingIoFormats = Arrays.asList(
447 net.fabricmc.mappingio.format.MappingFormat.ENIGMA,
448 net.fabricmc.mappingio.format.MappingFormat.TINY_2);
449 for (net.fabricmc.mappingio.format.MappingFormat format : writableMappingIoFormats) {
450 JMenuItem item = new JMenuItem(format.name + " (via mapping-io, experimental)");
451 item.addActionListener(event -> {
452 // TODO: Use a specific file chooser for it
453 if (gui.enigmaMappingsFileChooser.getCurrentDirectory() == null) {
454 gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir()));
455 }
456
457 if (gui.enigmaMappingsFileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
458 gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format);
459 saveMappingsItem.setEnabled(true);
460 UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString());
461 }
462 });
463 saveMappingsAsMenu.add(item);
464 }
442 } 465 }
443 466
444 private static void prepareDecompilerMenu(JMenu decompilerMenu, Gui gui) { 467 private static void prepareDecompilerMenu(JMenu decompilerMenu, Gui gui) {
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java
index 367af3b3..4790fee4 100644
--- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java
@@ -21,21 +21,23 @@ import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer;
21import cuchaz.enigma.translation.mapping.tree.EntryTree; 21import cuchaz.enigma.translation.mapping.tree.EntryTree;
22 22
23public enum MappingFormat { 23public enum MappingFormat {
24 ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE), 24 ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, null),
25 ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY), 25 ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA),
26 ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP), 26 ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null),
27 TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()), 27 TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2),
28 TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE), 28 TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY),
29 SRG_FILE(SrgMappingsWriter.INSTANCE, null), 29 SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG),
30 PROGUARD(null, ProguardMappingsReader.INSTANCE), 30 PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD),
31 RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE); 31 RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null);
32 32
33 private final MappingsWriter writer; 33 private final MappingsWriter writer;
34 private final MappingsReader reader; 34 private final MappingsReader reader;
35 private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart;
35 36
36 MappingFormat(MappingsWriter writer, MappingsReader reader) { 37 MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart) {
37 this.writer = writer; 38 this.writer = writer;
38 this.reader = reader; 39 this.reader = reader;
40 this.mappingIoCounterpart = mappingIoCounterpart;
39 } 41 }
40 42
41 public void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { 43 public void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) {
@@ -67,4 +69,9 @@ public enum MappingFormat {
67 public MappingsReader getReader() { 69 public MappingsReader getReader() {
68 return reader; 70 return reader;
69 } 71 }
72
73 @Nullable
74 public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() {
75 return mappingIoCounterpart;
76 }
70} 77}
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java
new file mode 100644
index 00000000..3a864766
--- /dev/null
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java
@@ -0,0 +1,126 @@
1package cuchaz.enigma.translation.mapping.serde;
2
3import java.util.Deque;
4import java.util.LinkedList;
5import java.util.List;
6
7import net.fabricmc.mappingio.MappedElementKind;
8import net.fabricmc.mappingio.tree.MemoryMappingTree;
9
10import cuchaz.enigma.translation.mapping.EntryMap;
11import cuchaz.enigma.translation.mapping.EntryMapping;
12import cuchaz.enigma.translation.mapping.tree.EntryTree;
13import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
14import cuchaz.enigma.translation.representation.entry.ClassEntry;
15import cuchaz.enigma.translation.representation.entry.Entry;
16import cuchaz.enigma.translation.representation.entry.FieldEntry;
17import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
18import cuchaz.enigma.translation.representation.entry.MethodEntry;
19
20public class MappingIoConverter {
21 public static MemoryMappingTree toMappingIo(EntryTree<EntryMapping> mappings) {
22 MemoryMappingTree mappingTree = new MemoryMappingTree();
23 mappingTree.visitNamespaces("intermediary", List.of("named"));
24
25 for (EntryTreeNode<EntryMapping> node : mappings) {
26 if (node.getEntry() instanceof ClassEntry) {
27 writeClass(node, mappings, mappingTree);
28 }
29 }
30
31 mappingTree.visitEnd();
32 return mappingTree;
33 }
34
35 private static void writeClass(EntryTreeNode<EntryMapping> classNode, EntryMap<EntryMapping> oldMappingTree, MemoryMappingTree newMappingTree) {
36 ClassEntry classEntry = (ClassEntry) classNode.getEntry();
37 EntryMapping mapping = oldMappingTree.get(classEntry);
38 Deque<String> parts = new LinkedList<>();
39
40 newMappingTree.visitClass(classEntry.getFullName());
41 newMappingTree.visitComment(MappedElementKind.CLASS, mapping.javadoc());
42
43 do {
44 mapping = oldMappingTree.get(classEntry);
45
46 if (mapping != null && mapping.targetName() != null) {
47 parts.addFirst(mapping.targetName());
48 } else {
49 parts.addFirst(classEntry.getName());
50 }
51
52 classEntry = classEntry.getOuterClass();
53 } while (classEntry != null);
54
55 String mappedName = String.join("$", parts);
56 newMappingTree.visitDstName(MappedElementKind.CLASS, 0, mappedName);
57
58 for (EntryTreeNode<EntryMapping> child : classNode.getChildNodes()) {
59 Entry<?> entry = child.getEntry();
60
61 if (entry instanceof FieldEntry) {
62 writeField(child, newMappingTree);
63 } else if (entry instanceof MethodEntry) {
64 writeMethod(child, newMappingTree);
65 }
66 }
67 }
68
69 private static void writeField(EntryTreeNode<EntryMapping> fieldNode, MemoryMappingTree mappingTree) {
70 if (fieldNode.getValue() == null || fieldNode.getValue().equals(EntryMapping.DEFAULT)) {
71 return; // Shortcut
72 }
73
74 FieldEntry fieldEntry = ((FieldEntry) fieldNode.getEntry());
75 mappingTree.visitField(fieldEntry.getName(), fieldEntry.getDesc().toString());
76
77 EntryMapping fieldMapping = fieldNode.getValue();
78
79 if (fieldMapping == null) {
80 fieldMapping = EntryMapping.DEFAULT;
81 }
82
83 mappingTree.visitDstName(MappedElementKind.FIELD, 0, fieldMapping.targetName());
84 mappingTree.visitComment(MappedElementKind.FIELD, fieldMapping.javadoc());
85 }
86
87 private static void writeMethod(EntryTreeNode<EntryMapping> methodNode, MemoryMappingTree mappingTree) {
88 MethodEntry methodEntry = ((MethodEntry) methodNode.getEntry());
89 mappingTree.visitMethod(methodEntry.getName(), methodEntry.getDesc().toString());
90
91 EntryMapping methodMapping = methodNode.getValue();
92
93 if (methodMapping == null) {
94 methodMapping = EntryMapping.DEFAULT;
95 }
96
97 mappingTree.visitDstName(MappedElementKind.METHOD, 0, methodMapping.targetName());
98 mappingTree.visitComment(MappedElementKind.METHOD, methodMapping.javadoc());
99
100 for (EntryTreeNode<EntryMapping> child : methodNode.getChildNodes()) {
101 Entry<?> entry = child.getEntry();
102
103 if (entry instanceof LocalVariableEntry) {
104 writeMethodArg(child, mappingTree);
105 }
106 }
107 }
108
109 private static void writeMethodArg(EntryTreeNode<EntryMapping> methodArgNode, MemoryMappingTree mappingTree) {
110 if (methodArgNode.getValue() == null || methodArgNode.getValue().equals(EntryMapping.DEFAULT)) {
111 return; // Shortcut
112 }
113
114 LocalVariableEntry methodArgEntry = ((LocalVariableEntry) methodArgNode.getEntry());
115 mappingTree.visitMethodArg(-1, methodArgEntry.getIndex(), methodArgEntry.getName());
116
117 EntryMapping methodArgMapping = methodArgNode.getValue();
118
119 if (methodArgMapping == null) {
120 methodArgMapping = EntryMapping.DEFAULT;
121 }
122
123 mappingTree.visitDstName(MappedElementKind.METHOD_ARG, 0, methodArgMapping.targetName());
124 mappingTree.visitComment(MappedElementKind.METHOD_ARG, methodArgMapping.javadoc());
125 }
126}
diff --git a/gradlew.bat b/gradlew.bat
index 6689b85b..93e3f59f 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,92 +1,92 @@
1@rem 1@rem
2@rem Copyright 2015 the original author or authors. 2@rem Copyright 2015 the original author or authors.
3@rem 3@rem
4@rem Licensed under the Apache License, Version 2.0 (the "License"); 4@rem Licensed under the Apache License, Version 2.0 (the "License");
5@rem you may not use this file except in compliance with the License. 5@rem you may not use this file except in compliance with the License.
6@rem You may obtain a copy of the License at 6@rem You may obtain a copy of the License at
7@rem 7@rem
8@rem https://www.apache.org/licenses/LICENSE-2.0 8@rem https://www.apache.org/licenses/LICENSE-2.0
9@rem 9@rem
10@rem Unless required by applicable law or agreed to in writing, software 10@rem Unless required by applicable law or agreed to in writing, software
11@rem distributed under the License is distributed on an "AS IS" BASIS, 11@rem distributed under the License is distributed on an "AS IS" BASIS,
12@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13@rem See the License for the specific language governing permissions and 13@rem See the License for the specific language governing permissions and
14@rem limitations under the License. 14@rem limitations under the License.
15@rem 15@rem
16 16
17@if "%DEBUG%"=="" @echo off 17@if "%DEBUG%"=="" @echo off
18@rem ########################################################################## 18@rem ##########################################################################
19@rem 19@rem
20@rem Gradle startup script for Windows 20@rem Gradle startup script for Windows
21@rem 21@rem
22@rem ########################################################################## 22@rem ##########################################################################
23 23
24@rem Set local scope for the variables with windows NT shell 24@rem Set local scope for the variables with windows NT shell
25if "%OS%"=="Windows_NT" setlocal 25if "%OS%"=="Windows_NT" setlocal
26 26
27set DIRNAME=%~dp0 27set DIRNAME=%~dp0
28if "%DIRNAME%"=="" set DIRNAME=. 28if "%DIRNAME%"=="" set DIRNAME=.
29@rem This is normally unused 29@rem This is normally unused
30set APP_BASE_NAME=%~n0 30set APP_BASE_NAME=%~n0
31set APP_HOME=%DIRNAME% 31set APP_HOME=%DIRNAME%
32 32
33@rem Resolve any "." and ".." in APP_HOME to make it shorter. 33@rem Resolve any "." and ".." in APP_HOME to make it shorter.
34for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 35
36@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 38
39@rem Find java.exe 39@rem Find java.exe
40if defined JAVA_HOME goto findJavaFromJavaHome 40if defined JAVA_HOME goto findJavaFromJavaHome
41 41
42set JAVA_EXE=java.exe 42set JAVA_EXE=java.exe
43%JAVA_EXE% -version >NUL 2>&1 43%JAVA_EXE% -version >NUL 2>&1
44if %ERRORLEVEL% equ 0 goto execute 44if %ERRORLEVEL% equ 0 goto execute
45 45
46echo. 46echo.
47echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48echo. 48echo.
49echo Please set the JAVA_HOME variable in your environment to match the 49echo Please set the JAVA_HOME variable in your environment to match the
50echo location of your Java installation. 50echo location of your Java installation.
51 51
52goto fail 52goto fail
53 53
54:findJavaFromJavaHome 54:findJavaFromJavaHome
55set JAVA_HOME=%JAVA_HOME:"=% 55set JAVA_HOME=%JAVA_HOME:"=%
56set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 57
58if exist "%JAVA_EXE%" goto execute 58if exist "%JAVA_EXE%" goto execute
59 59
60echo. 60echo.
61echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62echo. 62echo.
63echo Please set the JAVA_HOME variable in your environment to match the 63echo Please set the JAVA_HOME variable in your environment to match the
64echo location of your Java installation. 64echo location of your Java installation.
65 65
66goto fail 66goto fail
67 67
68:execute 68:execute
69@rem Setup the command line 69@rem Setup the command line
70 70
71set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 72
73 73
74@rem Execute Gradle 74@rem Execute Gradle
75"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 76
77:end 77:end
78@rem End local scope for the variables with windows NT shell 78@rem End local scope for the variables with windows NT shell
79if %ERRORLEVEL% equ 0 goto mainEnd 79if %ERRORLEVEL% equ 0 goto mainEnd
80 80
81:fail 81:fail
82rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83rem the _cmd.exe /c_ return code! 83rem the _cmd.exe /c_ return code!
84set EXIT_CODE=%ERRORLEVEL% 84set EXIT_CODE=%ERRORLEVEL%
85if %EXIT_CODE% equ 0 set EXIT_CODE=1 85if %EXIT_CODE% equ 0 set EXIT_CODE=1
86if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 86if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87exit /b %EXIT_CODE% 87exit /b %EXIT_CODE%
88 88
89:mainEnd 89:mainEnd
90if "%OS%"=="Windows_NT" endlocal 90if "%OS%"=="Windows_NT" endlocal
91 91
92:omega 92:omega