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

devonfw / IDEasy / 29746438846

20 Jul 2026 01:29PM UTC coverage: 72.449% (-0.02%) from 72.469%
29746438846

Pull #2175

github

web-flow
Merge caa73a558 into 24ff47ab6
Pull Request #2175: #2172: add getIdeMetadataPath() for $IDE_HOME/.ide/<ide>/<workspace>

4919 of 7504 branches covered (65.55%)

Branch coverage included in aggregate %.

12697 of 16811 relevant lines covered (75.53%)

3.19 hits per line

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

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

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

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

11
import com.devonfw.tools.ide.common.Tag;
12
import com.devonfw.tools.ide.context.IdeContext;
13
import com.devonfw.tools.ide.io.FileAccess;
14
import com.devonfw.tools.ide.process.ProcessMode;
15
import com.devonfw.tools.ide.process.ProcessResult;
16
import com.devonfw.tools.ide.step.Step;
17
import com.devonfw.tools.ide.tool.ToolCommandlet;
18
import com.devonfw.tools.ide.tool.ToolInstallRequest;
19
import com.devonfw.tools.ide.tool.ToolInstallation;
20
import com.devonfw.tools.ide.tool.eclipse.Eclipse;
21
import com.devonfw.tools.ide.tool.intellij.Intellij;
22
import com.devonfw.tools.ide.tool.plugin.PluginBasedCommandlet;
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 PluginBasedCommandlet {
29

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

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

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

45
  private boolean hasIde(Set<Tag> tags) {
46

47
    for (Tag tag : tags) {
10!
48
      if (tag.isAncestorOf(Tag.IDE) || (tag == Tag.IDE)) {
7!
49
        return true;
2✔
50
      }
51
    }
×
52
    throw new IllegalStateException("Tags of IdeTool has to be connected with tag IDE: " + tags);
×
53
  }
54

55
  @Override
56
  protected final void doRun() {
57
    super.doRun();
2✔
58
  }
1✔
59

60
  @Override
61
  public ProcessResult runTool(List<String> args) {
62

63
    return runTool(ProcessMode.BACKGROUND, null, args);
6✔
64
  }
65

66
  @Override
67
  public ToolInstallation install(ToolInstallRequest request) {
68

69
    configureWorkspace();
2✔
70
    return super.install(request);
4✔
71
  }
72

73
  /**
74
   * @return the {@link Path} to the IDE-specific metadata folder for the {@link IdeContext#getWorkspaceName() current workspace}, located at
75
   *     {@code $IDE_HOME/.ide/«ide»/«workspace»}. Unlike {@link IdeContext#getWorkspacePath() the workspace path} (which holds the projects to open), this
76
   *     folder keeps IDE-specific metadata (e.g. {@code .vmoptions} or {@code *.properties} files) out of the workspace so it stays clean and independent of
77
   *     the IDE being used.
78
   */
79
  protected Path getIdeMetadataPath() {
80

81
    return this.context.getIdeHome().resolve(IdeContext.FOLDER_DOT_IDE).resolve(getName()).resolve(this.context.getWorkspaceName());
13✔
82
  }
83

84
  /**
85
   * Configure (initialize or update) the workspace for this IDE using the templates from the settings.
86
   */
87
  protected void configureWorkspace() {
88

89
    FileAccess fileAccess = this.context.getFileAccess();
4✔
90
    Path workspaceFolder = this.context.getWorkspacePath();
4✔
91
    if (!fileAccess.isExpectedFolder(workspaceFolder)) {
4!
92
      LOG.warn("Current workspace does not exist: {}", workspaceFolder);
×
93
      return; // should actually never happen...
×
94
    }
95
    Step step = this.context.newStep("Configuring workspace " + workspaceFolder.getFileName() + " for IDE " + this.tool);
10✔
96
    step.run(() -> doMergeWorkspaceStep(step, workspaceFolder));
12✔
97
  }
1✔
98

99
  private void doMergeWorkspaceStep(Step step, Path workspaceFolder) {
100

101
    int errors = 0;
2✔
102
    errors = mergeWorkspace(this.context.getUserHomeIde(), workspaceFolder, errors);
8✔
103
    errors = mergeWorkspace(this.context.getSettingsPath(), workspaceFolder, errors);
8✔
104
    errors = mergeWorkspace(this.context.getConfPath(), workspaceFolder, errors);
8✔
105
    if (errors == 0) {
2!
106
      step.success();
3✔
107
    } else {
108
      step.error("Your workspace configuration failed with {} error(s) - see log above.\n"
×
109
          + "This is either a configuration error in your settings git repository or a bug in IDEasy.\n"
110
          + "Please analyze the above errors with your team or IDE-admin and try to fix the problem.", errors);
×
111
      this.context.askToContinue(
×
112
          "In order to prevent you from being blocked, you can start your IDE anyhow but some configuration may not be in sync.");
113
    }
114
  }
1✔
115

116
  private int mergeWorkspace(Path configFolder, Path workspaceFolder, int errors) {
117

118
    int result = errors;
2✔
119
    result = mergeWorkspaceSingle(configFolder.resolve(IdeContext.FOLDER_WORKSPACE), workspaceFolder, result);
8✔
120
    result = mergeWorkspaceSingle(configFolder.resolve(this.tool).resolve(IdeContext.FOLDER_WORKSPACE), workspaceFolder, result);
11✔
121
    return result;
2✔
122
  }
123

124
  private int mergeWorkspaceSingle(Path templatesFolder, Path workspaceFolder, int errors) {
125

126
    Path setupFolder = templatesFolder.resolve(IdeContext.FOLDER_SETUP);
4✔
127
    Path updateFolder = templatesFolder.resolve(IdeContext.FOLDER_UPDATE);
4✔
128
    if (!Files.isDirectory(setupFolder) && !Files.isDirectory(updateFolder)) {
10✔
129
      LOG.trace("Skipping empty or non-existing workspace template folder {}.", templatesFolder);
4✔
130
      return errors;
2✔
131
    }
132
    LOG.debug("Merging workspace templates from {}...", templatesFolder);
4✔
133
    return errors + this.context.getWorkspaceMerger().merge(setupFolder, updateFolder, this.context.getVariables(), workspaceFolder);
13✔
134
  }
135

136
  /**
137
   * Imports the repository specified by the given {@link Path} into the IDE managed by this {@link IdeToolCommandlet}.
138
   *
139
   * @param repositoryPath the {@link Path} to the repository directory to import.
140
   */
141
  public void importRepository(Path repositoryPath) {
142

143
    throw new UnsupportedOperationException("Repository import is not yet implemented for IDE " + this.tool);
×
144
  }
145
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc