Add own parser to Warning-NG-Plugin

Hi,

I have a question regarding to defining an own parser for compiler issues to report these with the Warning-NG-Plugin.

I managed to setup the custom parser via the GUI. Now I want to provide that parser as an library-item. That should provide me some managed configuration in one place by using git.

I already have another item in the library which works fine and load it with

@Library('zk-common-pipeline-libs@main') _

at the begin of the pipeline. I get loaded but I have some trouble to make work.

This is my parser-script, below resources\c166Parser.groovy:

import edu.hm.hafner.analysis.Severity

Severity level = (matcher.group(1) == 'ERROR')
    ? Severity.WARNING_HIGH
    : Severity.WARNING_NORMAL

builder.setFileName(matcher.group(4))
       .setLineStart(Integer.parseInt(matcher.group(3)))
       .setSeverity(level)
       .setCategory(matcher.group(2))
       .setMessage(matcher.group(5))

return builder.buildOptional()

That the same code I have configured via the Web-UI->Manage Jenkins->System->Groovy Based Warnings Parser

To call the parser I also have added a script below vars\c166Parser.groovy:

def call() {
  return analysisParser(
     name:    'C166 Groovy Parser',
     pattern: '^\\*\\*\\* (ERROR|WARNING) ([A-Z]\\d+) IN LINE (\\d+) OF (.*?): (.*)$',
     script:  libraryResource('c166Parser.groovy')
  )
}

It get’s called during the build-step by

               script {
                  if (COMPILER == 'c166') {
                    // Provided by warning-ng-plugin
                    globalIssues.c166 = scanForIssues (
                      tool: c166Parser()
                    )
                  }
                }

, but than fail to get executed.

WARNING: Unknown parameter(s) found for class type 'io.jenkins.plugins.analysis.warnings.RegisteredParser': script

java.lang.IllegalArgumentException: Could not instantiate {tool=@analysisParser(name=C166 Groovy Parser,pattern=^\*\*\* (ERROR|WARNING) ([A-Z]\d+) IN LINE (\d+) OF (.*?): (.*)$,script=import edu.hm.hafner.analysis.Severity


Severity level = (matcher.group(1) == 'ERROR')

    ? Severity.WARNING_HIGH

    : Severity.WARNING_NORMAL


builder.setFileName(matcher.group(4))

       .setLineStart(Integer.parseInt(matcher.group(3)))

       .setSeverity(level)

       .setCategory(matcher.group(2))

       .setMessage(matcher.group(5))


return builder.buildOptional()

)} for io.jenkins.plugins.analysis.core.steps.ScanForIssuesStep: java.lang.IllegalArgumentException: Could not instantiate {name=C166 Groovy Parser, pattern=^\*\*\* (ERROR|WARNING) ([A-Z]\d+) IN LINE (\d+) OF (.*?): (.*)$, script=import edu.hm.hafner.analysis.Severity


Severity level = (matcher.group(1) == 'ERROR')

    ? Severity.WARNING_HIGH

    : Severity.WARNING_NORMAL


builder.setFileName(matcher.group(4))

       .setLineStart(Integer.parseInt(matcher.group(3)))

       .setSeverity(level)

       .setCategory(matcher.group(2))

       .setMessage(matcher.group(5))


return builder.buildOptional()

} for io.jenkins.plugins.analysis.warnings.RegisteredParser: java.lang.reflect.InvocationTargetException

Is it even possible to have a parser defined like this? Are there any tutorials?

BR
Ben

Jenkins setup:

Jenkins: 2.510
OS: Linux - 5.10.0-28-amd64
Java: 21.0.7 - Eclipse Adoptium (OpenJDK 64-Bit Server VM)

