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

devonfw / IDEasy / 18699372415

21 Oct 2025 10:22PM UTC coverage: 68.541% (+0.02%) from 68.522%
18699372415

push

github

web-flow
#1536: Disable uninstall for corepack and npm (#1541)

3469 of 5543 branches covered (62.58%)

Branch coverage included in aggregate %.

9063 of 12741 relevant lines covered (71.13%)

3.13 hits per line

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

80.0
cli/src/main/java/com/devonfw/tools/ide/tool/node/NodeBasedCommandlet.java
1
package com.devonfw.tools.ide.tool.node;
2

3
import java.nio.file.Files;
4
import java.nio.file.Path;
5
import java.util.Set;
6

7
import com.devonfw.tools.ide.cache.CachedValue;
8
import com.devonfw.tools.ide.common.Tag;
9
import com.devonfw.tools.ide.context.IdeContext;
10
import com.devonfw.tools.ide.process.ProcessContext;
11
import com.devonfw.tools.ide.process.ProcessErrorHandling;
12
import com.devonfw.tools.ide.process.ProcessMode;
13
import com.devonfw.tools.ide.process.ProcessResult;
14
import com.devonfw.tools.ide.tool.LocalToolCommandlet;
15
import com.devonfw.tools.ide.tool.corepack.Corepack;
16
import com.devonfw.tools.ide.tool.repository.ToolRepository;
17
import com.devonfw.tools.ide.version.VersionIdentifier;
18

19
/**
20
 * {@link LocalToolCommandlet} for tools based on <a href="https://www.npmjs.com/">npm</a>.
21
 */
22
public abstract class NodeBasedCommandlet extends LocalToolCommandlet {
23

24
  private final CachedValue<VersionIdentifier> installedVersion;
25

26
  /**
27
   * The constructor.
28
   *
29
   * @param context the {@link IdeContext}.
30
   * @param tool the {@link #getName() tool name}.
31
   * @param tags the {@link #getTags() tags} classifying the tool. Should be created via {@link Set#of(Object) Set.of} method.
32
   */
33
  public NodeBasedCommandlet(IdeContext context, String tool, Set<Tag> tags) {
34

35
    super(context, tool, tags);
5✔
36
    this.installedVersion = new CachedValue<>(this::computeInstalledVersion);
7✔
37
  }
1✔
38

39
  /**
40
   * @return the computed value of the {@link #getInstalledVersion() installed version}.
41
   */
42
  protected abstract VersionIdentifier computeInstalledVersion();
43

44
  @Override
45
  protected boolean isIgnoreSoftwareRepo() {
46

47
    // node and node.js are messy - see https://github.com/devonfw/IDEasy/issues/352
48
    return true;
2✔
49
  }
50

51
  /**
52
   * @return the package of this tool from the NPM registry.
53
   */
54
  public String getPackageName() {
55

56
    return this.tool;
3✔
57
  }
58

59
  @Override
60
  public Path getToolPath() {
61

62
    return this.context.getSoftwarePath().resolve("node");
6✔
63
  }
64

65
  @Override
66
  public VersionIdentifier getInstalledVersion() {
67

68
    return this.installedVersion.get();
5✔
69
  }
70

71
  @Override
72
  public String getInstalledEdition() {
73

74
    if (getInstalledVersion() != null) {
3!
75
      return this.tool;
×
76
    }
77
    return null;
2✔
78
  }
79

80
  @Override
81
  protected void performToolInstallation(ToolRepository toolRepository, VersionIdentifier resolvedVersion, Path installationPath, String edition,
82
      ProcessContext processContext) {
83

84
    runPackageInstall(getPackageName() + "@" + resolvedVersion);
7✔
85
    this.installedVersion.invalidate();
3✔
86
  }
1✔
87

88
  /**
89
   * Checks if the tool can be uninstalled e.g. if the uninstall command for the tool should be disabled or not.
90
   *
91
   * @return {@code true} if the tool can be uninstalled, {@code false} if not.
92
   */
93
  protected boolean canBeUninstalled() {
94
    return true;
2✔
95
  }
96

97
  @Override
98
  protected void performUninstall(Path toolPath) {
99
    if (canBeUninstalled()) {
3✔
100
      runPackageUninstall(getPackageName());
4✔
101
      this.installedVersion.invalidate();
4✔
102
    } else {
103
      this.context.info("IDEasy does not support uninstalling the tool {} since this will break your installation.\n"
9✔
104
          + "If you really want to uninstall it, please uninstall the entire node installation:\n"
105
          + "ide uninstall node", getPackageName());
2✔
106
    }
107
  }
1✔
108

109
  /**
110
   * Checks if a provided binary can be found within node.
111
   *
112
   * @param binary name of the binary.
113
   * @return {@code true} if a binary was found in the node installation, {@code false} if not.
114
   */
115
  protected boolean hasNodeBinary(String binary) {
116

117
    return Files.exists(getToolBinPath().resolve(binary));
8✔
118
  }
119

120
  /**
121
   * Runs uninstall using the package manager.
122
   *
123
   * @param npmPackage the npm package to uninstall.
124
   */
125
  protected void runPackageUninstall(String npmPackage) {
126

127
    runPackageManager("uninstall", "-g", npmPackage).failOnError();
17✔
128
  }
1✔
129

130
  /**
131
   * Runs install using the package manager.
132
   *
133
   * @param npmPackage the npm package to install.
134
   */
135
  protected void runPackageInstall(String npmPackage) {
136

137
    runPackageManager("install", "-g", npmPackage).failOnError();
17✔
138
  }
1✔
139

140
  /**
141
   * @param args the arguments for the package manager.
142
   * @return the {@link ProcessResult}.
143
   */
144
  protected ProcessResult runPackageManager(String... args) {
145

146
    return runPackageManager(ProcessMode.DEFAULT, ProcessErrorHandling.THROW_CLI, args);
6✔
147
  }
148

149
  /**
150
   * @param args the arguments for {@link com.devonfw.tools.ide.tool.corepack.Corepack}.
151
   * @return the {@link ProcessResult}.
152
   */
153
  protected ProcessResult runCorepack(String... args) {
154

155
    return runCorepack(ProcessMode.DEFAULT, ProcessErrorHandling.THROW_CLI, args);
×
156
  }
157

158
  /**
159
   * @param processMode the {@link ProcessMode}.
160
   * @param errorHandling the {@link ProcessErrorHandling}.
161
   * @param args the arguments for the package manager.
162
   * @return the {@link ProcessResult}.
163
   */
164
  protected abstract ProcessResult runPackageManager(ProcessMode processMode, ProcessErrorHandling errorHandling, String... args);
165

166
  /**
167
   * @param processMode the {@link ProcessMode}.
168
   * @param errorHandling the {@link ProcessErrorHandling}.
169
   * @param args the arguments for {@link com.devonfw.tools.ide.tool.corepack.Corepack}.
170
   * @return the {@link ProcessResult}.
171
   */
172
  protected ProcessResult runCorepack(ProcessMode processMode, ProcessErrorHandling errorHandling, String... args) {
173
    ProcessContext pc = this.context.newProcess().errorHandling(errorHandling);
×
174
    Corepack corepack = this.context.getCommandletManager().getCommandlet(Corepack.class);
×
175
    return corepack.runTool(processMode, null, pc, args);
×
176
  }
177

178

179
  @Override
180
  public String getToolHelpArguments() {
181

182
    return "--help";
×
183
  }
184
}
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

© 2025 Coveralls, Inc