Skip to content

build(spotless): add Spotless and Ktlint for formatting and linting - #44

Open
LMLiam wants to merge 1 commit into
mainfrom
task/issue-4/add-spotless
Open

build(spotless): add Spotless and Ktlint for formatting and linting#44
LMLiam wants to merge 1 commit into
mainfrom
task/issue-4/add-spotless

Conversation

@LMLiam

@LMLiam LMLiam commented Jun 6, 2026

Copy link
Copy Markdown
Owner

📌 Summary

Adds Spotless and Ktlint to enforce code syntax

🔍 Related Issues / Tickets

🛠 Changes in Detail

  • Adds Spotless and Ktlint

🧩 Modules Affected

  • spi-tooling-annotations
  • spi-tooling-processor
  • Other:

📦 Versioning

  • Version bump applied (release PR)
  • Snapshot only (PR build)

🧪 Testing

Not necessary

✅ Checklist

  • Code builds locally without errors
  • All tests pass locally (./gradlew kotest)
  • Added/updated tests for new or changed logic
  • Updated documentation / README if needed
  • No unrelated changes included

📜 Notes for Reviewers


Recreated from #10 — the original PR was auto-closed when main’s history was rewritten to the verb(scope): convention and GitHub blocks reopening a PR whose branch was force-pushed. Same branch, rebased onto the rewritten main.

Summary by CodeRabbit

Release Notes

  • Chores
    • Established repository-wide code formatting standards and automated formatting checks during the build process to ensure consistent code quality across the codebase.

@LMLiam LMLiam added type:maintenance Maintenance, refactor, chore, or tooling upkeep area:tooling Build, Gradle, CI/release, packaging, and dependencies labels Jun 6, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR establishes repository-wide code formatting standards by introducing an .editorconfig file with language-specific rules and integrating spotless and ktlint Gradle plugins to enforce those rules during the build process.

Changes

Code Formatting Standards and Enforcement

Layer / File(s) Summary
Editor configuration defaults and language-specific overrides
.editorconfig
Global formatting standards (UTF-8, LF, 4-space indents, 120-char line limit, no final newline) with language-specific overrides for JavaScript/JSON (2-space), Kotlin (alignment, wrapping, operator spacing), Markdown, properties, and YAML.
Gradle build configuration for formatter enforcement
build.gradle
Declares ktlint and spotless Gradle plugins, applies them to all subprojects, configures spotless with ratcheting from origin/main and kotlin ktlint rules, and makes check and compileKotlin tasks depend on spotlessApply to enforce formatting during the build.

🐰 A format of rules both grand and true,
Spotless and ktlint through and through!
From Kotlin shines to markdown bright,
EditorConfig keeps the codebase tight.

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding Spotless and Ktlint for code formatting and linting, which aligns with the changeset modifications to build.gradle and the new .editorconfig file.
Description check ✅ Passed The description follows the template structure with most key sections completed: summary, related issues, changes detail, versioning selection, and checklist items. However, modules affected and testing sections are minimal or marked as unnecessary.
Linked Issues check ✅ Passed The PR addresses issue #4 by adding Spotless and Ktlint plugins to build.gradle and introducing .editorconfig for formatting rules, meeting the core objective of adding Spotless for syntax enforcement.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing Spotless and Ktlint formatting/linting as specified in issue #4; no unrelated modifications detected in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with 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.

Inline comments:
In @.editorconfig:
- 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.
- 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.

In `@build.gradle`:
- 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.
- Around line 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.
- Around line 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.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b4d985e4-dbfd-4cd6-a8da-596c670ef231

📥 Commits

Reviewing files that changed from the base of the PR and between fdc0ff3 and 1f2c46b.

📒 Files selected for processing (2)
  • .editorconfig
  • build.gradle

Comment thread .editorconfig
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.

Comment thread .editorconfig
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.

Comment thread build.gradle
Comment on lines +6 to +7
id "org.jlleitschuh.gradle.ktlint" version "13.1.0" apply false
id 'com.diffplug.spotless' version "7.2.1" apply 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

🧩 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.

Comment thread build.gradle
Comment on lines +78 to +84
tasks.named("check") {
dependsOn("spotlessApply")
}

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

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.

Comment thread build.gradle
}

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:tooling Build, Gradle, CI/release, packaging, and dependencies type:maintenance Maintenance, refactor, chore, or tooling upkeep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build(spotless): add Spotless for syntax enforcement

1 participant