Create Fabric

Create Fabric

10M Downloads

Gradle Kotlin DSL?

YTG1234 opened this issue ยท 3 comments

commented

Pros:

  • Type safety
  • More IDE support
  • Better syntax

Cons:

  • Disk space (need to generate all the Kotlin accessors etc.)
  • Slightly slower to compile

Our current buildscript:

plugins {
	id("fabric-loom") version "0.6-SNAPSHOT"
	id("maven-publish")
}

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group

repositories {
	maven {
		name = "Fabric"
		url = "https://maven.fabricmc.net/"
	}

	maven {
		name = "HalfOf2"
		url = "https://raw.githubusercontent.com/Devan-Kerman/Devan-Repo/master/"
	}

	maven {
		name = "TerraformersMC"
		url = "https://maven.terraformersmc.com/"
	}

	maven {
		name = "Shedaniel"
		url "https://maven.shedaniel.me/"
	}

	maven {
		name = "JitPack"
		url = "https://jitpack.io/"

		content {
			includeGroup("com.github.SuperCoder7979") // So Gradle doesn't spend time searching JitPack for other deps
		}
	}
}

dependencies {
	minecraft("com.mojang:minecraft:${project.minecraft_version}")
	mappings("net.fabricmc:yarn:${project.yarn_mappings}:v2")
	modImplementation("net.fabricmc:fabric-loader:${project.loader_version}")

	// Fabric API. This is technically optional, but you probably want it anyway.
	modImplementation("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}") {
		exclude(module: "fabric-biomes-v1")
	}

	// Runtime resource generation
	modImplementation("net.devtech:arrp:${project.arrp_version}")
	include("net.devtech:arrp:${project.arrp_version}")

	// DataBreaker
	modRuntime("com.github.SuperCoder7979:databreaker:master-SNAPSHOT") {
		exclude(group: "net.fabricmc")
		exclude(group: "fabric-api")
	}

	// ModMenu
	modImplementation("com.terraformersmc:modmenu:${project.modmenu_version}")

	// REI
	modCompileOnly("me.shedaniel:RoughlyEnoughItems-api:${project.rei_version}")
	modRuntime("me.shedaniel:RoughlyEnoughItems:${project.rei_version}")
}

//////////// Gradle Properties ////////////
Closure properties = {
	final String createPrefix = "create."
	Map<String, Closure<Project>> map = new HashMap<>()

	/**
	* Should be configured in {@code gradle.properties} like so:
	* <code>
	*     create.debug_logs=true
	*     create.mixin_export=true
	* </code>
	*/

	map["debug_logs"] = {
		loom.runConfigs.configureEach {
			property("fabric.log.level", "debug")
		}
	}

	map["mixin_export"] = {
		loom.runConfigs.configureEach {
			property("mixin.debug.export", "true")
		}
	}

	map.forEach { str, clr ->
		if (project.hasProperty(createPrefix + str) && (
			project.property(createPrefix + str) != null &&
				project.property(createPrefix + str) != false &&
				project.property(createPrefix + str) != "false"
		)) {
			clr.delegate = project
			clr()
		}
	}
}; properties() // Sadly we don't have IIFEs in Groovy

loom {
	accessWidener = file("src/main/resources/create.accesswidener")
}

processResources {
	inputs.property "version", project.version

	filesMatching("fabric.mod.json") {
		expand "version": project.version
	}
}

tasks.withType(JavaCompile).configureEach {
	it.options.encoding = "UTF-8"
	if (JavaVersion.current().isJava9Compatible()) {
		it.options.release = 8
	}
}

tasks.withType(Wrapper).configureEach {
	it.gradleVersion = "6.8.3"
	it.distributionType = Wrapper.DistributionType.BIN
}

java {
	// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
	// if it is present.
	// If you remove this line, sources will not be generated.
	withSourcesJar()
}

jar {
	from("LICENSE") {
		rename { "${it}_${project.archivesBaseName}" }
	}
}

// configure the maven publication
publishing {
	publications {
		mavenJava(MavenPublication) {
			// add all the jars that should be included when publishing to maven
			artifact(remapJar) {
				builtBy remapJar
			}
			artifact(sourcesJar) {
				builtBy remapSourcesJar
			}
		}
	}

	// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
	repositories {
		// Add repositories to publish to here.
		// Notice: This block does NOT have the same function as the block in the top level.
		// The repositories here will be used for publishing your artifact, not for
		// retrieving dependencies.
	}
}

A Kotlin buildscript might look like (yes I made all this):

