From f992d2c26530020ea6f91b6ca9b0ad5e45e1ad24 Mon Sep 17 00:00:00 2001 From: proletarius101 Date: Tue, 21 Oct 2025 12:11:53 +0000 Subject: [PATCH] feat: add PMD linting integration to GitLab CI --- .gitlab-ci.yml | 53 ++++++++++++++- .../java/org/fdroid/fdroid/Netstat.java | 1 + .../fdroid/fdroid/net/HttpDownloaderTest.java | 4 +- .../fdroid/fdroid/AppUpdateStatusManager.java | 1 + .../org/fdroid/fdroid/NotificationHelper.java | 10 +-- .../installer/SessionInstallManager.java | 54 +++++++-------- .../views/AppSecurityPermissions.java | 9 ++- .../views/AppDetailsRecyclerViewAdapter.java | 23 +++---- .../views/categories/AppCardController.java | 6 +- .../fdroid/views/main/MainActivity.java | 6 +- .../codec/binary/CharSequenceUtils.java | 12 ++-- .../org/apache/commons/codec/binary/Hex.java | 16 ++--- .../java/org/fdroid/fdroid/RepoUrlsTest.java | 4 +- config/pmd/pmd.gradle | 2 +- config/pmd/rules-main.xml | 14 ++-- config/pmd/rules-test.xml | 14 ++-- config/pmd/rules.xml | 13 ++-- gradle/verification-metadata.xml | 68 +++++++++++++++++++ 18 files changed, 210 insertions(+), 100 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 59f8f73a6..0deda6295 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -129,7 +129,7 @@ libs index test: script: - ./gradlew :libs:index:testDebugUnitTest -app lint pmd checkstyle: +app lint checkstyle: <<: *test-template stage: lint rules: @@ -140,7 +140,7 @@ app lint pmd checkstyle: # always report on lint errors to the build log - sed -i -e 's,textReport .*,textReport true,' app/build.gradle # the tasks "lint", "test", etc don't always include everything - - ./gradlew :app:lint :app:pmd :app:checkstyle :app:ktlintCheck + - ./gradlew :app:lint :app:checkstyle :app:ktlintCheck libs lint ktlintCheck: <<: *test-template @@ -154,6 +154,55 @@ libs lint ktlintCheck: - sed -i -e 's,textReport .*,textReport true,' app/build.gradle - ./gradlew :libs:database:lint :libs:download:lint :libs:index:lint ktlintCheck +# Reference: https://gitlab.com/components/code-quality-oss/codequality-os-scanners-integration/-/blob/4121970daed111dda84cab4547e1f2951684653c/templates/pmd.yml#L52-92 +app lint pmd: + stage: lint + image: + name: registry.gitlab.com/gitlab-ci-utils/gitlab-pmd-cpd:latest + entrypoint: [ "" ] + rules: + - <<: *always-on-these-changes + - changes: + - app/**/* + parallel: + matrix: + - PMD_VARIANT: main + PMD_RULESETS: "config/pmd/rules.xml,config/pmd/rules-main.xml" + PMD_FILE_PATHS: + - "app/src/main/java" + - PMD_VARIANT: test + PMD_RULESETS: "config/pmd/rules.xml,config/pmd/rules-test.xml" + PMD_FILE_PATHS: + - "app/src/test/java" + - "app/src/androidTest/java" + before_script: + - apt-get update + - apt-get -qy install --no-install-recommends jq + script: + - find ${PMD_FILE_PATHS[@]} -type f -name '*.java' ! -path '/vendored/*' > .pmd-files.txt + - pmd check --file-list .pmd-files.txt -R ${PMD_RULESETS} -f codeclimate -r gl-code-quality-not-formatted.json --no-fail-on-violation + after_script: + ## Fingerprint is required for reading Codequality: https://docs.gitlab.com/ee/ci/testing/code_quality.html#implement-a-custom-tool + ## PMD output does not contain fingerprint. Following snippet generates a fingerprint with md5sum for each code quality item and adds a comma at end of each line to format as JSON array + ## This returns true always. PMD rarely outputs codequality items which are not JSON conformant, because they are not properly escaped. + ## For example \w+ instead of \\w+ Therefore following snippet ignores those issues, so that all other lines are represented in the report + - | + sed 's/\\/\\\\/g' gl-code-quality-not-formatted.json | while IFS= read -r line; do + fingerprint=$(echo -n "$line" | md5sum | awk '{print $1}'); + echo "$line" | jq -c --arg fp "$fingerprint" '. + {fingerprint: $fp}' | sed 's/$/,/'; + done > gl-pmd-${PMD_VARIANT}-report.json || true + + # adds square bracket at the beginning for JSON array + - sed -i '1s/^/[/' gl-pmd-${PMD_VARIANT}-report.json + # adds square bracket at the end for JSON array + - sed -i '$s/,$/]/' gl-pmd-${PMD_VARIANT}-report.json + artifacts: + paths: + - gl-pmd-${PMD_VARIANT}-report.json + reports: + codequality: gl-pmd-${PMD_VARIANT}-report.json + when: always + app tools scripts: stage: lint image: debian:bookworm-slim diff --git a/app/src/androidTest/java/org/fdroid/fdroid/Netstat.java b/app/src/androidTest/java/org/fdroid/fdroid/Netstat.java index 99920e3fb..26416afc4 100644 --- a/app/src/androidTest/java/org/fdroid/fdroid/Netstat.java +++ b/app/src/androidTest/java/org/fdroid/fdroid/Netstat.java @@ -357,6 +357,7 @@ public class Netstat { } @NonNull + @Override public String toString() { return "[Prot=" + getProtocolAsString() + ",POwner=" + powner + diff --git a/app/src/androidTest/java/org/fdroid/fdroid/net/HttpDownloaderTest.java b/app/src/androidTest/java/org/fdroid/fdroid/net/HttpDownloaderTest.java index b7d67234d..377eda97a 100644 --- a/app/src/androidTest/java/org/fdroid/fdroid/net/HttpDownloaderTest.java +++ b/app/src/androidTest/java/org/fdroid/fdroid/net/HttpDownloaderTest.java @@ -94,7 +94,9 @@ public class HttpDownloaderTest { File destFile = File.createTempFile("dl-", ""); final DownloadRequest request = new DownloadRequest(path, mirrors, null, null, null); final HttpDownloader httpDownloader = new HttpDownloader(httpManager, request, destFile); - httpDownloader.setListener((bytesRead, totalBytes) -> receivedProgress = true); + httpDownloader.setListener((bytesRead, totalBytes) -> { + receivedProgress = true; + }); new Thread() { @Override public void run() { diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java index c2988ffc7..dd1e1ca76 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java +++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java @@ -149,6 +149,7 @@ public final class AppUpdateStatusManager { * Dumps some information about the status for debugging purposes. */ @NonNull + @Override public String toString() { return app.packageName + " [Status: " + status + ", Progress: " + progressCurrent + " / " + progressMax + ']'; diff --git a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java index 9066565ec..241edbdb1 100644 --- a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java @@ -177,11 +177,11 @@ public class NotificationHelper { private boolean shouldIgnoreEntry(AppUpdateStatusManager.AppUpdateStatus entry) { // Ignore unknown status // Ignore downloading, readyToInstall and installError if we are showing the details screen for this app - if (entry.status == AppUpdateStatusManager.Status.DownloadInterrupted) return true; - return (entry.status == AppUpdateStatusManager.Status.Downloading || - entry.status == AppUpdateStatusManager.Status.ReadyToInstall || - entry.status == AppUpdateStatusManager.Status.InstallError) && - AppDetailsActivity.isAppVisible(entry.app.packageName); + return entry.status == AppUpdateStatusManager.Status.DownloadInterrupted || + ((entry.status == AppUpdateStatusManager.Status.Downloading || + entry.status == AppUpdateStatusManager.Status.ReadyToInstall || + entry.status == AppUpdateStatusManager.Status.InstallError) && + AppDetailsActivity.isAppVisible(entry.app.packageName)); } private void createNotification(AppUpdateStatusManager.AppUpdateStatus entry) { diff --git a/app/src/main/java/org/fdroid/fdroid/installer/SessionInstallManager.java b/app/src/main/java/org/fdroid/fdroid/installer/SessionInstallManager.java index cb5235cb0..79d904fa8 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/SessionInstallManager.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/SessionInstallManager.java @@ -283,36 +283,34 @@ public class SessionInstallManager extends BroadcastReceiver { */ public static boolean canBeUsed(Context context) { // In case of bugs, let the user disable this while it is still beta. - if (Preferences.get().forceOldInstaller()) return false; - // We could use the SessionInstaller also on lower versions, - // but the benefit of unattended updates only starts with SDK 31. - // Before the extra bugs it has aren't worth it. - if (Build.VERSION.SDK_INT < 31) return false; - // Xiaomi MIUI (at least in version 12) is known to break the PackageInstaller API in several ways. - // Disabling MIUI "optimizations" in developer options fixes it, but we can't ask users to do this (bad UX). - // Therefore, we have no choice, but to disable it completely for those devices. - // See: https://github.com/vvb2060/PackageInstallerTest - if (isStockXiaomi(context)) return false; - // We don't use SessionInstaller, if PrivilegedInstaller can be used instead. - // This is the last check, because it is the most expensive one - // getting PackageInfo and doing service binding. - return !PrivilegedInstaller.isDefault(context); + return !Preferences.get().forceOldInstaller() && + // We could use the SessionInstaller also on lower versions, + // but the benefit of unattended updates only starts with SDK 31. + // Before the extra bugs it has aren't worth it. + Build.VERSION.SDK_INT >= 31 && + // Xiaomi MIUI (at least in version 12) is known to break the PackageInstaller API in several ways. + // Disabling MIUI "optimizations" in developer options fixes it, + // but we can't ask users to do this (bad UX). + // Therefore, we have no choice, but to disable it completely for those devices. + // See: https://github.com/vvb2060/PackageInstallerTest + !isStockXiaomi(context) && + // We don't use SessionInstaller, if PrivilegedInstaller can be used instead. + // This is the last check, because it is the most expensive one + // getting PackageInfo and doing service binding. + !PrivilegedInstaller.isDefault(context); } private static boolean isStockXiaomi(Context context) { if (isStockXiaomi == null) { boolean xiaomiPhone = "Xiaomi".equalsIgnoreCase(Build.BRAND) || "Redmi".equalsIgnoreCase(Build.BRAND); - if (xiaomiPhone) { + if (!xiaomiPhone) { + isStockXiaomi = false; + } else { // Calls for non-installed packages take longer than installed ones // MIUI OS will result in one call // Non-MIUI OS will result in two calls - if (Utils.getPackageInfo(context, "com.miui.securitycenter") != null) { - isStockXiaomi = true; - } else { - isStockXiaomi = Utils.getPackageInfo(context, "com.miui.packageinstaller") != null; - } - } else { - isStockXiaomi = false; + isStockXiaomi = Utils.getPackageInfo(context, "com.miui.securitycenter") != null || + Utils.getPackageInfo(context, "com.miui.packageinstaller") != null; } } return isStockXiaomi; @@ -324,15 +322,15 @@ public class SessionInstallManager extends BroadcastReceiver { * thus updating the app with the given targetSdk without user action. */ public static boolean isTargetSdkSupported(int targetSdk) { - if (Build.VERSION.SDK_INT < 31) return false; // not supported below Android 12 - if (Build.VERSION.SDK_INT == 31 && targetSdk >= 29) return true; - if (Build.VERSION.SDK_INT == 32 && targetSdk >= 29) return true; - if (Build.VERSION.SDK_INT == 33 && targetSdk >= 30) return true; - if (Build.VERSION.SDK_INT == 34 && targetSdk >= 31) return true; // This needs to be adjusted as new Android versions are released // https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(int) // https://cs.android.com/android/platform/superproject/+/android-16.0.0_r2:frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java;l=329;drc=73caa0299d9196ddeefe4f659f557fb880f6536d // current code requires targetSdk 33 on SDK 35+ - return Build.VERSION.SDK_INT >= 35 && targetSdk >= 33; + int sdk = Build.VERSION.SDK_INT; + if (sdk < 31) return false; // not supported below Android 12 + if (sdk <= 32) return targetSdk >= 29; + if (sdk == 33) return targetSdk >= 30; + if (sdk == 34) return targetSdk >= 31; + return targetSdk >= 33; } } diff --git a/app/src/main/java/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java b/app/src/main/java/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java index a2cf87ea2..5761cd823 100644 --- a/app/src/main/java/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java +++ b/app/src/main/java/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java @@ -351,11 +351,8 @@ public class AppSecurityPermissions { * this concept, permissions are never "new permissions". */ private static boolean isNewPermission(PackageInfo installedPkgInfo, int existingFlags) { - if (installedPkgInfo == null) { - return false; - } - - return (existingFlags & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0; + return installedPkgInfo != null && + (existingFlags & PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0; } private List getPermissionList(MyPermissionGroupInfo grp, int which) { @@ -454,6 +451,7 @@ public class AppSecurityPermissions { private final Collator collator = Collator.getInstance(); + @Override public final int compare(MyPermissionGroupInfo a, MyPermissionGroupInfo b) { return collator.compare(a.label, b.label); } @@ -466,6 +464,7 @@ public class AppSecurityPermissions { PermissionInfoComparator() { } + @Override public final int compare(MyPermissionInfo a, MyPermissionInfo b) { return collator.compare(a.label, b.label); } diff --git a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java index 732122717..ff3e40de6 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java +++ b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java @@ -821,12 +821,11 @@ public class AppDetailsRecyclerViewAdapter private class ScreenShotsViewHolder extends AppDetailsViewHolder implements ScreenShotsRecyclerViewAdapter.Listener { final RecyclerView recyclerView; - ItemDecorator itemDecorator; ScreenShotsViewHolder(View view) { super(view); recyclerView = view.findViewById(R.id.screenshots); - itemDecorator = new ItemDecorator(context); + ItemDecorator itemDecorator = new ItemDecorator(context); recyclerView.addItemDecoration(itemDecorator); } @@ -979,6 +978,7 @@ public class AppDetailsRecyclerViewAdapter updateExpandableItem(showVersions); } + @Override @DrawableRes protected int getIcon() { return R.drawable.ic_versions; @@ -1082,6 +1082,7 @@ public class AppDetailsRecyclerViewAdapter } } + @Override @DrawableRes protected int getIcon() { return R.drawable.ic_lock; @@ -1161,6 +1162,7 @@ public class AppDetailsRecyclerViewAdapter } } + @Override @DrawableRes protected int getIcon() { return R.drawable.ic_website; @@ -1179,7 +1181,6 @@ public class AppDetailsRecyclerViewAdapter final TextView size; final TextView api; final Button buttonInstallUpgrade; - Button buttonAction; final View busyIndicator; final TextView incompatibleReasons; final TextView targetArch; @@ -1372,21 +1373,20 @@ public class AppDetailsRecyclerViewAdapter } private void showActionButton(Button button, boolean isApkInstalled, boolean isApkDownloading) { - buttonAction = button; if (isApkDownloading) { // Don't show the button in this case // as the busy indicator will take its place - buttonAction.setVisibility(View.GONE); + button.setVisibility(View.GONE); } else { // The button should be shown but it should be also disabled // if either the APK isn't compatible or it's already installed // or also when some other APK is currently being downloaded - buttonAction.setVisibility(View.VISIBLE); + button.setVisibility(View.VISIBLE); boolean buttonActionDisabled = !apk.compatible || isApkInstalled || callbacks.isAppDownloading(); - buttonAction.setEnabled(!buttonActionDisabled); - buttonAction.setAlpha(buttonActionDisabled ? 0.15f : 1f); - buttonAction.setOnClickListener(v -> callbacks.installApk(apk)); + button.setEnabled(!buttonActionDisabled); + button.setAlpha(buttonActionDisabled ? 0.15f : 1f); + button.setOnClickListener(v -> callbacks.installApk(apk)); } } @@ -1487,10 +1487,7 @@ public class AppDetailsRecyclerViewAdapter } private boolean uriIsSet(String s) { - if (TextUtils.isEmpty(s)) { - return false; - } - return true; + return !TextUtils.isEmpty(s); } /** diff --git a/app/src/main/java/org/fdroid/fdroid/views/categories/AppCardController.java b/app/src/main/java/org/fdroid/fdroid/views/categories/AppCardController.java index f2600ef9e..d84406b5c 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/categories/AppCardController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/categories/AppCardController.java @@ -85,10 +85,8 @@ public class AppCardController extends RecyclerView.ViewHolder } private boolean isConsideredNew(@NonNull AppOverviewItem app) { - if (app.getAdded() != app.getLastUpdated()) { - return false; - } - return Utils.daysSince(app.getAdded()) <= DAYS_TO_CONSIDER_NEW; + return app.getAdded() == app.getLastUpdated() && + Utils.daysSince(app.getAdded()) <= DAYS_TO_CONSIDER_NEW; } /** diff --git a/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java b/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java index 32a83db23..c336e6d5c 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java @@ -83,6 +83,7 @@ public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; + @SuppressWarnings("StaticFieldLeak") public static final String EXTRA_VIEW_LATEST = "org.fdroid.fdroid.views.main.MainActivity.VIEW_LATEST"; private static final String EXTRA_VIEW_CATEGORIES = "org.fdroid.fdroid.views.main.MainActivity.VIEW_CATEGORIES"; private static final String EXTRA_VIEW_NEARBY = "org.fdroid.fdroid.views.main.MainActivity.VIEW_NEARBY"; @@ -176,7 +177,7 @@ public class MainActivity extends AppCompatActivity { } /** - * {@link android.material.navigation.NavigationBarView} says "Menu items + * {@link com.google.android.material.navigation.NavigationBarView} says "Menu items * can also be used for programmatically selecting which destination is * currently active. It can be done using {@code MenuItem.setChecked(true)}". */ @@ -190,6 +191,7 @@ public class MainActivity extends AppCompatActivity { } } + @SuppressWarnings("PMD.UnusedPrivateMethod") private void setSelectedMenuInNav(final String viewName) { if (EXTRA_VIEW_LATEST.equals(viewName)) { setSelectedMenuInNav(R.id.latest); @@ -227,7 +229,7 @@ public class MainActivity extends AppCompatActivity { } @Override - protected void onNewIntent(Intent intent) { + protected void onNewIntent(@NonNull Intent intent) { super.onNewIntent(intent); if (handleMainViewSelectIntent(intent)) { diff --git a/app/src/main/java/vendored/org/apache/commons/codec/binary/CharSequenceUtils.java b/app/src/main/java/vendored/org/apache/commons/codec/binary/CharSequenceUtils.java index f9e3fbb28..49f867bb0 100644 --- a/app/src/main/java/vendored/org/apache/commons/codec/binary/CharSequenceUtils.java +++ b/app/src/main/java/vendored/org/apache/commons/codec/binary/CharSequenceUtils.java @@ -54,13 +54,13 @@ public class CharSequenceUtils { if (cs instanceof String && substring instanceof String) { return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); } - int index1 = thisStart; - int index2 = start; - int tmpLen = length; + int index1 = thisStart; // NOPMD + int index2 = start; // NOPMD + int tmpLen = length; // NOPMD - while (tmpLen-- > 0) { - final char c1 = cs.charAt(index1++); - final char c2 = substring.charAt(index2++); + while (tmpLen-- > 0) { // NOPMD + final char c1 = cs.charAt(index1++); // NOPMD + final char c2 = substring.charAt(index2++); // NOPMD if (c1 == c2) { continue; diff --git a/app/src/main/java/vendored/org/apache/commons/codec/binary/Hex.java b/app/src/main/java/vendored/org/apache/commons/codec/binary/Hex.java index 83d3660a1..319bc3a6a 100644 --- a/app/src/main/java/vendored/org/apache/commons/codec/binary/Hex.java +++ b/app/src/main/java/vendored/org/apache/commons/codec/binary/Hex.java @@ -103,11 +103,11 @@ public class Hex implements BinaryEncoder, BinaryDecoder { } // two characters form the hex value. - for (int i = outOffset, j = 0; j < len; i++) { - int f = toDigit(data[j], j) << 4; - j++; - f = f | toDigit(data[j], j); - j++; + for (int i = outOffset, j = 0; j < len; i++) { // NOPMD + int f = toDigit(data[j], j) << 4; // NOPMD + j++; // NOPMD + f = f | toDigit(data[j], j); // NOPMD + j++; // NOPMD out[i] = (byte) (f & 0xFF); } @@ -219,9 +219,9 @@ public class Hex implements BinaryEncoder, BinaryDecoder { private static void encodeHex(final byte[] data, final int dataOffset, final int dataLen, final char[] toDigits, final char[] out, final int outOffset) { // two characters form the hex value. - for (int i = dataOffset, j = outOffset; i < dataOffset + dataLen; i++) { - out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; - out[j++] = toDigits[0x0F & data[i]]; + for (int i = dataOffset, j = outOffset; i < dataOffset + dataLen; i++) { // NOPMD + out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; // NOPMD + out[j++] = toDigits[0x0F & data[i]]; // NOPMD } } diff --git a/app/src/test/java/org/fdroid/fdroid/RepoUrlsTest.java b/app/src/test/java/org/fdroid/fdroid/RepoUrlsTest.java index d67a32f3d..f29984461 100644 --- a/app/src/test/java/org/fdroid/fdroid/RepoUrlsTest.java +++ b/app/src/test/java/org/fdroid/fdroid/RepoUrlsTest.java @@ -44,9 +44,9 @@ public class RepoUrlsTest { */ private static class TestRepo { // Repo URL for the test case - String repoUrl; + final String repoUrl; // String format pattern for generating file URLs, should contain a single %s for the filename - String fileUrlPattern; + final String fileUrlPattern; TestRepo(String repoUrl, String fileUrlPattern) { this.repoUrl = repoUrl; diff --git a/config/pmd/pmd.gradle b/config/pmd/pmd.gradle index 96f11a372..b25d4dd24 100644 --- a/config/pmd/pmd.gradle +++ b/config/pmd/pmd.gradle @@ -1,7 +1,7 @@ apply plugin: 'pmd' pmd { - toolVersion = '6.20.0' + toolVersion = '7.17.0' consoleOutput = true } diff --git a/config/pmd/rules-main.xml b/config/pmd/rules-main.xml index 81d6ca133..5a66d5b8b 100644 --- a/config/pmd/rules-main.xml +++ b/config/pmd/rules-main.xml @@ -1,12 +1,10 @@ - - - Rules for the project code aka "main". - + + + Rules for the project code aka "main". + diff --git a/config/pmd/rules-test.xml b/config/pmd/rules-test.xml index 1d9d81a86..3ae045bec 100644 --- a/config/pmd/rules-test.xml +++ b/config/pmd/rules-test.xml @@ -1,12 +1,10 @@ - - - Rules for the test harness code aka "androidTest" and "test". - + + + Rules for the test harness code aka "androidTest" and "test". + diff --git a/config/pmd/rules.xml b/config/pmd/rules.xml index 64b55aa49..8cbe65608 100644 --- a/config/pmd/rules.xml +++ b/config/pmd/rules.xml @@ -1,23 +1,22 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> Rules for the whole project - + - + @@ -43,9 +42,9 @@ - + - + diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index a40fceea8..ebe2f26a3 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -8160,6 +8160,11 @@ + + + + + @@ -8478,6 +8483,11 @@ + + + + + @@ -8751,6 +8761,11 @@ + + + + + @@ -13062,11 +13077,21 @@ + + + + + + + + + + @@ -13075,6 +13100,11 @@ + + + + + @@ -13083,6 +13113,11 @@ + + + + + @@ -13139,6 +13174,11 @@ + + + + + @@ -13239,6 +13279,11 @@ + + + + + @@ -13717,6 +13762,11 @@ + + + + + @@ -18225,6 +18275,11 @@ + + + + + @@ -18839,6 +18894,11 @@ + + + + + @@ -18975,6 +19035,14 @@ + + + + + + + +