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

devonfw / IDEasy / 22284264868

22 Feb 2026 08:00PM UTC coverage: 70.75% (+0.3%) from 70.474%
22284264868

Pull #1714

github

web-flow
Merge 98f01421f into 379acdc9d
Pull Request #1714: #404: #1713: advanced logging

4063 of 6346 branches covered (64.02%)

Branch coverage included in aggregate %.

10636 of 14430 relevant lines covered (73.71%)

3.1 hits per line

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

32.31
cli/src/main/java/com/devonfw/tools/ide/tool/pip/PipBasedCommandlet.java
1
package com.devonfw.tools.ide.tool.pip;
2

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

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

10
import com.devonfw.tools.ide.common.Tag;
11
import com.devonfw.tools.ide.context.IdeContext;
12
import com.devonfw.tools.ide.log.IdeLogLevel;
13
import com.devonfw.tools.ide.process.ProcessErrorHandling;
14
import com.devonfw.tools.ide.process.ProcessMode;
15
import com.devonfw.tools.ide.process.ProcessResult;
16
import com.devonfw.tools.ide.tool.PackageManagerBasedLocalToolCommandlet;
17
import com.devonfw.tools.ide.tool.PackageManagerRequest;
18
import com.devonfw.tools.ide.tool.ToolCommandlet;
19
import com.devonfw.tools.ide.tool.python.Python;
20
import com.devonfw.tools.ide.tool.repository.ToolRepository;
21
import com.devonfw.tools.ide.tool.uv.Uv;
22
import com.devonfw.tools.ide.version.VersionIdentifier;
23

24
/**
25
 * {@link PackageManagerBasedLocalToolCommandlet} for python tools based on <a href="https://pip.pypa.io/">pip</a>.
26
 * <p>
27
 */
28
public abstract class PipBasedCommandlet extends PackageManagerBasedLocalToolCommandlet<ToolCommandlet> {
29

30
  private static final Logger LOG = LoggerFactory.getLogger(PipBasedCommandlet.class);
4✔
31

32
  private static final String PIP_SHOW_VERSION_PREFIX = "Version:";
33

34
  /**
35
   * The constructor.
36
   *
37
   * @param context the {@link IdeContext}.
38
   * @param tool the {@link #getName() tool name}.
39
   * @param tags the {@link #getTags() tags} classifying the tool. Should be created via {@link Set#of(Object) Set.of} method.
40
   */
41
  public PipBasedCommandlet(IdeContext context, String tool, Set<Tag> tags) {
42

43
    super(context, tool, tags);
5✔
44
  }
1✔
45

46
  @Override
47
  public ToolRepository getToolRepository() {
48

49
    return this.context.getPipRepository();
4✔
50
  }
51

52
  @Override
53
  @SuppressWarnings({ "unchecked", "rawtypes" })
54
  protected Class<ToolCommandlet> getPackageManagerClass() {
55

56
    String edition = this.context.getVariables().getToolEdition("pip");
×
57
    Class<? extends ToolCommandlet> result =
58
        switch (edition) {
×
59
          case "pip" -> Pip.class;
×
60
          case "uv" -> Uv.class;
×
61
          default -> {
62
            LOG.warn("Undefined value: PIP_EDITION={}", edition);
×
63
            yield Pip.class;
×
64
          }
65
        };
66
    return (Class) result;
×
67
  }
68

69
  @Override
70
  protected String appendVersion(String tool, VersionIdentifier version) {
71

72
    return tool + "==" + version;
5✔
73
  }
74

75
  @Override
76
  protected void completeRequest(PackageManagerRequest request) {
77

78
    if (request.getTool().equals("pip")) {
5!
79
      // we cannot install pip with pip if pip is not already installed!
80
      request.setPackageManager(this.context.getCommandletManager().getCommandlet(Uv.class));
9✔
81
    }
82
    super.completeRequest(request);
3✔
83
  }
1✔
84

85
  @Override
86
  protected void completeRequestArgs(PackageManagerRequest request) {
87

88
    if (request.getPackageManager() instanceof Uv) {
4!
89
      request.addArg("pip");
4✔
90
    }
91
    super.completeRequestArgs(request);
3✔
92
  }
1✔
93

94
  @Override
95
  protected VersionIdentifier computeInstalledVersion() {
96

97
    Path toolBinPath = getToolBinPath();
3✔
98
    if ((toolBinPath == null) || !Files.isDirectory(toolBinPath)) {
7!
99
      return null;
2✔
100
    }
101
    if (this.tool.equals("pip")) {
×
102
      // if pip is not installed, we shall not call pip to find that out
103
      String binary = "pip";
×
104
      if (this.context.getSystemInfo().isWindows()) {
×
105
        binary = "pip.exe";
×
106
      }
107
      if (!Files.exists(toolBinPath.resolve(binary))) {
×
108
        return null;
×
109
      }
110
    }
111
    PackageManagerRequest request = new PackageManagerRequest("show", getPackageName()).setProcessMode(ProcessMode.DEFAULT_CAPTURE)
×
112
        .setProcessContext(this.context.newProcess().errorHandling(ProcessErrorHandling.NONE));
×
113
    ProcessResult processResult = runPackageManager(request);
×
114
    if (processResult.isSuccessful()) {
×
115
      for (String line : processResult.getOut()) {
×
116
        // we are looking for something like "Version: 25.3"
117
        if (line.startsWith(PIP_SHOW_VERSION_PREFIX)) {
×
118
          String version = line.substring(PIP_SHOW_VERSION_PREFIX.length()).trim();
×
119
          return VersionIdentifier.of(version);
×
120
        }
121
      }
×
122
    }
123
    LOG.debug("Could not find version from pip show output:");
×
124
    processResult.log(IdeLogLevel.DEBUG);
×
125
    return null;
×
126
  }
127

128
  @Override
129
  protected Python getParentTool() {
130

131
    return this.context.getCommandletManager().getCommandlet(Python.class);
7✔
132
  }
133

134
}
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