Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = false

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | πŸ”΅ Trivial | ⚑ Quick win

Reconsider disabling final newlines.

Setting insert_final_newline = false deviates from POSIX text file standards and common best practices. Most tools expect text files to end with a newline, and this setting conflicts with the endWithNewline() rule configured for Gradle files in build.gradle (line 94).

Consider setting this to true for consistency with spotless configuration and standard practices.

♻️ Proposed fix
-insert_final_newline = false
+insert_final_newline = true
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
insert_final_newline = false
insert_final_newline = true
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.editorconfig at line 6, Change the .editorconfig setting
insert_final_newline from false to true to ensure files end with a newline and
match the Gradle Spotless rule endWithNewline(); update insert_final_newline to
true so editor behavior is consistent with the spotless/endWithNewline()
configuration and POSIX text file expectations.

max_line_length = 120
tab_width = 4
ij_continuation_indent_size = 8
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = true
ij_smart_tabs = false
ij_visual_guides =
ij_wrap_on_typing = false

[.editorconfig]
ij_editorconfig_align_group_field_declarations = false
ij_editorconfig_space_after_colon = false
ij_editorconfig_space_after_comma = true
ij_editorconfig_space_before_colon = false
ij_editorconfig_space_before_comma = false
ij_editorconfig_spaces_around_assignment_operators = true

[{*.har,*.jsb2,*.jsb3,*.json,*.jsonc,*.png.mcmeta,*.postman_collection,*.postman_collection.json,*.postman_environment,*.postman_environment.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,.ws-context,jest.config,mcmod.info,pack.mcmeta}]
indent_size = 2
ij_json_array_wrapping = split_into_lines
ij_json_keep_blank_lines_in_code = 0
ij_json_keep_indents_on_empty_lines = false
ij_json_keep_line_breaks = true
ij_json_keep_trailing_comma = false
ij_json_object_wrapping = split_into_lines
ij_json_property_alignment = do_not_align
ij_json_space_after_colon = true
ij_json_space_after_comma = true
ij_json_space_before_colon = false
ij_json_space_before_comma = false
ij_json_spaces_within_braces = false
ij_json_spaces_within_brackets = false
ij_json_wrap_long_lines = false

[{*.kt,*.kts}]
ij_kotlin_align_in_columns_case_branch = true
ij_kotlin_align_multiline_binary_operation = false
ij_kotlin_align_multiline_extends_list = false
ij_kotlin_align_multiline_method_parentheses = false
ij_kotlin_align_multiline_parameters = true
ij_kotlin_align_multiline_parameters_in_calls = false
ij_kotlin_allow_trailing_comma = false
ij_kotlin_allow_trailing_comma_collection_literal_expression = false
ij_kotlin_allow_trailing_comma_context_receiver_list = true
ij_kotlin_allow_trailing_comma_destructuring_declaration = true
ij_kotlin_allow_trailing_comma_function_literal = true
ij_kotlin_allow_trailing_comma_indices = false
ij_kotlin_allow_trailing_comma_on_call_site = false
ij_kotlin_allow_trailing_comma_type_argument_list = false
ij_kotlin_allow_trailing_comma_type_parameter_list = true
ij_kotlin_allow_trailing_comma_value_argument_list = false
ij_kotlin_allow_trailing_comma_value_parameter_list = true
ij_kotlin_allow_trailing_comma_when_entry = true
ij_kotlin_assignment_wrap = normal
ij_kotlin_blank_lines_after_class_header = 0
ij_kotlin_blank_lines_around_block_when_branches = 0
ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
ij_kotlin_block_comment_add_space = false
ij_kotlin_block_comment_at_first_column = true
ij_kotlin_call_parameters_new_line_after_left_paren = true
ij_kotlin_call_parameters_right_paren_on_new_line = true
ij_kotlin_call_parameters_wrap = on_every_item
ij_kotlin_catch_on_new_line = false
ij_kotlin_class_annotation_wrap = split_into_lines
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
ij_kotlin_continuation_indent_for_chained_calls = false
ij_kotlin_continuation_indent_for_expression_bodies = false
ij_kotlin_continuation_indent_in_argument_lists = false
ij_kotlin_continuation_indent_in_elvis = false
ij_kotlin_continuation_indent_in_if_conditions = false
ij_kotlin_continuation_indent_in_parameter_lists = false
ij_kotlin_continuation_indent_in_supertype_lists = false
ij_kotlin_else_on_new_line = false
ij_kotlin_enum_constants_wrap = off
ij_kotlin_extends_list_wrap = normal
ij_kotlin_field_annotation_wrap = split_into_lines
ij_kotlin_finally_on_new_line = false
ij_kotlin_if_rparen_on_new_line = true
ij_kotlin_import_nested_classes = false
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
ij_kotlin_indent_before_arrow_on_new_line = true
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
ij_kotlin_keep_blank_lines_before_right_brace = 2
ij_kotlin_keep_blank_lines_in_code = 2
ij_kotlin_keep_blank_lines_in_declarations = 2
ij_kotlin_keep_first_column_comment = true
ij_kotlin_keep_indents_on_empty_lines = false
ij_kotlin_keep_line_breaks = true
ij_kotlin_lbrace_on_next_line = false
ij_kotlin_line_break_after_multiline_when_entry = true
ij_kotlin_line_comment_add_space = false
ij_kotlin_line_comment_add_space_on_reformat = false
ij_kotlin_line_comment_at_first_column = true
ij_kotlin_method_annotation_wrap = split_into_lines
ij_kotlin_method_call_chain_wrap = normal
ij_kotlin_method_parameters_new_line_after_left_paren = true
ij_kotlin_method_parameters_right_paren_on_new_line = true
ij_kotlin_method_parameters_wrap = on_every_item
ij_kotlin_name_count_to_use_star_import = 5
ij_kotlin_name_count_to_use_star_import_for_members = 3
ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.**

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | πŸ”΅ Trivial | πŸ’€ Low value

Verify wildcard imports are intentional.

The configuration allows wildcard imports for java.util.*, kotlinx.android.synthetic.**, and io.ktor.**. Wildcard imports can reduce code clarity by hiding import sources and may cause namespace pollution.

Confirm this is intentional for your project's conventions.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.editorconfig at line 108, The .editorconfig setting
ij_kotlin_packages_to_use_import_on_demand currently enables wildcard imports
for java.util.*, kotlinx.android.synthetic.**, and io.ktor.**; update this
setting to either remove the wildcard entries or replace them with explicit
package names you intend to allow as on-demand imports so wildcard imports are
not globally enabledβ€”modify the ij_kotlin_packages_to_use_import_on_demand entry
accordingly (e.g., remove java.util.*, kotlinx.android.synthetic.**, io.ktor.**)
or document/justify and restrict which specific packages should remain
wildcarded to match your project convention.

ij_kotlin_parameter_annotation_wrap = off
ij_kotlin_space_after_comma = true
ij_kotlin_space_after_extend_colon = true
ij_kotlin_space_after_type_colon = true
ij_kotlin_space_before_catch_parentheses = true
ij_kotlin_space_before_comma = false
ij_kotlin_space_before_extend_colon = true
ij_kotlin_space_before_for_parentheses = true
ij_kotlin_space_before_if_parentheses = true
ij_kotlin_space_before_lambda_arrow = true
ij_kotlin_space_before_type_colon = false
ij_kotlin_space_before_when_parentheses = true
ij_kotlin_space_before_while_parentheses = true
ij_kotlin_spaces_around_additive_operators = true
ij_kotlin_spaces_around_assignment_operators = true
ij_kotlin_spaces_around_elvis = true
ij_kotlin_spaces_around_equality_operators = true
ij_kotlin_spaces_around_function_type_arrow = true
ij_kotlin_spaces_around_logical_operators = true
ij_kotlin_spaces_around_multiplicative_operators = true
ij_kotlin_spaces_around_range = false
ij_kotlin_spaces_around_relational_operators = true
ij_kotlin_spaces_around_unary_operator = false
ij_kotlin_spaces_around_when_arrow = true
ij_kotlin_variable_annotation_wrap = off
ij_kotlin_while_on_new_line = false
ij_kotlin_wrap_elvis_expressions = 1
ij_kotlin_wrap_expression_body_functions = 1
ij_kotlin_wrap_first_method_in_call_chain = false

[{*.markdown,*.md}]
ij_markdown_force_one_space_after_blockquote_symbol = true
ij_markdown_force_one_space_after_header_symbol = true
ij_markdown_force_one_space_after_list_bullet = true
ij_markdown_force_one_space_between_words = true
ij_markdown_format_tables = true
ij_markdown_insert_quote_arrows_on_wrap = true
ij_markdown_keep_indents_on_empty_lines = false
ij_markdown_keep_line_breaks_inside_text_blocks = true
ij_markdown_max_lines_around_block_elements = 1
ij_markdown_max_lines_around_header = 1
ij_markdown_max_lines_between_paragraphs = 1
ij_markdown_min_lines_around_block_elements = 1
ij_markdown_min_lines_around_header = 1
ij_markdown_min_lines_between_paragraphs = 1
ij_markdown_wrap_text_if_long = true
ij_markdown_wrap_text_inside_blockquotes = true

[{*.properties,spring.handlers,spring.schemas}]
ij_properties_align_group_field_declarations = false
ij_properties_keep_blank_lines = false
ij_properties_key_value_delimiter = equals
ij_properties_spaces_around_key_value_delimiter = false

[{*.yaml,*.yml}]
indent_size = 2
ij_yaml_align_values_properties = do_not_align
ij_yaml_autoinsert_sequence_marker = true
ij_yaml_block_mapping_on_new_line = false
ij_yaml_indent_sequence_value = true
ij_yaml_keep_indents_on_empty_lines = false
ij_yaml_keep_line_breaks = true
ij_yaml_line_comment_add_space = false
ij_yaml_line_comment_add_space_on_reformat = false
ij_yaml_line_comment_at_first_column = true
ij_yaml_sequence_on_new_line = false
ij_yaml_space_before_colon = false
ij_yaml_spaces_within_braces = true
ij_yaml_spaces_within_brackets = true
34 changes: 30 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ plugins {
id 'org.jetbrains.kotlin.jvm' version '2.2.0'
id 'org.jetbrains.kotlin.kapt' version '2.2.0'
id "com.vanniktech.maven.publish" version "0.34.0"
id "org.jlleitschuh.gradle.ktlint" version "13.1.0" apply false
id 'com.diffplug.spotless' version "7.2.1" apply false
Comment on lines +6 to +7

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | πŸ”΅ Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check for latest versions and security advisories for Gradle plugins

echo "=== Checking ktlint-gradle plugin latest version ==="
curl -s "https://plugins.gradle.org/plugin/org.jlleitschuh.gradle.ktlint" | grep -o 'Version [0-9.]*' | head -1

echo -e "\n=== Checking spotless plugin latest version ==="
curl -s "https://plugins.gradle.org/plugin/com.diffplug.spotless" | grep -o 'Version [0-9.]*' | head -1

echo -e "\n=== Checking for GitHub security advisories ==="
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: MAVEN, package: "org.jlleitschuh.gradle:ktlint-gradle") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
    }
  }
}'

gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: MAVEN, package: "com.diffplug.spotless:spotless-plugin-gradle") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
    }
  }
}'

Repository: LMLiam/SPI-Tooling

Length of output: 532


Update ktlint/spotless Gradle plugin versions (security impact currently unclear, but pinned versions are behind latest).

  • ktlint-gradle: pinned 13.1.0; Plugin Portal shows latest 14.2.0; GitHub advisory query returned no vulnerabilities for this package.
  • spotless: pinned 7.2.1; Plugin Portal shows latest 8.6.0; GitHub advisory found a HIGH issue but it applies to versions < 3.20.0 (so 7.2.1 is outside that range).
  • Consider bumping both plugins to the latest versions for improved compatibility/maintenance.
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build.gradle` around lines 6 - 7, Update the pinned Gradle plugin versions
for the ktlint and Spotless plugins by changing the version strings for the
plugin identifiers org.jlleitschuh.gradle.ktlint and com.diffplug.spotless to
the current latest releases (replace "13.1.0" with "14.2.0" for
org.jlleitschuh.gradle.ktlint and "7.2.1" with "8.6.0" for
com.diffplug.spotless) in the build.gradle plugin declarations; run a Gradle
build to confirm compatibility and adjust any plugin-specific configuration if
the newer plugin versions introduce breaking changes.

}

allprojects {
Expand All @@ -22,17 +24,17 @@ subprojects {
apply plugin: 'org.jetbrains.kotlin.jvm'
apply plugin: 'org.jetbrains.kotlin.kapt'
apply plugin: 'com.vanniktech.maven.publish'
apply plugin: 'org.jlleitschuh.gradle.ktlint'
apply plugin: 'com.diffplug.spotless'

// Configure Vanniktech plugin
mavenPublishing {
publishToMavenCentral(true)
signAllPublications()

coordinates(
rootProject.group as String,
coordinates(rootProject.group as String,
"${rootProject.name}-${project.name}",
rootProject.version as String
)
rootProject.version as String)

pom {
name = "${rootProject.name}-${project.name}"
Expand Down Expand Up @@ -72,6 +74,30 @@ subprojects {
}
}
}

tasks.named("check") {
dependsOn("spotlessApply")
}

tasks.named("compileKotlin") {
dependsOn(tasks.named("spotlessApply"))
}
Comment on lines +78 to +84

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | πŸ”΄ Critical | ⚑ Quick win

Critical: Replace spotlessApply with spotlessCheck in task dependencies.

Making check and compileKotlin depend on spotlessApply causes automatic code reformatting during builds, which is an anti-pattern:

  1. Fails silently: Formatting violations are auto-fixed instead of failing the build, hiding issues in CI
  2. Unexpected changes: Developers compiling code will have their files reformatted without explicit consent
  3. CI/CD risk: Code can be silently modified during build pipelines

The standard pattern is:

  • check depends on spotlessCheck (fails if formatting is wrong)
  • Developers run ./gradlew spotlessApply manually or via pre-commit hooks to fix formatting
πŸ› Proposed fix
 tasks.named("check") {
-    dependsOn("spotlessApply")
+    dependsOn("spotlessCheck")
 }

-tasks.named("compileKotlin") {
-    dependsOn(tasks.named("spotlessApply"))
-}

Note: Remove the compileKotlin dependency entirely. Formatting checks should happen during check, not compilation.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build.gradle` around lines 78 - 84, The build currently makes
tasks.named("check") and tasks.named("compileKotlin") depend on spotlessApply;
change the dependency so tasks.named("check") depends on "spotlessCheck" (not
"spotlessApply") and remove the dependency on spotless for "compileKotlin"
entirely (i.e., drop tasks.named("compileKotlin") { dependsOn(...) }), ensuring
formatting is enforced via spotlessCheck during the check lifecycle while
developers run spotlessApply manually.


spotless {
ratchetFrom 'origin/main'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | πŸ”΅ Trivial | πŸ’€ Low value

Note: ratchetFrom only checks changed files.

The ratchetFrom 'origin/main' configuration means spotless will only check files modified since the origin/main branch. This is useful for incremental adoption but won't catch formatting issues in unchanged files.

Consider running a full ./gradlew spotlessApply across the entire codebase initially to establish a clean baseline.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build.gradle` at line 87, The Gradle configuration uses ratchetFrom
'origin/main' which limits Spotless checks to changed files; to fix this, run a
one-time full formatting pass by executing ./gradlew spotlessApply across the
repo to create a clean baseline, then keep ratchetFrom 'origin/main' for
incremental checks; ensure you commit the resulting formatting changes so
build.gradle's ratchetFrom behavior only filters already-formatted files going
forward.


format 'misc', {
target '*.gradle', '.gitattributes', '.gitignore'

trimTrailingWhitespace()
leadingTabsToSpaces()
endWithNewline()
}

kotlin {
ktlint().setEditorConfigPath("$rootDir/.editorconfig")
}
}
}

tasks.register('copyJar', Copy) {
Expand Down
Loading