Montag, 21. Dezember 2020

Java on the command line; and its errors in the vim-quickfix-error-window

Create a code coverage report with jacoco, which can then be found in target/site/jacoco/index.html:

 ./mvnw clean jacoco:prepare-agent install jacoco:report


Running specific tests:

./mvnw test -Punit-tests -Dtest=FirstNiceTest*,SomeOtherNice*UnitTest
./mvnw test -Pintegration-tests -Dtest=AlsoSomeNice*IntegrationTest


Running all tests:

./mvnw test
./mvnw verify


Skipping tests:

./mvnw clean compile install -DskipTests


Opening a jshell in with the project classpath:

./mvnw com.github.johnpoth:jshell-maven-plugin:1.3:run -DtestClasspath


Running static code analysis with SpotBugs, FindSecBugs, PMD:

./mvnw clean compile spotbugs:spotbugs pmd:pmd checkstyle:checkstyle -DskipTests


For this to work, you also need to add some code in the pom.xml, like:

  <build>
   <plugins>
     <plugin>
         <groupId>com.github.spotbugs</groupId>
         <artifactId>spotbugs-maven-plugin</artifactId>
         <version>4.1.3</version>
         <dependencies>
             <!-- overwrite dependency on spotbugs if you want to specify the version of spotbugs -->
             <dependency>
                 <groupId>com.github.spotbugs</groupId>
                 <artifactId>spotbugs</artifactId>
                 <version>4.2.0</version>
             </dependency>
         </dependencies>
         <configuration>
             <effort>Max</effort>
             <threshold>Low</threshold>
             <failOnError>false</failOnError>
             <plugins>
                 <plugin>
                     <groupId>com.h3xstream.findsecbugs</groupId>
                     <artifactId>findsecbugs-plugin</artifactId>
                     <version>1.11.0</version>
                 </plugin>
             </plugins>
         </configuration>
     </plugin>
     <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-pmd-plugin</artifactId>
         <version>3.14.0</version>
         <configuration>
             <format>txt</format>
             <failOnError>false</failOnError>
             <failOnViolation>false</failOnViolation>
             <linkXRef>false</linkXRef>
         </configuration>
     </plugin>
     <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
         <version>3.1.1</version>
         <configuration>
             <consoleOutput>false</consoleOutput>
             <failsOnError>false</failsOnError>
             <outputFileFormat>plain</outputFileFormat>
             <outputFile>${project.build.directory}/checkstyle-result.txt</outputFile>
             <linkXRef>false</linkXRef>
         </configuration>
     </plugin>
   </plugins>
 </build>

 <reporting>
     <plugins>
         <plugin>
             <groupId>com.github.spotbugs</groupId>
             <artifactId>spotbugs-maven-plugin</artifactId>
             <version>4.1.3</version>
         </plugin>
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-pmd-plugin</artifactId>
             <version>3.14.0</version>
         </plugin>
       <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-checkstyle-plugin</artifactId>
           <version>3.1.1</version>
       </plugin>
     </plugins>
 </reporting>



Having executed the checks, they create log files:

target/checkstyle-result.txt
target/pmd.txt
target/pmd.xml

target/spotbugsXml.xml


SpotBugs brings its own GUI to visualize its findings, which can be run via:

./mvnw spotbugs:gui


To have a look at the results of CheckStyle and PMD we can use vim and its QuickFix-commands: https://vimhelp.org/quickfix.txt.html

The two interesting ones for us are: 

:cg[etfile] [errorfile]                                 

:cg :cgetfile
                       Read the error file.  Just like ":cfile" but don't
                       jump to the first error.
                       If the encoding of the error file differs from the
                       'encoding' option, you can use the 'makeencoding'
                       option to specify the encoding. 


                                           :cope :cop
en w:quickfix_title

