@codacy/tools-detekt-1 0.6.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +235 -43
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1752,7 +1752,8 @@ var patterns_default = [
1752
1752
  title: "Avoid Redundant Suspend Modifier",
1753
1753
  enabled: false,
1754
1754
  languages: ["Kotlin"],
1755
- parameters: []
1755
+ parameters: [],
1756
+ tags: ["coroutines"]
1756
1757
  },
1757
1758
  {
1758
1759
  id: "RedundantVisibilityModifierRule",
@@ -1824,7 +1825,8 @@ var patterns_default = [
1824
1825
  title: "Avoid Usage of Thread.sleep() in Coroutines",
1825
1826
  enabled: false,
1826
1827
  languages: ["Kotlin"],
1827
- parameters: []
1828
+ parameters: [],
1829
+ tags: ["coroutines"]
1828
1830
  },
1829
1831
  {
1830
1832
  id: "SpacingAroundAngleBrackets",
@@ -2013,7 +2015,8 @@ var patterns_default = [
2013
2015
  title: "Avoid Using runCatching with suspend Lambda Blocks",
2014
2016
  enabled: false,
2015
2017
  languages: ["Kotlin"],
2016
- parameters: []
2018
+ parameters: [],
2019
+ tags: ["coroutines"]
2017
2020
  },
2018
2021
  {
2019
2022
  id: "SuspendFunWithCoroutineScopeReceiver",
@@ -2022,7 +2025,8 @@ var patterns_default = [
2022
2025
  title: "Avoid suspend modifier on functions with CoroutineScope receiver",
2023
2026
  enabled: false,
2024
2027
  languages: ["Kotlin"],
2025
- parameters: []
2028
+ parameters: [],
2029
+ tags: ["coroutines"]
2026
2030
  },
2027
2031
  {
2028
2032
  id: "SuspendFunWithFlowReturnType",
@@ -2031,7 +2035,8 @@ var patterns_default = [
2031
2035
  title: "Avoid suspend modifier on functions returning Flow",
2032
2036
  enabled: false,
2033
2037
  languages: ["Kotlin"],
2034
- parameters: []
2038
+ parameters: [],
2039
+ tags: ["coroutines"]
2035
2040
  },
2036
2041
  {
2037
2042
  id: "SwallowedException",
@@ -2727,6 +2732,8 @@ var TOOL_ID = "detekt";
2727
2732
  var DETEKT_VERSION = "1.23.8";
2728
2733
  var JAR_NAME = `detekt-cli-${DETEKT_VERSION}-all.jar`;
2729
2734
  var JAR_URL = `https://github.com/detekt/detekt/releases/download/v${DETEKT_VERSION}/${JAR_NAME}`;
2735
+ var FORMATTING_JAR_NAME = `detekt-formatting-${DETEKT_VERSION}.jar`;
2736
+ var FORMATTING_JAR_URL = `https://github.com/detekt/detekt/releases/download/v${DETEKT_VERSION}/${FORMATTING_JAR_NAME}`;
2730
2737
  var JAVA_VERSION_RANGE = ">=8";
2731
2738
  var PATTERN_META = new Map(
2732
2739
  patterns_default.map((p) => [
@@ -2737,6 +2744,152 @@ var PATTERN_META = new Map(
2737
2744
  }
2738
2745
  ])
2739
2746
  );
2747
+ var PATTERN_ID_ALIASES = /* @__PURE__ */ new Map([
2748
+ ["ClassNaming", "ClassName"],
2749
+ ["EnumNaming", "EnumEntryNameCase"],
2750
+ ["NewLineAtEndOfFile", "FinalNewline"],
2751
+ ["FunctionNaming", "FunctionName"],
2752
+ ["MaxLineLength", "MaximumLineLength"],
2753
+ ["ModifierOrder", "ModifierOrdering"],
2754
+ ["EmptyClassBlock", "NoEmptyClassBody"],
2755
+ ["PackageNaming", "PackageName"],
2756
+ ["VariableNaming", "PropertyName"]
2757
+ ]);
2758
+ var FORMATTING_RULES = /* @__PURE__ */ new Set([
2759
+ "AnnotationOnSeparateLine",
2760
+ "AnnotationSpacing",
2761
+ "ArgumentListWrapping",
2762
+ "BlockCommentInitialStarAlignment",
2763
+ "CascadingCallWrapping",
2764
+ "ChainWrapping",
2765
+ "ClassName",
2766
+ "CommentSpacing",
2767
+ "CommentWrapping",
2768
+ "EnumEntryNameCase",
2769
+ "EnumWrapping",
2770
+ "Filename",
2771
+ "FinalNewline",
2772
+ "FunKeywordSpacing",
2773
+ "FunctionName",
2774
+ "FunctionReturnTypeSpacing",
2775
+ "FunctionSignature",
2776
+ "FunctionStartOfBodySpacing",
2777
+ "FunctionTypeReferenceSpacing",
2778
+ "IfElseBracing",
2779
+ "IfElseWrapping",
2780
+ "ImportOrdering",
2781
+ "Indentation",
2782
+ "KdocWrapping",
2783
+ "MandatoryBracesLoops",
2784
+ "MaximumLineLength",
2785
+ "ModifierListSpacing",
2786
+ "ModifierOrdering",
2787
+ "MultiLineIfElse",
2788
+ "MultilineExpressionWrapping",
2789
+ "NoBlankLineBeforeRbrace",
2790
+ "NoBlankLineInList",
2791
+ "NoBlankLinesInChainedMethodCalls",
2792
+ "NoConsecutiveBlankLines",
2793
+ "NoConsecutiveComments",
2794
+ "NoEmptyClassBody",
2795
+ "NoEmptyFirstLineInClassBody",
2796
+ "NoEmptyFirstLineInMethodBlock",
2797
+ "NoLineBreakAfterElse",
2798
+ "NoLineBreakBeforeAssignment",
2799
+ "NoMultipleSpaces",
2800
+ "NoSemicolons",
2801
+ "NoSingleLineBlockComment",
2802
+ "NoTabs",
2803
+ "NoTrailingSpaces",
2804
+ "NoUnusedImports",
2805
+ "NoWildcardImports",
2806
+ "NullableTypeSpacing",
2807
+ "PackageName",
2808
+ "ParameterListSpacing",
2809
+ "ParameterListWrapping",
2810
+ "ParameterWrapping",
2811
+ "PropertyName",
2812
+ "PropertyWrapping",
2813
+ "SpacingAroundAngleBrackets",
2814
+ "SpacingAroundColon",
2815
+ "SpacingAroundComma",
2816
+ "SpacingAroundCurly",
2817
+ "SpacingAroundDot",
2818
+ "SpacingAroundDoubleColon",
2819
+ "SpacingAroundKeyword",
2820
+ "SpacingAroundOperators",
2821
+ "SpacingAroundParens",
2822
+ "SpacingAroundRangeOperator",
2823
+ "SpacingAroundUnaryOperator",
2824
+ "SpacingBetweenDeclarationsWithAnnotations",
2825
+ "SpacingBetweenDeclarationsWithComments",
2826
+ "SpacingBetweenFunctionNameAndOpeningParenthesis",
2827
+ "StringTemplate",
2828
+ "StringTemplateIndent",
2829
+ "TrailingCommaOnCallSite",
2830
+ "TrailingCommaOnDeclarationSite",
2831
+ "TrailingWhitespace",
2832
+ "TryCatchFinallySpacing",
2833
+ "TypeArgumentListSpacing",
2834
+ "TypeParameterListSpacing",
2835
+ "UnnecessaryParenthesesBeforeTrailingLambda",
2836
+ "Wrapping"
2837
+ ]);
2838
+ var TYPE_RESOLUTION_RULES = /* @__PURE__ */ new Set([
2839
+ "CanBeNonNullable",
2840
+ "CastNullableToNonNullableType",
2841
+ "CastToNullableType",
2842
+ "CouldBeSequence",
2843
+ "DontDowncastCollectionTypes",
2844
+ "ElseCaseInsteadOfExhaustiveWhen",
2845
+ "ExitOutsideMain",
2846
+ "ExplicitCollectionElementAccessMethod",
2847
+ "GlobalCoroutineUsage",
2848
+ "HasPlatformType",
2849
+ "IgnoredReturnValue",
2850
+ "ImplicitDefaultLocale",
2851
+ "ImplicitUnitReturnType",
2852
+ "InjectDispatcher",
2853
+ "LibraryCodeMustSpecifyReturnType",
2854
+ "LibraryEntitiesShouldNotBePublic",
2855
+ "MapGetWithNotNullAssertionOperator",
2856
+ "MayBeConst",
2857
+ "MissingWhenCase",
2858
+ "NullCheckOnMutableProperty",
2859
+ "NullableToStringCall",
2860
+ "ObjectExtendsThrowable",
2861
+ "ObjectLiteralToLambda",
2862
+ "RedundantExplicitType",
2863
+ "RedundantHigherOrderMapUsage",
2864
+ "RedundantSuspendModifier",
2865
+ "RedundantVisibilityModifierRule",
2866
+ "SleepInsteadOfDelay",
2867
+ "SpreadOperator",
2868
+ "SuspendFunSwallowedCancellation",
2869
+ "SuspendFunWithCoroutineScopeReceiver",
2870
+ "SuspendFunWithFlowReturnType",
2871
+ "UnconditionalJumpStatementInLoop",
2872
+ "UnnecessaryAbstractClass",
2873
+ "UnnecessaryAnnotationUseSiteTarget",
2874
+ "UnnecessaryBackticks",
2875
+ "UnnecessaryFilter",
2876
+ "UnnecessaryInnerClass",
2877
+ "UnnecessaryLet",
2878
+ "UnnecessaryNotNullCheck",
2879
+ "UnnecessaryNotNullOperator",
2880
+ "UnnecessaryPartOfBinaryExpression",
2881
+ "UnnecessarySafeCall",
2882
+ "UnnecessaryTemporaryInstantiation",
2883
+ "UnreachableCatchBlock",
2884
+ "UnreachableCode",
2885
+ "UnsafeCallOnNullableType",
2886
+ "UnsafeCast",
2887
+ "UseIfEmptyOrIfBlank",
2888
+ "UseIsNullOrEmpty",
2889
+ "UseSumOfInsteadOfFlatMapSize",
2890
+ "UselessCallOnNotNull",
2891
+ "VarCouldBeVal"
2892
+ ]);
2740
2893
  function ruleMetadata(ruleId) {
2741
2894
  return PATTERN_META.get(ruleId) ?? { category: "CodeStyle", severity: "Info" };
2742
2895
  }
@@ -2757,23 +2910,36 @@ function extractRuleId(source) {
2757
2910
  }
2758
2911
  return ruleId;
2759
2912
  }
2760
- async function resolveJavaPath(ctx) {
2761
- const jreDir = import_path.default.join(ctx.globalDir, "runtimes", "java-17");
2762
- const javaBin = import_path.default.join(jreDir, "bin", "java");
2913
+ async function resolveFormattingJarPath(ctx) {
2914
+ const jarPath = import_path.default.join(ctx.toolInstallDir, FORMATTING_JAR_NAME);
2763
2915
  try {
2764
- await import_promises.default.access(javaBin);
2765
- return javaBin;
2916
+ await import_promises.default.access(jarPath);
2917
+ return jarPath;
2766
2918
  } catch {
2919
+ return null;
2767
2920
  }
2768
- if (process.env.JAVA_HOME) {
2769
- const javaHome = import_path.default.join(process.env.JAVA_HOME, "bin", "java");
2921
+ }
2922
+ var CLASSPATH_CANDIDATES = [
2923
+ "build/classes/kotlin/main",
2924
+ "build/classes/java/main",
2925
+ "target/classes"
2926
+ ];
2927
+ async function resolveClasspath(ctx) {
2928
+ const found = [];
2929
+ for (const candidate of CLASSPATH_CANDIDATES) {
2930
+ const fullPath = import_path.default.join(ctx.repositoryRoot, candidate);
2770
2931
  try {
2771
- await import_promises.default.access(javaHome);
2772
- return javaHome;
2932
+ await import_promises.default.access(fullPath);
2933
+ found.push(fullPath);
2773
2934
  } catch {
2774
2935
  }
2775
2936
  }
2776
- return "java";
2937
+ if (found.length === 0) return null;
2938
+ ctx.logger.debug("Resolved classpath for type resolution", {
2939
+ toolId: TOOL_ID,
2940
+ paths: found
2941
+ });
2942
+ return found.join(import_path.default.delimiter);
2777
2943
  }
2778
2944
  async function resolveJarPath(ctx) {
2779
2945
  const jarPath = import_path.default.join(ctx.toolInstallDir, JAR_NAME);
@@ -2787,6 +2953,7 @@ async function resolveJarPath(ctx) {
2787
2953
  var CONFIG_FILE_CANDIDATES = ["detekt.yml", "default-detekt-config.yml"];
2788
2954
  var adapter = {
2789
2955
  ...descriptor,
2956
+ patternsMetadata: patterns_default,
2790
2957
  compatibleVersions: ">=1.20.0",
2791
2958
  website: "https://detekt.dev/",
2792
2959
  prerequisites: [
@@ -2800,35 +2967,24 @@ var adapter = {
2800
2967
  /**
2801
2968
  * Checks whether detekt is available (Java runtime + detekt JAR).
2802
2969
  *
2803
- * Checks:
2804
- * 1. Java runtime via findJava (JAVA_HOME, then PATH)
2805
- * 2. detekt CLI JAR in the tool install directory
2806
- *
2970
+ * Uses checkJavaRuntime() to probe managed JRE, JAVA_HOME, and PATH.
2807
2971
  * Reports Java as a dependency in the return value.
2808
2972
  */
2809
2973
  async checkAvailability(ctx) {
2810
2974
  ctx.logger.debug("Checking availability", { toolId: TOOL_ID });
2811
- const javaInfo = await (0, import_tooling.findJava)(JAVA_VERSION_RANGE, ctx.logger).catch(() => null);
2812
- const dependencies = javaInfo ? [{ name: "Java", available: true, version: javaInfo.version, installation: "global" }] : [{ name: "Java", available: false, reason: `Java (${JAVA_VERSION_RANGE}) not found` }];
2975
+ const { java: javaInfo, dependency: javaDep } = await (0, import_tooling.checkJavaRuntime)(
2976
+ ctx.globalDir,
2977
+ JAVA_VERSION_RANGE,
2978
+ ctx.logger
2979
+ );
2980
+ const dependencies = [javaDep];
2813
2981
  if (!javaInfo) {
2814
- const jreDir = import_path.default.join(ctx.globalDir, "runtimes", "java-17");
2815
- const javaBin = import_path.default.join(jreDir, "bin", "java");
2816
- try {
2817
- await import_promises.default.access(javaBin);
2818
- dependencies[0] = {
2819
- name: "Java",
2820
- available: true,
2821
- version: "17",
2822
- installation: "codacy"
2823
- };
2824
- } catch {
2825
- return {
2826
- available: false,
2827
- reason: "Java runtime not found (required for detekt)",
2828
- installHint: "Install JDK 17+, or run with --install-dependencies for auto-download",
2829
- dependencies
2830
- };
2831
- }
2982
+ return {
2983
+ available: false,
2984
+ reason: "Java runtime not found (required for detekt)",
2985
+ installHint: "Install JDK 8+ (17 recommended), or run with --install-dependencies for auto-download",
2986
+ dependencies
2987
+ };
2832
2988
  }
2833
2989
  const jarPath = await resolveJarPath(ctx);
2834
2990
  if (jarPath) {
@@ -2875,6 +3031,9 @@ var adapter = {
2875
3031
  ctx.logger.info(`Downloading detekt CLI JAR to ${ctx.toolInstallDir}...`);
2876
3032
  const jarPath = await (0, import_tooling.downloadJar)(JAR_URL, ctx.toolInstallDir, JAR_NAME, ctx.logger);
2877
3033
  ctx.logger.info(`Installed detekt to ${jarPath}`);
3034
+ ctx.logger.info(`Downloading detekt-formatting plugin JAR...`);
3035
+ await (0, import_tooling.downloadJar)(FORMATTING_JAR_URL, ctx.toolInstallDir, FORMATTING_JAR_NAME, ctx.logger);
3036
+ ctx.logger.info(`Installed detekt-formatting plugin`);
2878
3037
  return { success: true, installedPath: jarPath, installedVersion: DETEKT_VERSION };
2879
3038
  } catch (err) {
2880
3039
  return {
@@ -2939,7 +3098,21 @@ var adapter = {
2939
3098
  if (ctx.targetFiles.length === 0) {
2940
3099
  return (0, import_tooling.buildResult)(TOOL_ID, startedAt, /* @__PURE__ */ new Date(), issues, errors, 0);
2941
3100
  }
2942
- const javaBin = await resolveJavaPath(ctx);
3101
+ const classpath = await resolveClasspath(ctx);
3102
+ if (codacyConfig.patterns.length > 0) {
3103
+ const typeResPatterns = codacyConfig.patterns.map((p) => p.patternId).filter((id) => TYPE_RESOLUTION_RULES.has(id));
3104
+ if (typeResPatterns.length > 0 && !classpath) {
3105
+ errors.push({
3106
+ toolId: TOOL_ID,
3107
+ phase: "toolConfig",
3108
+ kind: "ParseWarning",
3109
+ message: `${typeResPatterns.length} pattern(s) require type resolution but no compiled classes found (build/classes/ or target/classes/): ${typeResPatterns.slice(0, 5).join(", ")}${typeResPatterns.length > 5 ? ` and ${typeResPatterns.length - 5} more` : ""}. Build the project first to enable these patterns.`,
3110
+ level: "warning"
3111
+ });
3112
+ }
3113
+ }
3114
+ const resolved = await (0, import_tooling.resolveJava)(ctx.globalDir, JAVA_VERSION_RANGE, ctx.logger);
3115
+ const javaBin = resolved?.path ?? "java";
2943
3116
  const jarPath = await resolveJarPath(ctx);
2944
3117
  if (!jarPath) {
2945
3118
  errors.push({
@@ -2970,6 +3143,25 @@ var adapter = {
2970
3143
  if (useLocal) {
2971
3144
  args.push("--config", codacyConfig.localConfigurationFile);
2972
3145
  }
3146
+ if (classpath) {
3147
+ args.push("--classpath", classpath);
3148
+ }
3149
+ const hasFormattingRules = codacyConfig.patterns.some((p) => FORMATTING_RULES.has(p.patternId));
3150
+ if (hasFormattingRules) {
3151
+ const formattingJar = await resolveFormattingJarPath(ctx);
3152
+ if (formattingJar) {
3153
+ args.push("--plugins", formattingJar);
3154
+ } else {
3155
+ const formattingPatterns = codacyConfig.patterns.map((p) => p.patternId).filter((id) => FORMATTING_RULES.has(id));
3156
+ errors.push({
3157
+ toolId: TOOL_ID,
3158
+ phase: "toolConfig",
3159
+ kind: "ParseWarning",
3160
+ message: `detekt-formatting plugin JAR not found; ${formattingPatterns.length} formatting pattern(s) will not produce findings: ${formattingPatterns.slice(0, 5).join(", ")}${formattingPatterns.length > 5 ? ` and ${formattingPatterns.length - 5} more` : ""}. Re-run install to download the plugin.`,
3161
+ level: "warning"
3162
+ });
3163
+ }
3164
+ }
2973
3165
  try {
2974
3166
  const { stderr, exitCode } = await (0, import_tooling.spawnTool)(javaBin, args, {
2975
3167
  cwd: ctx.repositoryRoot,
@@ -3034,13 +3226,13 @@ var adapter = {
3034
3226
  const source = error["@_source"] ?? "";
3035
3227
  const ruleId = extractRuleId(source);
3036
3228
  if (!ruleId) continue;
3037
- const patternId = ruleId;
3038
- if (enabledPatterns.size > 0 && !enabledPatterns.has(patternId)) {
3229
+ const patternId = PATTERN_ID_ALIASES.get(ruleId) ?? ruleId;
3230
+ if (enabledPatterns.size > 0 && !enabledPatterns.has(patternId) && !enabledPatterns.has(ruleId)) {
3039
3231
  continue;
3040
3232
  }
3041
3233
  const line = parseInt(error["@_line"], 10) || 1;
3042
3234
  const column = parseInt(error["@_column"] ?? "1", 10) || 1;
3043
- const meta = ruleMetadata(ruleId);
3235
+ const meta = ruleMetadata(patternId);
3044
3236
  issues.push({
3045
3237
  filePath: relPath,
3046
3238
  patternId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codacy/tools-detekt-1",
3
- "version": "0.6.2",
3
+ "version": "0.8.0",
4
4
  "description": "detekt adapter — CLI-mode Kotlin static analyzer",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,7 +9,7 @@
9
9
  ],
10
10
  "dependencies": {
11
11
  "fast-xml-parser": "^5.5.6",
12
- "@codacy/tooling": "0.6.2"
12
+ "@codacy/tooling": "0.8.0"
13
13
  },
14
14
  "license": "MIT",
15
15
  "author": "Codacy <support@codacy.com> (https://www.codacy.com)",