Skip to content
New issue

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

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

Already on GitHub? # to your account

0.49 support #667

Merged
merged 2 commits into from
Jun 5, 2023
Merged

0.49 support #667

merged 2 commits into from
Jun 5, 2023

Conversation

wakingrufus
Copy link
Collaborator

convert ktlint invocations from reflection to new method of using multiple compileOnly targets

@wakingrufus wakingrufus force-pushed the ktlint-49 branch 2 times, most recently from 6adfe1c to 260474a Compare April 27, 2023 17:55
@JLLeitschuh
Copy link
Owner

Looking solid so far. I didn't realize how easy source sets were to work with these days. I would have created separate projects per version of Ktlint, but your solution is so much simpler. I love it!

Nice work! 🎉

…tiple compileOnly targets

create common abstraction for Lint errors and reporters
@wakingrufus wakingrufus force-pushed the ktlint-49 branch 3 times, most recently from f6467ca to f87b082 Compare May 16, 2023 21:45
@wakingrufus wakingrufus marked this pull request as ready for review May 17, 2023 00:18
Copy link
Owner

@JLLeitschuh JLLeitschuh left a comment

Choose a reason for hiding this comment

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

In general, looking good. I would suggest using ValidatingInputStream when deserializing java objects if possible

@@ -10,9 +9,9 @@ import java.io.Serializable
* @param lintedFile file that was checked by KtLint
* @param lintErrors list of found errors and flag indicating if this error was corrected
*/
internal data class LintErrorResult(
Copy link
Owner

Choose a reason for hiding this comment

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

I presume this is because kotlin doesn't see this class as being a part of the same project? There is a way to configure the kotlin compiler "friend path" but I don't know if that API is exposed via Gradle. So this is reasonable.

But if you're curious, feel free to look into it.

Copy link
Owner

Choose a reason for hiding this comment

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

Oh hey... Look what I found. A ticket I opened 5 years ago on this same topic: https://youtrack.jetbrains.com/issue/KT-20760

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was able to get friend paths working, but making this internal will also require KtLintInvocation to be internal, and then the work action can't invoke it without also being internal, and I assume those can't be internal

Copy link
Owner

Choose a reason for hiding this comment

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

No worries

Comment on lines +9 to +15
class SerializableReportersProviderLoader :
ReportersLoaderAdapter<Reporter, SerializableReporterProvider, Ktlint34Reporter, Ktlint34ReporterProvider> {
override fun loadAllReporterProviders(): List<ReporterProviderWrapper<SerializableReporterProvider>> = ServiceLoader
.load(ReporterProvider::class.java)
.toList().map {
ReporterProviderWrapper(it.id, SerializableReporterProvider(it))
}
Copy link
Owner

Choose a reason for hiding this comment

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

Good use of service loaders IMHO!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I can't take credit, this code was already here :)

serializedReporterProviders.inputStream().buffered()
).use {
@Suppress("UNCHECKED_CAST")
it.readObject() as List<ReporterProviderV2<ReporterV2>>
Copy link
Owner

Choose a reason for hiding this comment

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

Sanity check. No way for this deserialization to come from untrusted user input? Arbitrary deserialization of untrusted java objects is a common source of remote code execution vulnerabilities, via deserialization gadget chains.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

its deserializing from a file created by this plugin, which is a list of the reporters used.
if you were able to replace that file between the time the plugin writes and and when it is read, I suppose it could be malicious input. or if you modified the build to point loadedReporterProviders another location containing the bad file. This is always how this plugin has worked though (since i came to it). I think we could remove this serialization, but it would require doing the serviceloader call every time we need reporters which would impact performance.

Copy link
Owner

Choose a reason for hiding this comment

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

There's also the validating deserializer that comes from apache Commons. I think we have a use of it elsewhere

Comment on lines +61 to +72
return enabledReporters
.map { reporterType ->
val provider = enabledProviders.find { reporterType.reporterName == it.id }
?: throw RuntimeException(
"KtLint plugin failed to load reporter ${reporterType.reporterName}."
)

val options = if (reporterType == ReporterType.PLAIN_GROUP_BY_FILE) {
reporterType.options.associateWith { "true" }
} else {
emptyMap()
}
Copy link
Owner

Choose a reason for hiding this comment

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

I feel like I've read this exact snippet a few times here. Any way to unify it into a common method?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Its the same logic, applied to different ReporterProvider types, and we do access properties on those types. We don't have duck typing so i'd have to wrap those classes and convert back and forth to commonize this code, and imho the duplication isn't bad enough to add that much complexity

Copy link
Owner

Choose a reason for hiding this comment

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

Fair enough! I thought that may have been what was probably going on. Just wanted to check

@@ -135,6 +135,7 @@ class KtlintBaselineSupportTest : AbstractPluginTest() {
buildGradle.appendText(
"""
ktlint.version = "$ktLintVersion"
ktlint.debug = true
Copy link
Owner

Choose a reason for hiding this comment

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

Very sane, why we haven't done this before, I don't know 😂

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

hah I needed this to debug some issues. I could remove it, but I guess we might as well leave this here otherwise we will probably forget about that option.

@@ -12,7 +12,7 @@ import kotlin.streams.asStream

object TestVersions {
const val minSupportedGradleVersion = KtlintBasePlugin.LOWEST_SUPPORTED_GRADLE_VERSION
const val maxSupportedGradleVersion = "8.0.1"
const val maxSupportedGradleVersion = "8.1.1"
Copy link
Owner

Choose a reason for hiding this comment

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

Woot!

@JLLeitschuh
Copy link
Owner

This is looking good. Anything else to make work?

Copy link
Owner

@JLLeitschuh JLLeitschuh left a comment

Choose a reason for hiding this comment

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

LGTM!

It may be a good sanity check to use the validating input stream when deserializing java objects though.

@wakingrufus wakingrufus force-pushed the ktlint-49 branch 3 times, most recently from 430c08e to d8b4213 Compare May 31, 2023 00:09
Copy link
Owner

@JLLeitschuh JLLeitschuh left a comment

Choose a reason for hiding this comment

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

One thing. Other than that. LGTM!

…tiple compileOnly targets

create common abstraction for Lint errors and reporters
Copy link
Owner

@JLLeitschuh JLLeitschuh left a comment

Choose a reason for hiding this comment

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

LGTM!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants