-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#759: upgrade settings commandlet #820
base: main
Are you sure you want to change the base?
#759: upgrade settings commandlet #820
Conversation
Added the command cd to the shell commandlet that allows the user to switch the directory inside the ide shell
…dlet.java Co-authored-by: jan-vcapgemini <[email protected]>
…dlet.java Co-authored-by: jan-vcapgemini <[email protected]>
added current working directory path to prompt name improved existing directory check adjusted exit codes
removed whitespace from ide prompt
Changed variable name from file_path to filePath
Changed checkForXMLNameSpace() to checkForXmlNamespace()
cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java
Outdated
Show resolved
Hide resolved
try { | ||
List<String> readLines = Files.readAllLines(filePath); | ||
String[] split; | ||
for (String line : readLines) { | ||
if (!line.contains("#") && !line.isEmpty()) { | ||
if (line.contains("DEVON_IDE_CUSTOM_TOOLS")) { | ||
createCustomToolsJson(line); | ||
continue; | ||
} | ||
if (line.contains("DEVON_")) { | ||
line = line.replace("DEVON_", ""); | ||
} | ||
split = line.split("[ =]"); | ||
if (split.length == 3) { | ||
devonProperties.put(split[1], new String[] { split[0], split[2] }); | ||
} | ||
if (split.length == 2) { | ||
devonProperties.put(split[0], split[1]); | ||
} | ||
} | ||
} | ||
|
||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are duplicating the code to read a devon.properties
and a ide.properties
file.
IDEasy/cli/src/main/java/com/devonfw/tools/ide/environment/EnvironmentVariablesPropertiesFile.java
Lines 71 to 86 in 76124f7
try (BufferedReader reader = Files.newBufferedReader(this.propertiesFilePath)) { | |
String line; | |
do { | |
line = reader.readLine(); | |
if (line != null) { | |
VariableLine variableLine = VariableLine.of(line, this.context, getSource()); | |
String name = variableLine.getName(); | |
if (name != null) { | |
VariableLine migratedVariableLine = migrateLine(variableLine, false); | |
if (migratedVariableLine == null) { | |
this.context.warning("Illegal variable definition: {}", variableLine); | |
continue; | |
} | |
String migratedName = migratedVariableLine.getName(); | |
String migratedValue = migratedVariableLine.getValue(); | |
boolean legacyVariable = IdeVariables.isLegacyVariable(name); |
We should use our existing infrastructure to do that.
Also your implementation contains some problems. E.g. #
can also be used inside a value (e.g. to separate branch of a git-url) and I guess you are trying to ignore comments here. Using String "fiddling" with methods such as contains
is also dangerous since it will also match in unexpected cases. Surely not a very relevant scenario but rather an odd edge-case but in case a user has DISABLED_DEVON_IDE_CUSTOM_TOOLS=(...)
in his config, this will cause undesired effects (and I have seen users who were not aware that you can outcomment a line by adding #
at the beginning but were simply adding DISABLED_
as prefix). As you can see in the linked code we already have better infrastructure to parse a line and separate variable name and value. This should be reused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After re-reading all the code of this method I understand this was an important blind spot.
You tried to reimplement a lot of things that have already been solved in our code but could not find this.
Therefore, you ran into all these challenges how to deal with comments, how to split into property name and value, etc.
if (set.getValue() instanceof String) { | ||
Files.write(filePath, ("\n" + set.getKey().toString() + "=" + set.getValue().toString()).getBytes(), StandardOpenOption.APPEND); | ||
} | ||
if (set.getValue() instanceof String[]) { | ||
String[] values = (String[]) set.getValue(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added BufferedReader which now only reads out the first 3 lines of all .xml files. Also, the BufferedReader now searches for a more consistent String
…hub.com/leonrohne27/IDEasy into implement/759-UpgradeSettingsCommandlet # Conflicts: # cli/src/main/java/com/devonfw/tools/ide/commandlet/UpgradeSettingsCommandlet.java
content = content.replace("{", "["); | ||
content = content.replace("}", "]"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is wrong. It will destroy all JSON files.
We need to use VariableSyntax
, like here:
IDEasy/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java
Lines 220 to 226 in 886cea3
Matcher matcher = syntax.getPattern().matcher(value); | |
if (!matcher.find()) { | |
return value; | |
} | |
StringBuilder sb = new StringBuilder(value.length() + EXTRA_CAPACITY); | |
do { | |
String variableName = syntax.getVariable(matcher); |
# Conflicts: # CHANGELOG.adoc # cli/src/main/resources/nls/Help.properties # cli/src/main/resources/nls/Help_de.properties
added more tests added new CustomToolsJson class moved constants to IdeContext
changed return type of readCustomToolsFromJson to CustomToolsJson
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jan-vcapgemini thanks for your nice improvements 👍
String FILE_CUSTOM_TOOLS = "ide-custom-tools.json"; | ||
|
||
String DEVON_IDE_CUSTOM_TOOLS = "DEVON_IDE_CUSTOM_TOOLS"; | ||
String IDE_CUSTOM_TOOLS = "IDE_CUSTOM_TOOLS"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove pointless constant.
String IDE_CUSTOM_TOOLS = "IDE_CUSTOM_TOOLS"; |
/** The filename of the configuration file in the settings for this {@link CustomToolRepository}. */ | ||
String FILE_CUSTOM_TOOLS = "ide-custom-tools.json"; | ||
|
||
String DEVON_IDE_CUSTOM_TOOLS = "DEVON_IDE_CUSTOM_TOOLS"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create in IdeVariables
or give a name that indicates that this is a variable name?
Please also add JavaDoc.
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<CustomTool> 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 + "'!"); | ||
} | ||
} catch (Exception e) { | ||
throw new IllegalStateException("Failed to read JSON from " + customToolsJson, e); | ||
// TODO | ||
String checksum = null; | ||
CustomTool customTool = new CustomTool(name, VersionIdentifier.of(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); | ||
} | ||
return new CustomToolRepositoryImpl(context, tools); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method and logic belong to CustomToolsJson
class. Furhter, we can use Jackson for the mapping instead of writing the mapping code manually. We can add an internal method for post-processing that will set the url
in all CustomTool
instances to the parent one from CustomToolsJson
in case it is null
. This method can then be called both from the JSON parsing as well as from the String parsing method.
@@ -0,0 +1,18 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename this file to ide-custom-tools.json
to keep our own contract.
context.setSystemInfo(systemInfo); | ||
Path testPath = Path.of("src/test/resources/customtools"); | ||
// act | ||
CustomToolsJson customToolsJson = CustomToolRepositoryImpl.readCustomToolsFromJson(context, testPath.resolve("custom-tools.json")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great that you added new test methods to increase coverage. 👍
As I already commented on the main code please follow SoC and put the code into the classes responsible for what is done by the according method.
Then do the same for JUnits:
If you test a class from src/main/java/my/package/MyClass.java
then the unit tests shall be in src/test/java/my/package/MyClassTest.java
.
Hence you should create CustomToolsJsonTest
instead of extending this test.
public void testReadCustomToolsFromLegacyConfig() { | ||
// arrange | ||
IdeContext context = new IdeTestContext(); | ||
String legacyProperties = "DEVON_IDE_CUSTOM_TOOLS=(jboss-eap:7.1.4.GA:all:https://host.tld/projects/my-project firefox:70.0.1:all:https://host.tld/projects/my-project2)"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already left review comments to Kian and Leon that the context of that method is kind of odd and also we need to reuse our existing infrastructure to parse ide.properties
and devon.properties
files.
Then we can just get the value of a variable and only need to pass that value to this method instead of fiddling the value from the variable inside a class that is not responsible for that and code gets more redundant.
BTW: We also have existing code to parse variable array syntax into a regular Java List
. This is currently in VariableDefinitionStringList
e.g. used by IdeVariables.IDE_TOOLS
to parse things like IDE_TOOLS=(java mvn node npm)
(see https://github.com/devonfw/IDEasy/blob/main/documentation/variables.adoc).
We could even extract that parsing code to VariableLine
for easier reuse here.
From the test perspective I would then only pass the value and not the entire variable declaration line.
@@ -0,0 +1 @@ | |||
c2de7dfbd9f8faaa21b4cdd8518f826dd558c9ab24a0616b3ed28437a674a97b |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since when do we add checksums for test projects? Are they actually used? I can not see how this could be used since the java
installation in our tests is not yet downloaded as archive but only copied as directory tree.
If these *.sha256
files are all not needed or used, please remove them.
… in workspace templates
replaced regex parsing with indexOf added JsonIgnores and JsonProperties to CustomTool converted version from versionIdentifier to String added Tool record to CustomToolsJson
moved fromString into VariableLine replaced parenthesis parsing with VariableLine.fromString
Fixes: #759
Implements: