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

devonfw / IDEasy / 14190247062

01 Apr 2025 07:54AM UTC coverage: 67.787% (+0.03%) from 67.755%
14190247062

Pull #1192

github

web-flow
Merge 7adccf4c9 into 74cc9908e
Pull Request #1192: #1191: Fixed vscode plugin detection

3061 of 4942 branches covered (61.94%)

Branch coverage included in aggregate %.

7886 of 11207 relevant lines covered (70.37%)

3.08 hits per line

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

85.11
cli/src/main/java/com/devonfw/tools/ide/tool/vscode/Vscode.java
1
package com.devonfw.tools.ide.tool.vscode;
2

3
import java.io.BufferedReader;
4
import java.io.IOException;
5
import java.nio.file.Files;
6
import java.nio.file.Path;
7
import java.util.ArrayList;
8
import java.util.Collection;
9
import java.util.HashMap;
10
import java.util.HashSet;
11
import java.util.List;
12
import java.util.Map;
13
import java.util.Set;
14

15
import com.devonfw.tools.ide.common.Tag;
16
import com.devonfw.tools.ide.context.IdeContext;
17
import com.devonfw.tools.ide.process.ProcessContext;
18
import com.devonfw.tools.ide.process.ProcessErrorHandling;
19
import com.devonfw.tools.ide.process.ProcessMode;
20
import com.devonfw.tools.ide.process.ProcessResult;
21
import com.devonfw.tools.ide.step.Step;
22
import com.devonfw.tools.ide.tool.ToolCommandlet;
23
import com.devonfw.tools.ide.tool.ide.IdeToolCommandlet;
24
import com.devonfw.tools.ide.tool.plugin.ToolPluginDescriptor;
25
import com.fasterxml.jackson.databind.ObjectMapper;
26

27
/**
28
 * {@link ToolCommandlet} for <a href="https://code.visualstudio.com/">vscode</a>.
29
 */
30
public class Vscode extends IdeToolCommandlet {
31

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

39
    super(context, "vscode", Set.of(Tag.VS_CODE));
6✔
40
  }
1✔
41

42
  @Override
43
  protected String getBinaryName() {
44

45
    return "code";
2✔
46
  }
47

48
  @Override
49
  public boolean installPlugin(ToolPluginDescriptor plugin, Step step, ProcessContext pc) {
50

51
    List<String> extensionsCommands = new ArrayList<>();
4✔
52
    extensionsCommands.add("--force");
4✔
53
    extensionsCommands.add("--install-extension");
4✔
54
    extensionsCommands.add(plugin.id());
5✔
55
    ProcessResult result = runTool(ProcessMode.DEFAULT, ProcessErrorHandling.THROW_ERR, pc, extensionsCommands.toArray(String[]::new));
13✔
56
    if (result.isSuccessful()) {
3!
57
      this.context.success("Successfully installed plugin: {}", plugin.name());
11✔
58
      step.success();
2✔
59
      return true;
2✔
60
    } else {
61
      this.context.warning("An error occurred while installing plugin: {}", plugin.name());
×
62
      return false;
×
63
    }
64
  }
65

66
  @Override
67
  protected void installPlugins(Collection<ToolPluginDescriptor> plugins, ProcessContext pc) {
68

69
    List<ToolPluginDescriptor> pluginsToInstall = new ArrayList<>();
4✔
70
    List<ToolPluginDescriptor> pluginsToRecommend = new ArrayList<>();
4✔
71

72
    Step step = this.context.newStep(true, "Install plugins for " + this.tool);
10✔
73
    try {
74
      for (ToolPluginDescriptor plugin : plugins) {
10✔
75
        if (plugin.active()) {
3✔
76
          if (retrievePluginMarkerFilePath(plugin) != null && Files.exists(retrievePluginMarkerFilePath(plugin))) {
11!
77
            this.context.debug("Markerfile for IDE: {} and active plugin: {} already exists.", getName(), plugin.name());
17✔
78
          } else {
79
            pluginsToInstall.add(plugin);
5✔
80
          }
81
        } else {
82
          pluginsToRecommend.add(plugin);
4✔
83
        }
84
      }
1✔
85
      if (pluginsToInstall.isEmpty()) {
3✔
86
        this.context.debug("No plugins to be installed");
4✔
87
        step.success();
3✔
88
      } else {
89
        for (ToolPluginDescriptor plugin : pluginsToInstall) {
10✔
90
          boolean result = installPlugin(plugin, step, pc);
6✔
91
          if (result) {
2!
92
            createPluginMarkerFile(plugin);
3✔
93
          }
94
        }
1✔
95
      }
96
      doAddRecommendations(pluginsToRecommend);
3✔
97
    } catch (RuntimeException e) {
×
98
      step.error(e, true);
×
99
      throw e;
×
100
    } finally {
101
      step.close();
2✔
102
    }
103

104
  }
1✔
105

106
  private void doAddRecommendations(List<ToolPluginDescriptor> recommendations) {
107
    Path extensionsJsonPath = this.context.getWorkspacePath().resolve(".vscode/extensions.json");
6✔
108

109
    ObjectMapper objectMapper = new ObjectMapper();
4✔
110
    Map<String, Object> recommendationsMap;
111

112
    if (Files.exists(extensionsJsonPath)) {
5!
113
      try (BufferedReader reader = Files.newBufferedReader(extensionsJsonPath)) {
3✔
114
        recommendationsMap = objectMapper.readValue(reader, Map.class);
6✔
115
      } catch (IOException e) {
×
116
        throw new RuntimeException(e);
×
117
      }
1✔
118
    } else {
119
      recommendationsMap = new HashMap<>();
×
120
    }
121

122
    List<String> existingRecommendations = (List<String>) recommendationsMap.getOrDefault("recommendations", new ArrayList<>());
8✔
123

124
    try {
125
      int addedRecommendations = 0;
2✔
126
      Set<String> existingRecommendationsSet = new HashSet<>(existingRecommendations);
5✔
127
      for (ToolPluginDescriptor recommendation : recommendations) {
10✔
128
        String recommendationId = recommendation.id();
3✔
129
        if (existingRecommendationsSet.add(recommendationId)) {
4✔
130
          existingRecommendations.add(recommendationId);
4✔
131
          addedRecommendations++;
1✔
132
        }
133
      }
1✔
134

135
      if (addedRecommendations > 0) {
2✔
136
        objectMapper.writeValue(extensionsJsonPath.toFile(), recommendationsMap);
5✔
137
      }
138

139
    } catch (IOException e) {
×
140
      this.context.error(e);
×
141
    }
1✔
142
  }
1✔
143

144
  @Override
145
  protected void configureToolArgs(ProcessContext pc, ProcessMode processMode, ProcessErrorHandling errorHandling, String... args) {
146

147
    Path vsCodeConf = this.context.getWorkspacePath().resolve(".vscode/.userdata");
6✔
148
    pc.addArg("--new-window");
4✔
149
    pc.addArg("--user-data-dir=" + vsCodeConf);
6✔
150
    Path vsCodeExtensionFolder = this.context.getIdeHome().resolve("plugins/vscode");
6✔
151
    pc.addArg("--extensions-dir=" + vsCodeExtensionFolder);
6✔
152
    pc.addArg(this.context.getWorkspacePath());
6✔
153
    super.configureToolArgs(pc, processMode, errorHandling, args);
6✔
154
  }
1✔
155

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