Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

Provide more friendly methods and accessors for configuring nested extensions added to the AppEngineExtension #191

Closed
mkobit opened this issue Jan 29, 2018 · 28 comments
Assignees

Comments

@mkobit
Copy link

mkobit commented Jan 29, 2018

The Kotlin DSL from Gradle is painful to use with this plugin because it extends an extension and doesn't provide methods for those nested objects on the root extension type. \

For an example of what a user would have to do, see this SO answer. Gradle currently doesn't generate nested accessors (see gradle/kotlin-dsl-samples#457 for that improvement) so it would be nice for this plugin to provide convenience methods for those nested objects.

@marceloverdijk
Copy link

+1

@loosebazooka
Copy link
Contributor

loosebazooka commented Jan 29, 2018

I'll take a look, but this requires a rewrite given how invested we are in using the dynamic extension addition. Any idea how close they are supporting it in Kotlin?

Edit: It's possible it's not a terribly large rewrite. But would still like Kotlin to just support it.

@mkobit
Copy link
Author

mkobit commented Jan 29, 2018

There is an open PR at gradle/kotlin-dsl-samples#624 , so I know that those guys are aware of it. I would expect that issue and PR to get more traction before 1.0 (which last time I heard was projected for Q1 2018). I'm not sure how many users will run into this as kotlin-dsl is still < 1.0, so it might be better to just follow that issue and take action when its status changes. If you did want to provide an immediate solution for users, you could take a route similar to how the JUnit 5 plugin handles it

@marceloverdijk
Copy link

@loosebazooka would it be an option to generate marker interfaces as described here? https://docs.gradle.org/current/userguide/custom_plugins.html#sec:using_the_java_gradle_plugin_development_plugin
That ways uses could more easily use the AppEngine plugin within the Gradle plugins {} block.
See also this comment: https://stackoverflow.com/questions/48502220/how-to-configure-appengine-gradle-plugin-using-kotlin-dsl#comment84017202_48510049

@marceloverdijk
Copy link

marceloverdijk commented Jan 30, 2018

@loosebazooka and would the route as JUnit 5 plugin took be an option to add to the AppEngine plugin to simplify users using a Kotlin build script? That sounds like an easy intermedia solution while waiting for gradle/kotlin-dsl-samples#457.

@loosebazooka
Copy link
Contributor

The solutions in those links don't appear to handle the case here that we generate different extension hierarchies for standard and flex projects (for example "run" doesn't appear in the appengine configuration block for flex projects). I think the point is that we just have to statically build our two different extensions (standard, flex) instead of building them up as we do now.

@loosebazooka
Copy link
Contributor

on that note, I'm working towards statically creating these extensions.

@marceloverdijk
Copy link

@loosebazooka if you need a tester or something, let me know if I can be of help.

@loosebazooka
Copy link
Contributor

@marceloverdijk I've tried this out and it doesn't seem to break my test suite, but not specifically with kotlin. You can try the code in #192 if you want to see if it fixes your issues.

Here are some simple instructions if you need them:

$ git clone https://github.com/GoogleCloudPlatform/app-gradle-plugin.git
$ git fetch origin staticExtensions
$ git checkout -b staticExtensions origin/staticExtensions
$ ./gradlew install

change your build file to add in pulling from mavenLocal and use the snapshot you just installed

buildscript {
  repositories {
    mavenLocal()
   ...
  }
  dependencies {
    classpath "com.google.cloud.tools:appengine-gradle-plugin:1.3.5-SNAPSHOT"
    ...
  }
}

@marceloverdijk
Copy link

@loosebazooka I'm getting this error:

* What went wrong:
A problem occurred configuring root project 'myproject'.
> com.google.cloud.tools.gradle.appengine.standard.AppEngineStandardExtension_Decorated cannot be cast to com.google.cloud.tools.gradle.appengine.core.AppEngineExtension

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project 'F1iDB'.
        at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:94)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:66)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:110)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:50)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:667)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:136)
        at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
        at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:60)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
        at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:249)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:167)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:126)
        at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:109)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:78)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:75)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
        at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:100)
        at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:75)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:49)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:32)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:57)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:45)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
        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: java.lang.ClassCastException: com.google.cloud.tools.gradle.appengine.standard.AppEngineStandardExtension_Decorated cannot be cast to com.google.cloud.tools.gradle.appengine.core.AppEngineExtension
        at Build_gradle$7.invoke(build.gradle.kts:8)
        at org.gradle.kotlin.dsl.AccessorsKt$sam$Action$29ba3305.execute(accessors.kt)
        at org.gradle.api.internal.plugins.ExtensionsStorage$ExtensionHolder.configure(ExtensionsStorage.java:183)
        at org.gradle.api.internal.plugins.ExtensionsStorage.configureExtension(ExtensionsStorage.java:67)
        at org.gradle.api.internal.plugins.DefaultConvention.configure(DefaultConvention.java:222)
        at org.gradle.kotlin.dsl.AccessorsKt.appengine(accessors.kt:171)
        at Build_gradle.<init>(build.gradle.kts:100)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler.executeScriptOf(KotlinBuildScriptCompiler.kt:331)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler.executeScriptWithContextClassLoader(KotlinBuildScriptCompiler.kt:255)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler.executeCompiledScript(KotlinBuildScriptCompiler.kt:150)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler.executeScriptBody(KotlinBuildScriptCompiler.kt:106)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler.prepareAndExecuteScriptBody(KotlinBuildScriptCompiler.kt:98)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler.access$prepareAndExecuteScriptBody(KotlinBuildScriptCompiler.kt:51)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler$compile$1.invoke(KotlinBuildScriptCompiler.kt:78)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler$compile$1.invoke(KotlinBuildScriptCompiler.kt:51)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler$asKotlinScript$1.invoke(KotlinBuildScriptCompiler.kt:92)
        at org.gradle.kotlin.dsl.provider.KotlinBuildScriptCompiler$asKotlinScript$1.invoke(KotlinBuildScriptCompiler.kt:51)
        at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$createScriptAction$1.invoke(KotlinScriptPluginFactory.kt:56)
        at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$createScriptAction$1.invoke(KotlinScriptPluginFactory.kt:33)
        at org.gradle.kotlin.dsl.provider.KotlinScriptPlugin.apply(KotlinScriptPlugin.kt:34)
        at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:61)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:58)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:41)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
        at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:64)
        ... 80 more

