Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin doesn't support projects that use both Kotlin and Java #39

Closed
JLLeitschuh opened this issue May 1, 2019 · 13 comments
Closed

Plugin doesn't support projects that use both Kotlin and Java #39

JLLeitschuh opened this issue May 1, 2019 · 13 comments
Assignees

Comments

@JLLeitschuh
Copy link

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.

@aaschmid
Copy link
Owner

aaschmid commented May 2, 2019

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...

@JLLeitschuh
Copy link
Author

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.

@aaschmid
Copy link
Owner

aaschmid commented May 3, 2019

That looks good from first view. Does it work for you?
And let me think about your suggestion...

@aaschmid aaschmid self-assigned this May 3, 2019
@JLLeitschuh
Copy link
Author

JLLeitschuh commented May 3, 2019

This does work well for me. I've embedded it in my own build.

And let me think about your suggestion...

🤔 Would be awesome!

@aaschmid
Copy link
Owner

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...

@giri-sh
Copy link

giri-sh commented Aug 28, 2020

Would it possible to provide an example using Gradle groovy DSL?

@aaschmid
Copy link
Owner

@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.

@giri-sh
Copy link

giri-sh commented Aug 31, 2020

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)

@aaschmid
Copy link
Owner

@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.

@giri-sh
Copy link

giri-sh commented Sep 1, 2020

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.

@aaschmid
Copy link
Owner

@JLLeitschuh any further thoughts on this?

@JLLeitschuh
Copy link
Author

@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.

@aaschmid
Copy link
Owner

Ok, so I will close this but anyone can reopen as soon as this is an issue anymore...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants