Closed JLLeitschuh closed 3 years ago
This is correct. Reason is that on Cpd
task can only run one langugage
. However, you can create multiple Cpd
tasks with differently configured language
and source
attributes. An example will follow...
This is the snippet that I've been using utilizing the Gradle Kotlin DSL:
tasks.register<Cpd>("cpdKotlin") {
language = "kotlin"
exclude { it.file.extension.contains("java") }
allprojects.forEach { project ->
project.plugins.withType<JavaBasePlugin> {
project.convention.getPlugin<JavaPluginConvention>().sourceSets.configureEach {
allJava.srcDirTrees.forEach { this@register.source(it) }
}
}
}
}
It would be nice if the plugin could detect mixed kotlin/java projects automatically and auto-generate the correct tasks for you.
That looks good from first view. Does it work for you? And let me think about your suggestion...
This does work well for me. I've embedded it in my own build.
And let me think about your suggestion...
🤔 Would be awesome!
Hi @JLLeitschuh, thought about it but unfortunately without any clear result. Only thing I can currently think of is to create a mapping and create cpdCheck${LANG}
tasks for every recognized and available LANG
applied by a known plugin...
I have no clue if a lot people use this plugin for multiple languages, however some kind of auto detection could be a nice improvement...
Would it possible to provide an example using Gradle groovy DSL?
@grushler the one to one translation of example above would be
import de.aaschmid.gradle.plugins.cpd.Cpd
task cpdKotlin(type: Cpd) {
language = "kotlin"
exclude { it.file.extension.contains("java") }
allprojects.forEach { project ->
project.plugins.withType(JavaBasePlugin) { plugin ->
project.sourceSets.forEach { ss -> ss.allJava.forEach { rootProject.cpdKotlin.source(it) } }
}
}
}
Disclaimer: not tested with a Kotlin project actually but don't hesitate to complain if it does not ;-)
Note: The rootProject
need to be adjusted if your copy-paste-detection should be applied to a different project.
Thank you @aaschmid . I tested the provided code, but get below error (added with stacktrace) -
> Task :cpdKotlin FAILED
1 actionable task: 1 executed
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':cpdKotlin'.
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:38)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: groovy.lang.MissingPropertyException: No such property: extension for class: java.io.File
at build_2p5hiyvlrsgqi2g70hxystd36$_run_closure17$_closure32.doCall(/Users/dev/workspace/test-api/build.gradle:320)
at org.gradle.api.specs.internal.ClosureSpec.isSatisfiedBy(ClosureSpec.java:32)
at org.gradle.api.specs.OrSpec.isSatisfiedBy(OrSpec.java:47)
at org.gradle.api.specs.NotSpec.isSatisfiedBy(NotSpec.java:35)
at org.gradle.api.internal.file.collections.AbstractSingletonFileTree.visit(AbstractSingletonFileTree.java:35)
at org.gradle.api.internal.file.collections.FileTreeAdapter.visit(FileTreeAdapter.java:118)
at org.gradle.api.internal.file.AbstractFileTree.isEmpty(AbstractFileTree.java:68)
at org.gradle.api.internal.file.CompositeFileCollection.isEmpty(CompositeFileCollection.java:99)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:67)
at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
at org.gradle.api.internal.tasks.execution.StartSnapshotTaskInputsBuildOperationTaskExecuter.execute(StartSnapshotTaskInputsBuildOperationTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:94)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:95)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
... 24 more
So I changed the exclude code and tried again - exclude { file("**/*.java") }
But I get the output as > Task :cpdKotlin NO-SOURCE
. Any changes that you would suggest?
Btw, my folder structure something like this - src -- main ---- java (contains all java files) ---- kotlin (contains all kotlin files)
@grushler
Hm ... actually I need a real reproducer in order to investigate. For now maybe you could add some print
of ss
, ss.allJava
and it
as well as cpdKotlin.source
and check the folders for their path and content. Note: For printing you may also need to use ...files
in order to displaying a readable version...
Another working way should be:
task cpdKotlin(type: Cpd) {
language = "kotlin"
source = allprojects*.file("src/main/kotlin")
}
It's a bit ugly because it hard-codes src/main/kotlin
but it is good for now IMO.
Thanks @aaschmid. That helps though there is a hardcoded path but seems to be ok to use as we usually never change the path. I will try out printing the source and verify if the location is being picked up as needed.
@JLLeitschuh any further thoughts on this?
@aaschmid sorry, this is no longer a project I'm actively using. I've left the company I was working for that was using it.
Ok, so I will close this but anyone can reopen as soon as this is an issue anymore...
I have quite a few projects that are slowly being migrated from Java to Kotlin. There doesn't seem to be a good way to support linting both Kotlin and Java since you can only specify one
language
.