plugins {
	id("fabric-loom") version "0.6-SNAPSHOT"
	`maven-publish`
}

java {
	sourceCompatibility = JavaVersion.VERSION_1_8
	targetCompatibility = JavaVersion.VERSION_1_8

	withSourcesJar()
}

base {
	archivesBaseName = properties["archives_base_name"] as String
}

version = properties["mod_version"]!!
group = properties["maven_group"]!!

repositories {
	maven("https://maven.fabricmc.net/") {
		name = "Fabric"
	}

	maven("https://raw.githubusercontent.com/Devan-Kerman/Devan-Repo/master/") {
		name = "HalfOf2"
	}

	maven("https://maven.terraformersmc.com/") {
		name = "TerraformersMC"
	}

	maven("https://maven.shedaniel.me/") {
		name = "Shedaniel"
	}

	maven("https://jitpack.io/") {
		name = "Jitpack"

		content {
			includeGroup("com.github.SuperCoder7979") // So Gradle doesn't spend time searching JitPack for other deps
		}
	}
}

dependencies {
	// We could also use properties["..."] here but this looks cleaner
	val minecraft_version: String by project
	val yarn_mappings: String by project
	val loader_version: String by project
	val fabric_version: String by project
	val arrp_version: String by project
	val modmenu_version: String by project
	val rei_version: String by project

	minecraft("com.mojang", "minecraft", minecraft_version)
	mappings("net.fabricmc", "yarn", yarn_mappings, classifier = "v2")
	modImplementation("net.fabricmc", "fabric-loader", loader_version)

	// Fabric API
	modImplementation("net.fabricmc.fabric-api", "fabric-api", fabric_version)


	// Runtime resource generation
	modImplementation("net.devtech", "arrp", arrp_version)
	include("net.devtech", "arrp", arrp_version)

	// DataBreaker
	modRuntime("com.github.SuperCoder7979", "databreaker", "master-SNAPSHOT") {
		exclude(group = "net.fabricmc")
		exclude(group = "fabric-api")
	}

	// ModMenu
	modImplementation("com.terraformersmc", "modmenu", modmenu_version)

	// REI
	modCompileOnly("me.shedaniel", "RoughlyEnoughItems-api", rei_version)
	modRuntime("me.shedaniel", "RoughlyEnoughItems", rei_version)
}

//////////// Gradle Properties ////////////
val lambda: () -> Unit = {
	val createPrefix = "create."
	val map = mutableMapOf<String, Project.() -> Unit>()

	/**
	 * Should be configured in {@code gradle.properties} like so:
	 * <code>
	 *     create.debug_logs=true
	 *     create.mixin_export=true
	 * </code>
	 */

	map["debug_logs"] = {
		loom.runConfigs.configureEach {
			property("fabric.log.level", "debug")
		}
	}

	map["mixin_export"] = {
		loom.runConfigs.configureEach {
			property("mixin.debug.export", "true")
		}
	}

	map.forEach { str, func ->
		if (project.hasProperty(createPrefix + str) && (
				project.property(createPrefix + str) != null &&
					project.property(createPrefix + str) != false &&
					project.property(createPrefix + str) != "false"
				)) {
			project.func()
		}
	}
}; lambda()

tasks {
	processResources {
		inputs.property("version", project.version)

		filesMatching("fabric.mod.json") {
			expand("version" to project.version)
		}
	}

	withType<JavaCompile> {
		options.encoding = "UTF-8"
		if (JavaVersion.current().isJava9Compatible()) {
			options.compilerArgs.addAll(listOf("--release", "8"))
		}
	}

	withType<Wrapper> {
		gradleVersion = "6.8.3"
		distributionType = Wrapper.DistributionType.BIN
	}

	jar {
		from("LICENSE") {
			rename { "${it}_${base.archivesBaseName}" }
		}
	}
}

publishing {
	publications {
		create<MavenPublication>("mavenJava") {
			artifact(tasks.remapJar) {
				builtBy(tasks.remapJar)
			}

			artifact(tasks["sourcesJar"]) {
				builtBy(tasks.remapSourcesJar)
			}
		}
	}
}

Update: I have a working version over at YTG1234/Create-Refabricated.

commented

What do I mean by "IDE support"?
Well, let's see.

Groovy:
image

Kotlin (you can even see linting!):
image

commented

The Forge and Fabric versions use completely different buildscripts so switching to kt will not break our decision of sticking as close as possible to the Forge version.

commented

I don't really have a preference.