Skip to content

Commit

Permalink
Merge branch 'main' into devonfw#590-asciidoc
Browse files Browse the repository at this point in the history
  • Loading branch information
alfeilex authored Oct 1, 2024
2 parents bd5bf94 + d571df9 commit 613908f
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 34 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ Release with new features and bugfixes:
* https://github.com/devonfw/IDEasy/issues/52[#52]: Adjusting Intellij settings in ide-settings
* https://github.com/devonfw/IDEasy/issues/588[#588]: ide create installs wrong Java version
* https://github.com/devonfw/IDEasy/issues/650[#650]: Improve default success message of step
* https://github.com/devonfw/IDEasy/issues/593[#593]: Tool error reporting still buggy
* https://github.com/devonfw/IDEasy/issues/593[#593]: Tool error reporting still buggy
* https://github.com/devonfw/IDEasy/issues/651[#651]: IDE not started in background anymore
* https://github.com/devonfw/IDEasy/issues/439[#439]: Refactor and improve tool-dependencies and tomcat
* https://github.com/devonfw/IDEasy/issues/356[#356]: Eclipse plugin installation opens an Eclipse window for each plugin installed
* https://github.com/devonfw/IDEasy/issues/655[#655]: CVE-2024-26308 and library updates
* https://github.com/devonfw/IDEasy/issues/627[#627]: Still log messages break processable command output
* https://github.com/devonfw/IDEasy/issues/525[#525]: Added online state check before downloading
* https://github.com/devonfw/IDEasy/issues/663[#663]: Endless loop when installing Eclipse in force mode
* https://github.com/devonfw/IDEasy/issues/657[#657]: Cannot install Java 8

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.devonfw.tools.ide.cli;

import java.net.URL;
import java.nio.file.Path;

import com.devonfw.tools.ide.process.ProcessResult;
import com.devonfw.tools.ide.version.VersionIdentifier;