:cope[n] [height]       Open a window to show the current list of errors.

                       When [height] is given, the window becomes that high
                       (if there is room).  When [height] is omitted the
                       window is made ten lines high.
                       If there already is a quickfix window, it will be made  
                       the current window.  It is not possible to open a
                       second quickfix window.  If [height] is given the
                       existing window will be resized to it.

                                                       quickfix-buffer
                       The window will contain a special buffer, with
                       'buftype' equal to "quickfix".  Don't change this!
                       The window will have the w:quickfix_title variable set
                       which will indicate the command that produced the
                       quickfix list. This can be used to compose a custom
                       status line if the value of 'statusline' is adjusted
                       properly. Whenever this buffer is modified by a
                       quickfix command or function, the b:changedtick
                       variable is incremented.  You can get the number of
                       this buffer using the getqflist() and getloclist()
                       functions by passing the 'qfbufnr' item. For a
                       location list, this buffer is wiped out when the
                       location list is removed.

First, we load our errorfile and then open the window showing the errors with:

:cgetfile target/pmd.txt
:cgetfile target/checkstyle-result.txt

:copen


That way we get a nice view of our errors, and hitting ENTER on them will directly open the mentioned file and line, and also the column if given.

Different programs may create different formats in their output. The formats used in vim are specified in the variable errorformat, which is a list of formats, which are tried until one fits. So it may not be correct.

Just as it is not correct for the checkstyle-result. Instead of writing a fitting format for parsing, I just removed the first and last line, and those [ERROR] entries in front of each line. After that the file was working nicely.


IntelliJ IDEA has the ability to also execute format and inspect from the command line. The two scripts can be found in its bin-folder.

Format a single file:

./idea-IU/bin/format.sh -s ./Googleish.xml MyNiceClass.java

Format a folder recursively:

./idea-IU/bin/format.sh -s ./Googleish.xml -r MyNiceJavaProgram/src

Inspect a project and write the log into a file:

./idea-IU/bin/inspect.sh

MyNiceJavaProgram ./Googleish.xml MyNiceJavaProgram/inspect.log -v2 -d MyNiceJavaProgram/src -format plain

I created shell scripts for easier access from vim:

  • format one file
    #!/bin/sh
    /home/myself/programs/idea-IU/bin/format.sh -s /home/myself/projects/ideaCLI/Googleish.xml $1
  • format recursive from a path
    #!/bin/sh
    /home/myself/programs/idea-IU/bin/format.sh -s /home/
    myself/projects/ideaCLI/Googleish.xml -r $1
  •  inspect a project
    #!/bin/sh
    /home/myself/programs/idea-IU/bin/inspect.sh $1 /home/
    myself/projects/ideaCLI/Googleish.xml $1/inspect.log -v2 -d $1/src -format plain

And in vim, in the .vimrc, I have set up custom commands to call those scripts:

  • format this file
    command IdeaFormatThis ! /home/myself/projects/ideaCLI/ideaFormat.sh %:p
  • format from current file path
    command IdeaFormatHere ! /home/myself/projects/ideaCLI/ideaFormatR.sh %:p:h
  • format some path
    command -nargs=1 IdeaFormatThere ! /home/myself/projects/ideaCLI/ideaFormatR.sh <args>
  • inspect current project
    command -nargs=1 IdeaInspect ! /home/myself/projects/ideaCLI/ideaInspect.sh <args>

The outputted inspect.log is again not in a vim compatible errorformat. And this time it needs a little more work to get it to that point.

  1. Remove all lines that are not beginning with a path
    :v/^\s*\.\//d
  2. Sort
    :sort
  3. Replace the dot with the full-path
    :%s!^\s*\.!/full/path/to/the/project!
  4. Put a colon behind the line number
    :%s/\(:\d\{1,}\)/\1:/

 Now the logged output looks nice in the quickfix / error window in vim.

Keine Kommentare:

Kommentar veröffentlichen

[Review/Critic] UDock X - 13,3" LapDock

The UDock X - 13.3" LapDock is a combination of touch display, keyboard, touch-pad and battery. It can be used as an extension of vari...