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

Generate sealed interfaces in response based codegen #3448

Merged
merged 11 commits into from
Oct 28, 2021

Conversation

BoD
Copy link
Contributor

@BoD BoD commented Oct 26, 2021

No description provided.

Contributing.md Show resolved Hide resolved
@BoD BoD marked this pull request as ready for review October 26, 2021 11:42
@BoD
Copy link
Contributor Author

BoD commented Oct 26, 2021

Question: I think Kotlin 1.4 is currently our minimum target Kotlin version, but not sure? Does that mean that we maybe need a flag to opt-in/out of sealed interfaces which work since Kotlin 1.5?

@martinbonnin
Copy link
Contributor

Looks good 👍

Also yep, you're 100% right we still need to support Kotlin 1.4. Let's make this a Gradle option similar to https://kotlinlang.org/docs/gradle.html#attributes-common-to-jvm-and-js?

apollo {
  // By default, infer it from the KotlinExtention
  languageVersion = "1.4"
}

@BoD
Copy link
Contributor Author

BoD commented Oct 27, 2021

Added a languageVersion property, which is passed to the KotlinContext, and a small Version utility class to be able to inspect it / compare it to other versions. Not sure what's the best way to add tests to this! Let me know what you think 😊

@martinbonnin
Copy link
Contributor

(I'm also about to allow "X.Y" in addition to "X.Y.Z")

👍 Does it even make sense to set languageVersion = "1.4.32"?

}
}
}

Copy link
Contributor

@martinbonnin martinbonnin Oct 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a 3rd test to make sure we can generate interfaces "not-sealed" ? (kotlin: 1.4, apollo: 1.4)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, you're totally right, with 1.4 on both sides 👍

@BoD
Copy link
Contributor Author

BoD commented Oct 27, 2021

Does it even make sense to set languageVersion = "1.4.32"?

Well the extension that returns the Kotlin plugin version does return the full version, so it's nice that this format is accepted (but we could also strip it of course)

usesKotlinDsl = true,
plugins = listOf(TestUtils.kotlinJvmPlugin, TestUtils.apolloPlugin),
apolloConfiguration = configuration,
graphqlPath = "hero",
Copy link
Contributor

@martinbonnin martinbonnin Oct 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I'm not using TestUtils.withProject for new tests as manually maintaining the code to generate build.gradle[.kts] files is tedious. Instead, I add projects to apollo-gradle-plugin/testProjects. The nice thing is that these are "standalone" so it's easy to test them without going through the whole GradleRunner thing:

./gradlew -p apollo-gradle-plugin/testProjects/$projectName build

(no need to change this though)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see!

Actually that was my first approach but then realized I would need several tests and saw this way to do it existed - but now that I think of it, maybe I could have one specific project and pass parameters to it for the different cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could do a testProject with simple templating too but no silver bullet at the end of the day 🤷 .

@martinbonnin
Copy link
Contributor

martinbonnin commented Oct 27, 2021

Well the extension that returns the Kotlin plugin version does return the full version, so it's nice that this format is accepted (but we could also strip it of course)

It's nice to accept it (be flexible about what you receive) but I think documentation and samples should use the "x.y" syntax, as in the Kotlin docs

/**
* Currently only used when [targetLanguage] is "kotlin".
*/
val targetLanguageVersion: String = defaultTargetLanguageVersion,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about merging that option with targetLanguage ?

"java"
"kotlin_1_4"
"kotlin_1_5"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting - you mean only at the Options level, and not at the user facing (Gradle plugin) level, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly!

In the Gradle plugin, I think it makes sense to keep languageLevel as in https://kotlinlang.org/docs/gradle.html#attributes-common-to-jvm-and-js. I'm not 100% convinced but I think it'd make sense

private val REGEX = Regex("(\\d)\\.(\\d)(\\.(\\d).*)?")

fun parse(s: String): VersionNumber {
val matchResult = REGEX.find(s) ?: error("Could not parse '$s' as a version number")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth catching this in the Gradle plugin and display a more user friendly message:

ApolloGraphQL: languageLevel "$languageLevel" is not supported.

TestUtils.executeTask(":assemble", dir)
Assert.fail("Compiling with incompatible languageVersion should fail")
} catch (e: UnexpectedBuildFailure) {
Truth.assertThat(e.message).contains("languageVersion '3.14' is not supported")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥧 ❤️

BoD and others added 4 commits October 28, 2021 11:16
Simplification: get rid of VersionNumber and explicitly allow only "1.4" or "1.5" instead.
@BoD BoD force-pushed the generate-sealed-interfaces branch from 0795137 to 37906e3 Compare October 28, 2021 09:18
@BoD BoD merged commit 4b9531f into dev-3.x Oct 28, 2021
@BoD BoD deleted the generate-sealed-interfaces branch October 28, 2021 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants