Skip to content

Commit

Permalink
Merge branch 'main' into feature/devonfw#103-implement-version-securi…
Browse files Browse the repository at this point in the history
…ty-checks

# Conflicts:
#	cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeContextTest.java
#	cli/src/test/resources/ide-projects/basic/_ide/urls/mvn/mvn/security.json
  • Loading branch information
jan-vcapgemini committed Feb 22, 2024
2 parents db6e276 + 2339c25 commit 6da9066
Show file tree
Hide file tree
Showing 48 changed files with 80 additions and 23 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
*.log
*.bak
.*
!.gitignore
!.ide.software.version
!.devon.software.version
!.ide
!.anyedit.properties
!.ide.properties
target/
eclipse-target/
generated/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ private void unpack(Path file, Path targetDir, Function<InputStream, ArchiveInpu
mkdirs(entryPath.getParent());
Files.copy(ais, entryPath);
}
if (isTar) {
if (isTar && !this.context.getSystemInfo().isWindows()) {
Set<PosixFilePermission> permissions = PosixFilePermissions.fromString(permissionStr);
Files.setPosixFilePermissions(entryPath, permissions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,48 +32,48 @@ public abstract class AbstractIdeContextTest extends Assertions {
private static final int CHUNK_SIZE = 1024;

/**
* @param projectName the (folder)name of the test project in {@link #PATH_PROJECTS}. E.g. "basic".
* @param projectTestCaseName the (folder)name of the project test case, in this folder a 'project' folder represents
* the test project in {@link #PATH_PROJECTS}. E.g. "basic".
* @return the {@link IdeTestContext} pointing to that project.
*/
protected IdeTestContext newContext(String projectName) {
protected IdeTestContext newContext(String projectTestCaseName) {

return newContext(projectName, null, true);
return newContext(projectTestCaseName, null, true);
}

/**
* @param projectName the (folder)name of the test project in {@link #PATH_PROJECTS}. E.g. "basic".
* @param projectTestCaseName the (folder)name of the project test case, in this folder a 'project' folder represents
* the test project in {@link #PATH_PROJECTS}. E.g. "basic".
* @param projectPath the relative path inside the test project where to create the context.
* @return the {@link IdeTestContext} pointing to that project.
*/
protected static IdeTestContext newContext(String projectName, String projectPath) {
protected static IdeTestContext newContext(String projectTestCaseName, String projectPath) {

return newContext(projectName, projectPath, true);
return newContext(projectTestCaseName, projectPath, true);
}

/**
* @param projectName the (folder)name of the test project in {@link #PATH_PROJECTS}. E.g. "basic".
* @param projectTestCaseName the (folder)name of the project test case, in this folder a 'project' folder represents
* the test project in {@link #PATH_PROJECTS}. E.g. "basic".
* @param projectPath the relative path inside the test project where to create the context.
* @param copyForMutation - {@code true} to create a copy of the project that can be modified by the test,
* {@code false} otherwise (only to save resources if you are 100% sure that your test never modifies anything
* in that project.
* in that project.)
* @param answers the answers to use for the {@link IdeTestContext}.
* @return the {@link IdeTestContext} pointing to that project.
*/
protected static IdeTestContext newContext(String projectName, String projectPath, boolean copyForMutation,
String... answers) {
protected static IdeTestContext newContext(String projectTestCaseName, String projectPath, boolean copyForMutation) {

Path sourceDir = PATH_PROJECTS.resolve(projectName);
Path userDir = sourceDir;
Path sourceDir = PATH_PROJECTS.resolve(projectTestCaseName);
Path userDir = sourceDir.resolve("project");
IdeTestContext context;
if (copyForMutation) {
Path projectDir = PATH_PROJECTS_COPY.resolve(projectName);
Path projectDir = PATH_PROJECTS_COPY.resolve(projectTestCaseName);
FileAccess fileAccess = new FileAccessImpl(IdeTestContextMock.get());
fileAccess.delete(projectDir);
fileAccess.mkdirs(PATH_PROJECTS_COPY);
fileAccess.copy(sourceDir, projectDir, FileCopyMode.COPY_TREE_OVERRIDE_TREE);
fileAccess.copy(PATH_PROJECTS.resolve(IdeContext.FOLDER_IDE), PATH_PROJECTS_COPY.resolve(IdeContext.FOLDER_IDE),
FileCopyMode.COPY_TREE_OVERRIDE_TREE);
userDir = projectDir;
userDir = projectDir.resolve("project");
}
if (projectPath != null) {
userDir = userDir.resolve(projectPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
*/
public class DirectoryMergerTest extends AbstractIdeContextTest {

private static final String IDE_HOME = PATH_PROJECTS.resolve(PROJECT_BASIC).toAbsolutePath().toString().replace('\\',
'/');
private static final String IDE_HOME = PATH_PROJECTS.resolve(PROJECT_BASIC).resolve("project").toAbsolutePath()
.toString().replace('\\', '/');

private static final Prop JAVA_VERSION = new Prop("java.version", "1.11");

Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

"manual" : false,
"urls" : {
"-997329125" : {
"success" : {
"timestamp" : "2023-04-28T07:12:26.601818Z"
}
}
}
}
1 change: 1 addition & 0 deletions cli/src/test/resources/ide-projects/basic/project/readme
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this is the IDE_HOME directory
2 changes: 1 addition & 1 deletion cli/src/test/resources/ide-projects/basic/readme
Original file line number Diff line number Diff line change
@@ -1 +1 @@
this is the IDE_HOME directory
this is the IDE_ROOT directory
1 change: 0 additions & 1 deletion cli/src/test/resources/ide-projects/readme

This file was deleted.

45 changes: 43 additions & 2 deletions documentation/coding-conventions.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@ So instead of just saying "Something failed" a really good example could look li
LOG.error("An unexpected error occurred whilst downloading the tool {} with edition {} and version {} from URL {}.", tool, edition, version, url, e);
----

=== Prefer general API
== Prefer general API
Avoid unnecessary strong bindings:

* Do not bind your code to implementations such as `Vector` or `ArrayList` instead of `List`
* In APIs for input (=parameters) always consider to make little assumptions:
** prefer `Collection` over `List` or `Set` where the difference does not matter (e.g. only use `Set` when you require uniqueness or highly efficient `contains`)
** consider preferring `Collection<? extends Foo>` over `Collection<Foo>` when `Foo` is an interface or super-class

=== Prefer primitive types
== Prefer primitive types
In general prefer primitive types (`boolean`, `int`, `long`, ...) instead of corresponding boxed object types (`Boolean`, `Integer`, `Long`, ...).
Only use boxed object types, if you explicitly want to allow `null` as a value.
Typically you never want to use `Boolean` but instead use `boolean`.
Expand Down Expand Up @@ -208,6 +208,47 @@ So we conclude:
* In classes we declare the constant with the visibility followed by the keywords `static final`.
* In interfaces, we omit all modifiers as they always default to `public static final` for type variables.

== Refactorings

Do refactorings with care and follow these best-practices:

* use `git mv «old» «new»` to move or rename things in git. Otherwise your diff may show that a file has been deleted somewhere and another file has been added but you cannot see that this file was moved/renamed and what changed inside the file.
* do not change Java signatures like in a text editor but use refactoring capabilities of your IDE. So e.g. when changing a method name, adding or removing a parameter, always use refactoring as otherwise you easily break references (and JavaDoc references will not give you compile errors so you break things without noticing).
* when adding paramaters to methods, please always consider to keep the existing signature and just create a new variant of the method with an additional parameter.

Lets assume we have this method:
[source,java]
----
public void doSomething() {
// ...
}
----

Now, assuming this method is called from multiple places, this change is bad:
[source,java]
----
// bad
public void doSomething(boolean newFlag) {
// ...
}
----
The reason is that it is most likely causing a lot of merge conflicts for feature-branches and PRs of other developers, currently working with code calling `doSomething()` that will not work after the change.

Instead keep the existing signature and add a new one:
[source,java]
----
// good
public void doSomething() {
doSomething(false);
}
public void doSomething(boolean newFlag) {
// ...
}
----

Typically, you should design flags such that `false` is a reasonable default.
That is why we are passing `false` in the example from the existing method to the new one.

== Optionals
With `Optional` you can wrap values to avoid a `NullPointerException` (NPE).
However, it is not a good code-style to use `Optional` for every parameter or result to express that it may be null.
Expand Down

0 comments on commit 6da9066

Please sign in to comment.