gantsign / ktlint-maven-plugin

Maven plugin for ktlint the Kotlin linter
http://gantsign.com/ktlint-maven-plugin/
MIT License
61 stars 17 forks source link

Question: Running plugin in Gitlab CI/CD pipeline in a multimodule project #558

Closed bnbalint closed 1 year ago

bnbalint commented 1 year ago

Question: I would like to lint my entire multimodule kotlin project and add the linting results in file(s) on the Gitlab CI/CD pipeline (similar to adding unit test results). Currently, the job in the pipeline fails on the first module that has linting violations and does not continue (same behavior on the local command line), even though the failOnViolation configuration is set to false. What is the correct configuration to accomplish what I am trying to do? This is my current configuration, set in the parent pom of the modules in my project.

Current behavior: Continues past modules with no linting errors. Lints modules with linting errors, prints linting violations to the console, fails the maven command, does not continue to subsequent modules. Does not produce file containing linting summary.

Even when I cd into a particular module and perform the linting command, a file containing the violations is not produced.

Hopeful behavior: Lints all modules, even when failures occurs. Creates files containing the failures.

    <profiles>
        <profile>
            <id>linting</id>
            <build>
                <plugins>
                    <plugin>
                        <!-- Applies linting-->
                        <!-- run with command   mvn -Plinting com.github.gantsign.maven:ktlint-maven-plugin:1.16.0:check-->
                        <groupId>com.github.gantsign.maven</groupId>
                        <artifactId>ktlint-maven-plugin</artifactId>
                        <version>1.16.0</version>
                        <executions>
                            <execution>
                                <id>check</id>
                                <goals>
                                    <goal>check</goal>
                                </goals>
                                <configuration>
                                    <failOnViolation>false</failOnViolation>
                                    <reporters>
                                        <reporter>
                                            <name>plain</name>
                                            <output>${project.build.directory}/ktlint.txt</output>
                                            <properties>
                                                <property>
                                                    <name>group_by_file</name>
                                                    <value>true</value>
                                                </property>
                                            </properties>
                                        </reporter>
                                    </reporters>
                                </configuration>
                            </execution>
                        </executions>
                        <dependencies>
                            <dependency>
                                <groupId>com.segmint</groupId>
                                <artifactId>ktlint-rules</artifactId>
                                <version>1.0.0-SNAPSHOT</version>
                            </dependency>
                        </dependencies>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

Thank you!

freemanjp commented 1 year ago

Hi, @bnbalint. There is a test for the failOnViolation functionality and it does appear to be working https://github.com/gantsign/ktlint-maven-plugin/blob/main/src/it/checkstyle/pom.xml. Your configuration looks correct, but I noticed you have the linting config in a Maven profile, which isn't configured with activation. Perhaps the Maven profile isn't activated in your GitLab pipeline (https://maven.apache.org/guides/introduction/introduction-to-profiles.html)? Running mvn with -X should reveal what configuration is active at runtime.

bnbalint commented 1 year ago

Does the test handle a multimodule project? I think that is where the issue is coming in, since the behavior is also happening locally. Both local and in the pipeline, I run the plugin with: mvn -Plinting com.github.gantsign.maven:ktlint-maven-plugin:1.16.0:check to activate the profile. This is what the output looks like:

INFO] ------------------< com.segmint:springboot-hibernate >------------------
[INFO] Building springboot-hibernate 2.5.10_0-SNAPSHOT                   [7/23]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- ktlint-maven-plugin:1.16.0:check (default-cli) @ springboot-hibernate ---
[ERROR] src/main/kotlin/com/segmint/hibernate/usertype/IntegerArrayUserType.kt:42:22: Usage of NotNullAssertion operator
[ERROR] src/main/kotlin/com/segmint/hibernate/usertype/DecimalArrayUserType.kt:43:22: Usage of NotNullAssertion operator
[ERROR] src/main/kotlin/com/segmint/hibernate/usertype/LongArrayUserType.kt:42:22: Usage of NotNullAssertion operator
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for springboot-reactor 2.5.10_0-SNAPSHOT:
[INFO] 
[INFO] springboot-reactor ................................. SUCCESS [  0.435 s]
[INFO] config-poms ........................................ SUCCESS [  0.003 s]
[INFO] segmint-bom ........................................ SUCCESS [  0.001 s]
[INFO] springboot-kotlin-lib-starter ...................... SUCCESS [  0.119 s]
[INFO] gizmo .............................................. SUCCESS [  0.729 s]
[INFO] springboot-configs ................................. SUCCESS [  0.037 s]
[INFO] springboot-hibernate ............................... FAILURE [  0.101 s]
[INFO] springboot-metrics ................................. SKIPPED
[INFO] swagger-ui ......................................... SKIPPED
[INFO] springboot-swagger ................................. SKIPPED
[INFO] springboot-jdbi .................................... SKIPPED
[INFO] springboot-kafka ................................... SKIPPED
[INFO] springboot-client-util ............................. SKIPPED
[INFO] springboot-rest .................................... SKIPPED
[INFO] springboot-logging ................................. SKIPPED
[INFO] springboot-mail .................................... SKIPPED
[INFO] springboot-security ................................ SKIPPED
[INFO] springboot-security-core ........................... SKIPPED
[INFO] springboot-test .................................... SKIPPED
[INFO] springboot-redis ................................... SKIPPED
[INFO] springboot-event-consumer-starter .................. SKIPPED
[INFO] springboot-service-starter ......................... SKIPPED
[INFO] starters ........................................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.643 s
[INFO] Finished at: 2023-06-05T08:59:36-07:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.github.gantsign.maven:ktlint-maven-plugin:1.16.0:check (default-cli) on project springboot-hibernate: Kotlin source failed ktlint check. 

It executes the linting on the modules in order, but it fails when the first module fails the linting. Ideally I would like it to note the failure and then continue through the other modules so that I end up with a report of all of the linting failures for the entire mmp.

freemanjp commented 1 year ago

Running mvn -Plinting com.github.gantsign.maven:ktlint-maven-plugin:1.16.0:check will ignore your configuration under the execution as you're running the plugin, not that execution. To run the execution you can run: mvn -Plinting com.github.gantsign.maven:ktlint-maven-plugin:1.16.0:check@check (where @check is @ followed by the execution ID). Alternatively, you could move the configuration directly under <plugin> so the configuration applies anytime the plugin is run (this can be problematic if you want a different config for check and format).

If that doesn't help run mvn -X -Plinting com.github.gantsign.maven:ktlint-maven-plugin:1.16.0:check@check and provide the output between:

[DEBUG] Configuring mojo 'com.github.gantsign.maven:ktlint-maven-plugin:1.16.0:check' with basic configurator -->

and

[DEBUG] -- end configuration --
bnbalint commented 1 year ago

Oh perfect, thank you so much for the help! It was totally user error 🤦

freemanjp commented 1 year ago

No problem, happy to help