Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.lagradost.cloudstream3.gradle.tasks

import org.gradle.api.tasks.Exec
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.provider.Property
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.GradleException
import java.io.File

abstract class EnsureJarCompatibilityTask : Exec() {

@get:InputFile
@get:Optional
abstract val jarFile: RegularFileProperty

@get:Input
abstract val hasCrossPlatformSupport: Property<Boolean>

@get:OutputFile
val outputFile = project.layout.buildDirectory.file("jdeps-output.txt")

override fun exec() {
if (!hasCrossPlatformSupport.get()) return

val jar = jarFile.get().asFile
if (!jar.exists()) throw GradleException("Jar file does not exist: ${jar.absolutePath}")

commandLine("jdeps", "--print-module-deps", jar.absolutePath)
standardOutput = outputFile.get().asFile.outputStream()
errorOutput = System.err
isIgnoreExitValue = true

super.exec() // actually runs the exec
}

fun checkOutput() {
val output = outputFile.get().asFile.readText().trim()
when {
output.isEmpty() -> logger.warn("No output from jdeps! Cannot analyze jar file for Android imports!")
"android." in output -> throw GradleException(
"The cross-platform jar file contains Android imports! " +
"This will cause compatibility issues.\nRemove 'isCrossPlatform = true' or remove the Android imports."
)
else -> logger.lifecycle("SUCCESS: The cross-platform jar file does not contain Android imports")
}
}
}
80 changes: 24 additions & 56 deletions src/main/kotlin/com/lagradost/cloudstream3/gradle/tasks/Tasks.kt
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
package com.lagradost.cloudstream3.gradle.tasks

import com.lagradost.cloudstream3.gradle.getCloudstream
import com.lagradost.cloudstream3.gradle.makeManifest
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.tasks.ProcessLibraryManifest
import com.lagradost.cloudstream3.gradle.getCloudstream
import com.lagradost.cloudstream3.gradle.makeManifest
import groovy.json.JsonBuilder
import groovy.json.JsonGenerator
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.tasks.AbstractCopyTask
import org.gradle.api.tasks.Exec
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.ByteArrayOutputStream
import org.gradle.api.GradleException
import java.io.File

const val TASK_GROUP = "cloudstream"