analysis-model-api:13.2.0
ant:513.vde9e7b_a_0da_0f
antisamy-markup-formatter:173.v680e3a_b_69ff3
apache-httpcomponents-client-4-api:4.5.14-269.vfa_2321039a_83
apache-httpcomponents-client-5-api:5.4.4-144.vc483d91903d2
asm-api:9.8-135.vb_2239d08ee90
authentication-tokens:1.131.v7199556c3004
blueocean:1.27.19
blueocean-bitbucket-pipeline:1.27.19
blueocean-commons:1.27.19
blueocean-config:1.27.19
blueocean-core-js:1.27.19
blueocean-dashboard:1.27.19
blueocean-display-url:2.4.4
blueocean-events:1.27.19
blueocean-git-pipeline:1.27.19
blueocean-github-pipeline:1.27.19
blueocean-i18n:1.27.19
blueocean-jwt:1.27.19
blueocean-personalization:1.27.19
blueocean-pipeline-api-impl:1.27.19
blueocean-pipeline-editor:1.27.19
blueocean-pipeline-scm-api:1.27.19
blueocean-rest:1.27.19
blueocean-rest-impl:1.27.19
blueocean-web:1.27.19
bootstrap5-api:5.3.5-1
bouncycastle-api:2.30.1.80-256.vf98926042a_9b_
branch-api:2.1217.v43d8b_b_d8b_2c7
build-timeout:1.38
caffeine-api:3.2.0-166.v72a_6d74b_870f
checks-api:370.vb_61a_c57328f3
cloudbees-bitbucket-branch-source:936.1.1
cloudbees-folder:6.1012.v79a_86a_1ea_c1f
commons-compress-api:1.27.1-3
commons-lang3-api:3.17.0-87.v5cf526e63b_8b_
commons-text-api:1.13.0-153.v91dcd89e2a_22
credentials:1415.v831096eb_5534
credentials-binding:687.v619cb_15e923f
dark-theme:524.vd675b_22b_30cb_
data-tables-api:2.2.2-1
display-url-api:2.209.v582ed814ff2f
docker-commons:451.vd12c371eeeb_3
docker-workflow:611.v16e84da_6d3ff
doxygen:178.v6ea_ef5f7dfdb
durable-task:587.v84b_877235b_45
echarts-api:5.6.0-4
eddsa-api:0.3.0.1-19.vc432d923e5ee
email-ext:1876.v28d8d38315b_d
favorite:2.225.v68765b_b_a_1fa_3
font-awesome-api:6.7.2-1
forensics-api:3.1.0
git:5.7.0
git-client:6.1.3
git-forensics:3.2.0
gitea:250.v76a_0b_d4fef5b_
gitea-checks:530.v38d502df428f
github:1.43.0
github-api:1.321-488.v9b_c0da_9533f8
github-branch-source:1815.v9152b_2ff7a_1b_
gradle:2.15
gson-api:2.13.1-139.v4569c2ef303f
handy-uri-templates-2-api:2.1.8-36.v85e4cb_234a_13
htmlpublisher:425
instance-identity:203.v15e81a_1b_7a_38
ionicons-api:88.va_4187cb_eddf1
jackson2-api:2.18.3-402.v74c4eb_f122b_2
jakarta-activation-api:2.1.3-2
jakarta-mail-api:2.1.3-2
javax-activation-api:1.2.0-8
javax-mail-api:1.6.2-11
jaxb:2.3.9-133.vb_ec76a_73f706
jenkins-design-language:1.27.19
jjwt-api:0.11.5-120.v0268cf544b_89
joda-time-api:2.14.0-127.v7d9da_295a_d51
jquery3-api:3.7.1-3
json-api:20250107-125.v28b_a_ffa_eb_f01
json-path-api:2.9.0-148.v22a_7ffe323ce
jsoup:1.20.1-46.ve5f1416988c2
junit:1335.v6b_a_a_e18534e1
ldap:780.vcb_33c9a_e4332
mailer:489.vd4b_25144138f
matrix-auth:3.2.6
matrix-project:849.v0cd64ed7e531
mina-sshd-api-common:2.15.0-161.vb_200831a_c15b_
mina-sshd-api-core:2.15.0-161.vb_200831a_c15b_
okhttp-api:4.11.0-189.v976fa_d3379d6
pam-auth:1.12
pipeline-build-step:567.vea_ce550ece97
pipeline-github-lib:65.v203688e7727e
pipeline-graph-analysis:237.v2b_75640ca_888
pipeline-groovy-lib:752.vdddedf804e72
pipeline-input-step:517.vf8e782ee645c
pipeline-milestone-step:138.v78ca_76831a_43
pipeline-model-api:2.2255.v56a_15e805f12
pipeline-model-definition:2.2255.v56a_15e805f12
pipeline-model-extensions:2.2255.v56a_15e805f12
pipeline-rest-api:2.38
pipeline-stage-step:322.vecffa_99f371c
pipeline-stage-tags-metadata:2.2255.v56a_15e805f12
pipeline-stage-view:2.38
pipeline-utility-steps:2.19.0
plain-credentials:195.vb_906e9073dee
plugin-util-api:6.1.0
prism-api:1.30.0-1
pubsub-light:1.19
resource-disposer:0.25
role-strategy:764.v3c95b_fcb_32ee
scm-api:704.v3ce5c542825a_
script-security:1373.vb_b_4a_a_c26fa_00
snakeyaml-api:2.3-125.v4d77857a_b_402
sonar:2.18
sse-gateway:1.28
ssh-credentials:355.v9b_e5b_cde5003
ssh-slaves:3.1031.v72c6b_883b_869
sshd:3.353.v2b_d33c46e970
structs:343.vdcf37b_a_c81d5
theme-manager:294.vf2c2fd783821
timestamper:1.28
token-macro:444.v52de7e9c573d
trilead-api:2.209.v0e69b_c43c245
variant:70.va_d9f17f859e0
warnings-ng:12.6.0
workflow-aggregator:608.v67378e9d3db_1
workflow-api:1373.v7b_813f10efa_b_
workflow-basic-steps:1079.vce64b_a_929c5a_
workflow-cps:4106.v7a_8a_8176d450
workflow-durable-task-step:1405.v1fcd4a_d00096
workflow-job:1520.v56d65e3b_4566
workflow-multibranch:806.vb_b_688f609ee9
workflow-scm-step:437.v05a_f66b_e5ef8
workflow-step-api:700.v6e45cb_a_5a_a_21
workflow-support:968.v8f17397e87b_8
ws-cleanup:0.48

