Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sb-contrib for SpotBugs #1309

Merged
merged 7 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:8.2.1'
classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:6.0.6'
classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:5.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.4"
classpath "org.jacoco:org.jacoco.core:$jacoco_version"
Expand Down Expand Up @@ -62,7 +62,7 @@ dependencies {
implementation 'org.bouncycastle:bcpkix-jdk18on:1.75'

spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0'
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.6.4'
spotbugsPlugins 'com.mebigfatguy.sb-contrib:sb-contrib:7.6.4'

// dependencies for tests
testImplementation "junit:junit:$junit_version"
Expand Down Expand Up @@ -97,10 +97,13 @@ tasks.withType(SpotBugsTask){task ->
classes = files("$project.buildDir/intermediates/javac/${variantName}")
excludeFilter = file("${project.rootDir}/scripts/analysis/spotbugs-filter.xml")
reports {
xml.enabled = false
xml {
required = true
}
html {
enabled = true
destination = file("$project.buildDir/reports/spotbugs/spotbugs.html")
required = true
outputLocation = file("$project.buildDir/reports/spotbugs/spotbugs.html")
stylesheet = 'fancy.xsl'
}
}
}
Expand Down
78 changes: 47 additions & 31 deletions scripts/analysis/analysis-wrapper.sh
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
#!/bin/sh
#!/usr/bin/env bash

BRANCH=$1
LOG_USERNAME=$2
LOG_PASSWORD=$3
BUILD_NUMBER=$4
PR_NUMBER=$5

#1: GIT_USERNAME
#2: GIT_TOKEN
#3: BRANCH
#4: LOG_USERNAME
#5: LOG_PASSWORD
#6: DRONE_BUILD_NUMBER
#7: PULL_REQUEST_NUMBER

stableBranch="master"
repository="library"
repository="android-library"

ruby scripts/analysis/findbugs-up.rb $1 $2 $3
findbugsValue=$?
curl "https://www.kaminsky.me/nc-dev/$repository-findbugs/$stableBranch.xml" -o "/tmp/$stableBranch.xml"
ruby scripts/analysis/spotbugs-up.rb "$stableBranch"
spotbugsValue=$?

# exit codes:
# 0: count was reduced
# 1: count was increased
# 2: count stayed the same

echo "Branch: $3"
source scripts/lib.sh

if [ $3 = $stableBranch ]; then
echo "New SpotBugs result for $stableBranch at: https://www.kaminsky.me/nc-dev/$repository-findbugs/$stableBranch.html"
curl -u $4:$5 -X PUT https://nextcloud.kaminsky.me/remote.php/dav/files/$4/$repository-findbugs/$stableBranch.html --upload-file library/build/reports/spotbugs/spotbugs.html
echo "Branch: $BRANCH"

summary=$(sed -n "/<h1>Summary<\/h1>/,/<h1>Warnings<\/h1>/p" library/build/reports/spotbugs/spotbugs.html | head -n-1 | sed s'/<\/a>//'g | sed s'/<a.*>//'g | sed s"/Summary/SpotBugs ($stableBranch)/" | tr "\"" "\'" | tr -d "\r\n" | sed 's/^ *//')
curl -u $4:$5 -X PUT -d "$summary" https://nextcloud.kaminsky.me/remote.php/dav/files/$4/$repository-findbugs/findbugs-summary-$stableBranch.html
if [ "$BRANCH" = $stableBranch ]; then
echo "New spotbugs result for $stableBranch at: https://www.kaminsky.me/nc-dev/$repository-findbugs/$stableBranch.html"
curl -u "${LOG_USERNAME}:${LOG_PASSWORD}" -X PUT https://nextcloud.kaminsky.me/remote.php/webdav/$repository-findbugs/$stableBranch.html --upload-file library/build/reports/spotbugs/spotbugs.html
curl 2>/dev/null -u "${LOG_USERNAME}:${LOG_PASSWORD}" -X PUT "https://nextcloud.kaminsky.me/remote.php/webdav/$repository-findbugs/$stableBranch.xml" --upload-file library/build/reports/spotbugs/spotbugs.html
else
if [ -e $6 ]; then
if [ -e "${BUILD_NUMBER}" ]; then
6=$stableBranch"-"$(date +%F)
fi
echo "New SpotBugs results at https://www.kaminsky.me/nc-dev/$repository-findbugs/$6.html"
curl 2>/dev/null -u $4:$5 -X PUT https://nextcloud.kaminsky.me/remote.php/dav/files/$4/$repository-findbugs/$6.html --upload-file library/build/reports/spotbugs/spotbugs.html

# delete all old comments
oldComments=$(curl 2>/dev/null -u $1:$2 -X GET https://api.github.com/repos/nextcloud/android-library/issues/$7/comments | jq '.[] | (.id |tostring) + "|" + (.user.login | test("nextcloud-android-bot") | tostring) ' | grep true | tr -d "\"" | cut -f1 -d"|")
echo "New spotbugs results at https://www.kaminsky.me/nc-dev/$repository-findbugs/${BUILD_NUMBER}.html"
curl 2>/dev/null -u "${LOG_USERNAME}:${LOG_PASSWORD}" -X PUT "https://nextcloud.kaminsky.me/remote.php/webdav/$repository-findbugs/${BUILD_NUMBER}.html" --upload-file library/build/reports/spotbugs/spotbugs.html

# delete all old comments, starting with Codacy
oldComments=$(curl_gh -X GET "https://api.github.com/repos/nextcloud/$repository/issues/${PR_NUMBER}/comments" | jq '.[] | select((.user.login | contains("github-actions")) and (.body | test("<h1>Codacy.*"))) | .id')

echo $oldComments | while read comment ; do
curl 2>/dev/null -u $1:$2 -X DELETE https://api.github.com/repos/nextcloud/android-library/issues/comments/$comment
echo "$oldComments" | while read -r comment ; do
curl_gh -X DELETE "https://api.github.com/repos/nextcloud/$repository/issues/comments/$comment"
done

# spotbugs file must exist
Expand All @@ -48,18 +49,33 @@ else
fi

# add comment with results
findbugsResultNew=$(sed -n "/<h1>Summary<\/h1>/,/<h1>Warnings<\/h1>/p" library/build/reports/spotbugs/spotbugs.html |head -n-1 | sed s'/<\/a>//'g | sed s'/<a.*>//'g | sed s"#Summary#<a href=\"https://www.kaminsky.me/nc-dev/$repository-findbugs/$6.html\">SpotBugs</a> (new)#" | tr "\"" "\'" | tr -d "\n" | sed 's/^ *//')
findbugsResultOld=$(curl 2>/dev/null https://www.kaminsky.me/nc-dev/$repository-findbugs/findbugs-summary-$stableBranch.html | tr "\"" "\'" | tr -d "\r\n" | sed s"#SpotBugs#<a href=\"https://www.kaminsky.me/nc-dev/$repository-findbugs/$stableBranch.html\">SpotBugs</a>#" | tr "\"" "\'" | tr -d "\n" | sed 's/^ *//')
spotbugsResult="<h1>SpotBugs</h1>$(scripts/analysis/spotbugsComparison.py "/tmp/$stableBranch.xml" library/build/reports/spotbugs/debug.xml --link-new "https://www.kaminsky.me/nc-dev/$repository-findbugs/${BUILD_NUMBER}.html" --link-base "https://www.kaminsky.me/nc-dev/$repository-findbugs/$stableBranch.html")"

if ( [ $findbugsValue -eq 1 ] ) ; then
findbugsMessage="<h1>SpotBugs increased!</h1>"
if ( [ $spotbugsValue -eq 1 ] ) ; then
spotbugsMessage="<h1>SpotBugs increased!</h1>"
fi

# check for NotNull
if [[ $(grep org.jetbrains.annotations library/src/main/* -irl | wc -l) -gt 0 ]] ; then
notNull="org.jetbrains.annotations.* is used. Please use androidx.annotation.* instead.<br><br>"
fi

curl -u $1:$2 -X POST https://api.github.com/repos/nextcloud/android-library/issues/$7/comments -d "{ \"body\" : \"$findbugsResultNew $findbugsResultOld $findbugsMessage \" }"
bodyContent="$spotbugsResult $spotbugsMessage $gplayLimitation $notNull"
echo "$bodyContent" >> "$GITHUB_STEP_SUMMARY"
payload="{ \"body\" : \"$bodyContent\" }"
curl_gh -X POST "https://api.github.com/repos/nextcloud/$repository/issues/${PR_NUMBER}/comments" -d "$payload"

if [ ! -z "$gplayLimitation" ]; then
exit 1
fi

if [ -n "$notNull" ]; then
exit 1
fi

if [ $findbugsValue -eq 2 ]; then
if [ $spotbugsValue -eq 2 ]; then
exit 0
else
exit $findbugsValue
exit $spotbugsValue
fi
fi
128 changes: 0 additions & 128 deletions scripts/analysis/findbugs-up.rb

This file was deleted.

48 changes: 48 additions & 0 deletions scripts/analysis/spotbugs-up.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
## Script originally from https://github.com/tir38/android-lint-entropy-reducer at 07.05.2017
# heavily modified since then

Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

puts "=================== starting Android Spotbugs Entropy Reducer ===================="

# get args
base_branch = ARGV[0]

require 'fileutils'
require 'pathname'
require 'open3'

# run Spotbugs
puts "running Spotbugs..."
system './gradlew spotbugsDebug 1>/dev/null 2>&1'

# find number of warnings
current_warning_count = `./scripts/analysis/spotbugsSummary.py --file library/build/reports/spotbugs/debug.xml --total`.to_i
puts "found warnings: " + current_warning_count.to_s

# get warning counts from target branch
previous_xml = "/tmp/#{base_branch}.xml"
previous_results = File.file?(previous_xml)

if previous_results == true
previous_warning_count = `./scripts/analysis/spotbugsSummary.py --total --file #{previous_xml}`.to_i
puts "previous warnings: " + previous_warning_count.to_s
end

# compare previous warning count with current warning count
if previous_results == true && current_warning_count > previous_warning_count
puts "FAIL: warning count increased"
exit 1
end

# check if warning and error count stayed the same
if previous_results == true && current_warning_count == previous_warning_count
puts "SUCCESS: count stayed the same"
exit 0
end

# warning count DECREASED
if previous_results == true && current_warning_count < previous_warning_count
puts "SUCCESS: count decreased from " + previous_warning_count.to_s + " to " + current_warning_count.to_s
end
54 changes: 54 additions & 0 deletions scripts/analysis/spotbugsComparison.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
import argparse
import defusedxml.ElementTree as ET

import spotbugsSummary


def print_comparison(old: dict, new: dict, link_base: str, link_new: str):
all_keys = sorted(set(list(old.keys()) + list(new.keys())))

output = "<table><tr><th>Category</th>"
old_header = f"<a href='{link_base}'>Base</a>" if link_base is not None else "Base"
output += f"<th>{old_header}</th>"
new_header = f"<a href='{link_new}'>New</a>" if link_new is not None else "New"
output += f"<th>{new_header}</th>"
output += "</tr>"

for category in all_keys:
category_count_old = old[category] if category in old else 0
category_count_new = new[category] if category in new else 0
new_str = f"<b>{category_count_new}</b>" if category_count_new != category_count_old else str(
category_count_new)
output += "<tr>"
output += f"<td>{category}</td>"
output += f"<td>{category_count_old}</td>"
output += f"<td>{new_str}</td>"
output += "</tr>"

output += "<tr>"
output += "<td><b>Total</b></td>"
output += f"<td><b>{sum(old.values())}</b></td>"
output += f"<td><b>{sum(new.values())}</b></td>"
output += "</tr>"

output += "</table>"

print(output)


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("base_file", help="base file for comparison")
parser.add_argument("new_file", help="new file for comparison")
parser.add_argument("--link-base", help="http link to base html report")
parser.add_argument("--link-new", help="http link to new html report")
args = parser.parse_args()

base_tree = ET.parse(args.base_file)
base_summary = spotbugsSummary.get_counts(base_tree)

new_tree = ET.parse(args.new_file)
new_summary = spotbugsSummary.get_counts(new_tree)

print_comparison(base_summary, new_summary, args.link_base, args.link_new)
Loading
Loading