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

devonfw / IDEasy / 13696929899

06 Mar 2025 10:48AM UTC coverage: 68.467% (+0.2%) from 68.253%
13696929899

Pull #1085

github

web-flow
Merge fe2061e2b into cb3091c59
Pull Request #1085: #654: improved plugin suppport

3065 of 4919 branches covered (62.31%)

Branch coverage included in aggregate %.

7924 of 11131 relevant lines covered (71.19%)

3.11 hits per line

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

79.52
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 void installPlugin(ToolPluginDescriptor plugin, Step step, ProcessContext pc) {
50

51
    doInstallPlugins(List.of(plugin), pc);
×
52
    step.success();
×
53
  }
×
54

55
  @Override
56
  protected void installPlugins(Collection<ToolPluginDescriptor> plugins, ProcessContext pc) {
57

58
    List<ToolPluginDescriptor> pluginsToInstall = new ArrayList<>();
4✔
59
    List<ToolPluginDescriptor> pluginsToRecommend = new ArrayList<>();
4✔
60

61
    for (ToolPluginDescriptor plugin : plugins) {
10✔
62
      if (plugin.active()) {
3✔
63
        if (Files.exists(retrievePluginMarkerFilePath(plugin))) {
7!
64
          this.context.debug("Markerfile for IDE: {} and active plugin: {} already exists.", getName(), plugin.name());
×
65
        } else {
66
          pluginsToInstall.add(plugin);
5✔
67
        }
68
      } else {
69
        pluginsToRecommend.add(plugin);
4✔
70
      }
71
    }
1✔
72
    doAddRecommendations(pluginsToRecommend);
3✔
73
    doInstallPlugins(pluginsToInstall, pc);
4✔
74

75
  }
1✔
76

77
  private void doInstallPlugins(List<ToolPluginDescriptor> pluginsToInstall, ProcessContext pc) {
78

79
    if (pluginsToInstall.isEmpty()) {
3!
80
      this.context.info("No plugins to be installed");
×
81
    } else {
82

83
      for (ToolPluginDescriptor plugin : pluginsToInstall) {
10✔
84
        List<String> extensionsCommands = new ArrayList<>();
4✔
85
        extensionsCommands.add("--force");
4✔
86
        extensionsCommands.add("--install-extension");
4✔
87
        extensionsCommands.add(plugin.id());
5✔
88
        ProcessResult result = runTool(ProcessMode.DEFAULT, ProcessErrorHandling.THROW_ERR, pc, extensionsCommands.toArray(String[]::new));
13✔
89
        if (result.isSuccessful()) {
3!
90
          createPluginMarkerFile(plugin);
4✔
91
        } else {
92
          this.context.warning("An error occurred while installing plugin: {}", plugin.name());
×
93
        }
94
      }
1✔
95
    }
96
  }
1✔
97

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

101
    ObjectMapper objectMapper = new ObjectMapper();
4✔
102
    Map<String, Object> recommendationsMap;
103

104
    if (Files.exists(extensionsJsonPath)) {
5!
105
      try (BufferedReader reader = Files.newBufferedReader(extensionsJsonPath)) {
3✔
106
        recommendationsMap = objectMapper.readValue(reader, Map.class);
6✔
107
      } catch (IOException e) {
×
108
        throw new RuntimeException(e);
×
109
      }
1✔
110
    } else {
111
      recommendationsMap = new HashMap<>();
×
112
    }
113

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

116
    try {
117
      int addedRecommendations = 0;
2✔
118
      Set<String> existingRecommendationsSet = new HashSet<>(existingRecommendations);
5✔
119
      for (ToolPluginDescriptor recommendation : recommendations) {
10✔
120
        String recommendationId = recommendation.id();
3✔
121
        if (existingRecommendationsSet.add(recommendationId)) {
4!
122
          existingRecommendations.add(recommendationId);
4✔
123
          addedRecommendations++;
1✔
124
        }
125
      }
1✔
126

127
      if (addedRecommendations > 0) {
2!
128
        objectMapper.writeValue(extensionsJsonPath.toFile(), recommendationsMap);
5✔
129
      }
130

131
    } catch (IOException e) {
×
132
      this.context.error(e);
×
133
    }
1✔
134
  }
1✔
135

136
  @Override
137
  protected void configureToolArgs(ProcessContext pc, ProcessMode processMode, ProcessErrorHandling errorHandling, String... args) {
138

139
    Path vsCodeConf = this.context.getWorkspacePath().resolve(".vscode/.userdata");
6✔
140
    pc.addArg("--new-window");
4✔
141
    pc.addArg("--user-data-dir=" + vsCodeConf);
6✔
142
    Path vsCodeExtensionFolder = this.context.getIdeHome().resolve("plugins/vscode");
6✔
143
    pc.addArg("--extensions-dir=" + vsCodeExtensionFolder);
6✔
144
    pc.addArg(this.context.getWorkspacePath());
6✔
145
    super.configureToolArgs(pc, processMode, errorHandling, args);
6✔
146
  }
1✔
147

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