Returning statuses from a custom Gradle task, or how to detect taboo filenames in a java project

Must-share information (formatted with Markdown):

  • which versions are you using (SonarQube, Scanner, Plugin, and any relevant extension)
    Sonarqube 9.5.0.56709

  • what are you trying to achieve
    I want to be able to scan a bitbucketed gradle+java project file system for the presence of specfic filenames, which will indicate whether the java project has a legacy configuration (a local construct we want to eliminate). We want people to stop using that construct, so to detect and dashboard their progress with upgrading their projects we want to detect those files as a “smell” and report it in Sonar’s dashboard.

  • what have you tried so far to achieve this
    I looked for a Rule that I could make a custom Template off, but found nothing I thought I could use. I have a simple linux “find” that discovers the bad files.
    I have a gradle task that will execute that linux find set up as per SonarScanner for Gradle | SonarCloud Docs
    It finds the bad files and fails the “gradle sonarqube” build locally as expected when files are present (via the Task using exit 1 if it finds the files), but it does not feed any details back to sonarqube’s localhost:9000 dashboard that I can find.
    If I run a sonarqube build without it my build shows up in the localhost dashboard. If I “exit 0” rather than “exit 1” then it shows the ERROR in the gradle build console and completes the sonarqube run, but still the specfic test result is not to be found in the localhost dashboard.

How do I get that “find bad file” Gradle Task result returned to the sonarqube Task and sent back as a “smell” to the Sonarqube dashboard?
Or, what other approach should I change to, to detect some nuisance file name pattern in java projects in bitbucket and flag them as having a smell?

NB: these are a particular local config file, not java files, so “find ./src/main -type f -iname bannedfilename*.yml”.

task detectTabooLocalFiles(type: Exec) {
    executable "sh"
    commandLine 'bash', '-c',  """
if [ 1 -le `find ./src/main -type f -iname bannedfilename*.yml | wc -l` ] ;
then
    echo 'ERROR: Found taboo local bannedfilename*.yml';
    find ./src/main -type f -iname bannedfilename*.yml
    echo 'To be fully compliant, move the content of these to the approved location.'
    exit 0;
fi
"""
}

project.tasks ["sonarqube"].dependsOn "detectTabooLocalFiles"

Thanks in advance
Rob

1 Like

Note, I’m also looking at whether I can do something similar with GitHub - sbaudoin/sonar-yaml: SonarQube plugin to analyze YAML files and Narrowing the Focus | SonarQube Docs

Hey there.

You really have two options:

  • Transform your “banned file names” report to Generic Issue Data and pass the report to the sonar.externalIssuesReportPaths analysis parameter. This is probably the simplest way of accomplishing this (you can reuse parts of your existing script, it scales to many languages), although it comes with some limitations (you have to make sure all your build scripts are updated, execution of the rule is not enforced by the Quality Profile)
  • Deploy a custom plugin after writing a custom rule. Specifically, this tutorial might help you.
1 Like

Thanks Colin, I appreciate your time and expertise in replying.
I’m banking the first approach as a backup option, and thanks for the advice on how to link it up.

I’m looking more at the second approach, using this custom YAML plugin’s Forbidden Key Check which seems to offer enough grunt to look for the non-compliant files that I’m hunting when combined with “Only apply specific rules to specific files”.

However, I am at a stop point again with that approach, as it shows the added Quality Profile (with the custom Rule) against my tested project (from → Project Settings → Quality Profiles → Choose which profile is associated with this project on a language-by-language basis. Shows Java, XML, YAML with 405, 24, 20 active rules), but only the java Quality Profile’s Rules are being reported after a gradle build is run. Even though the added XML and YAML Quality Profiles show up as being active in localhost:9000, none of their Rules are reported failing (despite goofing some code in the XML and YAML files to trigger it), while some of the java Rules report failing and I can make more trigger by goofing more java code.

Is there some magic to running added XML and YAML (or other) Quality Profiles alongside a Java Quality Profile on a Project? As I say, the UI shows them existing but none of their Rules fail. (A local suggestion was “Sonar-scanner for multiple languages in one SQ project using Applications” but I’m unsure if it’s the same situation testing passive XML and YAML alongside Java, versus Java alongside .NET etc.

Ideally, even then, we don’t want to have to pick through hundreds of projects and set these Quality Profiles per project, we’d rather have some enterprise default that includes YAML testing for all Java projects by default.

(Note I’m running Community Edition locally while testing this, but the outcome will be put into an Enterprise version running on the client’s system once I work out how to configure it.)

Thanks again for any help.

(PS: looking into this answer at present: Unable to configure multiple custom Quality Profiles to our Project in SonarQube - #3 by gdhingra)

(PPS: Ok, when I look at the Project → Information → Lines of Code I see “Java 557” and nothing else. So it’s not seeing the XML/YAML lines of code. I think there might be an inclusions filter in the Gradle settings imported from a proprietary Gradle plugin or something like that perhaps. Digging deeper.)

(PPPS: dug a lot, I was able to filter in and out assorted java files with the sonarqube properties in build.gradle, but nothing made the YAML tests come to life or show the inclusion of YAML files in the “lines covered” result.)

Regards
Rob