Skip to content

Commit

Permalink
feat: Allow creating extensions in packages
Browse files Browse the repository at this point in the history
  • Loading branch information
oSumAtrIX committed Nov 21, 2024
1 parent 0f42166 commit c0ef614
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 80 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package app.revanced.patches.gradle

import org.gradle.api.provider.Property

abstract class ExtensionExtension {
open class ExtensionExtension {
/**
* The name of the extension.
*
* The name is the full resource path of the extension in the final patches file.
* Example: `extensions/extension.rve`.
*/
abstract val name: Property<String>
var name: String? = null
}
10 changes: 8 additions & 2 deletions src/main/kotlin/app/revanced/patches/gradle/ExtensionPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,16 @@ abstract class ExtensionPlugin : Plugin<Project> {

dependsOn(dexTask)

val extensionName = if (extension.name != null) {
Path(extension.name!!)
} else {
projectDir.resolveSibling(project.name + ".rve").relativeTo(rootDir).toPath()
}

from(dexTask.outputs.files.asFileTree.matching { include("**/*.dex") })
into(layout.buildDirectory.dir("revanced/${Path(extension.name.get()).parent.pathString}"))
into(layout.buildDirectory.dir("revanced/${extensionName.parent.pathString}"))

rename { Path(extension.name.get()).fileName.toString() }
rename { extensionName.fileName.toString() }
}

configurations.create("extensionConfiguration").apply {
Expand Down
42 changes: 14 additions & 28 deletions src/main/kotlin/app/revanced/patches/gradle/PatchesExtension.kt
Original file line number Diff line number Diff line change
@@ -1,50 +1,36 @@
package app.revanced.patches.gradle

import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import javax.inject.Inject

@Suppress("unused")
abstract class PatchesExtension @Inject constructor(objectFactory: ObjectFactory) {
open class PatchesExtension {
/**
* The path to the extensions project relative to the root project.
*
* Used by the patches plugin to consume the extension artifacts.
*
* Defaults to `:extensions`.
*/
abstract val extensionsProjectPath: Property<String>
var extensionsProjectPath: String? = ":extensions"

internal val about = objectFactory.newInstance(About::class.java)
/**
* About information for the project.
*/
val about = About()

fun about(block: About.() -> Unit) {
about.block()
}

init {
extensionsProjectPath.convention(":extensions")
}

/**
* About information for the project.
*
* Used by the patches plugin to create the manifest file and set up the publication of the patches project.
*/
abstract class About @Inject constructor(project: Project) {
abstract val name: Property<String>
abstract val description: Property<String>
abstract val source: Property<String>
abstract val author: Property<String>
abstract val contact: Property<String>
abstract val website: Property<String>
abstract val license: Property<String>
internal abstract val version: Property<String>
internal abstract val timestamp: Property<Long>

init {
version.convention(project.version.toString())
timestamp.convention(System.currentTimeMillis())
}
class About {
var name: String? = null
var description: String? = null
var source: String? = null
var author: String? = null
var contact: String? = null
var website: String? = null
var license: String? = null
}
}
10 changes: 5 additions & 5 deletions src/main/kotlin/app/revanced/patches/gradle/PatchesPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,13 @@ abstract class PatchesPlugin : Plugin<Project> {
*/
private fun Project.configureConsumeExtensions(patchesExtension: PatchesExtension) {
val extensionsProject = try {
project(patchesExtension.extensionsProjectPath.get())
project(patchesExtension.extensionsProjectPath ?: return)
} catch (e: UnknownProjectException) {
return
}

val extensionProjects = extensionsProject.subprojects.filter {
it.parent == extensionsProject
val extensionProjects = extensionsProject.subprojects.filter { extensionProject ->
extensionProject.plugins.hasPlugin(ExtensionPlugin::class.java)
}

val extensionsDependencyScopeConfiguration =
Expand Down Expand Up @@ -232,8 +232,8 @@ private fun Project.configureJarTask(patchesExtension: PatchesExtension) {
it.manifest.apply {
attributes["Name"] = patchesExtension.about.name
attributes["Description"] = patchesExtension.about.description
attributes["Version"] = patchesExtension.about.version
attributes["Timestamp"] = patchesExtension.about.timestamp
attributes["Version"] = project.version.toString()
attributes["Timestamp"] = System.currentTimeMillis().toString()
attributes["Source"] = patchesExtension.about.source
attributes["Author"] = patchesExtension.about.author
attributes["Contact"] = patchesExtension.about.contact
Expand Down
37 changes: 15 additions & 22 deletions src/main/kotlin/app/revanced/patches/gradle/SettingsExtension.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
package app.revanced.patches.gradle

import org.gradle.api.provider.Property

abstract class SettingsExtension {
open class SettingsExtension {
/**
* The path to the patches project relative to the root project.
*
* Used by the settings plugin to include the patches project
* and apply the patches plugin to the patches project.
*
* Defaults to `patches`.
* The path to the patches project.
*/
abstract val patchesProjectPath: Property<String>
var patchesProjectPath = "patches"

/**
* The path to the extensions project relative to the root project.
*
* Used by the settings plugin to include the extensions project
* and apply the extensions plugin to the extensions project.
*
* Defaults to `extensions`.
*/
abstract val extensionsProjectPath: Property<String>
// Need to rename, otherwise it will conflict with the `getExtensions` property from ExtensionAware.
@get:JvmName("getExtensionsExtension")
val extensions = ExtensionsExtension()

fun extensions(block: ExtensionsExtension.() -> Unit) {
ExtensionsExtension().apply(block)
}

init {
patchesProjectPath.convention("patches")
extensionsProjectPath.convention("extensions")
class ExtensionsExtension {
/**
* The path to the project containing the extension projects.
*/
var projectPath: String? = "extensions"
}
}
47 changes: 28 additions & 19 deletions src/main/kotlin/app/revanced/patches/gradle/SettingsPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ abstract class SettingsPlugin @Inject constructor(
val extension = settings.extensions.create("settings", SettingsExtension::class.java)

settings.configureDependencies()
settings.configureIncludeProjects(extension)
settings.configurePlugins(extension)
settings.configureProjects(extension)
}

/**
Expand All @@ -39,36 +38,46 @@ abstract class SettingsPlugin @Inject constructor(
}

/**
* Add the patches and extension projects to the root project.
* Adds the required plugins to the patches and extension projects.
*/
private fun Settings.configureIncludeProjects(extension: SettingsExtension) {
include(extension.patchesProjectPath.get())
private fun Settings.configureProjects(extension: SettingsExtension) {
// region Include the projects

val extensionsProjectPath = extension.extensions.projectPath ?: return

objectFactory.fileTree().from(settingsDir.resolve(extension.extensionsProjectPath.get())).matching {
objectFactory.fileTree().from(rootDir.resolve(extensionsProjectPath)).matching {
it.include("**/build.gradle.kts")
}.forEach {
include(it.relativeTo(settingsDir).toPath().joinToString(":"))
include(it.relativeTo(rootDir).toPath().joinToString(":"))
}
}

/**
* Adds the required plugins to the patches and extension projects.
*/
private fun Settings.configurePlugins(extension: SettingsExtension) {
gradle.rootProject { rootProject ->
rootProject.project(extension.patchesProjectPath.get()).pluginManager.apply(PatchesPlugin::class.java)
include(extension.patchesProjectPath)

try {
rootProject.project(extension.extensionsProjectPath.get())
// endregion

// region Apply the plugins

gradle.rootProject { rootProject ->
val extensionsProject = try {
rootProject.project(extensionsProjectPath)
} catch (e: UnknownProjectException) {
return@rootProject
}.let { extensionsProject ->
extensionsProject.subprojects { extensionProject ->
if (extensionProject.parent != extensionsProject) return@subprojects
}

extensionsProject.subprojects { extensionProject ->
if (
extensionProject.buildFile.exists() &&
!extensionProject.parent!!.plugins.hasPlugin(ExtensionPlugin::class.java)
) {
extensionProject.pluginManager.apply(ExtensionPlugin::class.java)
}
}

// Needs to be applied after the extension plugin
// so that their extensionConfiguration is available for consumption.
rootProject.project(extension.patchesProjectPath).pluginManager.apply(PatchesPlugin::class.java)
}

// endregion
}
}

0 comments on commit c0ef614

Please sign in to comment.