Skip to content

Commit 275f230

Browse files
committed
Add --disable-gradle argument that skips the gradle specific variant options. Closes #9
1 parent 046156c commit 275f230

File tree

3 files changed

+135
-33
lines changed

3 files changed

+135
-33
lines changed

src/main/java/net/minecraftforge/mcmaven/cli/MavenTask.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ static void run(String[] args) throws Exception {
8888
var globalAuxiliaryVariantsO = parser.accepts("global-auxiliary-variants",
8989
"Declares sources and javadoc jars as global variants, no matter the mapping version. This is used to work around gradle/gradle#35065");
9090

91+
var disableGradleO = parser.accepts("disable-gradle",
92+
"Disabels the gradle module file, and writes all mappings to the main artifact files.");
93+
9194
var shorthandOptions = new HashMap<String, OptionSpecBuilder>();
9295
var artifacts = Map.of(
9396
"forge", Constants.FORGE_ARTIFACT,
@@ -158,7 +161,8 @@ static void run(String[] args) throws Exception {
158161
foreignRepositories.put(split[0], split[1]);
159162
}
160163

161-
var mcmaven = new MinecraftMaven(output, options.has(dependenciesOnlyO), cache, jdkCache, mappings, foreignRepositories, options.has(globalAuxiliaryVariantsO));
164+
var mcmaven = new MinecraftMaven(output, options.has(dependenciesOnlyO), cache, jdkCache, mappings,
165+
foreignRepositories, options.has(globalAuxiliaryVariantsO), options.has(disableGradleO));
162166
mcmaven.run(artifact);
163167
}
164168
}

src/main/java/net/minecraftforge/mcmaven/impl/MinecraftMaven.java

Lines changed: 128 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,39 @@
1414
import net.minecraftforge.mcmaven.impl.util.Artifact;
1515
import net.minecraftforge.mcmaven.impl.util.ComparableVersion;
1616
import net.minecraftforge.mcmaven.impl.util.Constants;
17+
import net.minecraftforge.mcmaven.impl.util.POMBuilder;
18+
import net.minecraftforge.mcmaven.impl.util.Util;
1719
import net.minecraftforge.util.data.json.JsonData;
20+
import net.minecraftforge.util.file.FileUtils;
1821
import net.minecraftforge.util.hash.HashStore;
1922
import net.minecraftforge.util.hash.HashUtils;
2023
import static net.minecraftforge.mcmaven.impl.Mavenizer.LOGGER;
2124

25+
import java.io.ByteArrayOutputStream;
2226
import java.io.File;
27+
import java.io.FileOutputStream;
28+
import java.io.IOException;
29+
import java.io.StringReader;
30+
import java.nio.charset.StandardCharsets;
2331
import java.util.ArrayList;
32+
import java.util.Arrays;
2433
import java.util.HashMap;
2534
import java.util.HashSet;
2635
import java.util.List;
2736
import java.util.Map;
2837

