Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ spotless {
kotlin {
ktlint().editorConfigOverride(
mapOf(
"indent_size" to "4",
"indent_size" to "2",
),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,119 +17,119 @@ import org.gradle.jvm.application.scripts.TemplateBasedScriptGenerator
import org.gradle.jvm.toolchain.JavaToolchainService

abstract class ShadowApplicationPlugin : Plugin<Project> {
private lateinit var project: Project
private lateinit var javaApplication: JavaApplication
private lateinit var project: Project
private lateinit var javaApplication: JavaApplication

override fun apply(project: Project) {
this.project = project
this.javaApplication = project.extensions.getByType(JavaApplication::class.java)
override fun apply(project: Project) {
this.project = project
this.javaApplication = project.extensions.getByType(JavaApplication::class.java)

addRunTask()
addCreateScriptsTask()
configureDistSpec()
configureJarMainClass()
configureInstallTask()
}
addRunTask()
addCreateScriptsTask()
configureDistSpec()
configureJarMainClass()
configureInstallTask()
}

protected open fun configureJarMainClass() {
val classNameProvider = javaApplication.mainClass
shadowJar.configure { jar ->
jar.inputs.property("mainClassName", classNameProvider)
jar.doFirst {
jar.manifest.attributes["Main-Class"] = classNameProvider.get()
}
}
protected open fun configureJarMainClass() {
val classNameProvider = javaApplication.mainClass
shadowJar.configure { jar ->
jar.inputs.property("mainClassName", classNameProvider)
jar.doFirst {
jar.manifest.attributes["Main-Class"] = classNameProvider.get()
}
}
}

protected open fun addRunTask() {
project.tasks.register(SHADOW_RUN_TASK_NAME, JavaJarExec::class.java) {
val install = project.tasks.named(SHADOW_INSTALL_TASK_NAME, Sync::class.java)
it.dependsOn(install)
it.mainClass.set("-jar")
it.description = "Runs this project as a JVM application using the shadow jar"
it.group = ApplicationPlugin.APPLICATION_GROUP
it.conventionMapping.map("jvmArgs") { javaApplication.applicationDefaultJvmArgs }
it.jarFile.fileProvider(
project.providers.provider {
project.file("${install.get().destinationDir.path}/lib/${shadowJar.get().archiveFile.get().asFile.name}")
},
)
val toolchain = project.extensions.getByType(JavaPluginExtension::class.java).toolchain
val defaultLauncher = project.extensions.getByType(JavaToolchainService::class.java)
.launcherFor(toolchain)
it.javaLauncher.set(defaultLauncher)
}
protected open fun addRunTask() {
project.tasks.register(SHADOW_RUN_TASK_NAME, JavaJarExec::class.java) {
val install = project.tasks.named(SHADOW_INSTALL_TASK_NAME, Sync::class.java)
it.dependsOn(install)
it.mainClass.set("-jar")
it.description = "Runs this project as a JVM application using the shadow jar"
it.group = ApplicationPlugin.APPLICATION_GROUP
it.conventionMapping.map("jvmArgs") { javaApplication.applicationDefaultJvmArgs }
it.jarFile.fileProvider(
project.providers.provider {
project.file("${install.get().destinationDir.path}/lib/${shadowJar.get().archiveFile.get().asFile.name}")
},
)
val toolchain = project.extensions.getByType(JavaPluginExtension::class.java).toolchain
val defaultLauncher = project.extensions.getByType(JavaToolchainService::class.java)
.launcherFor(toolchain)
it.javaLauncher.set(defaultLauncher)
}
}

protected open fun addCreateScriptsTask() {
project.tasks.register(SHADOW_SCRIPTS_TASK_NAME, CreateStartScripts::class.java) {
(it.unixStartScriptGenerator as TemplateBasedScriptGenerator).template =
project.resources.text.fromString(this::class.java.requireResourceAsText("internal/unixStartScript.txt"))
(it.windowsStartScriptGenerator as TemplateBasedScriptGenerator).template =
project.resources.text.fromString(this::class.java.requireResourceAsText("internal/windowsStartScript.txt"))
it.description = "Creates OS specific scripts to run the project as a JVM application using the shadow jar"
it.group = ApplicationPlugin.APPLICATION_GROUP
it.classpath = project.files(shadowJar)
it.conventionMapping.map("mainClassName") { javaApplication.mainClass.get() }
it.conventionMapping.map("applicationName") { javaApplication.applicationName }
it.conventionMapping.map("outputDir") { project.layout.buildDirectory.dir("scriptsShadow").get().asFile }
it.conventionMapping.map("defaultJvmOpts") { javaApplication.applicationDefaultJvmArgs }
it.inputs.files(project.files(shadowJar))
}
protected open fun addCreateScriptsTask() {
project.tasks.register(SHADOW_SCRIPTS_TASK_NAME, CreateStartScripts::class.java) {
(it.unixStartScriptGenerator as TemplateBasedScriptGenerator).template =
project.resources.text.fromString(this::class.java.requireResourceAsText("internal/unixStartScript.txt"))
(it.windowsStartScriptGenerator as TemplateBasedScriptGenerator).template =
project.resources.text.fromString(this::class.java.requireResourceAsText("internal/windowsStartScript.txt"))
it.description = "Creates OS specific scripts to run the project as a JVM application using the shadow jar"
it.group = ApplicationPlugin.APPLICATION_GROUP
it.classpath = project.files(shadowJar)
it.conventionMapping.map("mainClassName") { javaApplication.mainClass.get() }
it.conventionMapping.map("applicationName") { javaApplication.applicationName }
it.conventionMapping.map("outputDir") { project.layout.buildDirectory.dir("scriptsShadow").get().asFile }
it.conventionMapping.map("defaultJvmOpts") { javaApplication.applicationDefaultJvmArgs }
it.inputs.files(project.files(shadowJar))
}
}

protected open fun configureInstallTask() {
project.tasks.named(SHADOW_INSTALL_TASK_NAME, Sync::class.java).configure { task ->
val applicationName = project.providers.provider { javaApplication.applicationName }
protected open fun configureInstallTask() {
project.tasks.named(SHADOW_INSTALL_TASK_NAME, Sync::class.java).configure { task ->
val applicationName = project.providers.provider { javaApplication.applicationName }

task.doFirst {
if (
!task.destinationDir.listFiles().isNullOrEmpty() &&
(
!task.destinationDir.resolve("lib").isDirectory ||
!task.destinationDir.resolve("bin").isDirectory
)
) {
throw GradleException(
"The specified installation directory '${task.destinationDir}' is neither empty nor does it contain an installation for '${applicationName.get()}'.\n" +
"If you really want to install to this directory, delete it and run the install task again.\n" +
"Alternatively, choose a different installation directory.",
)
}
}
task.doLast {
task.eachFile {
if (it.path == "bin/${applicationName.get()}") {
it.mode = 0x755
}
}
}
task.doFirst {
if (
!task.destinationDir.listFiles().isNullOrEmpty() &&
(
!task.destinationDir.resolve("lib").isDirectory ||
!task.destinationDir.resolve("bin").isDirectory
)
) {
throw GradleException(
"The specified installation directory '${task.destinationDir}' is neither empty nor does it contain an installation for '${applicationName.get()}'.\n" +
"If you really want to install to this directory, delete it and run the install task again.\n" +
"Alternatively, choose a different installation directory.",
)
}
}
task.doLast {
task.eachFile {
if (it.path == "bin/${applicationName.get()}") {
it.mode = 0x755
}
}
}
}
}

protected open fun configureDistSpec() {
project.extensions.getByType(DistributionContainer::class.java)
.register(ShadowBasePlugin.DISTRIBUTION_NAME) { distributions ->
distributions.contents { contents ->
contents.from(project.file("src/dist"))
contents.into("lib") { lib ->
lib.from(shadowJar)
lib.from(project.configurations.named(ShadowBasePlugin.CONFIGURATION_NAME))
}
contents.into("bin") { bin ->
bin.from(project.tasks.named(SHADOW_SCRIPTS_TASK_NAME))
bin.filePermissions { it.unix(493) }
}
}
}
}
protected open fun configureDistSpec() {
project.extensions.getByType(DistributionContainer::class.java)
.register(ShadowBasePlugin.DISTRIBUTION_NAME) { distributions ->
distributions.contents { contents ->
contents.from(project.file("src/dist"))
contents.into("lib") { lib ->
lib.from(shadowJar)
lib.from(project.configurations.named(ShadowBasePlugin.CONFIGURATION_NAME))
}
contents.into("bin") { bin ->
bin.from(project.tasks.named(SHADOW_SCRIPTS_TASK_NAME))
bin.filePermissions { it.unix(493) }
}
}
}
}

protected val shadowJar: TaskProvider<ShadowJar>
get() = project.tasks.named(ShadowJavaPlugin.SHADOW_JAR_TASK_NAME, ShadowJar::class.java)
protected val shadowJar: TaskProvider<ShadowJar>
get() = project.tasks.named(ShadowJavaPlugin.SHADOW_JAR_TASK_NAME, ShadowJar::class.java)

companion object {
const val SHADOW_RUN_TASK_NAME: String = "runShadow"
const val SHADOW_SCRIPTS_TASK_NAME: String = "startShadowScripts"
const val SHADOW_INSTALL_TASK_NAME: String = "installShadowDist"
}
companion object {
const val SHADOW_RUN_TASK_NAME: String = "runShadow"
const val SHADOW_SCRIPTS_TASK_NAME: String = "startShadowScripts"
const val SHADOW_INSTALL_TASK_NAME: String = "installShadowDist"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@ import org.gradle.util.GradleVersion

abstract class ShadowBasePlugin : Plugin<Project> {

override fun apply(project: Project) {
if (GradleVersion.current() < GradleVersion.version("8.3")) {
throw GradleException("This version of Shadow supports Gradle 8.3+ only. Please upgrade.")
}
project.extensions.create(EXTENSION_NAME, ShadowExtension::class.java, project)
project.configurations.create(CONFIGURATION_NAME)
project.tasks.register(KnowsTask.NAME, KnowsTask::class.java) { knows ->
knows.group = GROUP_NAME
knows.description = KnowsTask.DESC
}
override fun apply(project: Project) {
if (GradleVersion.current() < GradleVersion.version("8.3")) {
throw GradleException("This version of Shadow supports Gradle 8.3+ only. Please upgrade.")
}

companion object {
const val SHADOW: String = "shadow"
const val GROUP_NAME: String = SHADOW
const val EXTENSION_NAME: String = SHADOW
const val CONFIGURATION_NAME: String = SHADOW
const val COMPONENT_NAME: String = SHADOW
const val DISTRIBUTION_NAME: String = SHADOW
project.extensions.create(EXTENSION_NAME, ShadowExtension::class.java, project)
project.configurations.create(CONFIGURATION_NAME)
project.tasks.register(KnowsTask.NAME, KnowsTask::class.java) { knows ->
knows.group = GROUP_NAME
knows.description = KnowsTask.DESC
}
}

companion object {
const val SHADOW: String = "shadow"
const val GROUP_NAME: String = SHADOW
const val EXTENSION_NAME: String = SHADOW
const val CONFIGURATION_NAME: String = SHADOW
const val COMPONENT_NAME: String = SHADOW
const val DISTRIBUTION_NAME: String = SHADOW
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import org.gradle.api.publish.maven.MavenPublication

@Deprecated("This is deprecated since 8.3.2")
abstract class ShadowExtension(project: Project) {
private val components = project.components
private val components = project.components

@Deprecated("configure publication using component.shadow directly.")
fun component(publication: MavenPublication) {
publication.from(components.findByName(ShadowBasePlugin.COMPONENT_NAME))
}
@Deprecated("configure publication using component.shadow directly.")
fun component(publication: MavenPublication) {
publication.from(components.findByName(ShadowBasePlugin.COMPONENT_NAME))
}
}
Loading