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

Replacing the linter #754

Merged
merged 14 commits into from
Jul 25, 2024
Merged

Replacing the linter #754

merged 14 commits into from
Jul 25, 2024

Conversation

Jolanrensen
Copy link
Collaborator

@Jolanrensen Jolanrensen commented Jun 25, 2024

Fixes #364, the last stopper for updating to Kotlin 2.0.

  • replaced kotlinter by jlleitschuh's ktlint plugin
  • .editorconfig is used to set the rules of the linter and the code style
  • Please use https://plugins.jetbrains.com/plugin/15057-ktlint from now on :)
  • Individual cases can be @Suppress-ed easily with that plugin
  • I mostly-automatically refactored the entire project, but I checked all changes
  • I fixed some manual things: *-imports, names of consts, @file:ExcludeFromSources to prevent "empty" files in generated-sources
  • Tests in samples/api are cleaned for now and ignored by ktlint on a per-file basis (@file:Suppress("ktlint"))
  • See the issue for more information

@Jolanrensen Jolanrensen force-pushed the ktlint-migration branch 2 times, most recently from a0b2e44 to 15fa2b2 Compare June 27, 2024 14:17
@Jolanrensen Jolanrensen force-pushed the ktlint-migration branch 2 times, most recently from 6460403 to 1e856c0 Compare July 1, 2024 07:52
@Jolanrensen Jolanrensen marked this pull request as ready for review July 1, 2024 09:52
@Jolanrensen Jolanrensen assigned zaleslaw and unassigned zaleslaw Jul 1, 2024
override fun convertSqlTypeToColumnSchemaValue(tableColumnMetadata: TableColumnMetadata): ColumnSchema? {
return null
}
override fun convertSqlTypeToColumnSchemaValue(tableColumnMetadata: TableColumnMetadata): ColumnSchema? = null
Copy link
Collaborator

Choose a reason for hiding this comment

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

is it really linter setting? could we change it? I don't like these short forms without brackets, it looks ugly and make me slower

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is https://pinterest.github.io/ktlint/latest/rules/standard/#function-expression-body.
Because of the official style guide: https://kotlinlang.org/docs/coding-conventions.html#functions.
To me, block bodies with just one return statement take up unnecessary space and feel like java-boilerplate. We could change it, it's a matter of taste. But I think the most important thing is consistency; Mixing single-line block body's and expression bodies is messy.

