• 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

34.31
cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java
1
package com.devonfw.tools.ide.tool.ide;
2

3
import java.io.IOException;
4
import java.nio.file.Files;
5
import java.nio.file.Path;
6
import java.util.Collection;
7
import java.util.Collections;
8
import java.util.HashMap;
9
import java.util.Iterator;
10
import java.util.Map;
11
import java.util.Set;
12
import java.util.stream.Stream;
13

14
import com.devonfw.tools.ide.cli.CliException;
15
import com.devonfw.tools.ide.common.Tag;
16
import com.devonfw.tools.ide.context.IdeContext;
17
import com.devonfw.tools.ide.io.FileAccess;
18
import com.devonfw.tools.ide.process.ProcessMode;
19
import com.devonfw.tools.ide.tool.LocalToolCommandlet;
20
import com.devonfw.tools.ide.tool.ToolCommandlet;
21
import com.devonfw.tools.ide.tool.eclipse.Eclipse;
22
import com.devonfw.tools.ide.tool.intellij.Intellij;
23
import com.devonfw.tools.ide.tool.vscode.Vscode;
24

25
/**
26
 * {@link ToolCommandlet} for an IDE (integrated development environment) such as {@link Eclipse}, {@link Vscode}, or {@link Intellij}.
27
 */
28
public abstract class IdeToolCommandlet extends LocalToolCommandlet {
1✔
29

30
  private Map<String, PluginDescriptor> pluginsMap;
31

32
  private Collection<PluginDescriptor> configuredPlugins;
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 IdeToolCommandlet(IdeContext context, String tool, Set<Tag> tags) {
42

43
    super(context, tool, tags);
5✔
44
    assert (hasIde(tags));
5!
45
  }
1✔
46

47
  private boolean hasIde(Set<Tag> tags) {
48

49
    for (Tag tag : tags) {
10!
50
      if (tag.isAncestorOf(Tag.IDE)) {
4!
51
        return true;
2✔
52
      }
53
    }
×
54
    throw new IllegalStateException("Tags of IdeTool hat to be connected with tag IDE: " + tags);
×
55
  }
56

57
  private Map<String, PluginDescriptor> getPluginsMap() {
58

59
    if (this.pluginsMap == null) {
3✔
60
      Map<String, PluginDescriptor> map = new HashMap<>();
4✔
61
      Path pluginsPath = getPluginsConfigPath();
3✔
62
      if (Files.isDirectory(pluginsPath)) {
5!
63
        try (Stream<Path> childStream = Files.list(pluginsPath)) {
×
64
          Iterator<Path> iterator = childStream.iterator();
×
65
          while (iterator.hasNext()) {
×
66
            Path child = iterator.next();
×
67
            String filename = child.getFileName().toString();
×
68
            if (filename.endsWith(IdeContext.EXT_PROPERTIES) && Files.exists(child)) {
×
69
              PluginDescriptor descriptor = PluginDescriptorImpl.of(child, this.context, isPluginUrlNeeded());
×
70
              map.put(descriptor.getName(), descriptor);
×
71
            }
72
          }
×
73
        } catch (IOException e) {
×
74
          throw new IllegalStateException("Failed to list children of directory " + pluginsPath, e);
×
75
        }
×
76
      }
77
      this.pluginsMap = map;
3✔
78
    }
79
    return this.pluginsMap;
3✔
80
  }
81

82
  private Path getPluginsConfigPath() {
83

84
    return this.context.getSettingsPath().resolve(this.tool).resolve(IdeContext.FOLDER_PLUGINS);
9✔
85
  }
86

87
  /**
88
   * @return {@code true} if {@link PluginDescriptor#getUrl() plugin URL} property is needed, {@code false} otherwise.
89
   */
90
  protected boolean isPluginUrlNeeded() {
91

92
    return false;
×
93
  }
94

95
  /**
96
   * @return the immutable {@link Collection} of {@link PluginDescriptor}s configured for this IDE tool.
97
   */
98
  public Collection<PluginDescriptor> getConfiguredPlugins() {
99

100
    if (this.configuredPlugins == null) {
×
101
      this.configuredPlugins = Collections.unmodifiableCollection(getPluginsMap().values());
×
102
    }
103
    return this.configuredPlugins;
×
104
  }
105

106
  /**
107
   * @return the {@link Path} where the plugins of this {@link IdeToolCommandlet} shall be installed.
108
   */
109
  public Path getPluginsInstallationPath() {
110

111
    // TODO add edition???
112
    return this.context.getPluginsPath().resolve(this.tool);
7✔
113
  }
114

115
  /**
116
   * @param key the filename of the properties file configuring the requested plugin (typically excluding the ".properties" extension).
117
   * @return the {@link PluginDescriptor} for the given {@code key}.
118
   */
119
  public PluginDescriptor getPlugin(String key) {
120

121
    if (key == null) {
×
122
      return null;
×
123
    }
124
    if (key.endsWith(IdeContext.EXT_PROPERTIES)) {
×
125
      key = key.substring(0, key.length() - IdeContext.EXT_PROPERTIES.length());
×
126
    }
127
    PluginDescriptor pluginDescriptor = getPluginsMap().get(key);
×
128
    if (pluginDescriptor == null) {
×
129
      throw new CliException(
×
130
          "Could not find plugin " + key + " at " + getPluginsConfigPath().resolve(key) + ".properties");
×
131
    }
132
    return pluginDescriptor;
×
133
  }
134

135
  @Override
136
  protected boolean doInstall(boolean silent) {
137

138
    boolean newlyInstalled = super.doInstall(silent);
4✔
139
    // post installation...
140
    boolean installPlugins = newlyInstalled;
2✔
141
    Path pluginsInstallationPath = getPluginsInstallationPath();
3✔
142
    if (newlyInstalled) {
2✔
143
      this.context.getFileAccess().delete(pluginsInstallationPath);
6✔
144
    } else if (!Files.isDirectory(pluginsInstallationPath)) {
5!
145
      installPlugins = true;
2✔
146
    }
147
    if (installPlugins) {
2!
148
      for (PluginDescriptor plugin : getPluginsMap().values()) {
8!
149
        if (plugin.isActive()) {
×
150
          installPlugin(plugin);
×
151
        } else {
152
          handleInstall4InactivePlugin(plugin);
×
153
        }
154
      }
×
155
    }
156
    return newlyInstalled;
2✔
157
  }
158

159
  /**
160
   * @param plugin the in{@link PluginDescriptor#isActive() active} {@link PluginDescriptor} that is skipped for regular plugin installation.
161
   */
162
  protected void handleInstall4InactivePlugin(PluginDescriptor plugin) {
163

164
    this.context.debug("Omitting installation of inactive plugin {} ({}).", plugin.getName(), plugin.getId());
×
165
  }
×
166

167
  /**
168
   * @param plugin the {@link PluginDescriptor} to install.
169
   */
170
  public abstract void installPlugin(PluginDescriptor plugin);
171

172
  /**
173
   * @param plugin the {@link PluginDescriptor} to uninstall.
174
   */
175
  public void uninstallPlugin(PluginDescriptor plugin) {
176

177
    Path pluginsPath = getPluginsInstallationPath();
×
178
    if (!Files.isDirectory(pluginsPath)) {
×
179
      this.context.debug("Omitting to uninstall plugin {} ({}) as plugins folder does not exist at {}",
×
180
          plugin.getName(), plugin.getId(), pluginsPath);
×
181
      return;
×
182
    }
183
    FileAccess fileAccess = this.context.getFileAccess();
×
184
    Path match = fileAccess.findFirst(pluginsPath, p -> p.getFileName().toString().startsWith(plugin.getId()), false);
×
185
    if (match == null) {
×
186
      this.context.debug("Omitting to uninstall plugin {} ({}) as plugins folder does not contain a match at {}",
×
187
          plugin.getName(), plugin.getId(), pluginsPath);
×
188
      return;
×
189
    }
190
    fileAccess.delete(match);
×
191
  }
×
192

193
  @Override
194
  public void run() {
195

196
    configureWorkspace();
2✔
197
    runIde(this.arguments.asArray());
5✔
198
  }
1✔
199

200
  /**
201
   * Run the actual IDE.
202
   *
203
   * @param args the additional arguments to pass to the IDE.
204
   */
205
  protected void runIde(String... args) {
206

207
    runTool(ProcessMode.DEFAULT, null, args);
5✔
208
  }
1✔
209

210
  /**
211
   * Configure the workspace for this IDE using the templates from the settings.
212
   */
213
  protected void configureWorkspace() {
214

215
    Path settingsWorkspaceFolder = this.context.getSettingsPath().resolve(this.tool)
7✔
216
        .resolve(IdeContext.FOLDER_WORKSPACE);
2✔
217
    FileAccess fileAccess = this.context.getFileAccess();
4✔
218
    if (!fileAccess.isExpectedFolder(settingsWorkspaceFolder)) {
4!
219
      return;
1✔
220
    }
221
    Path setupFolder = settingsWorkspaceFolder.resolve(IdeContext.FOLDER_SETUP);
×
222
    Path updateFolder = settingsWorkspaceFolder.resolve(IdeContext.FOLDER_UPDATE);
×
223
    if (!fileAccess.isExpectedFolder(setupFolder) && !fileAccess.isExpectedFolder(updateFolder)) {
×
224
      return;
×
225
    }
226
    Path ideWorkspacePath = this.context.getWorkspacePath();
×
227
    if (!fileAccess.isExpectedFolder(ideWorkspacePath)) {
×
228
      return; // should actually never happen...
×
229
    }
230
    this.context.step("Configuring workspace {} for IDE {}", ideWorkspacePath.getFileName(), this.tool);
×
231
    this.context.getWorkspaceMerger().merge(setupFolder, updateFolder, this.context.getVariables(), ideWorkspacePath);
×
232
  }
×
233

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