-
Notifications
You must be signed in to change notification settings - Fork 5
Conversation
…n dsl files to identify the project type
ktlint fixes
created a data class to avoid mistakes and help with maintenance
created a data class to avoid mistakes and help with maintenance
replaced deep search with walkTopDown function and added max depth extension field to improve looking for build scripts inner folders/paths now are separated by inner objects instead a constant using underscore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pushing this contribution 🙂
I have some questions for you :
[...] So, this pull request is not to solve test or check task only. But to deliver a new way to solve other things related to similar contexts.
Could you elaborate more around this use case? To be quite honest here, I don't see the correlation between constants auto-mapped at buildSrc
and Gradle task names
allAvailable now is a HashSet instead of List to avoid O(N²) in operations that requires check contains.
Why would be this optimisation needed at all? If you have a multi-hundred module build - ie, an already HUGE project - most likely the current version of this plugin parses the project structure in a few dozen milliseconds, which is pretty much doable in the overall build time for most of project tasks. In the other* hand, I felt the implementation driven by such HashSet looks harder to read and understand compared to the actual one ...
Do you have some concrete use cases and/or benchmarks that would make it clear why this optimisation is needed?
deepSearch was replaced with walkTopDown from FileTreeWalk. The main reasons are that we can use the maxDepth function to avoid walk until the last file in depth and onEnter to avoid enter in folders that doesn't contains build.gradle(.kts)
While this optimisation is quite handy, it is also possible to be achieved by fine tuning the current DSF, right? 😄
In addition to the question above, I'm curious to learn why did you remove yourself from the contributors for this project... It is my pleasure to have you listed here, given your previous PR 🙂
Last, but not least : seems the latest commit you pushed is missed a lost Github Check from Codebeat, could you please have a look on that (maybe pushing more commits, or squashing the existing ones)?
var rawLibraryPlugins: List<String> = listOf( | ||
"com.android.library", "kotlin", "com.android.dynamic-feature", "jvm" | ||
"com.android.library", "com.android.dynamic-feature" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very good addition 💯
override fun hashCode(): Int { | ||
return value.hashCode() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic looks like a bit convoluted, specially for equals
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was generated by IDE. I agree about convolution. This is a generated code that I avoid to use. It was generated while I was testing the write Tree. I'll change.
I knew that will generate some doubts. 😄
The correlation here is when we need link projects to tasks in some manner. Mainly when we need create custom or link Gradle tasks that depends other modules grade task.
val projectsToPublish = listOf(
JavaModules.PathA.MODULEA, // :patha:modulea
JavaModules.PathA.MODULEB, // :patha:moduleb
LibraryModules.PathB.MODULEA, // :pathb:modulea
LibraryModules.PathB.MODULEC, // :pathb:modulec
)
// This tasks publish all modules associated using dependsOn
tasks.register("publishLibraries") {
dependsOn(
*projectsToPublish
.map { modulePath -> "$modulePath:publish" }
.toTypedArray()
)
doLast {
println(">> All libraries published <<")
}
}
val javaModules = listOf(
JavaModules.PathA.MODULEA, // :patha:modulea
JavaModules.PathA.MODULEB, // :patha:moduleb
)
val librariesModules = listOf(
LibraryModules.PathB.MODULEA, // :pathb:modulea
LibraryModules.PathB.MODULEC, // :pathb:modulec
)
// This task runs just specific unit test tasks
tasks.register("runUnitTests") {
fun mapPathWithoutBuildType(projectPath: String) = "$projectPath:test"
fun mapPathWithBuildType(projectPath: String) = "$projectPath:testReleaseUnitTest"
dependsOn(
*(
javaModules.map(::mapPathWithoutBuildType) +
librariesModules.map(::mapPathWithBuildType)
).toTypedArray()
)
doLast {
println(">> All Unit test passed <<")
}
} And so on...
Well, about subprojects {
// HashSet helps here using contains insteand of other List operations
if (JavaModules.allAvailable.contains(this.path) || LibraryModules.PathA.allAvailable.contains(this.path)) {
// apply project configurations
}
}
Yes, I totally agree. But
This was a mistake. I'll revert 😄
I'll check what happened. |
revert README contribution section
@programadorthi Thanks for the explanations. My comments about About the correlation between module names and custom Gradle tasks The examples you provided are quite clear and the use case is quite legit. I think this change is quite welcome then. About Hashset implementation to store Module names Unfortunately, I don't see this a strong use case here. Looks really handy for your specific needs, but too specific for the purpose of this plugin and for the overall semantics it provides. About walkTopDown optimisation Imho, such optimisation is not related with the main use case you are trying to tackle here; but you can keep it as you wish. |
Btw, I just removed the Codebeat integration with this project for now, since it looks quite unstable regarding the CI checks |
I understand. I'm was analyzing and I think that HashSet is a specific case. I'll revert to List.
About this case, I made a mistake. I forgot to move time measurement from apply function to I'll keep for now because in a project with 50 modules, when all modules is organized in the root fold, without deepSearch was better than with it. First sync was 100 milliseconds with
Well, I was looking for the reason that has stopped codebeat validation, but I think the reason was not my PR. |
@programadorthi Looks great! Please, make sure your fork is up-to-date with current |
Sometimes we need apply some configurations to subprojects checking for project type (Application, Android Library or Java Library). For instance, when we have modules Java and Android inside same project, the only way to run both unit tests is calling
test
orcheck
task. The problem here is that if your Android module has many BuildTypes or combinations with ProductFlavors,test
orcheck
task will run for each BuildType/ProductFlavor.BuildTypes: debug and release
Tasks will be executed:
Things become worst if we have ProductFlavors: development, sandbox, production
Tasks will be executed:
So, this pull request is not to solve
test
orcheck
task only. But to deliver a new way to solve other things related to similar contexts.Libraries.kt
or broken inJavaModules.kt
andAndroidModules.kt
and now we know what projects are java or android only;:commons:utils
generate:allAvailable
now is a HashSet instead of List to avoid O(N²) in operatios that requires check contains.deepSearch
was replaced withwalkTopDown
from FileTreeWalk. The main reasons are that we can use themaxDepth
function to avoid walk until the last file in depth andonEnter
to avoid enter in folders that doesn't containsbuild.gradle(.kts)
files. MaxDepth can improve perfomance when we have a fixed structure.