Skip to content

Commit

Permalink
#759: upgrade settings commandlet (#820)
Browse files Browse the repository at this point in the history
  • Loading branch information
leonrohne27 authored Jan 14, 2025
1 parent 875fbff commit 241ce06
Show file tree
Hide file tree
Showing 54 changed files with 1,673 additions and 538 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE
Release with new features and bugfixes:

* https://github.com/devonfw/IDEasy/issues/894[#894]: Fix ide.bat printing for initialization and error output
* https://github.com/devonfw/IDEasy/issues/759[#759]: Add UpgradeSettingsCommandlet for the upgrade of legacy devonfw-ide settings to IDEasy

The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/18?closed=1[milestone 2025.01.001].

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import com.devonfw.tools.ide.git.GitUrl;
import com.devonfw.tools.ide.property.FlagProperty;
import com.devonfw.tools.ide.property.StringProperty;
import com.devonfw.tools.ide.repo.CustomTool;
import com.devonfw.tools.ide.repo.CustomToolMetadata;
import com.devonfw.tools.ide.step.Step;
import com.devonfw.tools.ide.tool.CustomToolCommandlet;
import com.devonfw.tools.ide.tool.ToolCommandlet;
Expand Down Expand Up @@ -164,7 +164,7 @@ private void updateSoftware() {
}

