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

devonfw / IDEasy / 9907372175

12 Jul 2024 11:49AM UTC coverage: 61.142% (-0.02%) from 61.162%
9907372175

push

github

hohwille
fixed tests

1997 of 3595 branches covered (55.55%)

Branch coverage included in aggregate %.

5296 of 8333 relevant lines covered (63.55%)

2.8 hits per line

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

2.22
cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java
1
package com.devonfw.tools.ide.tool;
2

3
import java.nio.file.Files;
4
import java.nio.file.Path;
5
import java.util.Arrays;
6
import java.util.List;
7
import java.util.Set;
8

9
import com.devonfw.tools.ide.common.Tag;
10
import com.devonfw.tools.ide.context.IdeContext;
11
import com.devonfw.tools.ide.io.FileAccess;
12
import com.devonfw.tools.ide.log.IdeLogLevel;
13
import com.devonfw.tools.ide.process.ProcessContext;
14
import com.devonfw.tools.ide.process.ProcessErrorHandling;
15
import com.devonfw.tools.ide.repo.ToolRepository;
16
import com.devonfw.tools.ide.version.VersionIdentifier;
17

18
/**
19
 * {@link ToolCommandlet} that is installed globally.
20
 */
21
public abstract class GlobalToolCommandlet extends ToolCommandlet {
22

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

32
    super(context, tool, tags);
5✔
33
  }
1✔
34

35
  /**
36
   * Performs the installation or uninstallation of the {@link #getName() tool} via a package manager.
37
   *
38
   * @param silent {@code true} if called recursively to suppress verbose logging, {@code false} otherwise.
39
   * @param commandStrings commandStrings The package manager command strings to execute.
40
   * @return {@code true} if installation or uninstallation succeeds with any of the package manager commands, {@code false} otherwise.
41
   */
42
  protected boolean runWithPackageManager(boolean silent, String... commandStrings) {
43

44
    List<PackageManagerCommand> pmCommands = Arrays.stream(commandStrings).map(PackageManagerCommand::of).toList();
×
45
    return runWithPackageManager(silent, pmCommands);
×
46
  }
47

48
  /**
49
   * Performs the installation or uninstallation of the {@link #getName() tool} via a package manager.
50
   *
51
   * @param silent {@code true} if called recursively to suppress verbose logging, {@code false} otherwise.
52
   * @param pmCommands A list of {@link PackageManagerCommand} to be used for installation or uninstallation.
53
   * @return {@code true} if installation or uninstallation succeeds with any of the package manager commands, {@code false} otherwise.
54
   */
55
  protected boolean runWithPackageManager(boolean silent, List<PackageManagerCommand> pmCommands) {
56

57
    for (PackageManagerCommand pmCommand : pmCommands) {
×
58
      PackageManager packageManager = pmCommand.packageManager();
×
59
      Path packageManagerPath = this.context.getPath().findBinary(Path.of(packageManager.getBinaryName()));
×
60
      if (packageManagerPath == null || !Files.exists(packageManagerPath)) {
×
61
        this.context.debug("{} is not installed", packageManager.toString());
×
62
        continue; // Skip to the next package manager command
×
63
      }
64

65
      if (executePackageManagerCommand(pmCommand, silent)) {
×
66
        return true; // Success
×
67
      }
68
    }
×
69
    return false; // None of the package manager commands were successful
×
70
  }
71

72
  /**
73
   * Executes the provided package manager command.
74
   *
75
   * @param pmCommand The {@link PackageManagerCommand} containing the commands to execute.
76
   * @param silent {@code true} if called recursively to suppress verbose logging, {@code false} otherwise.
77
   * @return {@code true} if the package manager commands execute successfully, {@code false} otherwise.
78
   */
79
  private boolean executePackageManagerCommand(PackageManagerCommand pmCommand, boolean silent) {
80

81
    String bashPath = this.context.findBash();
×
82
    for (String command : pmCommand.commands()) {
×
83
      ProcessContext pc = this.context.newProcess().errorHandling(ProcessErrorHandling.WARNING).executable(bashPath)
×
84
          .addArgs("-c", command);
×
85
      int exitCode = pc.run();
×
86
      if (exitCode != 0) {
×
87
        this.context.warning("{} command did not execute successfully", command);
×
88
        return false;
×
89
      }
90
    }
×
91

92
    if (!silent) {
×
93
      this.context.success("Successfully installed {}", this.tool);
×
94
    }
95
    return true;
×
96
  }
97

98
  @Override
99
  protected boolean isExtract() {
100

101
    // for global tools we usually download installers and do not want to extract them (e.g. installer.msi file shall
102
    // not be extracted)
103
    return false;
×
104
  }
105

106
  @Override
107
  protected boolean doInstall(boolean silent) {
108

109
    Path binaryPath = this.context.getPath().findBinary(Path.of(getBinaryName()));
×
110
    // if force mode is enabled, go through with the installation even if the tool is already installed
111
    if (binaryPath != null && Files.exists(binaryPath) && !this.context.isForceMode()) {
×
112
      IdeLogLevel level = silent ? IdeLogLevel.DEBUG : IdeLogLevel.INFO;
×
113
      this.context.level(level).log("{} is already installed at {}", this.tool, binaryPath);
×
114
      return false;
×
115
    }
116
    String edition = getConfiguredEdition();
×
117
    ToolRepository toolRepository = this.context.getDefaultToolRepository();
×
118
    VersionIdentifier configuredVersion = getConfiguredVersion();
×
119
    VersionIdentifier resolvedVersion = toolRepository.resolveVersion(this.tool, edition, configuredVersion);
×
120
    // download and install the global tool
121
    FileAccess fileAccess = this.context.getFileAccess();
×
122
    Path target = toolRepository.download(this.tool, edition, resolvedVersion);
×
123
    Path executable = target;
×
124
    Path tmpDir = null;
×
125
    boolean extract = isExtract();
×
126
    if (extract) {
×
127
      tmpDir = fileAccess.createTempDir(getName());
×
128
      Path downloadBinaryPath = tmpDir.resolve(target.getFileName());
×
129
      fileAccess.extract(target, downloadBinaryPath);
×
130
      executable = fileAccess.findFirst(downloadBinaryPath, Files::isExecutable, false);
×
131
    }
132
    ProcessContext pc = this.context.newProcess().errorHandling(ProcessErrorHandling.WARNING).executable(executable);
×
133
    int exitCode = pc.run();
×
134
    if (tmpDir != null) {
×
135
      fileAccess.delete(tmpDir);
×
136
    }
137
    if (exitCode == 0) {
×
138
      this.context.success("Successfully installed {} in version {}", this.tool, resolvedVersion);
×
139
    } else {
140
      this.context.warning("{} in version {} was not successfully installed", this.tool, resolvedVersion);
×
141
      return false;
×
142
    }
143
    postInstall();
×
144
    return true;
×
145
  }
146

147
  @Override
148
  public VersionIdentifier getInstalledVersion() {
149
    //TODO: handle "get-version <globaltool>"
150
    this.context.error("Couldn't get installed version of " + this.getName());
×
151
    return null;
×
152
  }
153

154
  @Override
155
  public String getInstalledEdition() {
156
    //TODO: handle "get-edition <globaltool>"
157
    this.context.error("Couldn't get installed edition of " + this.getName());
×
158
    return null;
×
159
  }
160

161
  @Override
162
  public void uninstall() {
163
    //TODO: handle "uninstall <globaltool>"
164
    this.context.error("Couldn't uninstall " + this.getName());
×
165
  }
×
166
}
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