dropbox / dependency-guard

A Gradle plugin that guards against unintentional dependency changes.
Apache License 2.0
417 stars 15 forks source link

Don't apply the LifecycleBasePlugin if already applied #36

Closed ZacSweers closed 2 years ago

ZacSweers commented 2 years ago

Ran into this crash while testing this out in our root project

Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin class 'org.gradle.language.base.plugins.LifecycleBasePlugin'.
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:173)
        at org.gradle.api.internal.plugins.DefaultPluginManager.addImperativePlugin(DefaultPluginManager.java:89)
        at org.gradle.api.internal.plugins.DefaultPluginManager.addImperativePlugin(DefaultPluginManager.java:96)
        at org.gradle.api.internal.plugins.DefaultPluginContainer.apply(DefaultPluginContainer.java:77)
        at com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPlugin.attachToCheckTask(DependencyGuardPlugin.kt:50)
        at com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPlugin.apply(DependencyGuardPlugin.kt:42)
        at com.dropbox.gradle.plugins.dependencyguard.DependencyGuardPlugin.apply(DependencyGuardPlugin.kt:16)
        at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:43)
        at org.gradle.api.internal.plugins.RuleBasedPluginTarget.applyImperative(RuleBasedPluginTarget.java:51)
        at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:187)
        at org.gradle.api.internal.plugins.DefaultPluginManager.access$100(DefaultPluginManager.java:52)
        at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:282)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
        at org.gradle.api.internal.plugins.DefaultPluginManager.lambda$doApply$0(DefaultPluginManager.java:167)
        at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:44)
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:166)
        at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:146)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$applyLegacyPlugin$2(DefaultPluginRequestApplicator.java:160)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:201)
        ... 179 more
Caused by: org.gradle.api.internal.tasks.DefaultTaskContainer$DuplicateTaskException: Cannot add task 'clean' as a task with that name already exists.
        at org.gradle.api.internal.tasks.DefaultTaskContainer.failOnDuplicateTask(DefaultTaskContainer.java:257)
        at org.gradle.api.internal.tasks.DefaultTaskContainer.registerTask(DefaultTaskContainer.java:398)
        at org.gradle.api.internal.tasks.DefaultTaskContainer.register(DefaultTaskContainer.java:375)
        at org.gradle.language.base.plugins.LifecycleBasePlugin.addClean(LifecycleBasePlugin.java:58)
        at org.gradle.language.base.plugins.LifecycleBasePlugin.apply(LifecycleBasePlugin.java:44)
        at org.gradle.language.base.plugins.LifecycleBasePlugin.apply(LifecycleBasePlugin.java:33)
        at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:43)
        at org.gradle.api.internal.plugins.RuleBasedPluginTarget.applyImperative(RuleBasedPluginTarget.java:51)
        at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:187)
        at org.gradle.api.internal.plugins.DefaultPluginManager.access$100(DefaultPluginManager.java:52)
        at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:282)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
        at org.gradle.api.internal.plugins.DefaultPluginManager.lambda$doApply$0(DefaultPluginManager.java:167)
        at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:44)
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:166)
        ... 204 more
ZacSweers commented 2 years ago

Actually I wonder if this would be better off like so. Thoughts? CC @autonomousapps

pluginManager.withPlugin("base") {
    // Attach the "dependencyGuard" task to the "check" lifecycle task
    target.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME).configure {
        this.dependsOn(dependencyGuardTask)
    }
}
autonomousapps commented 2 years ago

I think a solution that uses pluginManager.withPlugin("base") {} is strongly preferred. There is no reason to apply the plugin just to get the check task -- that doesn't give you anything. If the task exists, then configure it. If it doesn't, don't.

handstandsam commented 2 years ago

Alternate change that would still ensure a :check task exists for the root project. https://github.com/dropbox/dependency-guard/pull/39

handstandsam commented 2 years ago

This is the most idiomatic for Gradle. Approved!