opencode-sonarqube 1.2.47 → 1.2.48

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 +72 -47
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -16804,6 +16804,39 @@ async function detectProjectType(directory) {
16804
16804
  });
16805
16805
  return result;
16806
16806
  }
16807
+ var SOURCE_DIRECTORY_PATTERNS = [
16808
+ "apps",
16809
+ "packages",
16810
+ "modules",
16811
+ "services",
16812
+ "libs",
16813
+ "src",
16814
+ "source",
16815
+ "lib",
16816
+ "app",
16817
+ "cmd",
16818
+ "pkg",
16819
+ "internal",
16820
+ "main",
16821
+ "core"
16822
+ ];
16823
+ function detectSourceDirectories(directory) {
16824
+ const existingDirs = [];
16825
+ for (const pattern of SOURCE_DIRECTORY_PATTERNS) {
16826
+ try {
16827
+ const dirPath = `${directory}/${pattern}`;
16828
+ if (Bun.spawnSync(["test", "-d", dirPath]).exitCode === 0) {
16829
+ existingDirs.push(pattern);
16830
+ }
16831
+ } catch {}
16832
+ }
16833
+ if (existingDirs.length > 0) {
16834
+ logger2.info("Detected source directories", { directories: existingDirs });
16835
+ return existingDirs.join(",");
16836
+ }
16837
+ logger2.info("No common source directories found, scanning entire project");
16838
+ return ".";
16839
+ }
16807
16840
  async function generatePropertiesContent(options, config2, directory) {
16808
16841
  const dir = directory ?? process.cwd();
16809
16842
  const detection = await detectProjectType(dir);
@@ -16820,49 +16853,18 @@ async function generatePropertiesContent(options, config2, directory) {
16820
16853
  lines.push(`sonar.projectName=${options.projectName}`);
16821
16854
  }
16822
16855
  const exclusions = options.exclusions ?? config2?.exclusions ?? getDefaultExclusions(detection);
16856
+ const sources = options.sources ?? config2?.sources ?? detectSourceDirectories(dir);
16857
+ const tests = options.tests ?? config2?.tests ?? sources;
16823
16858
  const sourceConfig = [
16824
16859
  "",
16825
- "# Source Configuration - ALWAYS scans entire project",
16826
- `sonar.sources=.`
16860
+ "# Source Configuration",
16861
+ `sonar.sources=${sources}`,
16862
+ `sonar.tests=${tests}`,
16863
+ `sonar.test.inclusions=${getTestPatterns(detection.languages)}`,
16864
+ `sonar.exclusions=${exclusions}`,
16865
+ "",
16866
+ "# Language-Specific Configuration"
16827
16867
  ];
16828
- if (options.tests ?? config2?.tests) {
16829
- sourceConfig.push(`sonar.tests=${options.tests ?? config2?.tests}`);
16830
- }
16831
- const allInclusions = [
16832
- "**/*.ts",
16833
- "**/*.tsx",
16834
- "**/*.js",
16835
- "**/*.jsx",
16836
- "**/*.mjs",
16837
- "**/*.cjs",
16838
- "**/*.py",
16839
- "**/*.java",
16840
- "**/*.go",
16841
- "**/*.rs",
16842
- "**/*.php",
16843
- "**/*.rb",
16844
- "**/*.cs",
16845
- "**/*.vb",
16846
- "**/*.cpp",
16847
- "**/*.c",
16848
- "**/*.h",
16849
- "**/*.hpp",
16850
- "**/*.swift",
16851
- "**/*.kt",
16852
- "**/*.scala",
16853
- "**/*.groovy",
16854
- "**/*.html",
16855
- "**/*.css",
16856
- "**/*.scss",
16857
- "**/*.less",
16858
- "**/*.vue",
16859
- "**/*.svelte",
16860
- "**/*.xml",
16861
- "**/*.json",
16862
- "**/*.yaml",
16863
- "**/*.yml"
16864
- ].join(",");
16865
- sourceConfig.push(`sonar.inclusions=${allInclusions}`, `sonar.exclusions=${exclusions}`, `sonar.test.inclusions=${getTestPatterns(detection.languages)}`, "", "# Language-Specific Configuration");
16866
16868
  lines.push(...sourceConfig);
16867
16869
  if (detection.languages.includes("typescript") || detection.languages.includes("javascript")) {
16868
16870
  const tsJsConfig = ["", "# TypeScript/JavaScript"];
@@ -19006,13 +19008,20 @@ async function runAnalysis(config2, state, options, directory) {
19006
19008
  const dir = directory ?? process.cwd();
19007
19009
  const api2 = createSonarQubeAPI(config2, state);
19008
19010
  const projectName = options.projectName ?? options.projectKey;
19009
- await writePropertiesFile({
19010
- projectKey: options.projectKey,
19011
- projectName,
19012
- sources: ".",
19013
- tests: options.tests ?? config2.tests,
19014
- exclusions: options.exclusions ?? config2.exclusions
19015
- }, config2, dir);
19011
+ const propertiesPath = `${dir}/sonar-project.properties`;
19012
+ const propertiesExist = await Bun.file(propertiesPath).exists();
19013
+ if (propertiesExist) {
19014
+ logger3.info("Using existing sonar-project.properties (CI/CD compatible)");
19015
+ } else {
19016
+ await writePropertiesFile({
19017
+ projectKey: options.projectKey,
19018
+ projectName,
19019
+ sources: options.sources ?? config2.sources,
19020
+ tests: options.tests ?? config2.tests,
19021
+ exclusions: options.exclusions ?? config2.exclusions
19022
+ }, config2, dir);
19023
+ logger3.info("Created sonar-project.properties");
19024
+ }
19016
19025
  const scannerResult = await runScanner(config2, state, {
19017
19026
  projectKey: options.projectKey,
19018
19027
  projectName,
@@ -19155,6 +19164,21 @@ function resolveDirectoryFromImportMeta() {
19155
19164
  } catch {}
19156
19165
  return null;
19157
19166
  }
19167
+ async function ensurePluginsEnabled(client) {
19168
+ try {
19169
+ const response = await client.get("/api/settings/values", { keys: "sonar.plugins.downloadOnlyRequired" });
19170
+ const setting = response.settings.find((s) => s.key === "sonar.plugins.downloadOnlyRequired");
19171
+ if (setting?.value === "true") {
19172
+ await client.post("/api/settings/set", {
19173
+ key: "sonar.plugins.downloadOnlyRequired",
19174
+ value: "false"
19175
+ });
19176
+ logger5.info("Enabled full plugin loading on server (sonar.plugins.downloadOnlyRequired=false)");
19177
+ }
19178
+ } catch {
19179
+ logger5.warn("Could not check/set plugin loading setting");
19180
+ }
19181
+ }
19158
19182
  async function generateAnalysisToken(client, tokenName, projectKey) {
19159
19183
  try {
19160
19184
  return await client.post("/api/user_tokens/generate", { name: tokenName, type: "PROJECT_ANALYSIS_TOKEN", projectKey });
@@ -19204,6 +19228,7 @@ async function bootstrap(options) {
19204
19228
  throw SetupError(`Cannot connect to SonarQube: ${health.error}`);
19205
19229
  }
19206
19230
  logger5.info("Connected to SonarQube", { version: health.version });
19231
+ await ensurePluginsEnabled(adminClient);
19207
19232
  const detection = await detectProjectType(directory);
19208
19233
  const projectKey = config2.projectKey || sanitizeProjectKey(await deriveProjectKey(directory));
19209
19234
  const projectName = config2.projectName || projectKey;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-sonarqube",
3
- "version": "1.2.47",
3
+ "version": "1.2.48",
4
4
  "description": "OpenCode Plugin for SonarQube integration - Enterprise-level code quality from the start",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",