@loosebazooka
Copy link
Contributor

Any chance you can post a simple kotlin build file with appengine config?

@marceloverdijk
Copy link

Yes np, will setup a small Kotlin project later today.

@marceloverdijk
Copy link

@loosebazooka you can checkout this simple project setup https://github.com/marceloverdijk/kotlin-app-gradle-plugin
It works with version 1.3.4 of the plugin but it fails with the 1.3.5-SNAPSHOT version. Hope that helps.

@loosebazooka
Copy link
Contributor

loosebazooka commented Feb 2, 2018

I don't actually know what gradle/project-schema.json is, but it's forcing the "appengine" extension to resolve to com.google.cloud.tools.gradle.appengine.core.AppEngineExtension which is a file from 1.3.4 that was the root extension for all our configuration, which is gone in this branch.

What you actually need to do is either regenerate that file somehow (how would one do this?) or just change what the extension resolves to : com.google.cloud.tools.gradle.appengine.standard.AppEngineStandardExtension

It's quite a strange file, and it be interesting to know why and how it's generated.

@marceloverdijk
Copy link

Aha, yes this file is generated by kotlinDslAccessorsSnapshot. Let me try to generate it again!

@marceloverdijk
Copy link

Had to do a couple of trick to re-generate it but it worked. I pushed the changes to my repo for reference as well.

I can now simply configure the plugin like:

appengine {
    run {
        port = 8077
    }
    deploy {
        stopPreviousVersion = true
        promote = true
    }
}

which is really great! 💪

@marceloverdijk
Copy link

I was also able to remove the appengine resolutionStrategy from my settings.gradle.kts. Is it correct that the mentioned marker artifacts are already part of 1.3.5-SNAPSHOT?

@loosebazooka
Copy link
Contributor

loosebazooka commented Feb 2, 2018

Sorry, I don't know what you mean by marker artifacts?

It looks like that block of code with resolutionStrategy is so that you can potentially use

plugins {
  "com.google.cloud.tools.appengine"
}

instead of

apply {
 plugin("com.google.cloud.tools.appengine")
}

but the sample you sent me puts it in apply?

We don't publish to the gradle plugin portal yet, since they do not provide the necessary statistics we need (for example downloading).

@marceloverdijk
Copy link

Yes you are probably right. For me it does not matter to have it part of the plugins block to be honest. To have it apply is fine enough.

@loosebazooka
Copy link
Contributor

Hey @marceloverdijk can you describe how you regenerated the project-schema file with kotlinDslAccessorsSnapshot. If a user deletes this file, how would one get it back?

@marceloverdijk
Copy link

I simply executed ./gradlew kotlinDslAccessorsSnapshot.

@loosebazooka
Copy link
Contributor

loosebazooka commented Feb 8, 2018

even if the file is deleted?

might be a local config issue. Thanks for your help, I'll look at this on my side.

@marceloverdijk
Copy link

marceloverdijk commented Feb 8, 2018

Hmmm, indeed that fails... let me think.

UPDATE I'm not able to do get it re-generated again atm :-( (have to to check it out again from git)...

@loosebazooka
Copy link
Contributor

1.3.5 is out, but @marceloverdijk do you have any update on how to generate this file?

@marceloverdijk
Copy link

marceloverdijk commented Feb 21, 2018

I just upgraded successfully to the latest 1.3.5 version of the plugin.

Here are the steps I had to do:

  1. Update plugin version to 1.3.5
  2. Remove any com.google.cloud.tools.gradle.appengine imports from the build file
  3. Remove the unfriendly appengine { .. } block from the build file
  4. Run ./gradlew kotlinDslAccessorsSnapshot (to regenerate the mentioned project-schema.json file)
  5. Add the new friendly appengine { .. } block to the build file like:
appengine {
    run {
        port = 8888
        // enable when needed: jvmFlags = listOf("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005")
    }
    deploy {
        stopPreviousVersion = true
        promote = true
    }
}

That's it! It worked flawlessly; I think we can close this issue now 😄

@loosebazooka
Copy link
Contributor

Alright, I'm going to leave this open for a little, since I'm not super familiar with the kotlin builds.

@jpink
Copy link

jpink commented Feb 11, 2019

I've got error in step 3:

Task 'kotlinDslAccessorsSnapshot' not found in root project xxx

and in step 5

Script compilation errors:

  Line xxx:     appengine {
                ^ Unresolved reference: appengine

  Line xxx:             port = 80
                        ^ Unresolved reference: port

2 errors

How to get the following work in Kotlin DSL?:

appengine {
    run {
        port = 80
    }
}

@jpink
Copy link

jpink commented Feb 11, 2019

Nevermind... I got it working. My syntax was incorrect. Kotlin DSL syntax is:

import com.google.cloud.tools.gradle.appengine.standard.AppEngineStandardExtension

the<AppEngineStandardExtension>().apply {
    run {
        port = 80
    }
}

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

No branches or pull requests

5 participants