val selectAllQuery = if (limit > 0) dbType.sqlQueryLimit("SELECT * FROM $tableName", limit)
else "SELECT * FROM $tableName"
val selectAllQuery = if (limit > 0) {
dbType.sqlQueryLimit("SELECT * FROM $tableName", limit)
Copy link
Collaborator

Choose a reason for hiding this comment

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

and again, here we don't need these brackets in the code

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's more readable for multiline if-statements: https://pinterest.github.io/ktlint/latest/rules/standard/#if-else-bracing and https://kotlinlang.org/docs/coding-conventions.html#control-flow-statements.
No brackets in if-statements are only allowed/clear when it fits on the same line.

connection.createStatement().execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (4, 'Sam', NULL, 15)")
connection.createStatement().execute(
"INSERT INTO TestTable1 (id, name, surname, age) VALUES (1, 'John', 'Crawford', 40)",
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

All inserts looks now to so cool as earlier, they should be single-rowd

Copy link
Collaborator Author

@Jolanrensen Jolanrensen Jul 23, 2024

Choose a reason for hiding this comment

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

@zaleslaw

It can be solved either like:

connection.createStatement()
    .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (1, 'John', 'Crawford', 40)")
connection.createStatement()
    .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (2, 'Alice', 'Smith', 25)")
connection.createStatement()
    .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (3, 'Bob', 'Johnson', 47)")
connection.createStatement()
    .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (4, 'Sam', NULL, 15)")

or by adding @Suppress("ktlint:standard:max-line-length") to the function declaration. What would you prefer? :)

)
private fun generateColumnSchemaValue(dbType: DbType, tableColumnMetadata: TableColumnMetadata): ColumnSchema =
dbType.convertSqlTypeToColumnSchemaValue(tableColumnMetadata) ?: ColumnSchema.Value(
makeCommonSqlToKTypeMapping(tableColumnMetadata),
Copy link
Collaborator

Choose a reason for hiding this comment

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

sorry, but it's fine with signatures, but not fine with the client code for passing parameters, it breaks the reading for me

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, this can indeed look better. How about:

dbType.convertSqlTypeToColumnSchemaValue(tableColumnMetadata) 
    ?: ColumnSchema.Value(makeCommonSqlToKTypeMapping(tableColumnMetadata))

or

dbType.convertSqlTypeToColumnSchemaValue(tableColumnMetadata) 
    ?: ColumnSchema.Value(
          makeCommonSqlToKTypeMapping(tableColumnMetadata),
    )

?

JDK >= 11 referred to by the `JAVA_HOME` environment variable.
* JDK >= 11 referred to by the `JAVA_HOME` environment variable.

* Note, any version above 11 should work in theory, but JDK 11 is the only version we test with,
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's with the formatting here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's a double indent

  • something
    • like this

@zaleslaw
Copy link
Collaborator

zaleslaw commented Jul 2, 2024

@Jolanrensen you did a great job leading us forward to K2, but let's discuss that when you return and change if possible some rules

@Jolanrensen
Copy link
Collaborator Author

@Jolanrensen you did a great job leading us forward to K2, but let's discuss that when you return and change if possible some rules

Thanks for reviewing!

I think some of your suggestions are in conflict with the official Kotlin styleguide which are honored by Ktlint. We could deviate as I've done with a small number of rules in the .editorconfig file but we would need to be sure it'd be in the best interest of the library and our users.

For example, I've turned off the filename check, as we name our API files after the function-family it represents. I also turned off chain-method-continuation so DataFrame notations like:

df.update { .. }.where { .. }.with { .. }
  .update { .. }.with { .. }

are allowed and not replaced with:

df
  .update { .. }
  .where { .. }
  .with { .. }
  .update { .. }
  .with { .. }

# Conflicts:
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/all.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/cast.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convert.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/frameCols.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/GeneratedField.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/MarkersExtractor.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/generateCode.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toDataFrame.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/codeGen/CodeGeneratorImpl.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/codeGen/SchemaProcessorImpl.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/schema/Utils.kt
#	core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/jupyter/CellRenderer.kt
#	core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/ShortNamesRenderingTest.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/all.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/cast.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convert.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/frameCols.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/GeneratedField.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/MarkersExtractor.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/generateCode.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/toDataFrame.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/codeGen/CodeGeneratorImpl.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/codeGen/SchemaProcessorImpl.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/schema/Utils.kt
#	core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/jupyter/CellRenderer.kt
#	core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/codeGen/ShortNamesRenderingTest.kt
#	dataframe-openapi/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/OpenApiType.kt
#	dataframe-openapi/src/test/kotlin/OpenApiTests.kt
#	plugins/symbol-processor/src/main/kotlin/org/jetbrains/dataframe/ksp/PropertyRenderer.kt
Copy link
Contributor

Generated sources will be updated after merging this PR.
Please inspect the changes in here.

@Jolanrensen
Copy link
Collaborator Author

Jolanrensen commented Jul 24, 2024

As for the trailing-comma case, there are many viewpoints on what's best.
The Kotlin coding convention specifies many benefits:

It makes version-control diffs cleaner – as all the focus is on the changed value.

It makes it easy to add and reorder elements – there is no need to add or delete the comma if you manipulate elements.

It simplifies code generation, for example, for object initializers. The last element can also have a comma.

It even encourages it at declaration site (so defining classes, functions, etc.) and leaves it at our own discretion for the call site.

Ktlint enables trailing commas on call site by default for the same reasons as on the declaration site, however, while IntelliJ can be configured to allow or disallow trailing commas, Ktlint can only be configured to enforce or disallow them. Consistency is preferred, which is honestly a good decision I think.

Now, enforcing trailing commas does make notation like

myFunction(
  singleArg,
)

appear. Which is debatably ugly and can hurt our ability to read it well, however it can often be rewritten like:

myFunction(singleArg)

or

myFunction(
  arg = singleArg,
)

Having trailing commas for function calls with many (optional) named arguments is still a must for me:

createValueColumn(
    name = name,
    values = values,
    type = getValuesType(
        values = values,
        type = typeOf<T>(),
        infer = infer,
    ),
)

Being able to reorder arguments like these or add new ones is something that occurs a lot and it can save headaches with merge conflicts if every line simply ends with a comma.

So, to conclude, I think we should follow kotlin-juypter and just enable them both on the call- and the declaration site.

@Jolanrensen Jolanrensen merged commit 75aa799 into master Jul 25, 2024
5 checks passed
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.

Updating the linter
2 participants