diff --git a/.mvn/maven.config b/.mvn/maven.config index 18f1acba3..70a680831 100644 --- a/.mvn/maven.config +++ b/.mvn/maven.config @@ -1 +1 @@ --Drevision=2025.01.001-beta-SNAPSHOT +-Drevision=2025.01.002-beta-SNAPSHOT diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index f03264c85..e2b632fc5 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -6,16 +6,20 @@ 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/790[#790]: Fix intellij plugin installation * https://github.com/devonfw/IDEasy/issues/915[#915]: custom-tools not working * https://github.com/devonfw/IDEasy/issues/916[#916]: download is missing status code error handling * https://github.com/devonfw/IDEasy/issues/757[#757]: Support to allow settings in code repository * https://github.com/devonfw/IDEasy/issues/826[#826]: Fix git settings check when settings folder is empty * https://github.com/devonfw/IDEasy/issues/898[#898]: Improved output of get-version/edition and uninstall/-plugin -* https://github.com/devonfw/IDEasy/issues/894[#894]: Fix ide.bat printing for initialization and error output +* https://github.com/devonfw/IDEasy/issues/894[#894]: ide.bat not printing if IDEasy was initialized * https://github.com/devonfw/IDEasy/issues/759[#759]: Add UpgradeSettingsCommandlet for the upgrade of legacy devonfw-ide settings to IDEasy * https://github.com/devonfw/IDEasy/issues/498[#498]: Improvement of XML merger: resolve before merge * https://github.com/devonfw/IDEasy/issues/691[#691]: XMLMerger can not handle merge of subnodes properly * https://github.com/devonfw/IDEasy/issues/815[#815]: Links within IDEasy.pdf generally do not work +* https://github.com/devonfw/IDEasy/issues/914[#914]: Setup needs to create .bashrc if not existent +* https://github.com/devonfw/IDEasy/issues/853[#853]: NPE when trying to auto-complete after ide repository +* https://github.com/devonfw/IDEasy/issues/734[#734]: Improve ProcessResult: get out and err in order 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]. @@ -36,7 +40,6 @@ Then run the `setup` and all should work fine. Release with new features and bugfixes: -* https://github.com/devonfw/IDEasy/issues/734[#734]: Improve ProcessResult: get out and err in order * https://github.com/devonfw/IDEasy/issues/764[#764]: Fix IDEasy in CMD * https://github.com/devonfw/IDEasy/issues/774[#774]: HTTP proxy support not working properly * https://github.com/devonfw/IDEasy/issues/792[#792]: Honor new variable IDE_OPTIONS in ide command wrapper diff --git a/cli/src/main/java/com/devonfw/tools/ide/json/JsonMapping.java b/cli/src/main/java/com/devonfw/tools/ide/json/JsonMapping.java index deac9067b..9756c680a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/json/JsonMapping.java +++ b/cli/src/main/java/com/devonfw/tools/ide/json/JsonMapping.java @@ -1,5 +1,11 @@ package com.devonfw.tools.ide.json; +import com.devonfw.tools.ide.repo.CustomToolJson; +import com.devonfw.tools.ide.repo.CustomToolJsonDeserializer; +import com.devonfw.tools.ide.repo.CustomToolJsonSerializer; +import com.devonfw.tools.ide.repo.CustomToolsJson; +import com.devonfw.tools.ide.repo.CustomToolsJsonDeserializer; +import com.devonfw.tools.ide.repo.CustomToolsJsonSerializer; import com.devonfw.tools.ide.url.model.file.json.ToolDependency; import com.devonfw.tools.ide.version.VersionIdentifier; import com.devonfw.tools.ide.version.VersionRange; @@ -30,6 +36,10 @@ public static ObjectMapper create() { customModule.addDeserializer(VersionIdentifier.class, new VersionIdentifierDeserializer()); customModule.addDeserializer(VersionRange.class, new VersionRangeDeserializer()); customModule.addDeserializer(ToolDependency.class, new ToolDependencyDeserializer()); + customModule.addDeserializer(CustomToolJson.class, new CustomToolJsonDeserializer()); + customModule.addDeserializer(CustomToolsJson.class, new CustomToolsJsonDeserializer()); + customModule.addSerializer(CustomToolJson.class, new CustomToolJsonSerializer()); + customModule.addSerializer(CustomToolsJson.class, new CustomToolsJsonSerializer()); customModule.addKeyDeserializer(VersionRange.class, new VersionRangeKeyDeserializer()); mapper = mapper.registerModule(customModule); return mapper; 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 index 6bbe9ebc1..92503e962 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java @@ -1,7 +1,6 @@ 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}. @@ -13,8 +12,22 @@ * @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) { +public record CustomToolJson(String name, String version, boolean osAgnostic, boolean archAgnostic, String url) { + + /** JSON property name for {@link #name()}. */ + public static final String PROPERTY_NAME = "name"; + + /** JSON property name for {@link #version()}. */ + public static final String PROPERTY_VERSION = "version"; + + /** JSON property name for {@link #osAgnostic()}. */ + public static final String PROPERTY_OS_AGNOSTIC = "os-agnostic"; + + /** JSON property name for {@link #archAgnostic()}. */ + public static final String PROPERTY_ARCH_AGNOSTIC = "arch-agnostic"; + + /** JSON property name for {@link #url()}. */ + public static final String PROPERTY_URL = "url"; /** * @return a new {@link CustomToolsJson} having {@link #url()} set to {@code null}. diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonDeserializer.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonDeserializer.java new file mode 100644 index 000000000..ee159b20f --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonDeserializer.java @@ -0,0 +1,71 @@ +package com.devonfw.tools.ide.repo; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +/** + * {@link JsonDeserializer} for {@link CustomToolJson}. + */ +public class CustomToolJsonDeserializer extends JsonDeserializer { + + private static final String INVALID_CUSTOM_TOOL = "Invalid JSON for custom tool!"; + + @Override + public CustomToolJson deserialize(JsonParser p, DeserializationContext context) throws IOException { + + JsonToken token = p.getCurrentToken(); + if (token == JsonToken.START_OBJECT) { + token = p.nextToken(); + String name = null; + String version = null; + boolean osAgnostic = true; + boolean archAgnostic = true; + String url = null; + while (token == JsonToken.FIELD_NAME) { + String property = p.currentName(); + if (property.equals(CustomToolJson.PROPERTY_NAME)) { + token = p.nextToken(); + assert token == JsonToken.VALUE_STRING; + name = p.getValueAsString(); + } else if (property.equals(CustomToolJson.PROPERTY_VERSION)) { + token = p.nextToken(); + assert token == JsonToken.VALUE_STRING; + version = p.getValueAsString(); + } else if (property.equals(CustomToolJson.PROPERTY_OS_AGNOSTIC)) { + token = p.nextToken(); + osAgnostic = parseBoolean(token, CustomToolJson.PROPERTY_OS_AGNOSTIC); + } else if (property.equals(CustomToolJson.PROPERTY_ARCH_AGNOSTIC)) { + token = p.nextToken(); + archAgnostic = parseBoolean(token, CustomToolJson.PROPERTY_ARCH_AGNOSTIC); + } else if (property.equals(CustomToolJson.PROPERTY_URL)) { + token = p.nextToken(); + assert token == JsonToken.VALUE_STRING; + url = p.getValueAsString(); + } else { + // ignore unknown property + // currently cannot log here due to https://github.com/devonfw/IDEasy/issues/404 + } + token = p.nextToken(); + } + if ((name != null) && (version != null)) { + return new CustomToolJson(name, version, osAgnostic, archAgnostic, url); + } + } + throw new IllegalStateException(INVALID_CUSTOM_TOOL); + } + + private boolean parseBoolean(JsonToken token, String name) { + if (token == JsonToken.VALUE_TRUE) { + return true; + } else if (token == JsonToken.VALUE_FALSE) { + return false; + } else { + throw new IllegalStateException(INVALID_CUSTOM_TOOL + " Property " + name + " must have boolean value (true or false)."); + } + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonSerializer.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonSerializer.java new file mode 100644 index 000000000..56b83f140 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonSerializer.java @@ -0,0 +1,37 @@ +package com.devonfw.tools.ide.repo; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +/** + * {@link JsonDeserializer} for {@link CustomToolJson}. + */ +public class CustomToolJsonSerializer extends JsonSerializer { + + @Override + public void serialize(CustomToolJson customToolJson, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException { + if (customToolJson == null) { + return; + } + jgen.writeStartObject(); + jgen.writeFieldName(CustomToolJson.PROPERTY_NAME); + jgen.writeString(customToolJson.name()); + jgen.writeFieldName(CustomToolJson.PROPERTY_VERSION); + jgen.writeString(customToolJson.version()); + jgen.writeFieldName(CustomToolJson.PROPERTY_OS_AGNOSTIC); + jgen.writeBoolean(customToolJson.osAgnostic()); + jgen.writeFieldName(CustomToolJson.PROPERTY_ARCH_AGNOSTIC); + jgen.writeBoolean(customToolJson.archAgnostic()); + String url = customToolJson.url(); + if ((url != null) && !url.isBlank()) { + jgen.writeFieldName(CustomToolJson.PROPERTY_URL); + jgen.writeString(url); + } + jgen.writeEndObject(); + } + +} 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 7f8a8b19d..9789ce773 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 @@ -11,4 +11,10 @@ */ public record CustomToolsJson(String url, List tools) { + /** JSON property name for {@link #url()}. */ + public static final String PROPERTY_URL = "url"; + + /** JSON property name for {@link #tools()}. */ + public static final String PROPERTY_TOOLS = "tools"; + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonDeserializer.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonDeserializer.java new file mode 100644 index 000000000..ee6ba4725 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonDeserializer.java @@ -0,0 +1,56 @@ +package com.devonfw.tools.ide.repo; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +/** + * {@link JsonDeserializer} for {@link CustomToolsJson}. + */ +public class CustomToolsJsonDeserializer extends JsonDeserializer { + + private static final String INVALID_CUSTOM_TOOLS = "Invalid JSON for custom tools!"; + + @Override + public CustomToolsJson deserialize(JsonParser p, DeserializationContext context) throws IOException { + + JsonToken token = p.getCurrentToken(); + if (token == JsonToken.START_OBJECT) { + token = p.nextToken(); + String url = null; + List tools = new ArrayList<>(); + while (token == JsonToken.FIELD_NAME) { + String property = p.currentName(); + if (property.equals(CustomToolsJson.PROPERTY_URL)) { + token = p.nextToken(); + assert token == JsonToken.VALUE_STRING; + url = p.getValueAsString(); + } else if (property.equals(CustomToolsJson.PROPERTY_TOOLS)) { + token = p.nextToken(); + if (token == JsonToken.START_ARRAY) { + token = p.nextToken(); + while (token != JsonToken.END_ARRAY) { + CustomToolJson customToolJson = p.readValueAs(CustomToolJson.class); + tools.add(customToolJson); + token = p.nextToken(); + } + } + } else { + // ignore unknown property + // currently cannot log here due to https://github.com/devonfw/IDEasy/issues/404 + } + token = p.nextToken(); + } + if ((url != null) && !tools.isEmpty()) { + return new CustomToolsJson(url, tools); + } + } + throw new IllegalStateException(INVALID_CUSTOM_TOOLS); + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonSerializer.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonSerializer.java new file mode 100644 index 000000000..1a77794c9 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonSerializer.java @@ -0,0 +1,34 @@ +package com.devonfw.tools.ide.repo; + +import java.io.IOException; +import java.util.List; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +/** + * {@link JsonDeserializer} for {@link CustomToolsJson}. + */ +public class CustomToolsJsonSerializer extends JsonSerializer { + + @Override + public void serialize(CustomToolsJson customToolsJson, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException { + if (customToolsJson == null) { + return; + } + jgen.writeStartObject(); + jgen.writeFieldName(CustomToolsJson.PROPERTY_URL); + jgen.writeString(customToolsJson.url()); + jgen.writeFieldName(CustomToolsJson.PROPERTY_TOOLS); + jgen.writeStartArray(); + List tools = customToolsJson.tools(); + for (CustomToolJson tool : tools) { + jgen.writeObject(tool); + } + jgen.writeEndArray(); + jgen.writeEndObject(); + } + +}