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

devonfw / IDEasy / 22241505980

20 Feb 2026 09:16PM UTC coverage: 70.656% (+0.2%) from 70.474%
22241505980

Pull #1710

github

web-flow
Merge 04e4bdacd into 379acdc9d
Pull Request #1710: #404: allow logging via SLF4J

4121 of 6440 branches covered (63.99%)

Branch coverage included in aggregate %.

10704 of 14542 relevant lines covered (73.61%)

3.13 hits per line

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

76.63
cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java
1
package com.devonfw.tools.ide.commandlet;
2

3
import java.io.IOException;
4
import java.nio.file.Files;
5
import java.nio.file.Path;
6
import java.nio.file.StandardCopyOption;
7
import java.nio.file.StandardOpenOption;
8
import java.util.List;
9
import java.util.function.Function;
10

11
import org.slf4j.Logger;
12
import org.slf4j.LoggerFactory;
13

14
import com.devonfw.tools.ide.context.IdeContext;
15
import com.devonfw.tools.ide.environment.EnvironmentVariables;
16
import com.devonfw.tools.ide.environment.EnvironmentVariablesPropertiesFile;
17
import com.devonfw.tools.ide.environment.EnvironmentVariablesType;
18
import com.devonfw.tools.ide.io.FileAccess;
19
import com.devonfw.tools.ide.log.IdeLogLevel;
20
import com.devonfw.tools.ide.merge.DirectoryMerger;
21
import com.devonfw.tools.ide.tool.custom.CustomTools;
22
import com.devonfw.tools.ide.tool.custom.CustomToolsMapper;
23
import com.devonfw.tools.ide.tool.mvn.Mvn;
24
import com.devonfw.tools.ide.variable.IdeVariables;
25
import com.devonfw.tools.ide.variable.VariableDefinition;
26

27
/**
28
 * {@link Commandlet} to upgrade settings after a migration from devonfw-ide to IDEasy.
29
 */