fun registerTasks(project: Project) {
val extension = project.extensions.getCloudstream()
val intermediates = project.buildDir.resolve("intermediates")
val intermediatesDir = project.layout.buildDirectory.dir("intermediates")

if (project.rootProject.tasks.findByName("makePluginsJson") == null) {
project.rootProject.tasks.register("makePluginsJson", MakePluginsJsonTask::class.java) {
it.group = TASK_GROUP

it.outputs.upToDateWhen { false }

it.outputFile.set(it.project.buildDir.resolve("plugins.json"))
it.outputFile.set(it.project.layout.buildDirectory.file("plugins.json"))
}
}

project.tasks.register("genSources", GenSourcesTask::class.java) {
it.group = TASK_GROUP
}

val pluginClassFile = intermediates.resolve("pluginClass")
val pluginClassFile = intermediatesDir.map { it.file("pluginClass") }

val compileDex = project.tasks.register("compileDex", CompileDexTask::class.java) {
it.group = TASK_GROUP
Expand All @@ -56,7 +56,7 @@ fun registerTasks(project: Project) {
// it.input.from(javacTask.destinationDirectory)
// }

it.outputFile.set(intermediates.resolve("classes.dex"))
it.outputFile.set(intermediatesDir.map { it.file("classes.dex") })
}

val compileResources =
Expand All @@ -71,7 +71,7 @@ fun registerTasks(project: Project) {
it.input.set(android.sourceSets.getByName("main").res.srcDirs.single())
it.manifestFile.set(processManifestTask.manifestOutputFile)

it.outputFile.set(intermediates.resolve("res.apk"))
it.outputFile.set(intermediatesDir.map { it.file("res.apk") })

it.doLast { _ ->
val resApkFile = it.outputFile.asFile.get()
Expand All @@ -92,8 +92,8 @@ fun registerTasks(project: Project) {

it.doFirst {
if (extension.pluginClassName == null) {
if (pluginClassFile.exists()) {
extension.pluginClassName = pluginClassFile.readText()
if (pluginClassFile.get().asFile.exists()) {
extension.pluginClassName = pluginClassFile.get().asFile.readText()
}
}
}
Expand All @@ -107,8 +107,7 @@ fun registerTasks(project: Project) {
val jarFile =
jarTask.outputs.files.singleFile // Output directory of createFullJarDebug
if (jarFile != null) {
val targetDir = project.buildDir // Top-level build directory
val targetFile = targetDir.resolve("${project.name}.jar")
val targetFile = project.layout.buildDirectory.file("${project.name}.jar").get().asFile
jarFile.copyTo(targetFile, overwrite = true)
extension.jarFileSize = jarFile.length()
it.logger.lifecycle("Made Cloudstream cross-platform package at ${targetFile.absolutePath}")
Expand All @@ -118,44 +117,13 @@ fun registerTasks(project: Project) {
}
}

val ensureJarCompatibility = project.tasks.register("ensureJarCompatibility") {
it.group = TASK_GROUP
it.dependsOn("compilePluginJar")
it.doLast { task ->
if (!extension.isCrossPlatform) {
return@doLast
}

val jarFile = File("${project.buildDir}/${project.name}.jar")
if (!jarFile.exists()) {
throw GradleException("Jar file does not exist.")
return@doLast
}

// Run jdeps command
try {
val jdepsOutput = ByteArrayOutputStream()
val jdepsCommand = listOf("jdeps", "--print-module-deps", jarFile.absolutePath)

project.exec { execTask ->
execTask.setCommandLine(jdepsCommand)
execTask.setStandardOutput(jdepsOutput)
execTask.setErrorOutput(System.err)
execTask.setIgnoreExitValue(true)
}

val output = jdepsOutput.toString()

// Check if 'android.' is in the output
if (output.isEmpty()) {
task.logger.warn("No output from jdeps! Cannot analyze jar file for Android imports!")
} else if (output.contains("android.")) {
throw GradleException("The cross-platform jar file contains Android imports! This will cause compatibility issues.\nRemove 'isCrossPlatform = true' or remove the Android imports.")
} else {
task.logger.lifecycle("SUCCESS: The cross-platform jar file does not contain Android imports")
}
} catch (e: org.gradle.process.internal.ExecException) {
task.logger.warn("Jdeps failed! Cannot analyze jar file for Android imports!")
project.tasks.register("ensureJarCompatibility", EnsureJarCompatibilityTask::class.java) { task ->
task.dependsOn("compilePluginJar")
task.hasCrossPlatformSupport.set(extension.isCrossPlatform)
if (extension.isCrossPlatform) {
task.jarFile.set(project.layout.buildDirectory.file("${project.name}.jar"))
task.doLast {
task.checkOutput()
}
}
}
Expand All @@ -168,16 +136,16 @@ fun registerTasks(project: Project) {
it.dependsOn(compilePluginJar)
}

val manifestFile = intermediates.resolve("manifest.json")
val manifestFile = intermediatesDir.map { it.file("manifest.json") }.get()
it.from(manifestFile)
it.doFirst {
if (extension.pluginClassName == null) {
if (pluginClassFile.exists()) {
extension.pluginClassName = pluginClassFile.readText()
if (pluginClassFile.get().asFile.exists()) {
extension.pluginClassName = pluginClassFile.get().asFile.readText()
}
}

manifestFile.writeText(
manifestFile.asFile.writeText(
JsonBuilder(
project.makeManifest(),
JsonGenerator.Options()
Expand All @@ -197,7 +165,7 @@ fun registerTasks(project: Project) {
zip.archiveBaseName.set(project.name)
zip.archiveExtension.set("cs3")
zip.archiveVersion.set("")
zip.destinationDirectory.set(project.buildDir)
zip.destinationDirectory.set(project.layout.buildDirectory)

it.doLast { task ->
extension.fileSize = task.outputs.files.singleFile.length()
Expand Down