/**
* {@link CliException} that is thrown if further processing requires network but the user if offline.
Expand All @@ -20,9 +24,51 @@ public CliOfflineException() {
*
* @param message the {@link #getMessage() message}.
*/
public CliOfflineException(String message) {

private CliOfflineException(String message) {
super(message, ProcessResult.OFFLINE);
}

/**
* Factory method, which is called, when trying to download via a URL
*
* @param url the url, which the software should be downloaded from.
* @return A {@link CliOfflineException} with an informative message.
*/
public static CliOfflineException ofDownloadViaUrl(String url) {
return new CliOfflineException("You are offline and cannot download from URL " + url);
}

/**
* Factory method, which is called, when trying to download via tool name, edition and version
*
* @param tool the name of the tool, we want to download.
* @param edition the edition of the tool, we want to download.
* @param version the {@link VersionIdentifier} of the tool, we want to download.
* @return A {@link CliOfflineException} with an informative message.
*/
public static CliOfflineException ofDownloadOfTool(String tool, String edition, VersionIdentifier version) {
return new CliOfflineException("Not able to download tool " + tool + " in edition " + edition + " with version " + version + " because we are offline");
}

/**
* Factory method, which is called, when just a purpose is given.
*
* @param purpose the purpose, which the internet connection serves.
* @return A {@link CliOfflineException} with an informative message.
*/
public static CliOfflineException ofPurpose(String purpose) {
return new CliOfflineException("You are offline but Internet access is required for " + purpose);
}

/**
* Factory method, which is called, when a clone is performed in offline mode
*
* @param url the url, in which the clone should be executed.
* @param repository the path, where the repository should be cloned to.
* @return A {@link CliOfflineException} with an informative message.
*/
public static CliOfflineException ofClone(URL url, Path repository) {
return new CliOfflineException("Could not clone " + url + " to " + repository + " because you are offline.");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public void clone(GitUrl gitRepoUrl, Path targetRepository) {
}
}
} else {
throw new CliOfflineException("Could not clone " + parsedUrl + " to " + targetRepository + " because you are offline.");
throw CliOfflineException.ofClone(parsedUrl, targetRepository);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ default void askToContinue(String question) {
default void requireOnline(String purpose) {

if (isOfflineMode()) {
throw new CliOfflineException("You are offline but Internet access is required for " + purpose);
throw CliOfflineException.ofPurpose(purpose);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;

import com.devonfw.tools.ide.cli.CliException;
import com.devonfw.tools.ide.cli.CliOfflineException;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.os.SystemInfoImpl;
import com.devonfw.tools.ide.process.ProcessContext;
Expand Down Expand Up @@ -96,6 +97,9 @@ public void download(String url, Path target) {
this.context.info("Trying to download {} from {}", target.getFileName(), url);
mkdirs(target.getParent());
try {
if (this.context.isOffline()) {
throw CliOfflineException.ofDownloadViaUrl(url);
}
if (url.startsWith("http")) {

HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).GET().build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.Set;

import com.devonfw.tools.ide.cli.CliException;
import com.devonfw.tools.ide.cli.CliOfflineException;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.log.IdeLogLevel;
import com.devonfw.tools.ide.os.OperatingSystem;
Expand Down Expand Up @@ -49,6 +50,9 @@ public Path download(String tool, String edition, VersionIdentifier version) {
UrlDownloadFileMetadata metadata = getMetadata(tool, edition, version);
VersionIdentifier resolvedVersion = metadata.getVersion();
Set<String> urlCollection = metadata.getUrls();
if (context.isOffline()) {
throw CliOfflineException.ofDownloadOfTool(tool, edition, version);
}
if (urlCollection.isEmpty()) {
throw new IllegalStateException("Invalid download metadata with empty urls file for " + metadata);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
package com.devonfw.tools.ide.tool.java;

import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;

/**
* Mock of {@link JavaUrlUpdater} to allow integration testing with wiremock.
*/
public class JavaUrlUpdaterMock extends JavaUrlUpdater {

private final static String TEST_URL = "http://localhost:8080/";
private final String baseUrl;

JavaUrlUpdaterMock(WireMockRuntimeInfo wireMockRuntimeInfo) {

super();
this.baseUrl = wireMockRuntimeInfo.getHttpBaseUrl();
}

@Override
protected String getMirror() {

return TEST_URL + "downloads/";
return this.baseUrl + "/downloads/";
}

@Override
protected String doGetVersionUrl() {

return TEST_URL + "versions/";
return this.baseUrl + "/versions/";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
import com.devonfw.tools.ide.tool.npm.NpmUrlUpdater;
import com.devonfw.tools.ide.url.model.folder.UrlRepository;
import com.devonfw.tools.ide.url.updater.JsonUrlUpdater;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;

/**
* Test class for integrations of the {@link NpmUrlUpdater}
*/
@WireMockTest(httpPort = 8080)
@WireMockTest
public class JavaUrlUpdaterTest extends Assertions {

/**
Expand All @@ -37,10 +38,11 @@ public class JavaUrlUpdaterTest extends Assertions {
* Test of {@link JsonUrlUpdater} for the creation of {@link JavaUrlUpdater} download URLs and checksums.
*
* @param tempDir Path to a temporary directory
* @param wmRuntimeInfo the {@link WireMockRuntimeInfo}.
* @throws IOException test fails
*/
@Test
public void testJavaUrlUpdaterCreatesDownloadUrlsAndChecksums(@TempDir Path tempDir) throws IOException {
public void testJavaUrlUpdaterCreatesDownloadUrlsAndChecksums(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) throws IOException {

// given
stubFor(get(urlMatching("/versions/")).willReturn(aResponse().withStatus(200)
Expand All @@ -49,8 +51,7 @@ public void testJavaUrlUpdaterCreatesDownloadUrlsAndChecksums(@TempDir Path temp
stubFor(any(urlMatching("/downloads/.*")).willReturn(aResponse().withStatus(200).withBody("aBody")));

UrlRepository urlRepository = UrlRepository.load(tempDir);
JavaUrlUpdaterMock updater = new JavaUrlUpdaterMock();

JavaUrlUpdaterMock updater = new JavaUrlUpdaterMock(wmRuntimeInfo);
// when
updater.update(urlRepository);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

Expand All @@ -16,12 +17,13 @@

import com.devonfw.tools.ide.url.model.folder.UrlRepository;
import com.devonfw.tools.ide.url.updater.JsonUrlUpdater;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;

/**
* Test class for integrations of the {@link NpmUrlUpdater}
*/
@WireMockTest(httpPort = 8080)
@WireMockTest
public class NpmJsonUrlUpdaterTest extends Assertions {

/**
Expand All @@ -36,50 +38,57 @@ public class NpmJsonUrlUpdaterTest extends Assertions {
* Test of {@link JsonUrlUpdater} for the creation of {@link NpmUrlUpdater} download URLs and checksums.
*
* @param tempDir Path to a temporary directory
* @param wmRuntimeInfo the {@link WireMockRuntimeInfo}.
* @throws IOException test fails
*/
@Test
public void testNpmJsonUrlUpdaterCreatesDownloadUrlsAndChecksums(@TempDir Path tempDir) throws IOException {
public void testNpmJsonUrlUpdaterCreatesDownloadUrlsAndChecksums(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) throws IOException {

// given
stubFor(get(urlMatching("/npm")).willReturn(
aResponse().withStatus(200).withBody(Files.readAllBytes(Path.of(TEST_DATA_ROOT).resolve("npm-version.json")))));
aResponse().withStatus(200).withBody(getJsonBody(wmRuntimeInfo))));

stubFor(any(urlMatching("/npm/-/npm-[1-9.]*.tgz")).willReturn(aResponse().withStatus(200).withBody("aBody")));

UrlRepository urlRepository = UrlRepository.load(tempDir);
NpmUrlUpdaterMock updater = new NpmUrlUpdaterMock();
NpmUrlUpdaterMock updater = new NpmUrlUpdaterMock(wmRuntimeInfo);

// when
updater.update(urlRepository);

Path NpmVersionsPath = tempDir.resolve("npm").resolve("npm").resolve("1.2.32");
Path npmVersionsPath = tempDir.resolve("npm").resolve("npm").resolve("1.2.32");

// then
assertThat(NpmVersionsPath.resolve("status.json")).exists();
assertThat(NpmVersionsPath.resolve("urls")).exists();
assertThat(NpmVersionsPath.resolve("urls.sha256")).exists();
assertThat(npmVersionsPath.resolve("status.json")).exists();
assertThat(npmVersionsPath.resolve("urls")).exists();
assertThat(npmVersionsPath.resolve("urls.sha256")).exists();

}

private static byte[] getJsonBody(WireMockRuntimeInfo wmRuntimeInfo) throws IOException {
Path jsonFile = Path.of(TEST_DATA_ROOT).resolve("npm-version.json");
return Files.readString(jsonFile).replace("${testbaseurl}", wmRuntimeInfo.getHttpBaseUrl()).getBytes(StandardCharsets.UTF_8);
}

/**
* Test if the {@link JsonUrlUpdater} for {@link NpmUrlUpdater} for a non-existent version does successfully not create a download folder.
*
* @param tempDir Path to a temporary directory
* @param wmRuntimeInfo the {@link WireMockRuntimeInfo}.
* @throws IOException test fails
*/
@Test
public void testNpmJsonUrlUpdaterWithMissingDownloadsDoesNotCreateVersionFolder(@TempDir Path tempDir)
public void testNpmJsonUrlUpdaterWithMissingDownloadsDoesNotCreateVersionFolder(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo)
throws IOException {

// given
stubFor(get(urlMatching("/npm")).willReturn(
aResponse().withStatus(200).withBody(Files.readAllBytes(Path.of(TEST_DATA_ROOT).resolve("npm-version.json")))));
aResponse().withStatus(200).withBody(getJsonBody(wmRuntimeInfo))));

stubFor(any(urlMatching("/npm/-/npm-[1-9.]*.tgz")).willReturn(aResponse().withStatus(200).withBody("aBody")));

UrlRepository urlRepository = UrlRepository.load(tempDir);
NpmUrlUpdaterMock updater = new NpmUrlUpdaterMock();
NpmUrlUpdaterMock updater = new NpmUrlUpdaterMock(wmRuntimeInfo);

// when
updater.update(urlRepository);
Expand All @@ -95,19 +104,20 @@ public void testNpmJsonUrlUpdaterWithMissingDownloadsDoesNotCreateVersionFolder(
* Test if the {@link JsonUrlUpdater} for {@link NpmUrlUpdater} can handle filtering of versions.
*
* @param tempDir Path to a temporary directory
* @param wmRuntimeInfo the {@link WireMockRuntimeInfo}.
* @throws IOException test fails
*/
@Test
public void testNpmJsonUrlUpdaterFilteredVersionCreateVersionFolder(@TempDir Path tempDir) throws IOException {
public void testNpmJsonUrlUpdaterFilteredVersionCreateVersionFolder(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) throws IOException {

// given
stubFor(get(urlMatching("/npm")).willReturn(
aResponse().withStatus(200).withBody(Files.readAllBytes(Path.of(TEST_DATA_ROOT).resolve("npm-version.json")))));
aResponse().withStatus(200).withBody(getJsonBody(wmRuntimeInfo))));

stubFor(any(urlMatching("/npm/-/npm-[1-9.]*.tgz")).willReturn(aResponse().withStatus(200).withBody("aBody")));

UrlRepository urlRepository = UrlRepository.load(tempDir);
NpmUrlUpdaterMock updater = new NpmUrlUpdaterMock();
NpmUrlUpdaterMock updater = new NpmUrlUpdaterMock(wmRuntimeInfo);

// when
updater.update(urlRepository);
Expand All @@ -124,19 +134,20 @@ public void testNpmJsonUrlUpdaterFilteredVersionCreateVersionFolder(@TempDir Pat
* checksum was provided)
*
* @param tempDir Path to a temporary directory
* @param wmRuntimeInfo the {@link WireMockRuntimeInfo}.
* @throws IOException test fails
*/
@Test
public void testNpmJsonUrlUpdaterGeneratesChecksum(@TempDir Path tempDir) throws IOException {
public void testNpmJsonUrlUpdaterGeneratesChecksum(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) throws IOException {

// given
stubFor(get(urlMatching("/npm")).willReturn(
aResponse().withStatus(200).withBody(Files.readAllBytes(Path.of(TEST_DATA_ROOT).resolve("npm-version.json")))));
aResponse().withStatus(200).withBody(getJsonBody(wmRuntimeInfo))));

stubFor(any(urlMatching("/npm/-/npm-[1-9.]*.tgz")).willReturn(aResponse().withStatus(200).withBody("aBody")));

UrlRepository urlRepository = UrlRepository.load(tempDir);
NpmUrlUpdaterMock updater = new NpmUrlUpdaterMock();
NpmUrlUpdaterMock updater = new NpmUrlUpdaterMock(wmRuntimeInfo);

// when
updater.update(urlRepository);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package com.devonfw.tools.ide.tool.npm;

import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;

/**
* Mock of {@link NpmUrlUpdater} to allow integration testing with wiremock.
*/
public class NpmUrlUpdaterMock extends NpmUrlUpdater {

private final static String TEST_URL = "http://localhost:8080/";
private final String baseUrl;

NpmUrlUpdaterMock(WireMockRuntimeInfo wireMockRuntimeInfo) {
super();
this.baseUrl = wireMockRuntimeInfo.getHttpBaseUrl() + "/";
}

@Override
protected String getBaseUrl() {

return TEST_URL;
return this.baseUrl;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
],
"dist": {
"shasum": "",
"tarball": "http://localhost:8080/npm/-/npm-1.1.25.tgz",
"tarball": "${testbaseurl}/npm/-/npm-1.1.25.tgz",
"integrity": "",
"signatures": [
{
Expand Down Expand Up @@ -126,7 +126,7 @@
],
"dist": {
"shasum": "",
"tarball": "http://localhost:8080/npm/-/npm-1.2.32.tgz",
"tarball": "${testbaseurl}/npm/-/npm-1.2.32.tgz",
"integrity": "",
"signatures": [
{
Expand Down Expand Up @@ -214,7 +214,7 @@
],
"dist": {
"shasum": "",
"tarball": "http://localhost:8080/npm/-/npm-2.0.0-beta.0.tgz",
"tarball": "${testbaseurl}/npm/-/npm-2.0.0-beta.0.tgz",
"integrity": "",
"signatures": [
{
Expand Down

0 comments on commit 613908f

Please sign in to comment.