In my test cases for the plugin I moved the parser definition into a separate configuration step, see

Then the pipeline step simply referenced the parser by ID.

Might this be the problem? Can’t you use that approach?

Thanks for replying.

I’m not sure if I get the point right. Yes I have already setup the parser via the WEB-UI and could use the approach calling it by it’s ID.

Do I get it right, that this is the only way to do it at all?
No chance to use the “CasC” by defining it as script and load it by the @Library-Pipeline-Command?

Here is a screenshot of my setup for a KEIL C166 C-Compiler.

This is how I call it in the pipeline:

script {
  if (COMPILER == 'c166') {
    // Provided by warning-ng-plugin
    globalIssues.c166 = scanForIssues (
      tool: groovyScript (
        parserId: 'c166-parser-issues'
      )
    )
  }
}

And in the post-stage of the build-stage:

failure {
  script {
    if (env.COMPILER == 'c166') {
      recordIssues(
        enabledForFailure: true,
        tools:          [ groovyScript(parserId: 'c166-parser-issues') ],
        consoleParsers: ['c166-parser-issues']
      )
    }
  }
}

You can configure the parsers in your Jenkins instance using JCasC: Example from my tests: warnings-ng-plugin/plugin/src/test/resources/io/jenkins/plugins/analysis/warnings/integrations/parsers.yaml at 3ce0b20bf0c072c733f06b5663c7338304e97021 · jenkinsci/warnings-ng-plugin · GitHub

These parsers can then be referenced in your pipeline steps.

I have no idea how to combine it with @Library-Pipeline-Command, I never used that so far.