// custom tools in ide-custom-tools.json
for (CustomTool customTool : this.context.getCustomToolRepository().getTools()) {
for (CustomToolMetadata customTool : this.context.getCustomToolRepository().getTools()) {
CustomToolCommandlet customToolCommandlet = new CustomToolCommandlet(this.context, customTool);
toolCommandlets.add(customToolCommandlet);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public CommandletManagerImpl(IdeContext context) {
add(new RepositoryCommandlet(context));
add(new UninstallCommandlet(context));
add(new UpdateCommandlet(context));
add(new UpgradeSettingsCommandlet(context));
add(new CreateCommandlet(context));
add(new BuildCommandlet(context));
add(new InstallPluginCommandlet(context));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public void run() {
return;
}

List<Path> propertiesFiles = this.context.getFileAccess().listChildren(repositories, path -> path.getFileName().toString().endsWith(".properties"));
List<Path> propertiesFiles = this.context.getFileAccess()
.listChildren(repositories, path -> path.getFileName().toString().endsWith(".properties"));

boolean forceMode = this.context.isForceMode();
for (Path propertiesFile : propertiesFiles) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package com.devonfw.tools.ide.commandlet;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.function.Function;

import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.environment.EnvironmentVariables;
import com.devonfw.tools.ide.environment.EnvironmentVariablesPropertiesFile;
import com.devonfw.tools.ide.environment.EnvironmentVariablesType;
import com.devonfw.tools.ide.merge.DirectoryMerger;
import com.devonfw.tools.ide.repo.CustomToolsJson;
import com.devonfw.tools.ide.repo.CustomToolsJsonMapper;
import com.devonfw.tools.ide.tool.mvn.Mvn;
import com.devonfw.tools.ide.variable.IdeVariables;
import com.devonfw.tools.ide.variable.VariableDefinition;

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

/**
* The constructor.
*
* @param context the {@link IdeContext}.
*/
public UpgradeSettingsCommandlet(IdeContext context) {

super(context);
addKeyword(getName());
}

@Override
public String getName() {

return "upgrade-settings";
}

@Override
public void run() {
updateLegacyFolders();
updateProperties();
updateWorkspaceTemplates();
}

private void updateLegacyFolders() {
this.context.info("Updating legacy folders if present...");
Path settingsPath = context.getSettingsPath();
updateLegacyFolder(settingsPath, IdeContext.FOLDER_LEGACY_REPOSITORIES, IdeContext.FOLDER_REPOSITORIES);
updateLegacyFolder(settingsPath, IdeContext.FOLDER_LEGACY_TEMPLATES, IdeContext.FOLDER_TEMPLATES);
updateLegacyFolder(settingsPath.resolve(IdeContext.FOLDER_TEMPLATES).resolve(IdeContext.FOLDER_CONF), Mvn.MVN_CONFIG_LEGACY_FOLDER, Mvn.MVN_CONFIG_FOLDER);
}

private void updateLegacyFolder(Path folder, String legacyName, String newName) {

Path legacyFolder = folder.resolve(legacyName);
Path newFolder = folder.resolve(newName);
if (Files.isDirectory(legacyFolder)) {
try {
if (!Files.exists(newFolder)) {
Files.move(legacyFolder, newFolder, StandardCopyOption.REPLACE_EXISTING);
this.context.success("Successfully renamed folder '{}' to '{}' in {}.", legacyName, newName, folder);
}
} catch (IOException e) {
this.context.error(e, "Error renaming folder {} to {} in {}", legacyName, newName, folder);
}
}
}

private void updateWorkspaceTemplates() {
this.context.info("Updating workspace templates (replace legacy variables and change variable syntax)...");

DirectoryMerger merger = this.context.getWorkspaceMerger();
Path settingsDir = this.context.getSettingsPath();
Path workspaceDir = settingsDir.resolve(IdeContext.FOLDER_WORKSPACE);
if (Files.isDirectory(workspaceDir)) {
merger.upgrade(workspaceDir);
}
this.context.getFileAccess().listChildrenMapped(settingsDir, child -> {
Path childWorkspaceDir = child.resolve(IdeContext.FOLDER_WORKSPACE);
if (Files.isDirectory(childWorkspaceDir)) {
merger.upgrade(childWorkspaceDir);
}
return null;
});
}

private void updateProperties() {
// updates DEVON_IDE_CUSTOM_TOOLS to new ide-custom-tools.json
String devonCustomTools = IdeVariables.DEVON_IDE_CUSTOM_TOOLS.get(this.context);
if (devonCustomTools != null) {
CustomToolsJson customToolsJson = CustomToolsJsonMapper.parseCustomToolsFromLegacyConfig(devonCustomTools, context);
if (customToolsJson != null) {
CustomToolsJsonMapper.saveJson(customToolsJson, this.context.getSettingsPath().resolve(IdeContext.FILE_CUSTOM_TOOLS));
}
}

// update properties (devon.properties -> ide.properties, convert legacy properties)
EnvironmentVariables environmentVariables = context.getVariables();
while (environmentVariables != null) {
if (environmentVariables instanceof EnvironmentVariablesPropertiesFile environmentVariablesProperties) {
updateProperties(environmentVariablesProperties);
}
environmentVariables = environmentVariables.getParent();
}
Path templatePropertiesDir = this.context.getSettingsTemplatePath().resolve(IdeContext.FOLDER_CONF);
if (Files.exists(templatePropertiesDir)) {
EnvironmentVariablesPropertiesFile environmentVariablesProperties = new EnvironmentVariablesPropertiesFile(null, EnvironmentVariablesType.CONF,
templatePropertiesDir, null, this.context);
updateProperties(environmentVariablesProperties);
}
}

private void updateProperties(EnvironmentVariablesPropertiesFile environmentVariables) {
Path propertiesFilePath = environmentVariables.getPropertiesFilePath();
if (environmentVariables.getLegacyConfiguration() != null) {
if (environmentVariables.getType() == EnvironmentVariablesType.SETTINGS) {
// adds disabled legacySupportEnabled variable if missing in ide.properties
environmentVariables.set(IdeVariables.IDE_VARIABLE_SYNTAX_LEGACY_SUPPORT_ENABLED.getName(), "false", false);
}
environmentVariables.remove(IdeVariables.DEVON_IDE_CUSTOM_TOOLS.getName());
for (VariableDefinition<?> var : IdeVariables.VARIABLES) {
String legacyName = var.getLegacyName();
if (legacyName != null) {
String value = environmentVariables.get(legacyName);
if (value != null) {
String name = var.getName();
String newValue = environmentVariables.get(name);
if (newValue == null) {
environmentVariables.set(name, value, environmentVariables.isExported(name));
}
}
environmentVariables.remove(legacyName);
}
}
updatePropertiesLegacyEdition(environmentVariables, "INTELLIJ_EDITION_TYPE", "INTELLIJ_EDITION", this::mapLegacyIntellijEdition);
updatePropertiesLegacyEdition(environmentVariables, "ECLIPSE_EDITION_TYPE", "ECLIPSE_EDITION", this::mapLegacyEclipseEdition);
environmentVariables.save();
this.context.getFileAccess().backup(environmentVariables.getLegacyPropertiesFilePath());
}
}

private String mapLegacyIntellijEdition(String legacyEdition) {

return switch (legacyEdition) {
case "U" -> "ultimate";
case "C" -> "intellij";
default -> {
this.context.warning("Undefined legacy edition {}", legacyEdition);
yield "intellij";
}
};
}

private String mapLegacyEclipseEdition(String legacyEdition) {

return switch (legacyEdition) {
case "java" -> "eclipse";
case "jee" -> "jee";
case "cpp" -> "cpp";
default -> {
this.context.warning("Undefined legacy edition {}", legacyEdition);
yield "eclipse";
}
};
}

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

String legacyEdition = environmentVariables.get(legacyEditionVariable);
if (legacyEdition != null) {
String newEdition = environmentVariables.get(newEditionVariable);
if (newEdition == null) {
environmentVariables.set(newEditionVariable, editionMapper.apply(legacyEdition), false);
}
environmentVariables.remove(legacyEditionVariable);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public abstract class AbstractIdeContext implements IdeContext {

private Path softwareExtraPath;

private Path softwareRepositoryPath;
private final Path softwareRepositoryPath;

protected Path pluginsPath;

Expand All @@ -91,15 +91,15 @@ public abstract class AbstractIdeContext implements IdeContext {

protected Path urlsPath;

private Path tempPath;
private final Path tempPath;

private Path tempDownloadPath;
private final Path tempDownloadPath;

private Path cwd;

private Path downloadPath;

private Path toolRepositoryPath;
private final Path toolRepositoryPath;

protected Path userHome;

Expand Down Expand Up @@ -308,11 +308,10 @@ private boolean isIdeHome(Path dir) {
private EnvironmentVariables createVariables() {

AbstractEnvironmentVariables system = createSystemVariables();
AbstractEnvironmentVariables user = extendVariables(system, this.userHomeIde, EnvironmentVariablesType.USER);
AbstractEnvironmentVariables settings = extendVariables(user, this.settingsPath, EnvironmentVariablesType.SETTINGS);
// TODO should we keep this workspace properties? Was this feature ever used?
AbstractEnvironmentVariables workspace = extendVariables(settings, this.workspacePath, EnvironmentVariablesType.WORKSPACE);
AbstractEnvironmentVariables conf = extendVariables(workspace, this.confPath, EnvironmentVariablesType.CONF);
AbstractEnvironmentVariables user = system.extend(this.userHomeIde, EnvironmentVariablesType.USER);
AbstractEnvironmentVariables settings = user.extend(this.settingsPath, EnvironmentVariablesType.SETTINGS);
AbstractEnvironmentVariables workspace = settings.extend(this.workspacePath, EnvironmentVariablesType.WORKSPACE);
AbstractEnvironmentVariables conf = workspace.extend(this.confPath, EnvironmentVariablesType.CONF);
return conf.resolved();
}

Expand All @@ -321,26 +320,6 @@ protected AbstractEnvironmentVariables createSystemVariables() {
return EnvironmentVariables.ofSystem(this);
}

protected AbstractEnvironmentVariables extendVariables(AbstractEnvironmentVariables envVariables, Path propertiesPath, EnvironmentVariablesType type) {

Path propertiesFile = null;
if (propertiesPath == null) {
trace("Configuration directory for type {} does not exist.", type);
} else if (Files.isDirectory(propertiesPath)) {
propertiesFile = propertiesPath.resolve(EnvironmentVariables.DEFAULT_PROPERTIES);
boolean legacySupport = (type != EnvironmentVariablesType.USER);
if (legacySupport && !Files.exists(propertiesFile)) {
Path legacyFile = propertiesPath.resolve(EnvironmentVariables.LEGACY_PROPERTIES);
if (Files.exists(legacyFile)) {
propertiesFile = legacyFile;
}
}
} else {
debug("Configuration directory {} does not exist.", propertiesPath);
}
return envVariables.extend(propertiesFile, type);
}

@Override
public SystemInfo getSystemInfo() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ public interface IdeContext extends IdeStartContext {
/** Legacy folder name used as compatibility fallback if {@link #FOLDER_TEMPLATES} does not exist. */
String FOLDER_LEGACY_TEMPLATES = "devon";

/** The filename of the configuration file in the settings for this {@link CustomToolRepository}. */
String FILE_CUSTOM_TOOLS = "ide-custom-tools.json";

/**
* @return {@code true} if {@link #isOfflineMode() offline mode} is active or we are NOT {@link #isOnline() online}, {@code false} otherwise.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ public VariableSource getSource() {
protected boolean isExported(String name) {

if (this.parent != null) {
if (this.parent.isExported(name)) {
return true;
}
return this.parent.isExported(name);
}
return false;
}
Expand Down Expand Up @@ -144,13 +142,14 @@ protected VariableLine createVariableLine(String name, boolean onlyExported, Abs
}

/**
* @param propertiesFilePath the {@link #getPropertiesFilePath() propertiesFilePath} of the child {@link EnvironmentVariables}.
* @param propertiesFolderPath the {@link Path} to the folder containing the {@link #getPropertiesFilePath() properties file} of the child
* {@link EnvironmentVariables}.
* @param type the {@link #getType() type}.
* @return the new {@link EnvironmentVariables}.
*/
public AbstractEnvironmentVariables extend(Path propertiesFilePath, EnvironmentVariablesType type) {
public AbstractEnvironmentVariables extend(Path propertiesFolderPath, EnvironmentVariablesType type) {

return new EnvironmentVariablesPropertiesFile(this, type, propertiesFilePath, this.context);
return new EnvironmentVariablesPropertiesFile(this, type, propertiesFolderPath, null, this.context);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ default EnvironmentVariables getParent() {
return null;
}

/**
* @param name the {@link com.devonfw.tools.ide.variable.VariableDefinition#getName() name} of the variable to set.
* @param value the new {@link #get(String) value} of the variable to set. May be {@code null} to unset the variable.
* @return the old variable value.
*/
default String set(String name, String value) {

throw new UnsupportedOperationException();
}

/**
* @param name the {@link com.devonfw.tools.ide.variable.VariableDefinition#getName() name} of the variable to set.
* @param value the new {@link #get(String) value} of the variable to set. May be {@code null} to unset the variable.
Expand Down Expand Up @@ -263,5 +273,4 @@ static String getToolEditionVariable(String tool) {

return tool.toUpperCase(Locale.ROOT) + "_EDITION";
}

}
Loading

0 comments on commit 241ce06

Please sign in to comment.