38+
import javax.xml.parsers.DocumentBuilderFactory;
39+
import javax.xml.parsers.ParserConfigurationException;
40+
import javax.xml.transform.OutputKeys;
41+
import javax.xml.transform.TransformerException;
42+
import javax.xml.transform.TransformerFactory;
43+
import javax.xml.transform.dom.DOMSource;
44+
import javax.xml.transform.stream.StreamResult;
45+
import javax.xml.transform.stream.StreamSource;
46+
47+
import org.w3c.dom.Node;
48+
import org.xml.sax.SAXException;
49+
2950
// TODO [MCMavenizer][Deobf] ADD DEOBF
3051
// use single detached configuration to resolve individual configurations
3152
// pass in downloaded files to mcmaven (absolute path)
@@ -35,12 +56,14 @@ public record MinecraftMaven(
3556
Cache cache,
3657
Mappings mappings,
3758
Map<String, String> foreignRepositories,
38-
boolean globalAuxiliaryVariants
59+
boolean globalAuxiliaryVariants,
60+
boolean disableGradle
3961
) {
4062
private static final ComparableVersion MIN_SUPPORTED_FORGE = new ComparableVersion("1.14.4"); // Only 1.14.4+ has official mappings, we can support more when we add more mappings
4163

42-
public MinecraftMaven(File output, boolean dependenciesOnly, File cacheRoot, File jdkCacheRoot, Mappings mappings, Map<String, String> foreignRepositories, boolean globalAuxiliaryVariants) {
43-
this(output, dependenciesOnly, new Cache(cacheRoot, jdkCacheRoot, foreignRepositories), mappings, foreignRepositories, globalAuxiliaryVariants);
64+
public MinecraftMaven(File output, boolean dependenciesOnly, File cacheRoot, File jdkCacheRoot, Mappings mappings,
65+
Map<String, String> foreignRepositories, boolean globalAuxiliaryVariants, boolean disableGradle) {
66+
this(output, dependenciesOnly, new Cache(cacheRoot, jdkCacheRoot, foreignRepositories), mappings, foreignRepositories, globalAuxiliaryVariants, disableGradle);
4467
}
4568

4669
public MinecraftMaven {
@@ -54,6 +77,7 @@ public MinecraftMaven(File output, boolean dependenciesOnly, File cacheRoot, Fil
5477
if (!foreignRepositories.isEmpty())
5578
LOGGER.info(" Foreign Repos: [" + String.join(", ", foreignRepositories.values()) + ']');
5679
LOGGER.info(" GradleVariantHack: " + globalAuxiliaryVariants);
80+
LOGGER.info(" Disable Gradle: " + disableGradle);
5781
LOGGER.info();
5882
}
5983

@@ -138,7 +162,13 @@ private void finalize(Artifact module, Mappings mappings, List<Repo.PendingArtif
138162
// I haven't added an opt-in for making artifacts that use mappings, so just assume any artifact with variants
139163
var artifact = pending.artifact();
140164
String suffix = null;
141-
if (pending.variants() != null && !mappings.isPrimary()) {
165+
if (!disableGradle && pending.variants() != null && !mappings.isPrimary()) {
166+
// If we are not the primary mapping, but we haven't generated the primary mapping yet, do so.
167+
// This will duplicate the files. But the other option is to require not writing the variants until the primary mapping is requested.
168+
var primaryTarget = new File(this.output, artifact.getLocalPath());
169+
if (!primaryTarget.exists())
170+
updateFile(primaryTarget, pending.get(), pending.artifact());
171+
142172
suffix = mappings.channel() + '-' + mappings.version();
143173
if (artifact.getClassifier() == null)
144174
artifact = artifact.withClassifier(suffix);
@@ -147,41 +177,18 @@ private void finalize(Artifact module, Mappings mappings, List<Repo.PendingArtif
147177
}
148178

149179
var target = new File(this.output, artifact.getLocalPath());
150-
var varTarget = new File(this.output, artifact.getLocalPath() + ".variants");
151-
{
152-
var source = pending.get();
153-
var cache = HashStore.fromFile(target)
154-
.add("source", source);
155-
156-
boolean write;
157-
if ("pom".equals(pending.artifact().getExtension())) {
158-
// Write the pom for non-primary mappings if we haven't generated primary mappings yet
159-
write = !target.exists() || (mappings.isPrimary() && !cache.isSame());
160-
} else {
161-
write = !target.exists() || !cache.isSame();
162-
}
163-
164-
if (write) {
165-
// TODO: [MCMavenizer] Add --api argument to turn class artifacts to api-only targets for a public repo
166-
try {
167-
org.apache.commons.io.FileUtils.copyFile(source, target);
168-
HashUtils.updateHash(target);
169-
cache.save();
170-
} catch (Throwable t) {
171-
throw new RuntimeException("Failed to generate artifact: %s".formatted(artifact), t);
172-
}
173-
}
174-
}
180+
updateFile(target, pending.get(), pending.artifact());
175181

176-
if (pending.variants() != null) {
182+
var varTarget = new File(this.output, artifact.getLocalPath() + ".variants");
183+
if (!disableGradle && pending.variants() != null) {
177184
var source = pending.variants().execute();
178185
var cache = HashStore.fromFile(varTarget)
179186
.add("source", source);
180187

181188
if (!varTarget.exists() || !cache.isSame()) {
182189
variants.add(Artifact.from(artifact.getGroup(), artifact.getName(), artifact.getVersion()));
183190
try {
184-
var data = JsonData.fromJson(source, GradleModule.Variant[].class);
191+
GradleModule.Variant[] data = JsonData.fromJson(source, GradleModule.Variant[].class);
185192
if (!dependenciesOnly) {
186193
var file = new GradleModule.Variant.File(target);
187194
for (var variant : data) {
@@ -190,6 +197,8 @@ private void finalize(Artifact module, Mappings mappings, List<Repo.PendingArtif
190197
variant.name = variant.name + '-' + suffix;
191198
}
192199
}
200+
// Sort them to make it predictable/easy to diff
201+
Arrays.sort(data, (a, b) -> a.name.compareTo(b.name));
193202
JsonData.toJson(data, varTarget);
194203
cache.save();
195204
} catch (Throwable t) {
@@ -204,6 +213,36 @@ private void finalize(Artifact module, Mappings mappings, List<Repo.PendingArtif
204213
}
205214
}
206215

216+
private void updateFile(File target, File source, Artifact artifact) {
217+
var cache = HashStore.fromFile(target)
218+
.add("source", source);
219+
220+
var isPom = "pom".equals(artifact.getExtension());
221+
boolean write;
222+
if (isPom) {
223+
cache.addKnown("disableGradle", Boolean.toString(disableGradle));
224+
// Write the pom for non-primary mappings if we haven't generated primary mappings yet
225+
write = !target.exists() || ((disableGradle || mappings.isPrimary()) && !cache.isSame());
226+
} else {
227+
write = !target.exists() || !cache.isSame();
228+
}
229+
230+
if (write) {
231+
// TODO: [MCMavenizer] Add --api argument to turn class artifacts to api-only targets for a public repo
232+
try {
233+
if (disableGradle && isPom) {
234+
makeNonGradlePom(source, target);
235+
} else {
236+
org.apache.commons.io.FileUtils.copyFile(source, target);
237+
}
238+
HashUtils.updateHash(target);
239+
cache.save();
240+
} catch (Throwable t) {
241+
throw new RuntimeException("Failed to generate artifact: %s".formatted(artifact), t);
242+
}
243+
}
244+
}
245+
207246
private void updateVariants(Artifact artifact) {
208247
var root = new File(this.output, artifact.getFolder());
209248
var inputs = new ArrayList<File>();
@@ -241,4 +280,62 @@ private void updateVariants(Artifact artifact) {
241280
throw new RuntimeException("Failed to write artifact module: %s".formatted(artifact), t);
242281
}
243282
}
283+
284+
private void makeNonGradlePom(File source, File target) throws IOException, SAXException, ParserConfigurationException, TransformerException {
285+
var docFactory = DocumentBuilderFactory.newInstance();
286+
var docBuilder = docFactory.newDocumentBuilder();
287+
var doc = docBuilder.parse(source);
288+
289+
var modified = false;
290+
var projects = doc.getElementsByTagName("project");
291+
for (var x = 0; x < projects.getLength(); x++) {
292+
var project = projects.item(x);
293+
var children = project.getChildNodes();
294+
for (int y = 0; y < children.getLength(); y++) {
295+
var child = children.item(y);
296+
if (child.getNodeType() == Node.COMMENT_NODE) {
297+
var content = child.getTextContent();
298+
if (content.equals(POMBuilder.GRADLE_MAGIC_COMMENT)) {
299+
project.removeChild(child);
300+
y--;
301+
modified = true;
302+
}
303+
}
304+
}
305+
}
306+
307+
if (!modified) {
308+
org.apache.commons.io.FileUtils.copyFile(source, target);
309+
return;
310+
}
311+
312+
var transformerFactory = TransformerFactory.newInstance();
313+
var transformer = transformerFactory.newTransformer(new StreamSource(new StringReader(
314+
// This needs to strip spacing so our output doesn't have extra whitespace
315+
"""
316+
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
317+
<xsl:strip-space elements="*"/>
318+
<xsl:output method="xml" encoding="UTF-8"/>
319+
320+
<xsl:template match="@*|node()">
321+
<xsl:copy>
322+
<xsl:apply-templates select="@*|node()"/>
323+
</xsl:copy>
324+
</xsl:template>
325+
</xsl:stylesheet>
326+
"""
327+
)));
328+
329+
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //Make it pretty
330+
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
331+
332+
var output = new ByteArrayOutputStream();
333+
transformer.transform(new DOMSource(doc), new StreamResult(output));
334+
var data = output.toString().getBytes(StandardCharsets.UTF_8);
335+
336+
FileUtils.ensureParent(target);
337+
try (var os = new FileOutputStream(target)) {
338+
os.write(data);
339+
}
340+
}
244341
}

src/main/java/net/minecraftforge/mcmaven/impl/util/POMBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.function.Consumer;
2424

2525
public final class POMBuilder {
26+
public static final String GRADLE_MAGIC_COMMENT = " do_not_remove: published-with-gradle-metadata ";
2627
private final String group, name, version;
2728
private final Dependencies dependencies = new Dependencies();
2829
private @Nullable String description;
@@ -72,7 +73,7 @@ public String build() throws ParserConfigurationException, TransformerException
7273
doc.appendChild(project);
7374

7475
if (this.preferGradleModule)
75-
project.appendChild(doc.createComment(" do_not_remove: published-with-gradle-metadata "));
76+
project.appendChild(doc.createComment(GRADLE_MAGIC_COMMENT));
7677

7778
set(doc, project, "modelVersion", "4.0.0");
7879
set(doc, project, "groupId", this.group);

0 commit comments

Comments
 (0)