• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 22949388609

11 Mar 2026 11:02AM UTC coverage: 70.337% (+0.05%) from 70.283%
22949388609

Pull #1734

github

web-flow
Merge b72d84ea1 into a3d55f57f
Pull Request #1734: #1731: Fixed Solar Install returning NPE

4075 of 6388 branches covered (63.79%)

Branch coverage included in aggregate %.

10617 of 14500 relevant lines covered (73.22%)

3.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

36.51
cli/src/main/java/com/devonfw/tools/ide/tool/sonar/Sonar.java
1
package com.devonfw.tools.ide.tool.sonar;
2

3
import java.nio.file.Path;
4
import java.util.List;
5
import java.util.Properties;
6
import java.util.Set;
7

8
import org.slf4j.Logger;
9
import org.slf4j.LoggerFactory;
10

11
import com.devonfw.tools.ide.common.Tag;
12
import com.devonfw.tools.ide.context.IdeContext;
13
import com.devonfw.tools.ide.process.ProcessContext;
14
import com.devonfw.tools.ide.process.ProcessMode;
15
import com.devonfw.tools.ide.property.EnumProperty;
16
import com.devonfw.tools.ide.tool.LocalToolCommandlet;
17
import com.devonfw.tools.ide.tool.ToolInstallation;
18
import com.devonfw.tools.ide.tool.java.Java;
19
import com.devonfw.tools.ide.tool.mvn.Mvn;
20

21
/**
22
 * {@link LocalToolCommandlet} for <a href="https://sonarqube.org/">SonarQube</a>.
23
 */
24
public class Sonar extends LocalToolCommandlet {
25

26
  private static final Logger LOG = LoggerFactory.getLogger(Sonar.class);
4✔
27

28
  /** The {@link SonarCommand} to run. */
29
  public final EnumProperty<SonarCommand> command;
30

31
  /**
32
   * The constructor.
33
   *
34
   * @param context the {@link IdeContext}. method.
35
   */
36
  public Sonar(IdeContext context) {
37

38
    super(context, "sonar", Set.of(Tag.CODE_QA));
6✔
39

40
    this.command = add(new EnumProperty<>("", true, "command", SonarCommand.class));
12✔
41
    add(this.arguments);
5✔
42
  }
1✔
43

44
  @Override
45
  protected void initProperties() {
46

47
    // Empty on purpose
48
  }
1✔
49

50
  @Override
51
  public ToolInstallation install(boolean silent) {
52

53
    getCommandlet(Java.class).install();
6✔
54
    return super.install(silent);
4✔
55
  }
56

57
  @Override
58
  protected void doRun() {
59

60
    SonarCommand command = this.command.getValue();
×
61

62
    Path toolPath = getToolPath();
×
63
    if (!toolPath.toFile().exists()) {
×
64
      super.install(true);
×
65
    }
66

67
    switch (command) {
×
68
      case ANALYZE:
69
        getCommandlet(Mvn.class).runTool(List.of("sonar:sonar"));
×
70
        break;
×
71
      case START:
72
        printSonarWebPort();
×
73
        this.arguments.setValueAsString("start", this.context);
×
74
        super.run();
×
75
        break;
×
76
      case STOP:
77
        this.arguments.setValueAsString("stop", this.context);
×
78
        super.run();
×
79
        break;
×
80
      default:
81
    }
82
  }
×
83

84
  @Override
85
  protected String getBinaryName() {
86
    SonarCommand command = this.command.getValue();
5✔
87
    if (this.context.getSystemInfo().isWindows()) {
5✔
88
      if (command != null && command.equals(SonarCommand.STOP)) {
6!
89
        return "windows-x86-64/SonarService.bat";
2✔
90

91
      } else {
92
        return "windows-x86-64/StartSonar.bat";
2✔
93
      }
94
    } else if (this.context.getSystemInfo().isMac()) {
5✔
95
      return "macosx-universal-64/sonar.sh";
2✔
96
    }
97
    return "linux-x86-64/sonar.sh";
2✔
98
  }
99

100
  //  Instead of relying on relative Path (which breaks), we directly construct the absolute path
101
//  so getToolBinPath would return /software/sonar/bin and .resolve adds x86-x64
102
//  ProcessContext can now execute the abs path without any issues.
103
//   Worst case, we fall back to the default configureToolBinary, which uses relative path.
104
  @Override
105
  protected void configureToolBinary(ProcessContext pc, ProcessMode processMode) {
106
    Path toolBinPath = getToolBinPath();
×
107
    if (toolBinPath != null) {
×
108
      Path binaryPath = toolBinPath.resolve(getBinaryName());
×
109
      pc.executable(binaryPath);
×
110
    } else {
×
111
      super.configureToolBinary(pc, processMode);
×
112
    }
113
  }
×
114

115
  private void printSonarWebPort() {
116

117
    LOG.info("SonarQube is running at localhost on the following port (default 9000):");
×
118
    Path sonarPropertiesPath = getToolPath().resolve("conf/sonar.properties");
×
119

120
    Properties sonarProperties = this.context.getFileAccess().readProperties(sonarPropertiesPath);
×
121
    String sonarWebPort = sonarProperties.getProperty("sonar.web.port");
×
122
    if (sonarWebPort != null) {
×
123
      LOG.info(sonarWebPort);
×
124
    }
125
  }
×
126
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc