-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCreateAndroidModuleTask.kt
More file actions
101 lines (86 loc) · 3.26 KB
/
CreateAndroidModuleTask.kt
File metadata and controls
101 lines (86 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.options.Option
import java.io.File
import java.nio.file.Path
import kotlin.io.path.createDirectories
import kotlin.io.path.div
import kotlin.io.path.exists
import kotlin.io.path.writeText
/**
* Adds the following hierarchy to the project root:
* ```
* - subdirectories/module_name
* - .gitignore
* - build.gradle.kts
* - src/main/java/base_package/module_name
* ```
*/
abstract class CreateAndroidModuleTask : DefaultTask() {
private val nameRegex = "(:?[A-Za-z][A-Za-z0-9_]*)+"
init {
description = "Creates necessary directories and files for a new android library module."
}
/**
* Specifies a package name in a form like "com.base.package" to which a module name will be
* added to make necessary directories and android namespace for build.gradle.kts file.
*/
@Input
lateinit var basePackageName: String
@Input
@Option(
option = "name",
description = "Sets a name for the new module. To place a module in a subdirectory, use " +
"syntax :subdirectory:module_name.",
)
var moduleName: String = ""
@TaskAction
fun createModule() {
when {
moduleName.isBlank() -> throw IllegalArgumentException("Module name cannot be blank.")
!moduleName.matches(Regex(nameRegex)) ->
throw IllegalArgumentException("Module name doesn't match regex '$nameRegex'.")
}
val subdirs = moduleName.trim().trimStart(':').split(':')
val justModuleName = subdirs.last()
val namespace = "$basePackageName.$justModuleName"
val modulePath = project.projectDir.absoluteFile.toPath() /
subdirs.joinToString(File.separator)
if (modulePath.exists()) {
throw IllegalArgumentException("Path '$modulePath' already exists.")
}
println("Creating '$modulePath'.")
modulePath.createDirectories()
modulePath.writeGitignore()
modulePath.writeBuildGradle(namespace)
val javaAndPackage = modulePath / "src" / "main" / "java" /
namespace.split('.').joinToString(File.separator)
javaAndPackage.createDirectories()
println(
"Module $moduleName created, please include it in the settings.gradle.kts file " +
"and add to :app module.",
)
}
private fun Path.writeGitignore() = this
.resolve(".gitignore")
.writeText("""/build""")
// In case something needs to be added to all modules, firstly, please check if it can be added
// to convention plugins, instead of adding it here
private fun Path.writeBuildGradle(namespace: String) = this
.resolve("build.gradle.kts")
.writeText(
"""
plugins {
// TODO: Pick one of the convention plugins
id(libs.plugins.convention.android.library.get().pluginId)
id(libs.plugins.convention.feature.module.get().pluginId)
}
android {
namespace = "$namespace"
}
dependencies {
}
""".trimIndent(),
)
}