From d607fa6aaf0445aa2f6c4cc55269470d83d1c5a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Wed, 8 Jan 2025 00:44:11 +0100 Subject: [PATCH] #759: refactored updateProperties and custom-tools.json replaced regex parsing with indexOf added JsonIgnores and JsonProperties to CustomTool converted version from versionIdentifier to String added Tool record to CustomToolsJson --- .../commandlet/AbstractUpdateCommandlet.java | 4 +- .../commandlet/UpgradeSettingsCommandlet.java | 94 ++++----- .../tools/ide/merge/DirectoryMerger.java | 3 +- .../devonfw/tools/ide/merge/FileMerger.java | 2 +- .../tools/ide/merge/xmlmerger/XmlMerger.java | 2 +- .../devonfw/tools/ide/repo/CustomTool.java | 195 ------------------ .../tools/ide/repo/CustomToolJson.java | 26 +++ .../tools/ide/repo/CustomToolMetadata.java | 119 +++++++++++ .../tools/ide/repo/CustomToolRepository.java | 4 +- .../ide/repo/CustomToolRepositoryImpl.java | 150 ++------------ .../tools/ide/repo/CustomToolsJson.java | 138 +------------ .../tools/ide/repo/CustomToolsJsonMapper.java | 186 +++++++++++++++++ .../tools/ide/tool/CustomToolCommandlet.java | 8 +- .../UpgradeSettingsCommandletTest.java | 52 +++-- .../ide/context/AbstractIdeContextTest.java | 2 +- .../ide/repo/CustomToolMetadataTest.java | 68 ++++++ .../tools/ide/repo/CustomToolTest.java | 67 ------ ...st.java => CustomToolsJsonMapperTest.java} | 27 +-- .../project/settings/devon.properties | 14 +- .../project/settings/devon/devon.properties | 4 + .../settings/projects/IDEasy.properties | 5 + ...tVariableSyntax => testVariableSyntax.txt} | 0 22 files changed, 528 insertions(+), 642 deletions(-) delete mode 100644 cli/src/main/java/com/devonfw/tools/ide/repo/CustomTool.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolMetadata.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonMapper.java create mode 100644 cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolMetadataTest.java delete mode 100644 cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolTest.java rename cli/src/test/java/com/devonfw/tools/ide/repo/{CustomToolsJsonTest.java => CustomToolsJsonMapperTest.java} (62%) create mode 100644 cli/src/test/resources/ide-projects/upgrade-settings/project/settings/devon/devon.properties create mode 100644 cli/src/test/resources/ide-projects/upgrade-settings/project/settings/projects/IDEasy.properties rename cli/src/test/resources/ide-projects/upgrade-settings/project/settings/workspace/{testVariableSyntax => testVariableSyntax.txt} (100%) diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java index 78df57524..54c985f03 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/AbstractUpdateCommandlet.java @@ -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; @@ -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); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java index 1bc59a059..780ed13e7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java @@ -8,8 +8,10 @@ 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.variable.IdeVariables; /** @@ -36,47 +38,31 @@ public String getName() { @Override public void run() { + updateLegacyFolders(); updateProperties(); replaceLegacyVariablesAndBracketsInWorkspace(); - checkIfLegacyFolderExists(); } - private void checkIfLegacyFolderExists() { + private void updateLegacyFolders() { this.context.info("Scanning for legacy folders..."); - Path settingsPath = context.getSettingsPath(); + updateLegacyFolder(settingsPath, IdeContext.FOLDER_LEGACY_TEMPLATES, IdeContext.FOLDER_TEMPLATES); + updateLegacyFolder(settingsPath, IdeContext.FOLDER_LEGACY_REPOSITORIES, IdeContext.FOLDER_REPOSITORIES); + } - Path devonFolder = settingsPath.resolve("devon"); - - Path templatesFolder = settingsPath.resolve("templates"); - - Path projectsFolder = settingsPath.resolve("projects"); - - Path repositoriesFolder = settingsPath.resolve("repositories"); + private void updateLegacyFolder(Path folder, String legacyName, String newName) { - if (Files.exists(devonFolder) && Files.isDirectory(devonFolder)) { + Path legacyFolder = folder.resolve(legacyName); + Path newFolder = folder.resolve(newName); + if (Files.isDirectory(legacyFolder)) { try { - if (!Files.exists(templatesFolder)) { - Files.move(devonFolder, templatesFolder, StandardCopyOption.REPLACE_EXISTING); - this.context.success("Successfully updated folder name from 'settings/devon' to 'settings/templates'."); + 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("Error updating 'settings/devon' folder to 'settings/templates': " + e.getMessage()); + this.context.error("Error renaming folder " + legacyName + " to " + newName + " in " + folder, e); } - } else { - this.context.warning("The 'templates' folder already exists, skipping renaming."); - } - if (Files.exists(projectsFolder) && Files.isDirectory(projectsFolder)) { - try { - if (!Files.exists(repositoriesFolder)) { - Files.move(projectsFolder, repositoriesFolder, StandardCopyOption.REPLACE_EXISTING); - this.context.success("Successfully updated folder name from 'settings/projects' to 'settings/repositories'."); - } - } catch (IOException e) { - this.context.error("Error updating 'settings/projects' folder to 'settings/repositories': " + e.getMessage()); - } - } else { - this.context.warning("The 'repositories' folder already exists, skipping renaming."); } } @@ -99,44 +85,46 @@ private void replaceLegacyVariablesAndBracketsInWorkspace() { } private void updateProperties() { - EnvironmentVariables environmentVariables = context.getVariables(); - CustomToolsJson customToolsJson = null; - // updates DEVON_IDE_CUSTOM_TOOLS to new ide-custom-tools.json - String devonCustomToolsName = IdeVariables.DEVON_IDE_CUSTOM_TOOLS.getName(); - String devonCustomTools = environmentVariables.getParent().get(devonCustomToolsName); + String devonCustomTools = IdeVariables.DEVON_IDE_CUSTOM_TOOLS.get(this.context); if (devonCustomTools != null) { - String customToolsContent = environmentVariables.getParent().get(devonCustomToolsName); - if (!customToolsContent.isEmpty()) { - customToolsJson = CustomToolsJson.retrieveCustomToolsFromLegacyConfig(customToolsContent, context); - } + CustomToolsJson customToolsJson = CustomToolsJsonMapper.parseCustomToolsFromLegacyConfig(devonCustomTools, context); if (customToolsJson != null) { - customToolsJson.doSave(context.getSettingsPath().resolve(IdeContext.FILE_CUSTOM_TOOLS)); + CustomToolsJsonMapper.saveJson(customToolsJson, this.context.getSettingsPath().resolve(IdeContext.FILE_CUSTOM_TOOLS)); } } + EnvironmentVariables environmentVariables = context.getVariables(); while (environmentVariables != null) { + if (environmentVariables instanceof EnvironmentVariablesPropertiesFile environmentVariablesProperties) { + updateProperties(environmentVariablesProperties); + } + environmentVariables = environmentVariables.getParent(); + } + Path templateProperties = this.context.getSettingsTemplatePath().resolve(EnvironmentVariables.LEGACY_PROPERTIES); + if (Files.exists(templateProperties)) { + EnvironmentVariablesPropertiesFile environmentVariablesProperties = new EnvironmentVariablesPropertiesFile(null, EnvironmentVariablesType.USER, + templateProperties, this.context); + updateProperties(environmentVariablesProperties); + } - if (environmentVariables instanceof EnvironmentVariablesPropertiesFile) { - if (environmentVariables.getLegacyPropertiesFilePath() == null && environmentVariables.getPropertiesFilePath() == null) { - continue; - } - Path propertiesFilePath = environmentVariables.getPropertiesFilePath(); + } + private static void updateProperties(EnvironmentVariablesPropertiesFile environmentVariables) { + Path propertiesFilePath = environmentVariables.getPropertiesFilePath(); + if (propertiesFilePath != null || environmentVariables.getLegacyPropertiesFilePath() != null) { + if (environmentVariables.getType() == EnvironmentVariablesType.SETTINGS) { // adds disabled legacySupportEnabled variable if missing in ide.properties String legacySupportEnabledName = IdeVariables.IDE_VARIABLE_SYNTAX_LEGACY_SUPPORT_ENABLED.getName(); - String legacySupportEnabled = environmentVariables.get(legacySupportEnabledName); - if (legacySupportEnabled == null && propertiesFilePath != null && propertiesFilePath.endsWith(EnvironmentVariables.LEGACY_PROPERTIES)) { + String legacySupportEnabledValue = environmentVariables.get(legacySupportEnabledName); + if (!"false".equals(legacySupportEnabledValue)) { environmentVariables.set(legacySupportEnabledName, "false", false); } - - if (propertiesFilePath != null && propertiesFilePath.endsWith(EnvironmentVariables.LEGACY_PROPERTIES)) { - environmentVariables.remove(devonCustomToolsName); - environmentVariables.save(); - } - } - environmentVariables = environmentVariables.getParent(); + if ((propertiesFilePath != null) && propertiesFilePath.endsWith(EnvironmentVariables.LEGACY_PROPERTIES)) { + environmentVariables.remove(IdeVariables.DEVON_IDE_CUSTOM_TOOLS.getName()); + } + environmentVariables.save(); } } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java index 02da25956..af5e56c40 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/DirectoryMerger.java @@ -52,6 +52,7 @@ public DirectoryMerger(IdeContext context) { TextMerger textMerger = new TextMerger(context); this.extension2mergerMap.put("name", textMerger); // intellij specific this.extension2mergerMap.put("editorconfig", textMerger); + this.extension2mergerMap.put("txt", textMerger); this.fallbackMerger = new FallbackMerger(context); } @@ -154,7 +155,7 @@ public void upgrade(Path folder) { String filename = child.getFileName().toString(); if ("replacement-patterns.properties".equals(filename)) { this.context.warning("Found obsolete file {}", child); - // Files.delete(child); + Files.delete(child); } FileMerger merger = getMerger(child); merger.upgrade(child); diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/FileMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/FileMerger.java index ba18ea0bb..ff092ddc0 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/FileMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/FileMerger.java @@ -101,7 +101,7 @@ protected boolean doUpgradeTextContent(Path workspaceFile) throws IOException { String migratedContent = upgradeWorkspaceContent(content); boolean modified = !migratedContent.equals(content); if (modified) { - Files.writeString(workspaceFile, content); + Files.writeString(workspaceFile, migratedContent); } return modified; } diff --git a/cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/XmlMerger.java b/cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/XmlMerger.java index b491739ea..48579230a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/XmlMerger.java +++ b/cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/XmlMerger.java @@ -330,7 +330,7 @@ private void checkForXmlNamespace(Document document, Path workspaceFile) { } } this.context.warning( - "The XML file {} does not contain the XML merge namespace as seems outdated. For details see:\n" + "The XML file {} does not contain the XML merge namespace and seems outdated. For details see:\n" + "https://github.com/devonfw/IDEasy/blob/main/documentation/configurator.adoc#xml-merger", workspaceFile); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomTool.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomTool.java deleted file mode 100644 index b085d0d97..000000000 --- a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomTool.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.devonfw.tools.ide.repo; - -import java.util.Set; - -import com.devonfw.tools.ide.os.OperatingSystem; -import com.devonfw.tools.ide.os.SystemArchitecture; -import com.devonfw.tools.ide.os.SystemInfo; -import com.devonfw.tools.ide.url.model.file.UrlDownloadFileMetadata; -import com.devonfw.tools.ide.version.VersionIdentifier; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * Representation of a {@link CustomTool} from a {@link CustomToolRepository}. - */ -public final class CustomTool implements UrlDownloadFileMetadata { - - private final String tool; - - private final VersionIdentifier version; - - private final String versionString; - - private final boolean osAgnostic; - - private final boolean archAgnostic; - - private final String repositoryUrl; - - private final String url; - - private final String checksum; - - private final OperatingSystem os; - - private final SystemArchitecture arch; - - /** - * The constructor. - * - * @param tool the {@link #getTool() tool}. - * @param versionString the {@link #getVersion() version}. - * @param osAgnostic the {@link #isOsAgnostic() OS-agnostic flag}. - * @param archAgnostic the {@link #isArchAgnostic() architecture-agnostic flag}. - * @param repositoryUrl the {@link #getRepositoryUrl() repository URL}. - * @param checksum the {@link #getChecksum() checksum}. - * @param systemInfo the {@link SystemInfo}. - */ - public CustomTool(String tool, String versionString, boolean osAgnostic, boolean archAgnostic, - String repositoryUrl, String checksum, SystemInfo systemInfo) { - - super(); - this.tool = tool; - this.versionString = versionString; - this.version = VersionIdentifier.of(versionString); - this.osAgnostic = osAgnostic; - this.archAgnostic = archAgnostic; - this.repositoryUrl = repositoryUrl; - int capacity = repositoryUrl.length() + 2 * tool.length() + 2 * versionString.length() + 7; - if (osAgnostic) { - this.os = null; - } else { - this.os = systemInfo.getOs(); - capacity += this.os.toString().length() + 1; - } - if (archAgnostic) { - this.arch = null; - } else { - this.arch = systemInfo.getArchitecture(); - capacity += this.arch.toString().length() + 1; - } - this.checksum = checksum; - StringBuilder sb = new StringBuilder(capacity); - sb.append(this.repositoryUrl); - char last = this.repositoryUrl.charAt(repositoryUrl.length() - 1); - if ((last != '/') && (last != '\\')) { - sb.append('/'); - } - sb.append(tool); - sb.append('/'); - sb.append(versionString); - sb.append('/'); - sb.append(tool); - sb.append('-'); - sb.append(versionString); - if (this.os != null) { - sb.append('-'); - sb.append(this.os); - } - if (this.arch != null) { - sb.append('-'); - sb.append(this.arch); - } - sb.append(".tgz"); - this.url = sb.toString(); - } - - @Override - @JsonProperty(value = "name") - public String getTool() { - - return this.tool; - } - - @Override - @JsonIgnore - public String getEdition() { - - return this.tool; - } - - @Override - @JsonIgnore - public VersionIdentifier getVersion() { - - return version; - } - - @JsonProperty(value = "version") - public String getVersionString() { - - return version.toString(); - } - - /** - * @return {@code true} if {@link OperatingSystem} agnostic, {@code false} otherwise. - */ - @JsonProperty(value = "os-agnostic") - public boolean isOsAgnostic() { - - return this.osAgnostic; - } - - /** - * @return {@code true} if {@link SystemArchitecture} agnostic, {@code false} otherwise. - */ - @JsonProperty(value = "arch-agnostic") - public boolean isArchAgnostic() { - - return this.archAgnostic; - } - - /** - * @return the repository base URL. This may be a typical URL (e.g. "https://host/path") but may also be a path in your file-system (e.g. to a mounted remote - * network drive). - */ - @JsonIgnore - public String getRepositoryUrl() { - - return this.repositoryUrl; - } - - /** - * @return the URL to the download artifact. - */ - public String getUrl() { - - return this.url; - } - - @Override - @JsonIgnore - public String getChecksum() { - - return this.checksum; - } - - @Override - @JsonIgnore - public OperatingSystem getOs() { - - return this.os; - } - - @Override - @JsonIgnore - public SystemArchitecture getArch() { - - return this.arch; - } - - @Override - @JsonIgnore - public Set getUrls() { - - return Set.of(this.url); - } - - @Override - public String toString() { - - return "CustomTool[" + this.tool + ":" + this.version + "@" + this.repositoryUrl + "]"; - } - -} diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java new file mode 100644 index 000000000..6bbe9ebc1 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java @@ -0,0 +1,26 @@ +package com.devonfw.tools.ide.repo; + +import com.devonfw.tools.ide.os.OperatingSystem; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * JSON representation of a single {@link CustomToolMetadata}. + * + * @param name the {@link CustomToolMetadata#getTool() tool name}. + * @param version the {@link CustomToolMetadata#getVersion() tool version}. + * @param osAgnostic {@code true} if {@link OperatingSystem} agnostic, {@code false} otherwise. + * @param archAgnostic {@code true} if {@link com.devonfw.tools.ide.os.SystemArchitecture} agnostic, {@code false} otherwise. + * @param url the overridden {@link CustomToolsJson#url() repository URL} or {@code null} to inherit. + * @see CustomToolsJson#tools() + */ +public record CustomToolJson(String name, String version, @JsonProperty(value = "os-agnostic") boolean osAgnostic, + @JsonProperty(value = "arch-agnostic") boolean archAgnostic, String url) { + + /** + * @return a new {@link CustomToolsJson} having {@link #url()} set to {@code null}. + */ + public CustomToolJson withoutUrl() { + + return new CustomToolJson(name, version, osAgnostic, archAgnostic, null); + } +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolMetadata.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolMetadata.java new file mode 100644 index 000000000..085492b27 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolMetadata.java @@ -0,0 +1,119 @@ +package com.devonfw.tools.ide.repo; + +import java.util.Set; + +import com.devonfw.tools.ide.os.OperatingSystem; +import com.devonfw.tools.ide.os.SystemArchitecture; +import com.devonfw.tools.ide.url.model.file.UrlDownloadFileMetadata; +import com.devonfw.tools.ide.version.VersionIdentifier; +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Representation of a {@link CustomToolMetadata} from a {@link CustomToolRepository}. + */ +public final class CustomToolMetadata implements UrlDownloadFileMetadata { + + private final String tool; + + private final VersionIdentifier version; + + private final OperatingSystem os; + + private final SystemArchitecture arch; + + private final String url; + + private final String checksum; + + private final String repositoryUrl; + + /** + * The constructor. + * + * @param tool the {@link #getTool() tool}. + * @param versionString the {@link #getVersion() version} as {@link String}. + * @param os the {@link #getOs() OS}. + * @param arch the {@link #getArch() architecture}. + * @param url the {@link #getUrl() download URL}. + * @param checksum the {@link #getChecksum() checksum}. + * @param repositoryUrl the {@link #getRepositoryUrl() repository URL}. + */ + public CustomToolMetadata(String tool, String versionString, OperatingSystem os, SystemArchitecture arch, + String url, String checksum, String repositoryUrl) { + + super(); + this.tool = tool; + this.version = VersionIdentifier.of(versionString); + this.os = os; + this.arch = arch; + this.url = url; + this.checksum = checksum; + this.repositoryUrl = repositoryUrl; + } + + @Override + public String getTool() { + + return this.tool; + } + + @Override + public String getEdition() { + + return this.tool; + } + + @Override + public VersionIdentifier getVersion() { + + return version; + } + + /** + * @return the URL to the download artifact. + */ + public String getUrl() { + + return this.url; + } + + @Override + public String getChecksum() { + + return this.checksum; + } + + @Override + public OperatingSystem getOs() { + + return this.os; + } + + @Override + public SystemArchitecture getArch() { + + return this.arch; + } + + @Override + public Set getUrls() { + + return Set.of(this.url); + } + + /** + * @return the {@link CustomToolsJson#url() repository base URL}. + */ + @JsonIgnore + public String getRepositoryUrl() { + + return this.repositoryUrl; + } + + @Override + public String toString() { + + return "CustomTool[" + this.tool + ":" + this.version + "@" + this.url + "]"; + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolRepository.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolRepository.java index 916dd1f54..bac2a6064 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolRepository.java +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolRepository.java @@ -8,8 +8,8 @@ public interface CustomToolRepository extends ToolRepository { /** - * @return the {@link Collection} with the {@link CustomTool}s. Will be {@link Collection#isEmpty() empty} if no custom tools are configured. + * @return the {@link Collection} with the {@link CustomToolMetadata}s. Will be {@link Collection#isEmpty() empty} if no custom tools are configured. */ - Collection getTools(); + Collection getTools(); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolRepositoryImpl.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolRepositoryImpl.java index b73669643..b29d87df3 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolRepositoryImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolRepositoryImpl.java @@ -1,9 +1,5 @@ package com.devonfw.tools.ide.repo; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -14,14 +10,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import jakarta.json.Json; -import jakarta.json.JsonArray; -import jakarta.json.JsonObject; -import jakarta.json.JsonReader; -import jakarta.json.JsonString; -import jakarta.json.JsonStructure; -import jakarta.json.JsonValue; -import jakarta.json.JsonValue.ValueType; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.url.model.file.UrlDownloadFileMetadata; @@ -36,24 +24,24 @@ public class CustomToolRepositoryImpl extends AbstractToolRepository implements private final String id; - private final Map toolsMap; + private final Map toolsMap; - private final Collection tools; + private final Collection tools; /** * The constructor. * * @param context the owning {@link IdeContext}. - * @param tools the {@link CustomTool}s. + * @param tools the {@link CustomToolMetadata}s. */ - public CustomToolRepositoryImpl(IdeContext context, Collection tools) { + public CustomToolRepositoryImpl(IdeContext context, Collection tools) { super(context); this.toolsMap = new HashMap<>(tools.size()); String repoId = null; - for (CustomTool tool : tools) { + for (CustomToolMetadata tool : tools) { String name = tool.getTool(); - CustomTool duplicate = this.toolsMap.put(name, tool); + CustomToolMetadata duplicate = this.toolsMap.put(name, tool); if (duplicate != null) { throw new IllegalStateException("Duplicate custom tool '" + name + "'!"); } @@ -76,7 +64,7 @@ private static String computeId(String url) { id = id.substring(schemaIndex + 3); // remove schema like "https://" id = URLDecoder.decode(id, StandardCharsets.UTF_8); } - id.replace('\\', '/').replace("//", "/"); // normalize slashes + id = id.replace('\\', '/').replace("//", "/"); // normalize slashes if (id.startsWith("/")) { id = id.substring(1); } @@ -111,7 +99,7 @@ public String getId() { @Override protected UrlDownloadFileMetadata getMetadata(String tool, String edition, VersionIdentifier version) { - CustomTool customTool = getCustomTool(tool); + CustomToolMetadata customTool = getCustomTool(tool); if (!version.equals(customTool.getVersion())) { throw new IllegalArgumentException("Undefined version '" + version + "' for custom tool '" + tool + "' - expected version '" + customTool.getVersion() + "'!"); @@ -122,8 +110,8 @@ protected UrlDownloadFileMetadata getMetadata(String tool, String edition, Versi return customTool; } - private CustomTool getCustomTool(String tool) { - CustomTool customTool = this.toolsMap.get(tool); + private CustomToolMetadata getCustomTool(String tool) { + CustomToolMetadata customTool = this.toolsMap.get(tool); if (customTool == null) { throw new IllegalArgumentException("Undefined custom tool '" + tool + "'!"); } @@ -133,7 +121,7 @@ private CustomTool getCustomTool(String tool) { @Override public VersionIdentifier resolveVersion(String tool, String edition, GenericVersionRange version) { - CustomTool customTool = getCustomTool(tool); + CustomToolMetadata customTool = getCustomTool(tool); VersionIdentifier customToolVerstion = customTool.getVersion(); if (!version.contains(customToolVerstion)) { throw new IllegalStateException(customTool + " does not satisfy version to install " + version); @@ -142,7 +130,7 @@ public VersionIdentifier resolveVersion(String tool, String edition, GenericVers } @Override - public Collection getTools() { + public Collection getTools() { return this.tools; } @@ -160,116 +148,18 @@ public Collection findDependencies(String tool, String edition, public static CustomToolRepository of(IdeContext context) { Path settingsPath = context.getSettingsPath(); - Path customToolsJson = null; + Path customToolsJsonFile = null; if (settingsPath != null) { - customToolsJson = settingsPath.resolve(IdeContext.FILE_CUSTOM_TOOLS); + customToolsJsonFile = settingsPath.resolve(IdeContext.FILE_CUSTOM_TOOLS); } - List tools = new ArrayList<>(); - if ((customToolsJson != null) && Files.exists(customToolsJson)) { - readCustomToolsFromJson(context, customToolsJson); - } - return new CustomToolRepositoryImpl(context, tools); - } - - public static CustomToolsJson readCustomToolsFromJson(IdeContext context, Path customToolsJsonPath) { - try (InputStream in = Files.newInputStream(customToolsJsonPath); - Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) { - - JsonReader jsonReader = Json.createReader(new BufferedReader(reader)); - JsonStructure json = jsonReader.read(); - JsonObject jsonRoot = requireObject(json); - String defaultUrl = getString(jsonRoot, "url", ""); - JsonArray jsonTools = requireArray(jsonRoot.get("tools")); - List customTools = new ArrayList<>(); - - for (JsonValue jsonTool : jsonTools) { - JsonObject jsonToolObject = requireObject(jsonTool); - String name = getString(jsonToolObject, "name"); - String version = getString(jsonToolObject, "version"); - String url = getString(jsonToolObject, "url", defaultUrl); - boolean osAgnostic = getBoolean(jsonToolObject, "os-agnostic", Boolean.FALSE); - boolean archAgnostic = getBoolean(jsonToolObject, "arch-agnostic", Boolean.TRUE); - if (url.isEmpty()) { - throw new IllegalStateException("Missing 'url' property for tool '" + name + "'!"); - } - // TODO - String checksum = null; - CustomTool customTool = new CustomTool(name, version, osAgnostic, archAgnostic, url, - checksum, context.getSystemInfo()); - customTools.add(customTool); - } - return new CustomToolsJson("tools", defaultUrl, customTools); - } catch (Exception e) { - throw new IllegalStateException("Failed to read JSON from " + customToolsJsonPath, e); - } - } - - private static boolean getBoolean(JsonObject json, String property, Boolean defaultValue) { - - JsonValue value = json.get(property); - if (value == null) { - if (defaultValue == null) { - throw new IllegalArgumentException("Missing string property '" + property + "' in JSON: " + json); - } - return defaultValue.booleanValue(); - } - ValueType valueType = value.getValueType(); - if (valueType == ValueType.TRUE) { - return true; - } else if (valueType == ValueType.FALSE) { - return false; + List tools; + if ((customToolsJsonFile != null) && Files.exists(customToolsJsonFile)) { + CustomToolsJson customToolsJson = CustomToolsJsonMapper.loadJson(customToolsJsonFile); + tools = CustomToolsJsonMapper.convert(customToolsJson, context); } else { - throw new IllegalStateException("Expected value type boolean but found " + valueType + " for JSON: " + json); - } - } - - private static String getString(JsonObject json, String property) { - - return getString(json, property, null); - } - - private static String getString(JsonObject json, String property, String defaultValue) { - - JsonValue value = json.get(property); - if (value == null) { - if (defaultValue == null) { - throw new IllegalArgumentException("Missing string property '" + property + "' in JSON: " + json); - } - return defaultValue; - } - require(value, ValueType.STRING); - return ((JsonString) value).getString(); - } - - /** - * @param json the {@link JsonValue} to check. - */ - private static JsonObject requireObject(JsonValue json) { - - require(json, ValueType.OBJECT); - return (JsonObject) json; - } - - /** - * @param json the {@link JsonValue} to check. - */ - private static JsonArray requireArray(JsonValue json) { - - require(json, ValueType.ARRAY); - return (JsonArray) json; - } - - /** - * @param json the {@link JsonValue} to check. - * @param type the expected {@link ValueType}. - */ - private static void require(JsonValue json, ValueType type) { - - ValueType actualType = json.getValueType(); - if (actualType != type) { - throw new IllegalStateException( - "Expected value type " + type + " but found " + actualType + " for JSON: " + json); + tools = new ArrayList<>(); } + return new CustomToolRepositoryImpl(context, tools); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJson.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJson.java index 09ee9967a..7f8a8b19d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJson.java +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJson.java @@ -1,142 +1,14 @@ package com.devonfw.tools.ide.repo; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; -import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.environment.VariableLine; -import com.devonfw.tools.ide.os.SystemInfo; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.databind.ObjectMapper; - /** * {@link CustomToolsJson} for the ide-custom-tools.json file. + * + * @param url the repository base URL. This may be a typical URL (e.g. "https://host/path") but may also be a path in your file-system (e.g. to a mounted + * remote network drive). + * @param tools the {@link List} of {@link CustomToolJson}. */ -public record CustomToolsJson(@JsonIgnore String title, String url, List tools) { - - private static final ObjectMapper MAPPER = new ObjectMapper(); - - /** - * Retrieves custom tools from a devonfw-ide legacy config. - * - * @param customToolsContent String of custom tools - * @param context the {@link IdeContext}. - * @return {@link CustomToolsJson}. - */ - public static CustomToolsJson retrieveCustomToolsFromLegacyConfig(String customToolsContent, IdeContext context) { - List tools = VariableLine.parseArray(customToolsContent); - - if (!tools.isEmpty()) { - List customToolJsonList = new ArrayList<>(); - Tool toolObject = parseTool(tools.get(0), ""); - String defaultUrl = ""; - if (toolObject != null) { - defaultUrl = toolObject.url(); - } - - if (!defaultUrl.isEmpty()) { - for (String tool : tools) { - customToolJsonList.add(createCustomToolFromString(tool, defaultUrl, context.getSystemInfo())); - } - - return new CustomToolsJson("tools", defaultUrl, customToolJsonList); - } - - } - return null; - } - - // TODO: move to separate file - private record Tool(String name, String version, boolean osAgnostic, boolean archAgnostic, String url) { - - } - - private static CustomTool createCustomToolFromString(String tool, String defaultUrl, SystemInfo systemInfo) { - Tool toolObject = parseTool(tool, defaultUrl); - String toolName = ""; - String version = ""; - boolean osAgnostic = false; - boolean archAgnostic = false; - String url = ""; - if (toolObject != null) { - toolName = toolObject.name(); - version = toolObject.version(); - osAgnostic = toolObject.osAgnostic(); - archAgnostic = toolObject.archAgnostic(); - url = toolObject.url(); - } - String checksum = ""; - - return new CustomTool(toolName, version, osAgnostic, archAgnostic, url, checksum, - systemInfo); - } - - private static Tool parseTool(String tool, String defaultUrl) { - int firstColon = tool.indexOf(":"); - if (firstColon < 0) { - return null; - } - String toolName = tool.substring(0, firstColon); - int secondColon = tool.indexOf(":", firstColon + 1); - if (secondColon < 0) { - return null; - } - String version = tool.substring(firstColon + 1, secondColon); - int thirdColon = tool.indexOf(":", secondColon + 1); - boolean osAgnostic = false; - boolean archAgnostic = false; - if (thirdColon < 0) { - return new Tool(toolName, version, osAgnostic, archAgnostic, defaultUrl); - } - String isAgnostic = tool.substring(secondColon + 1, thirdColon); - if (isAgnostic.equals("all")) { - osAgnostic = true; - archAgnostic = true; - } - int fourthColon = tool.indexOf(":", thirdColon + 1); - if (fourthColon < 0) { - return null; - } - String url = parseToolUrl(tool, thirdColon + 1); - if (url == null) { - url = defaultUrl; - } - - return new Tool(toolName, version, osAgnostic, archAgnostic, url); - } - - private static String parseToolUrl(String tool, int index) { - String url = tool.substring(index); - if (url.isEmpty()) { - return null; - } - return url; - } - - - public void doSave(Path path) { - - try (BufferedWriter writer = Files.newBufferedWriter(path)) { - MAPPER.writerWithDefaultPrettyPrinter().writeValue(writer, this); - } catch (Exception e) { - throw new IllegalStateException("Failed to save file " + path, e); - } - } - - public CustomToolsJson doLoad(Path path) { - CustomToolsJson customToolsJson = null; - if (Files.exists(path)) { - try (BufferedReader reader = Files.newBufferedReader(path)) { - customToolsJson = MAPPER.readValue(reader, CustomToolsJson.class); - } catch (Exception e) { - throw new IllegalStateException("Failed to load " + path, e); - } - } - return customToolsJson; - } +public record CustomToolsJson(String url, List tools) { } diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonMapper.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonMapper.java new file mode 100644 index 000000000..192432dee --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonMapper.java @@ -0,0 +1,186 @@ +package com.devonfw.tools.ide.repo; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.environment.VariableLine; +import com.devonfw.tools.ide.json.JsonMapping; +import com.devonfw.tools.ide.os.OperatingSystem; +import com.devonfw.tools.ide.os.SystemArchitecture; +import com.devonfw.tools.ide.os.SystemInfo; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Mapper of {@link CustomToolsJson} from/to JSON. + */ +public class CustomToolsJsonMapper { + + private static final ObjectMapper MAPPER = JsonMapping.create(); + + /** + * @param customTools the {@link CustomToolsJson} to save. + * @param path the {@link Path} of the file where to save as JSON. + */ + public static void saveJson(CustomToolsJson customTools, Path path) { + + try (BufferedWriter writer = Files.newBufferedWriter(path)) { + MAPPER.writerWithDefaultPrettyPrinter().writeValue(writer, customTools); + } catch (Exception e) { + throw new IllegalStateException("Failed to save file " + path, e); + } + } + + /** + * @param path the {@link Path} of the JSON file to load. + * @return the parsed {@link CustomToolsJson} or {@code null} if the {@link Path} is not an existing file. + */ + public static CustomToolsJson loadJson(Path path) { + CustomToolsJson customToolsJson = null; + if (Files.isRegularFile(path)) { + try (BufferedReader reader = Files.newBufferedReader(path)) { + customToolsJson = MAPPER.readValue(reader, CustomToolsJson.class); + } catch (Exception e) { + throw new IllegalStateException("Failed to load " + path, e); + } + } + return customToolsJson; + } + + /** + * @param customTools the {@link CustomToolsJson} to convert. + * @param context the {@link IdeContext}. + * @return the converted {@link List} of {@link CustomToolMetadata}. + */ + public static List convert(CustomToolsJson customTools, IdeContext context) { + + String repositoryUrl = customTools.url(); + List tools = customTools.tools(); + List result = new ArrayList<>(tools.size()); + for (CustomToolJson customTool : tools) { + result.add(convert(customTool, repositoryUrl, context)); + } + return result; + } + + private static CustomToolMetadata convert(CustomToolJson customTool, String repositoryUrl, IdeContext context) { + + String tool = customTool.name(); + String version = customTool.version(); + SystemInfo systemInfo = context.getSystemInfo(); + String repoUrl = customTool.url(); + if ((repoUrl == null) || repoUrl.isEmpty()) { + repoUrl = repositoryUrl; + } + int capacity = repoUrl.length() + 2 * tool.length() + 2 * version.length() + 7; + OperatingSystem os; + if (customTool.osAgnostic()) { + os = null; + } else { + os = systemInfo.getOs(); + capacity += os.toString().length() + 1; + } + SystemArchitecture arch; + if (customTool.archAgnostic()) { + arch = null; + } else { + arch = systemInfo.getArchitecture(); + capacity += arch.toString().length() + 1; + } + StringBuilder sb = new StringBuilder(capacity); + sb.append(repoUrl); + char last = repoUrl.charAt(repoUrl.length() - 1); + if ((last != '/') && (last != '\\')) { + sb.append('/'); + } + sb.append(tool); + sb.append('/'); + sb.append(version); + sb.append('/'); + sb.append(tool); + sb.append('-'); + sb.append(version); + if (os != null) { + sb.append('-'); + sb.append(os); + } + if (arch != null) { + sb.append('-'); + sb.append(arch); + } + sb.append(".tgz"); + String url = sb.toString(); + return new CustomToolMetadata(tool, version, os, arch, url, null, repoUrl); + } + + /** + * Retrieves custom tools from a devonfw-ide legacy config. + * + * @param customToolsContent String of custom tools + * @param context the {@link IdeContext}. + * @return {@link CustomToolsJson}. + */ + public static CustomToolsJson parseCustomToolsFromLegacyConfig(String customToolsContent, IdeContext context) { + List customToolEntries = VariableLine.parseArray(customToolsContent); + if (customToolEntries.isEmpty()) { + return null; + } + List customTools = new ArrayList<>(customToolEntries.size()); + String defaultUrl = null; + for (String customToolConfig : customToolEntries) { + CustomToolJson customToolJson = parseCustomToolFromLegacyConfig(customToolConfig); + if (customToolJson == null) { + context.warning("Invalid custom tool entry: {}", customToolConfig); + } else { + String url = customToolJson.url(); + if (defaultUrl == null) { + if (url.isEmpty()) { + context.warning("First custom tool entry has no URL specified: {}", customToolConfig); + } else { + defaultUrl = url; + customToolJson = customToolJson.withoutUrl(); + } + } else if (defaultUrl.equals(url)) { + customToolJson = customToolJson.withoutUrl(); + } + customTools.add(customToolJson); + } + } + if (customTools.isEmpty() || (defaultUrl == null)) { + return null; + } + return new CustomToolsJson(defaultUrl, customTools); + } + + private static CustomToolJson parseCustomToolFromLegacyConfig(String customToolConfig) { + int firstColon = customToolConfig.indexOf(":"); + if (firstColon < 0) { + return null; + } + String toolName = customToolConfig.substring(0, firstColon); + int secondColon = customToolConfig.indexOf(":", firstColon + 1); + if (secondColon < 0) { + return null; + } + String version = customToolConfig.substring(firstColon + 1, secondColon); + int thirdColon = customToolConfig.indexOf(":", secondColon + 1); + boolean osAgnostic = false; + boolean archAgnostic = false; + String url = null; + if (thirdColon > 0) { + if (customToolConfig.substring(secondColon + 1, thirdColon).equals("all")) { + osAgnostic = true; + archAgnostic = true; + url = customToolConfig.substring(thirdColon + 1); + } else { + url = customToolConfig.substring(secondColon + 1); + } + } + return new CustomToolJson(toolName, version, osAgnostic, archAgnostic, url); + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/CustomToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/CustomToolCommandlet.java index acb4cb1ad..3a0be1d2f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/CustomToolCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/CustomToolCommandlet.java @@ -1,17 +1,17 @@ package com.devonfw.tools.ide.tool; import com.devonfw.tools.ide.context.IdeContext; -import com.devonfw.tools.ide.repo.CustomTool; +import com.devonfw.tools.ide.repo.CustomToolMetadata; import com.devonfw.tools.ide.version.VersionIdentifier; /** - * {@link LocalToolCommandlet} for a {@link CustomTool}. + * {@link LocalToolCommandlet} for a {@link CustomToolMetadata}. */ public class CustomToolCommandlet extends LocalToolCommandlet { - private CustomTool customTool; + private CustomToolMetadata customTool; - public CustomToolCommandlet(IdeContext context, CustomTool customTool) { + public CustomToolCommandlet(IdeContext context, CustomToolMetadata customTool) { super(context, customTool.getTool(), null); this.customTool = customTool; diff --git a/cli/src/test/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandletTest.java index c0a7b9b6e..518d4858b 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandletTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandletTest.java @@ -3,9 +3,10 @@ import java.nio.file.Files; import java.nio.file.Path; -import org.junit.Test; +import org.junit.jupiter.api.Test; import com.devonfw.tools.ide.context.AbstractIdeContextTest; +import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.context.IdeTestContext; /** @@ -13,10 +14,9 @@ */ public class UpgradeSettingsCommandletTest extends AbstractIdeContextTest { - private static final Path UPGRADESETTINGS_PATH = Path.of("target/test-projects/upgrade-settings/project/"); - - private static final String PROJECT_UPGRADESETTINGS = "upgrade-settings"; - private final IdeTestContext context = newContext(PROJECT_UPGRADESETTINGS); + private static final String PROJECT_UPGRADE_SETTINGS = "upgrade-settings"; + private final IdeTestContext context = newContext(PROJECT_UPGRADE_SETTINGS); + private static final Path UPGRADE_SETTINGS_PATH = TEST_PROJECTS_COPY.resolve(PROJECT_UPGRADE_SETTINGS).resolve("project"); /** * Ensure that all devon.properties are renamed to ide.properties and that the variables inside have been adjusted. @@ -28,37 +28,32 @@ public void testDevonPropertiesUpgrade() { // act upgradeSettingsCommandlet.run(); // assert that files where renamed - assertThat(Files.exists(UPGRADESETTINGS_PATH.resolve("conf/ide.properties"))).isTrue(); - assertThat(Files.exists(UPGRADESETTINGS_PATH.resolve("settings/ide.properties"))).isTrue(); - assertThat(Files.exists(UPGRADESETTINGS_PATH.resolve("workspaces/main/ide.properties"))).isTrue(); + assertThat(Files.exists(UPGRADE_SETTINGS_PATH.resolve("conf/ide.properties"))).isTrue(); + assertThat(Files.exists(UPGRADE_SETTINGS_PATH.resolve("settings/ide.properties"))).isTrue(); + assertThat(Files.exists(UPGRADE_SETTINGS_PATH.resolve("workspaces/main/ide.properties"))).isTrue(); //assert that file content was changed - assertThat(UPGRADESETTINGS_PATH.resolve("conf/ide.properties")).content() + assertThat(UPGRADE_SETTINGS_PATH.resolve("conf/ide.properties")).content() .isEqualTo("#********************************************************************************\n" + "# This file contains project specific environment variables defined by the user\n" + "#********************************************************************************\n" + "\n" - + "MVN_VERSION=test\n" - + "\n" - + "HOME_DIR=test\n" - + "IDE_HOME=test\n" - + "JAVA_VERSION=test\n" - + "IDE_VARIABLE_SYNTAX_LEGACY_SUPPORT_ENABLED=false"); + + "MVN_VERSION=test\n"); } /** * Ensure that the custom-tools.json was created with the correct content. */ @Test - public void testCustomJsonFileCreation() { + public void testCustomJsonFileCreation() throws Exception { // arrange UpgradeSettingsCommandlet upgradeSettingsCommandlet = new UpgradeSettingsCommandlet(context); // act upgradeSettingsCommandlet.run(); - // assert that custom-tools exists - assertThat(Files.exists(UPGRADESETTINGS_PATH.resolve("settings/custom-tools.json"))).isTrue(); - //assert that custom-tools has the correct content - assertThat(UPGRADESETTINGS_PATH.resolve("settings/custom-tools.json")).content().isEqualTo( - "{\"tools\":[{\"os-agnostic\":true,\"arch-agnostic\":true,\"name\":\"jboss-eap\",\"version\":\"7.1.4.GA\"},{\"os-agnostic\":false,\"arch-agnostic\":false,\"name\":\"firefox\",\"version\":\"70.0.1\"}],\"url\":\"https:\\/\\/host.tld\\/projects\\/my-project\"}"); + // assert + Path customToolsJsonFile = UPGRADE_SETTINGS_PATH.resolve("settings").resolve(IdeContext.FILE_CUSTOM_TOOLS); + assertThat(customToolsJsonFile).exists(); + assertThat(Files.readString(customToolsJsonFile).replace("\r", "").replace("\n", "").replace(" ", "")).isEqualTo( + "{\"url\":\"https://host.tld/projects/my-project\",\"tools\":[{\"name\":\"jboss-eap\",\"version\":\"7.1.4.GA\",\"os-agnostic\":true,\"arch-agnostic\":true},{\"name\":\"firefox\",\"version\":\"70.0.1\",\"os-agnostic\":false,\"arch-agnostic\":false}]}"); } /** @@ -71,8 +66,8 @@ public void testIfFolderAreRenamed() { // act upgradeSettingsCommandlet.run(); //assert - assertThat(Files.isDirectory(UPGRADESETTINGS_PATH.resolve("settings/templates"))).isTrue(); - assertThat(Files.isDirectory(UPGRADESETTINGS_PATH.resolve("settings/repositories"))).isTrue(); + assertThat(UPGRADE_SETTINGS_PATH.resolve("settings/templates/ide.properties")).exists(); + assertThat(UPGRADE_SETTINGS_PATH.resolve("settings/repositories")).isDirectory(); } /** @@ -85,7 +80,7 @@ public void testIfVariableSyntaxIsChanged() { // act upgradeSettingsCommandlet.run(); //assert - assertThat(UPGRADESETTINGS_PATH.resolve("settings/workspace/testVariableSyntax")).content().isEqualTo("$[IDE_HOME]\n" + assertThat(UPGRADE_SETTINGS_PATH.resolve("settings/workspace/testVariableSyntax.txt")).content().isEqualTo("$[IDE_HOME]\n" + "This is a test text,this is a test text,this is a test text,this is a test text,\n" + "this is a test text,\n" + "this is a test text,$[MVN_VERSION]this is a test text,this is a test text,$[IDE_HOME]/settings\n" @@ -99,12 +94,13 @@ public void testIfVariableSyntaxIsChanged() { public void testLoggingOfXmlFiles() { // arrange UpgradeSettingsCommandlet upgradeSettingsCommandlet = new UpgradeSettingsCommandlet(context); + Path workspace = UPGRADE_SETTINGS_PATH.resolve(IdeContext.FOLDER_SETTINGS).resolve("intellij").resolve(IdeContext.FOLDER_WORKSPACE).resolve("TestXml.xml") + .toAbsolutePath(); // act upgradeSettingsCommandlet.run(); //assert - assertThat(context).logAtWarning().hasMessageContaining( - "The XML file C:\\projects\\IDEasy\\workspaces\\main\\IDEasy\\cli\\target\\test-projects\\upgrade-settings\\project\\settings\\intellij\\workspace\\TestXml.xml does not contain the required 'xmlns:merge' attribute."); - assertThat(context).logAtWarning() - .hasMessageContaining("For further information, please visit https://github.com/devonfw/IDEasy/blob/main/documentation/configurator.adoc#xml-merger"); + assertThat(context).logAtWarning().hasMessage( + "The XML file " + workspace + " does not contain the XML merge namespace and seems outdated. For details see:\n" + + "https://github.com/devonfw/IDEasy/blob/main/documentation/configurator.adoc#xml-merger"); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java index 39a0f0016..943145513 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java @@ -28,7 +28,7 @@ public abstract class AbstractIdeContextTest extends Assertions { protected static final Path TEST_PROJECTS = TEST_RESOURCES.resolve("ide-projects"); // will not use eclipse-target like done in maven via eclipse profile... - private static final Path TEST_PROJECTS_COPY = Path.of("target/test-projects"); + protected static final Path TEST_PROJECTS_COPY = Path.of("target/test-projects"); /** Chunk size to use for progress bars **/ private static final int CHUNK_SIZE = 1024; diff --git a/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolMetadataTest.java b/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolMetadataTest.java new file mode 100644 index 000000000..d98183157 --- /dev/null +++ b/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolMetadataTest.java @@ -0,0 +1,68 @@ +package com.devonfw.tools.ide.repo; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.devonfw.tools.ide.os.OperatingSystem; +import com.devonfw.tools.ide.os.SystemArchitecture; +import com.devonfw.tools.ide.version.VersionIdentifier; + +/** + * Test of {@link CustomToolMetadata}. + */ +public class CustomToolMetadataTest extends Assertions { + + /** + * Test of {@link CustomToolMetadata}. + */ + @Test + public void testAgnostic() { + + // arrange + String name = "jboss-eap"; + String version = "7.4.5.GA"; + String repositoryUrl = "https://host.domain.tld:8443/folder/repo/"; + String url = repositoryUrl + "jboss-eap/7.4.5.GA/jboss-eap-7.4.5.GA.tgz"; + String checksum = "4711"; + OperatingSystem os = null; + SystemArchitecture arch = null; + // act + CustomToolMetadata tool = new CustomToolMetadata(name, version, os, arch, url, checksum, repositoryUrl); + // assert + assertThat(tool.getTool()).isEqualTo(name); + assertThat(tool.getVersion()).isEqualTo(VersionIdentifier.of(version)); + assertThat(tool.getOs()).isEqualTo(os); + assertThat(tool.getArch()).isEqualTo(arch); + assertThat(tool.getUrl()).isEqualTo(url); + assertThat(tool.getChecksum()).isEqualTo(checksum); + assertThat(tool.getRepositoryUrl()).isEqualTo(repositoryUrl); + } + + /** + * Test of {@link CustomToolMetadata}. + */ + @Test + public void testSpecific() { + + // arrange + String name = "firefox"; + String version = "70.0.1"; + String repositoryUrl = "https://host.domain.tld:8443/folder/repo"; + String url = repositoryUrl + "/firefox/70.0.1/firefox-70.0.1-windows.tgz"; + String checksum = "4711"; + OperatingSystem os = OperatingSystem.MAC; + SystemArchitecture arch = SystemArchitecture.ARM64; + // act + CustomToolMetadata tool = new CustomToolMetadata(name, version, os, arch, url, checksum, repositoryUrl); + // assert + assertThat(tool.getTool()).isEqualTo(name); + assertThat(tool.getVersion()).isEqualTo(VersionIdentifier.of(version)); + assertThat(tool.getOs()).isEqualTo(os); + assertThat(tool.getArch()).isEqualTo(arch); + assertThat(tool.getUrl()).isEqualTo(url); + assertThat(tool.getChecksum()).isEqualTo(checksum); + assertThat(tool.getRepositoryUrl()).isEqualTo(repositoryUrl); + } + + +} diff --git a/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolTest.java b/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolTest.java deleted file mode 100644 index 305d5e56d..000000000 --- a/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.devonfw.tools.ide.repo; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -import com.devonfw.tools.ide.os.SystemInfoMock; - -/** - * Test of {@link CustomTool}. - */ -public class CustomToolTest extends Assertions { - - /** - * Test of {@link CustomTool}. - */ - @Test - public void testAgnostic() { - - // arrange - String name = "jboss-eap"; - String version = "7.4.5.GA"; - String repositoryUrl = "https://host.domain.tld:8443/folder/repo"; - String checksum = "4711"; - boolean osAgnostic = true; - boolean archAgnostic = true; - // act - CustomTool tool = new CustomTool(name, version, osAgnostic, archAgnostic, repositoryUrl, checksum, null); - // assert - assertThat(tool.getTool()).isEqualTo(name); - assertThat(tool.getVersionString()).isEqualTo(version); - assertThat(tool.isOsAgnostic()).isEqualTo(osAgnostic); - assertThat(tool.isArchAgnostic()).isEqualTo(archAgnostic); - assertThat(tool.getRepositoryUrl()).isEqualTo(repositoryUrl); - assertThat(tool.getUrl()).isEqualTo( - "https://host.domain.tld:8443/folder/repo/jboss-eap/7.4.5.GA/jboss-eap-7.4.5.GA.tgz"); - assertThat(tool.getChecksum()).isEqualTo(checksum); - } - - /** - * Test of {@link CustomTool}. - */ - @Test - public void testSpecific() { - - // arrange - String name = "firefox"; - String version = "70.0.1"; - String repositoryUrl = "https://host.domain.tld:8443/folder/repo"; - String checksum = "4711"; - boolean osAgnostic = false; - boolean archAgnostic = true; - // act - CustomTool tool = new CustomTool(name, version, osAgnostic, archAgnostic, repositoryUrl, checksum, - SystemInfoMock.WINDOWS_X64); - // assert - assertThat(tool.getTool()).isEqualTo(name); - assertThat(tool.getVersionString()).isEqualTo(version); - assertThat(tool.isOsAgnostic()).isEqualTo(osAgnostic); - assertThat(tool.isArchAgnostic()).isEqualTo(archAgnostic); - assertThat(tool.getRepositoryUrl()).isEqualTo(repositoryUrl); - assertThat(tool.getUrl()).isEqualTo( - "https://host.domain.tld:8443/folder/repo/firefox/70.0.1/firefox-70.0.1-windows.tgz"); - assertThat(tool.getChecksum()).isEqualTo(checksum); - } - - -} diff --git a/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolsJsonTest.java b/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolsJsonMapperTest.java similarity index 62% rename from cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolsJsonTest.java rename to cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolsJsonMapperTest.java index 9bf0386fc..8baf84e60 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolsJsonTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/repo/CustomToolsJsonMapperTest.java @@ -1,6 +1,7 @@ package com.devonfw.tools.ide.repo; import java.nio.file.Path; +import java.util.List; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; @@ -13,9 +14,9 @@ import com.devonfw.tools.ide.os.SystemInfoMock; /** - * Test of {@link CustomToolsJson}. + * Test of {@link CustomToolsJsonMapper}. */ -public class CustomToolsJsonTest extends Assertions { +public class CustomToolsJsonMapperTest extends Assertions { @Test public void testReadCustomToolsFromJson() { @@ -25,12 +26,13 @@ public void testReadCustomToolsFromJson() { context.setSystemInfo(systemInfo); Path testPath = Path.of("src/test/resources/customtools"); // act - CustomToolsJson customToolsJson = CustomToolRepositoryImpl.readCustomToolsFromJson(context, testPath.resolve("ide-custom-tools.json")); + CustomToolsJson customToolsJson = CustomToolsJsonMapper.loadJson(testPath.resolve("ide-custom-tools.json")); + List customToolsMetadata = CustomToolsJsonMapper.convert(customToolsJson, context); // assert assertThat(customToolsJson.url()).isEqualTo("https://some-file-server.company.com/projects/my-project"); - assertThat(customToolsJson.tools().get(0).getUrl()).isEqualTo( + assertThat(customToolsMetadata.get(0).getUrl()).isEqualTo( "https://some-file-server.company.com/projects/my-project/jboss-eap/7.1.4.GA/jboss-eap-7.1.4.GA.tgz"); - assertThat(customToolsJson.tools().get(1).getUrl()).isEqualTo( + assertThat(customToolsMetadata.get(1).getUrl()).isEqualTo( "https://some-file-server.company.com/projects/my-project2/firefox/70.0.1/firefox-70.0.1-linux-x64.tgz"); } @@ -38,15 +40,16 @@ public void testReadCustomToolsFromJson() { public void testReadCustomToolsFromLegacyConfig() { // arrange IdeContext context = new IdeTestContext(); - String legacyProperties = "(jboss-eap:7.1.4.GA:all:https://host.tld/projects/my-project firefox:70.0.1:all:https://host.tld/projects/my-project2)"; + String legacyProperties = "(jboss-eap:7.1.4.GA:all:https://host.tld/projects/my-project firefox:70.0.1:all:)"; // act - CustomToolsJson customToolsJson = CustomToolsJson.retrieveCustomToolsFromLegacyConfig(legacyProperties, context); + CustomToolsJson customToolsJson = CustomToolsJsonMapper.parseCustomToolsFromLegacyConfig(legacyProperties, context); + List customToolsMetadata = CustomToolsJsonMapper.convert(customToolsJson, context); // assert assertThat(customToolsJson.url()).isEqualTo("https://host.tld/projects/my-project"); - assertThat(customToolsJson.tools().get(0).getUrl()).isEqualTo( + assertThat(customToolsMetadata.get(0).getUrl()).isEqualTo( "https://host.tld/projects/my-project/jboss-eap/7.1.4.GA/jboss-eap-7.1.4.GA.tgz"); - assertThat(customToolsJson.tools().get(1).getUrl()).isEqualTo( - "https://host.tld/projects/my-project2/firefox/70.0.1/firefox-70.0.1.tgz"); + assertThat(customToolsMetadata.get(1).getUrl()).isEqualTo( + "https://host.tld/projects/my-project/firefox/70.0.1/firefox-70.0.1.tgz"); } @Test @@ -55,7 +58,7 @@ public void testReadEmptyCustomToolsFromLegacyConfig() { IdeContext context = new IdeTestContext(); String legacyProperties = "()"; // act - CustomToolsJson customToolsJson = CustomToolsJson.retrieveCustomToolsFromLegacyConfig(legacyProperties, context); + CustomToolsJson customToolsJson = CustomToolsJsonMapper.parseCustomToolsFromLegacyConfig(legacyProperties, context); // assert assertThat(customToolsJson).isNull(); } @@ -66,7 +69,7 @@ public void testReadFaultyCustomToolsFromLegacyConfig() { IdeContext context = new IdeTestContext(); String legacyProperties = "(jboss-eap:7.1.4.GA:all)"; // act - CustomToolsJson customToolsJson = CustomToolsJson.retrieveCustomToolsFromLegacyConfig(legacyProperties, context); + CustomToolsJson customToolsJson = CustomToolsJsonMapper.parseCustomToolsFromLegacyConfig(legacyProperties, context); // assert assertThat(customToolsJson).isNull(); } diff --git a/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/devon.properties b/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/devon.properties index 739677d82..db57079d1 100644 --- a/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/devon.properties +++ b/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/devon.properties @@ -4,16 +4,6 @@ JAVA_VERSION=17* MVN_VERSION=3.9.0 ECLIPSE_VERSION=2023-03 -INTELLIJ_EDITION=ultimate -IDE_TOOLS=mvn,eclipse -BAR=bar-${SOME} -TEST_ARGS1=${TEST_ARGS1} settings1 -TEST_ARGS4=${TEST_ARGS4} settings4 -TEST_ARGS5=${TEST_ARGS5} settings5 -TEST_ARGS6=${TEST_ARGS6} settings6 -TEST_ARGS7=${TEST_ARGS7} settings7 -TEST_ARGS8=settings8 -TEST_ARGS9=settings9 -TEST_ARGSb=${TEST_ARGS10} settingsb ${TEST_ARGSa} ${TEST_ARGSb} -TEST_ARGSc=${TEST_ARGSc} settingsc +INTELLIJ_EDITION_TYPE=U +DEVON_IDE_TOOLS=(mvn eclipse) DEVON_IDE_CUSTOM_TOOLS=(jboss-eap:7.1.4.GA:all:https://host.tld/projects/my-project firefox:70.0.1:) diff --git a/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/devon/devon.properties b/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/devon/devon.properties new file mode 100644 index 000000000..84fbccc23 --- /dev/null +++ b/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/devon/devon.properties @@ -0,0 +1,4 @@ +#******************************************************************************** +# This file contains project specific environment variables defined by the user +#******************************************************************************** +M2_REPO=~/.m2/repository diff --git a/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/projects/IDEasy.properties b/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/projects/IDEasy.properties new file mode 100644 index 000000000..ca321ca01 --- /dev/null +++ b/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/projects/IDEasy.properties @@ -0,0 +1,5 @@ +path=IDEasy +git_url=https://github.com/devonfw/IDEasy.git +git_branch=main +eclipse=import +active=false diff --git a/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/workspace/testVariableSyntax b/cli/src/test/resources/ide-projects/upgrade-settings/project/settings/workspace/testVariableSyntax.txt similarity index 100% rename from cli/src/test/resources/ide-projects/upgrade-settings/project/settings/workspace/testVariableSyntax rename to cli/src/test/resources/ide-projects/upgrade-settings/project/settings/workspace/testVariableSyntax.txt