30
public class UpgradeSettingsCommandlet extends Commandlet {
31

32
  private static final Logger LOG = LoggerFactory.getLogger(UpgradeSettingsCommandlet.class);
4✔
33

34
  /**
35
   * The constructor.
36
   *
37
   * @param context the {@link IdeContext}.
38
   */
39
  public UpgradeSettingsCommandlet(IdeContext context) {
40

41
    super(context);
3✔
42
    addKeyword(getName());
4✔
43
  }
1✔
44

45
  @Override
46
  public String getName() {
47

48
    return "upgrade-settings";
2✔
49
  }
50

51
  @Override
52
  protected void doRun() {
53
    updateLegacyFolders();
2✔
54
    updateProperties();
2✔
55
    updateWorkspaceTemplates();
2✔
56
  }
1✔
57

58
  private void updateLegacyFolders() {
59
    LOG.info("Updating legacy folders if present...");
3✔
60
    Path settingsPath = context.getSettingsPath();
4✔
61
    updateLegacyFolder(settingsPath, IdeContext.FOLDER_LEGACY_REPOSITORIES, IdeContext.FOLDER_REPOSITORIES);
5✔
62
    updateLegacyFolder(settingsPath, IdeContext.FOLDER_LEGACY_TEMPLATES, IdeContext.FOLDER_TEMPLATES);
5✔
63
    updateLegacyFolder(settingsPath.resolve(IdeContext.FOLDER_TEMPLATES).resolve(IdeContext.FOLDER_CONF), Mvn.MVN_CONFIG_LEGACY_FOLDER, Mvn.MVN_CONFIG_FOLDER);
9✔
64
  }
1✔
65

66
  private void updateLegacyFolder(Path folder, String legacyName, String newName) {
67
    FileAccess fileAccess = this.context.getFileAccess();
4✔
68
    Path legacyFolder = folder.resolve(legacyName);
4✔
69
    Path newFolder = folder.resolve(newName);
4✔
70
    if (fileAccess.isExpectedFolder(legacyFolder)) {
4✔
71
      try {
72
        if (!Files.exists(newFolder)) {
5!
73
          fileAccess.move(legacyFolder, newFolder, StandardCopyOption.REPLACE_EXISTING);
10✔
74
          LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully renamed folder '{}' to '{}' in {}.", legacyName, newName, folder);
19✔
75
        }
76
      } catch (IllegalStateException e) {
×
77
        LOG.error("Error renaming folder {} to {} in {}", legacyName, newName, folder, e);
×
78
      }
1✔
79
    }
80
  }
1✔
81

82
  private void updateWorkspaceTemplates() {
83
    LOG.info("Updating workspace templates (replace legacy variables and change variable syntax)...");
3✔
84

85
    FileAccess fileAccess = this.context.getFileAccess();
4✔
86
    DirectoryMerger merger = this.context.getWorkspaceMerger();
4✔
87
    Path settingsDir = this.context.getSettingsPath();
4✔
88
    Path workspaceDir = settingsDir.resolve(IdeContext.FOLDER_WORKSPACE);
4✔
89
    if (fileAccess.isExpectedFolder(workspaceDir)) {
4!
90
      merger.upgrade(workspaceDir);
3✔
91
    }
92
    fileAccess.listChildrenMapped(settingsDir, child -> {
7✔
93
      Path childWorkspaceDir = child.resolve(IdeContext.FOLDER_WORKSPACE);
4✔
94
      if (fileAccess.isExpectedFolder(childWorkspaceDir)) {
4✔
95
        merger.upgrade(childWorkspaceDir);
3✔
96
      }
97
      return null;
2✔
98
    });
99
  }
1✔
100

101
  private void updateProperties() {
102
    // updates DEVON_IDE_CUSTOM_TOOLS to new ide-custom-tools.json
103
    String devonCustomTools = IdeVariables.DEVON_IDE_CUSTOM_TOOLS.get(this.context);
6✔
104
    if (devonCustomTools != null) {
2✔
105
      CustomTools customTools = CustomToolsMapper.parseCustomToolsFromLegacyConfig(devonCustomTools, context);
5✔
106
      if (customTools != null) {
2!
107
        CustomToolsMapper.get().saveJsonToFolder(customTools, this.context.getSettingsPath());
6✔
108
      }
109
    }
110

111
    // update properties (devon.properties -> ide.properties, convert legacy properties)
112
    EnvironmentVariables environmentVariables = context.getVariables();
4✔
113
    while (environmentVariables != null) {
2✔
114
      if (environmentVariables instanceof EnvironmentVariablesPropertiesFile environmentVariablesProperties) {
6✔
115
        updateProperties(environmentVariablesProperties);
3✔
116
      }
117
      environmentVariables = environmentVariables.getParent();
4✔
118
    }
119
    Path templatePropertiesDir = this.context.getSettingsTemplatePath().resolve(IdeContext.FOLDER_CONF);
6✔
120
    if (Files.exists(templatePropertiesDir)) {
5!
121
      EnvironmentVariablesPropertiesFile environmentVariablesProperties = new EnvironmentVariablesPropertiesFile(null, EnvironmentVariablesType.CONF,
10✔
122
          templatePropertiesDir, null, this.context);
123
      updateProperties(environmentVariablesProperties);
3✔
124
    }
125
  }
1✔
126

127
  private void updateProperties(EnvironmentVariablesPropertiesFile environmentVariables) {
128
    Path propertiesFilePath = environmentVariables.getPropertiesFilePath();
3✔
129
    if (environmentVariables.getLegacyConfiguration() != null) {
3!
130
      if (environmentVariables.getType() == EnvironmentVariablesType.SETTINGS) {
4✔
131
        // adds disabled legacySupportEnabled variable if missing in ide.properties
132
        environmentVariables.set(IdeVariables.IDE_VARIABLE_SYNTAX_LEGACY_SUPPORT_ENABLED.getName(), "false", false);
7✔
133
      }
134
      environmentVariables.remove(IdeVariables.DEVON_IDE_CUSTOM_TOOLS.getName());
4✔
135
      for (VariableDefinition<?> var : IdeVariables.VARIABLES) {
10✔
136
        String legacyName = var.getLegacyName();
3✔
137
        if (legacyName != null) {
2✔
138
          String value = environmentVariables.get(legacyName);
4✔
139
          if (value != null) {
2!
140
            String name = var.getName();
×
141
            String newValue = environmentVariables.get(name);
×
142
            if (newValue == null) {
×
143
              environmentVariables.set(name, value, environmentVariables.isExported(name));
×
144
            }
145
          }
146
          environmentVariables.remove(legacyName);
3✔
147
        }
148
      }
1✔
149
      updatePropertiesLegacyEdition(environmentVariables, "INTELLIJ_EDITION_TYPE", "INTELLIJ_EDITION", this::mapLegacyIntellijEdition);
6✔
150
      updatePropertiesLegacyEdition(environmentVariables, "ECLIPSE_EDITION_TYPE", "ECLIPSE_EDITION", this::mapLegacyEclipseEdition);
6✔
151
      cleanupLegacyProperties();
2✔
152
      environmentVariables.save();
2✔
153
      this.context.getFileAccess().backup(environmentVariables.getLegacyPropertiesFilePath());
7✔
154
    }
155
  }
1✔
156

157
  private String mapLegacyIntellijEdition(String legacyEdition) {
158

159
    return switch (legacyEdition) {
9!
160
      case "U" -> "ultimate";
2✔
161
      case "C" -> "intellij";
×
162
      default -> {
163
        LOG.warn("Undefined legacy edition {}", legacyEdition);
×
164
        yield "intellij";
×
165
      }
166
    };
167
  }
168

169
  private String mapLegacyEclipseEdition(String legacyEdition) {
170

171
    return switch (legacyEdition) {
×
172
      case "java" -> "eclipse";
×
173
      case "jee" -> "jee";
×
174
      case "cpp" -> "cpp";
×
175
      default -> {
176
        LOG.warn("Undefined legacy edition {}", legacyEdition);
×
177
        yield "eclipse";
×
178
      }
179
    };
180
  }
181

182
  private static void updatePropertiesLegacyEdition(EnvironmentVariablesPropertiesFile environmentVariables, String legacyEditionVariable,
183
      String newEditionVariable, Function<String, String> editionMapper) {
184

185
    String legacyEdition = environmentVariables.get(legacyEditionVariable);
4✔
186
    if (legacyEdition != null) {
2✔
187
      String newEdition = environmentVariables.get(newEditionVariable);
4✔
188
      if (newEdition == null) {
2✔
189
        environmentVariables.set(newEditionVariable, editionMapper.apply(legacyEdition), false);
9✔
190
      }
191
      environmentVariables.remove(legacyEditionVariable);
3✔
192
    }
193
  }
1✔
194

195
  private void cleanupLegacyProperties() {
196
    LOG.info("Cleaning up legacy properties...");
3✔
197

198
    Path settingsPath = context.getSettingsPath();
4✔
199
    Path repositoriesPath = settingsPath.resolve(IdeContext.FOLDER_REPOSITORIES);
4✔
200

201
    FileAccess fileAccess = this.context.getFileAccess();
4✔
202
    if (fileAccess.isExpectedFolder(repositoriesPath)) {
4!
203
      fileAccess.listChildrenMapped(repositoriesPath, child -> {
6✔
204
        try {
205
          if (Files.isRegularFile(child) && child.getFileName().toString().endsWith(".properties")) {
11!
206
            updateRepositoryPropertiesFile(child);
3✔
207
          }
208
        } catch (IOException e) {
×
209
          throw new RuntimeException(e);
×
210
        }
1✔
211
        return null;
2✔
212
      });
213
    }
214
  }
1✔
215

216
  private void updateRepositoryPropertiesFile(Path filePath) throws IOException {
217
    List<String> lines = Files.readAllLines(filePath);
3✔
218
    boolean updated = false;
2✔
219

220
    for (int i = 0; i < lines.size(); i++) {
8✔
221
      String line = lines.get(i).trim();
6✔
222
      if (line.startsWith("git.url=") || line.startsWith("git-url")) {
8!
223
        String gitUrl = line.substring(line.indexOf("=") + 1).trim();
×
224
        lines.set(i, "git_url=" + gitUrl);
×
225
        updated = true;
×
226
        continue;
×
227
      }
228
      if (line.startsWith("eclipse=import")) {
4✔
229
        lines.set(i, "import=eclipse");
5✔
230
        updated = true;
2✔
231
      }
232
    }
233
    if (updated) {
2✔
234
      try {
235
        Files.write(filePath, lines, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
14✔
236
        LOG.info(IdeLogLevel.SUCCESS.getSlf4jMarker(), "Successfully updated repository configuration file {}", filePath);
6✔
237
      } catch (IOException e) {
×
238
        LOG.error("Failed to write updated repository configuration file {}", filePath);
×
239
        throw e;
×
240
      }
1✔
241
    }
242
  }
1✔
243
}
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