From 60bb713082ebb122b54fa52b1808184729910589 Mon Sep 17 00:00:00 2001 From: mbilda Date: Fri, 7 Mar 2025 14:56:25 +0100 Subject: [PATCH 01/16] https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Docker causes installation problems - deleted the new line patterns out of the regex in DockerDesktopUrlUpdater because Pattern.DOTALL already handles this --- .../tools/ide/tool/docker/DockerDesktopUrlUpdater.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerDesktopUrlUpdater.java b/cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerDesktopUrlUpdater.java index f4dd68754d..48f0e4692d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerDesktopUrlUpdater.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/docker/DockerDesktopUrlUpdater.java @@ -31,13 +31,13 @@ protected void addVersion(UrlVersion urlVersion) { // get Code for version String body = doGetResponseBodyAsString("https://docs.docker.com/desktop/release-notes/"); String regex = "href=#" + version - // .......1.........................................................2................. - + ".{8,12}(\r\n|\r|\n).{0,350}href=https://desktop\\.docker\\.com.*?(\\d{5,6}).*\\.exe"; + // .....................................................(Group.1.).......... + + ".{8,12}.{0,350}href=https://desktop\\.docker\\.com.*?(\\d{5,6}).*\\.exe"; Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); Matcher matcher = pattern.matcher(body); String code; if (matcher.find()) { - code = matcher.group(2); + code = matcher.group(1); boolean success = doAddVersion(urlVersion, "https://desktop.docker.com/win/main/amd64/" + code + "/Docker%20Desktop%20Installer.exe", WINDOWS); if (!success) { From 331047132a8eb2f048b66b21bb4773bea06d158d Mon Sep 17 00:00:00 2001 From: mbilda Date: Tue, 11 Mar 2025 13:55:47 +0100 Subject: [PATCH 02/16] https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Docker causes installation problems - Added a fallback for "*" (Latest) - Version to be found in the filesystem - Added a fallback to name the downloadcache file to latest if version is "*" (latest) --- .../tools/ide/tool/repository/AbstractToolRepository.java | 8 ++++++-- .../tools/ide/url/model/folder/AbstractUrlFolder.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java b/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java index 086ed96816..8b32ede363 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java @@ -27,7 +27,7 @@ public abstract class AbstractToolRepository implements ToolRepository { private static final int MAX_TEMP_DOWNLOADS = 9; - + /** The owning {@link IdeContext}. */ protected final IdeContext context; @@ -135,7 +135,11 @@ protected String createDownloadFilename(String tool, String edition, VersionIden StringBuilder sb = new StringBuilder(32); sb.append(tool); sb.append("-"); - sb.append(version); + if (version.equals(VersionIdentifier.LATEST)) { + sb.append("latest"); + } else { + sb.append(version); + } if (!edition.equals(tool)) { sb.append("-"); sb.append(edition); diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java index 2daa4f1c8d..e607c11c65 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java @@ -58,7 +58,7 @@ public int getChildCount() { public C getChild(String name) { load(false); - return this.childMap.get(name); + return name.equals("*") ? this.childMap.get("latest") : this.childMap.get(name); } @Override From 2037ae20c3d885c76eccf8e7370f870f5822335d Mon Sep 17 00:00:00 2001 From: mbilda Date: Tue, 11 Mar 2025 16:34:08 +0100 Subject: [PATCH 03/16] https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Docker causes installation problems - Changed order to prevent nullpointer - changed structure to if-else --- .../tools/ide/tool/repository/AbstractToolRepository.java | 2 +- .../tools/ide/url/model/folder/AbstractUrlFolder.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java b/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java index 8b32ede363..bb9b679dd0 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java @@ -135,7 +135,7 @@ protected String createDownloadFilename(String tool, String edition, VersionIden StringBuilder sb = new StringBuilder(32); sb.append(tool); sb.append("-"); - if (version.equals(VersionIdentifier.LATEST)) { + if (VersionIdentifier.LATEST.equals(version)) { sb.append("latest"); } else { sb.append(version); diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java index e607c11c65..de0b81f1d1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java @@ -58,7 +58,10 @@ public int getChildCount() { public C getChild(String name) { load(false); - return name.equals("*") ? this.childMap.get("latest") : this.childMap.get(name); + if (name.equals("*")) { + return this.childMap.get("latest"); + } + return this.childMap.get(name); } @Override From be49cea9993c55d95d8970bb6fd75a14c17948d8 Mon Sep 17 00:00:00 2001 From: mbilda Date: Wed, 12 Mar 2025 10:12:01 +0100 Subject: [PATCH 04/16] https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Docker causes installation problems - Changed order to prevent nullpointer --- .../devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java index de0b81f1d1..fed985b67d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java @@ -58,7 +58,7 @@ public int getChildCount() { public C getChild(String name) { load(false); - if (name.equals("*")) { + if ("*".equals(name)) { return this.childMap.get("latest"); } return this.childMap.get(name); From 56f1c73805680b50f1e25e0958c68828854c9f51 Mon Sep 17 00:00:00 2001 From: mbilda Date: Thu, 13 Mar 2025 11:55:07 +0100 Subject: [PATCH 05/16] https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Docker causes installation problems - Added test for only latest version --- .../tools/ide/tool/UrlUpdaterMockLatest.java | 38 +++++++++++++++++++ .../tools/ide/tool/UrlUpdaterTest.java | 28 ++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockLatest.java diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockLatest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockLatest.java new file mode 100644 index 0000000000..533383f34f --- /dev/null +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockLatest.java @@ -0,0 +1,38 @@ +package com.devonfw.tools.ide.tool; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.devonfw.tools.ide.url.model.folder.UrlVersion; +import com.devonfw.tools.ide.url.updater.UrlUpdater; +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; + +/** + * Test mock for {@link UrlUpdater} using a single tool, the latest version and distribution. + */ +public class UrlUpdaterMockLatest extends UrlUpdaterMock { + + private static final Set versions = new HashSet<>(List.of("latest")); + + /** + * The constructor + * + * @param wmRuntimeInfo the {@link WireMockRuntimeInfo} holding the http url and port of the wiremock server. + */ + public UrlUpdaterMockLatest(WireMockRuntimeInfo wmRuntimeInfo) { + + super(wmRuntimeInfo); + } + + @Override + protected Set getVersions() { + return versions; + } + + @Override + protected void addVersion(UrlVersion urlVersion) { + doAddVersion(urlVersion, wmRuntimeInfo.getHttpBaseUrl() + "/os/windows_x64_url.tgz", WINDOWS, X64, "123"); + } + +} diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java index b312a98a57..94f5a45ccd 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -17,6 +18,7 @@ import com.devonfw.tools.ide.os.OperatingSystem; import com.devonfw.tools.ide.os.SystemArchitecture; +import com.devonfw.tools.ide.tool.docker.DockerDesktopUrlUpdater; import com.devonfw.tools.ide.url.model.file.UrlChecksum; import com.devonfw.tools.ide.url.model.file.UrlDownloadFile; import com.devonfw.tools.ide.url.model.file.UrlStatusFile; @@ -36,6 +38,17 @@ @WireMockTest public class UrlUpdaterTest extends AbstractUrlUpdaterTest { + @Test + public void testUpdateDockerUrl() { + String testdataRoot = "src/test/resources/UpdateManager/versions"; + Path repoPath = Paths.get(testdataRoot); + UrlRepository urlRepository = UrlRepository.load(repoPath); + DockerDesktopUrlUpdater updater = new DockerDesktopUrlUpdater(); + + updater.update(urlRepository); + + } + /** * Test resource location */ @@ -280,4 +293,19 @@ public void testUrlUpdaterWithTextContentTypeWillNotCreateStatusJson(@TempDir Pa } + @Test + public void testUrlUpdaterWithOnlyLatestVersion(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) { + //given + stubFor(any(urlMatching("/os/.*")).willReturn(aResponse().withStatus(200).withBody("aBody"))); + UrlRepository urlRepository = UrlRepository.load(tempDir); + UrlUpdaterMockLatest updater = new UrlUpdaterMockLatest(wmRuntimeInfo); + + // when + updater.update(urlRepository); + + // then + Path versionsPath = tempDir.resolve("mocked").resolve("mocked").resolve("latest"); + assertThat(versionsPath.resolve("status.json")).exists(); + } + } From a1046cc5c32bfa2b6d1139404ce25c476067d883 Mon Sep 17 00:00:00 2001 From: mbilda Date: Thu, 13 Mar 2025 14:04:25 +0100 Subject: [PATCH 06/16] https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Docker causes installation problems - Refactored UrlUpdaterMockSingle to modify the verion which should be tested - deleted temporary test case --- .../tools/ide/tool/UrlUpdaterMockLatest.java | 38 ------------------- .../tools/ide/tool/UrlUpdaterMockSingle.java | 11 +++++- .../tools/ide/tool/UrlUpdaterTest.java | 22 ++++------- 3 files changed, 18 insertions(+), 53 deletions(-) delete mode 100644 cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockLatest.java diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockLatest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockLatest.java deleted file mode 100644 index 533383f34f..0000000000 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockLatest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.devonfw.tools.ide.tool; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.devonfw.tools.ide.url.model.folder.UrlVersion; -import com.devonfw.tools.ide.url.updater.UrlUpdater; -import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; - -/** - * Test mock for {@link UrlUpdater} using a single tool, the latest version and distribution. - */ -public class UrlUpdaterMockLatest extends UrlUpdaterMock { - - private static final Set versions = new HashSet<>(List.of("latest")); - - /** - * The constructor - * - * @param wmRuntimeInfo the {@link WireMockRuntimeInfo} holding the http url and port of the wiremock server. - */ - public UrlUpdaterMockLatest(WireMockRuntimeInfo wmRuntimeInfo) { - - super(wmRuntimeInfo); - } - - @Override - protected Set getVersions() { - return versions; - } - - @Override - protected void addVersion(UrlVersion urlVersion) { - doAddVersion(urlVersion, wmRuntimeInfo.getHttpBaseUrl() + "/os/windows_x64_url.tgz", WINDOWS, X64, "123"); - } - -} diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockSingle.java b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockSingle.java index b31272829c..8c79899d80 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockSingle.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterMockSingle.java @@ -13,7 +13,7 @@ */ public class UrlUpdaterMockSingle extends UrlUpdaterMock { - private static final Set versions = new HashSet<>(List.of("1.0")); + private static Set versions = new HashSet<>(List.of("1.0")); /** * The constructor @@ -30,6 +30,15 @@ protected Set getVersions() { return versions; } + /** + * Enables the possibility to change the version which should be tested. + * + * @param newVersion the new Version to be set. + */ + protected void setVersion(final String newVersion) { + versions = Set.of(newVersion); + } + @Override protected void addVersion(UrlVersion urlVersion) { doAddVersion(urlVersion, wmRuntimeInfo.getHttpBaseUrl() + "/os/windows_x64_url.tgz", WINDOWS, X64, "123"); diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java index 94f5a45ccd..2ee8d8deca 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/UrlUpdaterTest.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -18,7 +17,6 @@ import com.devonfw.tools.ide.os.OperatingSystem; import com.devonfw.tools.ide.os.SystemArchitecture; -import com.devonfw.tools.ide.tool.docker.DockerDesktopUrlUpdater; import com.devonfw.tools.ide.url.model.file.UrlChecksum; import com.devonfw.tools.ide.url.model.file.UrlDownloadFile; import com.devonfw.tools.ide.url.model.file.UrlStatusFile; @@ -38,17 +36,6 @@ @WireMockTest public class UrlUpdaterTest extends AbstractUrlUpdaterTest { - @Test - public void testUpdateDockerUrl() { - String testdataRoot = "src/test/resources/UpdateManager/versions"; - Path repoPath = Paths.get(testdataRoot); - UrlRepository urlRepository = UrlRepository.load(repoPath); - DockerDesktopUrlUpdater updater = new DockerDesktopUrlUpdater(); - - updater.update(urlRepository); - - } - /** * Test resource location */ @@ -293,12 +280,19 @@ public void testUrlUpdaterWithTextContentTypeWillNotCreateStatusJson(@TempDir Pa } + /** + * Tests if the {@link com.devonfw.tools.ide.url.updater.UrlUpdater} will handle the literally latest version of a tool correctly + * + * @param tempDir Temporary directory + * @param wmRuntimeInfo wireMock server on a random port + */ @Test public void testUrlUpdaterWithOnlyLatestVersion(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) { //given stubFor(any(urlMatching("/os/.*")).willReturn(aResponse().withStatus(200).withBody("aBody"))); UrlRepository urlRepository = UrlRepository.load(tempDir); - UrlUpdaterMockLatest updater = new UrlUpdaterMockLatest(wmRuntimeInfo); + UrlUpdaterMockSingle updater = new UrlUpdaterMockSingle(wmRuntimeInfo); + updater.setVersion("latest"); // when updater.update(urlRepository); From ff8fe15738d4d246b107b734a830c196a6158149 Mon Sep 17 00:00:00 2001 From: mbilda Date: Thu, 13 Mar 2025 14:14:00 +0100 Subject: [PATCH 07/16] https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Docker causes installation problems - Updated CHANGELOG.adoc --- CHANGELOG.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index c2acecfcb7..d44c54afd9 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -6,6 +6,9 @@ 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/692[#692]: "Latest" version of Docker causes installation problems + + The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/24?closed=1[milestone 2025.03.002]. == 2025.03.001 From c2d0e2bd8f5ece04a78c8623f609470d7b606e0b Mon Sep 17 00:00:00 2001 From: mbilda Date: Mon, 17 Mar 2025 16:36:27 +0100 Subject: [PATCH 08/16] https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Docker causes installation problems - Refactored DockerDesktopUrlUpdater to verify each version before downloading --- .../tool/docker/DockerDesktopUrlUpdater.java | 97 ++++++++++++++++--- 1 file changed, 81 insertions(+), 16 deletions(-) diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java index bcd61e7c32..6000fcbcc5 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java @@ -1,5 +1,7 @@ package com.devonfw.tools.ide.url.tool.docker; +import static java.lang.String.format; + import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -17,6 +19,21 @@ public class DockerDesktopUrlUpdater extends WebsiteUrlUpdater { VersionIdentifier.of("4.4.3"), VersionIdentifier.of("4.4.4"), VersionIdentifier.of("4.17.1"), VersionIdentifier.of("4.5.1")); + private final static String DOCKER_RELEASE_NOTES_URL = "https://docs.docker.com/desktop/release-notes/"; + + private final static String REGEX_FOR_DOCKER_VERSION = + "href=#%s" // Find the href with the readable version - %s provided by urlVersion + + ".{0,300}" // We have to look in close range for the next part (docker lists a summary at top. If this range is to big + // we'll find the latest listed version with download links that doesn't match the version we are looking for + + "href=https://desktop\\.docker\\.com" // Start of download link + + ".*?" // We don't care if its windows or mac - match as least as possible characters + + "(\\d{5,6})"; // Associated docker-version to readable version we are looking for + private final static String REGEX_FOR_DOWNLOAD_URLS = "https://desktop.docker.com/%s/main/%s/%s/"; + private final static String WIN_VERSION = "win"; + private final static String MAC_VERSION = "mac"; + private final static String AMD_ARCH_TYPE = "amd64"; + private final static String ARM_ARCH_TYPE = "arm64"; + @Override protected String getTool() { @@ -29,31 +46,79 @@ protected void addVersion(UrlVersion urlVersion) { VersionIdentifier vid = VersionIdentifier.of(urlVersion.getName()); String version = urlVersion.getName().replaceAll("\\.", ""); // get Code for version - String body = doGetResponseBodyAsString("https://docs.docker.com/desktop/release-notes/"); - String regex = "href=#" + version - // .....................................................(Group.1.).......... - + ".{8,12}.{0,350}href=https://desktop\\.docker\\.com.*?(\\d{5,6}).*\\.exe"; - Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); - Matcher matcher = pattern.matcher(body); + String body = doGetResponseBodyAsString(DOCKER_RELEASE_NOTES_URL); + String regexForDockerVersion = format(REGEX_FOR_DOCKER_VERSION, version); + Pattern patternForDockerVersion = Pattern.compile(regexForDockerVersion, Pattern.DOTALL); + Matcher matcherForDockerVersion = patternForDockerVersion.matcher(body); String code; - if (matcher.find()) { - code = matcher.group(1); - boolean success = doAddVersion(urlVersion, - "https://desktop.docker.com/win/main/amd64/" + code + "/Docker%20Desktop%20Installer.exe", WINDOWS); - if (!success) { - return; - } + if (matcherForDockerVersion.find()) { + code = matcherForDockerVersion.group(1); + addVersionsForWindows(urlVersion, code, body); if (!WINDOWS_ONLY_VERSIONS.stream().anyMatch(i -> vid.compareVersion(i).isEqual())) { - doAddVersion(urlVersion, "https://desktop.docker.com/mac/main/amd64/" + code + "/Docker.dmg", MAC, X64); - doAddVersion(urlVersion, "https://desktop.docker.com/mac/main/arm64/" + code + "/Docker.dmg", MAC, ARM64); + addVersionsForMac(urlVersion, code, body); } } } + /** + * Adds the windows versions for docker if they exist + * + * @param urlVersion the readable version e.g. 4332 (4.33.2) + * @param dockerVersion the associated docker version to readable version e.g. 179689 + * @param body the html body to search in + */ + private void addVersionsForWindows(UrlVersion urlVersion, String dockerVersion, String body) { + boolean versionExists = checkIfVersionExists(dockerVersion, body, WIN_VERSION, AMD_ARCH_TYPE); + if (versionExists) { + doAddVersion(urlVersion, "https://desktop.docker.com/win/main/amd64/" + dockerVersion + "/Docker%20Desktop%20Installer.exe", WINDOWS, X64); + } + versionExists = checkIfVersionExists(dockerVersion, body, WIN_VERSION, ARM_ARCH_TYPE); + if (versionExists) { + doAddVersion(urlVersion, "https://desktop.docker.com/win/main/arm64/" + dockerVersion + "/Docker%20Desktop%20Installer.exe", WINDOWS, ARM64); + } + } + + /** + * Adds the mac versions for docker if they exist + * + * @param urlVersion the readable version e.g. 4332 (4.33.2) + * @param dockerVersion the associated docker version to readable version e.g. 179689 + * @param body the html body to search in + */ + private void addVersionsForMac(UrlVersion urlVersion, String dockerVersion, String body) { + boolean versionExists = checkIfVersionExists(dockerVersion, body, MAC_VERSION, AMD_ARCH_TYPE); + if (versionExists) { + doAddVersion(urlVersion, "https://desktop.docker.com/mac/main/amd64/" + dockerVersion + "/Docker.dmg", MAC, X64); + } + versionExists = checkIfVersionExists(dockerVersion, body, MAC_VERSION, ARM_ARCH_TYPE); + if (versionExists) { + doAddVersion(urlVersion, "https://desktop.docker.com/mac/main/arm64/" + dockerVersion + "/Docker.dmg", MAC, ARM64); + } + } + + /** + * As docker is very inconsistent by releasing versions we have to check every single one if the download link exists to prevent failing downloads + * (403-errors) E.g. for only amd64 windows download link provided- 4.24.1 E.g. for no + * download links provided - 4.24.2 E.g. for only mac download links provided - 4.36.1 + * + * @param dockerVersion the associated docker version to readable version e.g. 179689 (4.33.2) + * @param body the html body to search in + * @param osVersion the os versions - win or mac + * @param archType the archType - amd64 or arm64 + * @return true if the version exists - false if not + */ + private boolean checkIfVersionExists(String dockerVersion, String body, String osVersion, String archType) { + String regexForDownloadUrlS = format(REGEX_FOR_DOWNLOAD_URLS, osVersion, archType, dockerVersion); + Pattern patternForDownloadUrls = Pattern.compile(regexForDownloadUrlS, Pattern.DOTALL); + Matcher matcherForDownloadUrls = patternForDownloadUrls.matcher(body); + return matcherForDownloadUrls.find(); + } + @Override protected String getVersionUrl() { - return "https://docs.docker.com/desktop/release-notes/"; + return DOCKER_RELEASE_NOTES_URL; } @Override From 20652d36c3630f9a2140f6d5308cef56e89b8847 Mon Sep 17 00:00:00 2001 From: mbilda Date: Thu, 27 Mar 2025 08:38:20 +0100 Subject: [PATCH 09/16] https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater for docker desktop to pull all necessary versions #1181 - removed the fix for issue https://github.com/devonfw/IDEasy/issues/692 --- .../tools/ide/tool/repository/AbstractToolRepository.java | 6 +----- .../tools/ide/url/model/folder/AbstractUrlFolder.java | 3 --- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java b/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java index bb9b679dd0..6cca091a43 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/repository/AbstractToolRepository.java @@ -135,11 +135,7 @@ protected String createDownloadFilename(String tool, String edition, VersionIden StringBuilder sb = new StringBuilder(32); sb.append(tool); sb.append("-"); - if (VersionIdentifier.LATEST.equals(version)) { - sb.append("latest"); - } else { - sb.append(version); - } + sb.append(version); if (!edition.equals(tool)) { sb.append("-"); sb.append(edition); diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java index fed985b67d..2daa4f1c8d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/AbstractUrlFolder.java @@ -58,9 +58,6 @@ public int getChildCount() { public C getChild(String name) { load(false); - if ("*".equals(name)) { - return this.childMap.get("latest"); - } return this.childMap.get(name); } From d954a5a1addb0bd548cb46457eaba57bbaffa704 Mon Sep 17 00:00:00 2001 From: mbilda Date: Thu, 27 Mar 2025 08:47:35 +0100 Subject: [PATCH 10/16] https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater for docker desktop to pull all necessary versions - removed changelog --- CHANGELOG.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index c5a745fc37..2c4ddd7261 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -6,7 +6,6 @@ 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/692[#692]: "Latest" version of Docker causes installation problems * https://github.com/devonfw/IDEasy/issues/1153[#1153]: Print SystemInfo in ide status * https://github.com/devonfw/IDEasy/issues/1006[#1006]: Eclipse automation opens UI that blocks further processing until closed * https://github.com/devonfw/IDEasy/issues/1110[#1110]: ide status fails with IllegalStateException when offline From 340a1490ee825eec7d3bc0ce9d0207741bebf4b5 Mon Sep 17 00:00:00 2001 From: mbilda Date: Thu, 27 Mar 2025 08:56:52 +0100 Subject: [PATCH 11/16] https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater for docker desktop to pull all necessary versions - removed test for different issue --- .../ide/url/tool/UrlUpdaterMockSingle.java | 9 -------- .../tools/ide/url/tool/UrlUpdaterTest.java | 23 ------------------- 2 files changed, 32 deletions(-) diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java index e0697f6682..de611ba418 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java @@ -30,15 +30,6 @@ protected Set getVersions() { return versions; } - /** - * Enables the possibility to change the version which should be tested. - * - * @param newVersion the new Version to be set. - */ - protected void setVersion(final String newVersion) { - versions = Set.of(newVersion); - } - @Override protected void addVersion(UrlVersion urlVersion) { doAddVersion(urlVersion, wmRuntimeInfo.getHttpBaseUrl() + "/os/windows_x64_url.tgz", WINDOWS, X64, "123"); diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java index 9692fe5fd9..d751c0b392 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java @@ -279,27 +279,4 @@ public void testUrlUpdaterWithTextContentTypeWillNotCreateStatusJson(@TempDir Pa assertThat(versionsPath.resolve("status.json")).doesNotExist(); } - - /** - * Tests if the {@link com.devonfw.tools.ide.url.updater.UrlUpdater} will handle the literally latest version of a tool correctly - * - * @param tempDir Temporary directory - * @param wmRuntimeInfo wireMock server on a random port - */ - @Test - public void testUrlUpdaterWithOnlyLatestVersion(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) { - //given - stubFor(any(urlMatching("/os/.*")).willReturn(aResponse().withStatus(200).withBody("aBody"))); - UrlRepository urlRepository = UrlRepository.load(tempDir); - UrlUpdaterMockSingle updater = new UrlUpdaterMockSingle(wmRuntimeInfo); - updater.setVersion("latest"); - - // when - updater.update(urlRepository); - - // then - Path versionsPath = tempDir.resolve("mocked").resolve("mocked").resolve("latest"); - assertThat(versionsPath.resolve("status.json")).exists(); - } - } From 97f4083db3ded37723e9f852c133cc1e48ee2cac Mon Sep 17 00:00:00 2001 From: mbilda Date: Thu, 27 Mar 2025 08:59:40 +0100 Subject: [PATCH 12/16] https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater for docker desktop to pull all necessary versions - formatting --- .../com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java | 2 +- .../java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java index de611ba418..3ca4b44072 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterMockSingle.java @@ -13,7 +13,7 @@ */ public class UrlUpdaterMockSingle extends UrlUpdaterMock { - private static Set versions = new HashSet<>(List.of("1.0")); + private static final Set versions = new HashSet<>(List.of("1.0")); /** * The constructor diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java index d751c0b392..e6abb0db03 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/UrlUpdaterTest.java @@ -279,4 +279,5 @@ public void testUrlUpdaterWithTextContentTypeWillNotCreateStatusJson(@TempDir Pa assertThat(versionsPath.resolve("status.json")).doesNotExist(); } + } From 0af8fa2b12d8c2a72142ebbd70fdb1832f85c806 Mon Sep 17 00:00:00 2001 From: mbilda Date: Thu, 27 Mar 2025 12:17:40 +0100 Subject: [PATCH 13/16] https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater for docker desktop to pull all necessary versions - added checksum curl to get checksum for specific version - added checksum result to addVersion to prevent url updater to calculate checksum by itself --- .../tool/docker/DockerDesktopUrlUpdater.java | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java index 6000fcbcc5..d52d1b4097 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java @@ -33,6 +33,12 @@ public class DockerDesktopUrlUpdater extends WebsiteUrlUpdater { private final static String MAC_VERSION = "mac"; private final static String AMD_ARCH_TYPE = "amd64"; private final static String ARM_ARCH_TYPE = "arm64"; + private final static String WIN_BASE_URL = "https://desktop.docker.com/win/main/"; + private final static String WIN_AMD_URL = WIN_BASE_URL + AMD_ARCH_TYPE + "/"; + private final static String WIN_ARM_URL = WIN_BASE_URL + ARM_ARCH_TYPE + "/"; + private final static String MAC_BASE_URL = "https://desktop.docker.com/mac/main/"; + private final static String MAC_AMD_URL = MAC_BASE_URL + AMD_ARCH_TYPE + "/"; + private final static String MAC_ARM_URL = MAC_BASE_URL + ARM_ARCH_TYPE + "/"; @Override protected String getTool() { @@ -70,11 +76,13 @@ protected void addVersion(UrlVersion urlVersion) { private void addVersionsForWindows(UrlVersion urlVersion, String dockerVersion, String body) { boolean versionExists = checkIfVersionExists(dockerVersion, body, WIN_VERSION, AMD_ARCH_TYPE); if (versionExists) { - doAddVersion(urlVersion, "https://desktop.docker.com/win/main/amd64/" + dockerVersion + "/Docker%20Desktop%20Installer.exe", WINDOWS, X64); + String cs = getChecksum(WIN_AMD_URL + dockerVersion + "/checksum.txt"); + doAddVersion(urlVersion, WIN_AMD_URL + dockerVersion + "/Docker%20Desktop%20Installer.exe", WINDOWS, X64, cs); } versionExists = checkIfVersionExists(dockerVersion, body, WIN_VERSION, ARM_ARCH_TYPE); if (versionExists) { - doAddVersion(urlVersion, "https://desktop.docker.com/win/main/arm64/" + dockerVersion + "/Docker%20Desktop%20Installer.exe", WINDOWS, ARM64); + String cs = getChecksum(WIN_ARM_URL + dockerVersion + "/checksum.txt"); + doAddVersion(urlVersion, WIN_ARM_URL + dockerVersion + "/Docker%20Desktop%20Installer.exe", WINDOWS, ARM64, cs); } } @@ -88,11 +96,13 @@ private void addVersionsForWindows(UrlVersion urlVersion, String dockerVersion, private void addVersionsForMac(UrlVersion urlVersion, String dockerVersion, String body) { boolean versionExists = checkIfVersionExists(dockerVersion, body, MAC_VERSION, AMD_ARCH_TYPE); if (versionExists) { - doAddVersion(urlVersion, "https://desktop.docker.com/mac/main/amd64/" + dockerVersion + "/Docker.dmg", MAC, X64); + String cs = getChecksum(MAC_AMD_URL + dockerVersion + "/checksum.txt"); + doAddVersion(urlVersion, MAC_AMD_URL + dockerVersion + "/Docker.dmg", MAC, X64, cs); } versionExists = checkIfVersionExists(dockerVersion, body, MAC_VERSION, ARM_ARCH_TYPE); if (versionExists) { - doAddVersion(urlVersion, "https://desktop.docker.com/mac/main/arm64/" + dockerVersion + "/Docker.dmg", MAC, ARM64); + String cs = getChecksum(MAC_ARM_URL + dockerVersion + "/checksum.txt"); + doAddVersion(urlVersion, MAC_ARM_URL + dockerVersion + "/Docker.dmg", MAC, ARM64, cs); } } @@ -115,6 +125,18 @@ private boolean checkIfVersionExists(String dockerVersion, String body, String o return matcherForDownloadUrls.find(); } + /** + * Retrieves the checksum for the passed url + * + * @param url url for specific version to download + * @return the checksum in string format + */ + private String getChecksum(String url) { + String checksumAsString = doGetResponseBodyAsString(url); + // Example checksum response: e832d4c2c99300436096b2e990220068e69ede845137a9dd63eff0a51e8a14e9 *Docker Desktop Installer.exe + return checksumAsString.split(" ")[0]; + } + @Override protected String getVersionUrl() { From 2d97315441ec0abb888d1d9aa690aa2c573654a1 Mon Sep 17 00:00:00 2001 From: mbilda Date: Mon, 7 Apr 2025 11:43:54 +0200 Subject: [PATCH 14/16] https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater for docker desktop to pull all necessary versions - added review remarks - introduced constants to remove hardcoded filename --- .../tool/docker/DockerDesktopUrlUpdater.java | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java index d52d1b4097..68cbf53cef 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java @@ -20,26 +20,32 @@ public class DockerDesktopUrlUpdater extends WebsiteUrlUpdater { VersionIdentifier.of("4.5.1")); private final static String DOCKER_RELEASE_NOTES_URL = "https://docs.docker.com/desktop/release-notes/"; - - private final static String REGEX_FOR_DOCKER_VERSION = - "href=#%s" // Find the href with the readable version - %s provided by urlVersion - + ".{0,300}" // We have to look in close range for the next part (docker lists a summary at top. If this range is to big - // we'll find the latest listed version with download links that doesn't match the version we are looking for - + "href=https://desktop\\.docker\\.com" // Start of download link - + ".*?" // We don't care if its windows or mac - match as least as possible characters - + "(\\d{5,6})"; // Associated docker-version to readable version we are looking for - private final static String REGEX_FOR_DOWNLOAD_URLS = "https://desktop.docker.com/%s/main/%s/%s/"; - private final static String WIN_VERSION = "win"; - private final static String MAC_VERSION = "mac"; private final static String AMD_ARCH_TYPE = "amd64"; private final static String ARM_ARCH_TYPE = "arm64"; + private final static String CHECKSUM_FILE = "checksum.txt"; + + private final static String WIN_VERSION = "win"; + private final static String WIN_FILE = "Docker%20Desktop%20Installer.exe"; private final static String WIN_BASE_URL = "https://desktop.docker.com/win/main/"; private final static String WIN_AMD_URL = WIN_BASE_URL + AMD_ARCH_TYPE + "/"; private final static String WIN_ARM_URL = WIN_BASE_URL + ARM_ARCH_TYPE + "/"; + + private final static String MAC_VERSION = "mac"; + private final static String MAC_FILE = "Docker.dmg"; private final static String MAC_BASE_URL = "https://desktop.docker.com/mac/main/"; private final static String MAC_AMD_URL = MAC_BASE_URL + AMD_ARCH_TYPE + "/"; private final static String MAC_ARM_URL = MAC_BASE_URL + ARM_ARCH_TYPE + "/"; + private final static String REGEX_FOR_DOWNLOAD_URLS = "https://desktop.docker.com/%s/main/%s/%s/"; + private final static String REGEX_FOR_DOCKER_VERSION = + "href=#%s" // Find the href with the readable version - %s provided by urlVersion + + ".{0,300}" // We have to look in close range for the next part (docker lists a summary at top. If this range is to big + // we'll find the latest listed version with download links that doesn't match the version we are looking for + + "href=https://desktop\\.docker\\.com" // Start of download link + + ".*?" // We don't care if its windows or mac - match as least as possible characters + + "(\\d{5,6})"; // Associated docker-version to readable version we are looking for + + @Override protected String getTool() { @@ -76,13 +82,13 @@ protected void addVersion(UrlVersion urlVersion) { private void addVersionsForWindows(UrlVersion urlVersion, String dockerVersion, String body) { boolean versionExists = checkIfVersionExists(dockerVersion, body, WIN_VERSION, AMD_ARCH_TYPE); if (versionExists) { - String cs = getChecksum(WIN_AMD_URL + dockerVersion + "/checksum.txt"); - doAddVersion(urlVersion, WIN_AMD_URL + dockerVersion + "/Docker%20Desktop%20Installer.exe", WINDOWS, X64, cs); + String cs = getChecksum(WIN_AMD_URL + dockerVersion + "/" + CHECKSUM_FILE); + doAddVersion(urlVersion, WIN_AMD_URL + dockerVersion + "/" + WIN_FILE, WINDOWS, X64, cs); } versionExists = checkIfVersionExists(dockerVersion, body, WIN_VERSION, ARM_ARCH_TYPE); if (versionExists) { - String cs = getChecksum(WIN_ARM_URL + dockerVersion + "/checksum.txt"); - doAddVersion(urlVersion, WIN_ARM_URL + dockerVersion + "/Docker%20Desktop%20Installer.exe", WINDOWS, ARM64, cs); + String cs = getChecksum(WIN_ARM_URL + dockerVersion + "/" + CHECKSUM_FILE); + doAddVersion(urlVersion, WIN_ARM_URL + dockerVersion + "/" + WIN_FILE, WINDOWS, ARM64, cs); } } @@ -96,13 +102,13 @@ private void addVersionsForWindows(UrlVersion urlVersion, String dockerVersion, private void addVersionsForMac(UrlVersion urlVersion, String dockerVersion, String body) { boolean versionExists = checkIfVersionExists(dockerVersion, body, MAC_VERSION, AMD_ARCH_TYPE); if (versionExists) { - String cs = getChecksum(MAC_AMD_URL + dockerVersion + "/checksum.txt"); - doAddVersion(urlVersion, MAC_AMD_URL + dockerVersion + "/Docker.dmg", MAC, X64, cs); + String cs = getChecksum(MAC_AMD_URL + dockerVersion + "/" + CHECKSUM_FILE); + doAddVersion(urlVersion, MAC_AMD_URL + dockerVersion + "/" + MAC_FILE, MAC, X64, cs); } versionExists = checkIfVersionExists(dockerVersion, body, MAC_VERSION, ARM_ARCH_TYPE); if (versionExists) { - String cs = getChecksum(MAC_ARM_URL + dockerVersion + "/checksum.txt"); - doAddVersion(urlVersion, MAC_ARM_URL + dockerVersion + "/Docker.dmg", MAC, ARM64, cs); + String cs = getChecksum(MAC_ARM_URL + dockerVersion + "/" + CHECKSUM_FILE); + doAddVersion(urlVersion, MAC_ARM_URL + dockerVersion + "/" + MAC_FILE, MAC, ARM64, cs); } } From 55dbbfe49bfa7b2079ead4798d03ce1598e8e49c Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Mon, 12 May 2025 15:10:16 +0200 Subject: [PATCH 15/16] #692: fixed checksum detection --- .../tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java index bcf6aa2d2d..60df614728 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java @@ -22,7 +22,7 @@ public class DockerDesktopUrlUpdater extends WebsiteUrlUpdater { private final static String DOCKER_RELEASE_NOTES_URL = "https://docs.docker.com/desktop/release-notes/"; private final static String AMD_ARCH_TYPE = "amd64"; private final static String ARM_ARCH_TYPE = "arm64"; - private final static String CHECKSUM_FILE = "checksum.txt"; + private final static String CHECKSUM_FILE = "checksums.txt"; private final static String WIN_VERSION = "win"; private final static String WIN_FILE = "Docker%20Desktop%20Installer.exe"; From e54e8f9438044541ac114f4ff5c55b5fe2f644be Mon Sep 17 00:00:00 2001 From: jan-vcapgemini Date: Wed, 13 Aug 2025 00:30:30 +0200 Subject: [PATCH 16/16] #692: Optimized DockerDesktopUrlUpdater for tests fixed the regex for the download urls (made sure that all versions can be found) made sure that a dynamic base URL can be used by WireMock added a test for the DockerDesktopUrlUpdater (using an old download URL pattern and a new one) added a test resource file based on the original website --- .../tool/docker/DockerDesktopUrlUpdater.java | 47 ++++++++-------- .../docker/DockerDesktopUrlUpdaterMock.java | 35 ++++++++++++ .../docker/DockerDesktopUrlUpdaterTest.java | 55 +++++++++++++++++++ .../DockerDesktopUrlUpdater/index.html | 35 ++++++++++++ 4 files changed, 150 insertions(+), 22 deletions(-) create mode 100644 url-updater/src/test/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdaterMock.java create mode 100644 url-updater/src/test/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdaterTest.java create mode 100644 url-updater/src/test/resources/integrationtest/DockerDesktopUrlUpdater/index.html diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java index 1c72f2dfd1..826fa8c9a0 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java @@ -27,22 +27,22 @@ public class DockerDesktopUrlUpdater extends WebsiteUrlUpdater { private final static String WIN_VERSION = "win"; private final static String WIN_FILE = "Docker%20Desktop%20Installer.exe"; - private final static String WIN_BASE_URL = "https://desktop.docker.com/win/main/"; + private final static String WIN_BASE_URL = "/win/main/"; private final static String WIN_AMD_URL = WIN_BASE_URL + AMD_ARCH_TYPE + "/"; private final static String WIN_ARM_URL = WIN_BASE_URL + ARM_ARCH_TYPE + "/"; private final static String MAC_VERSION = "mac"; private final static String MAC_FILE = "Docker.dmg"; - private final static String MAC_BASE_URL = "https://desktop.docker.com/mac/main/"; + private final static String MAC_BASE_URL = "/mac/main/"; private final static String MAC_AMD_URL = MAC_BASE_URL + AMD_ARCH_TYPE + "/"; private final static String MAC_ARM_URL = MAC_BASE_URL + ARM_ARCH_TYPE + "/"; - private final static String REGEX_FOR_DOWNLOAD_URLS = "https://desktop.docker.com/%s/main/%s/%s/"; + private final static String REGEX_FOR_DOWNLOAD_URLS = "/%s/main/%s/%s/"; private final static String REGEX_FOR_DOCKER_VERSION = "href=#%s" // Find the href with the readable version - %s provided by urlVersion - + ".{0,300}" // We have to look in close range for the next part (docker lists a summary at top. If this range is to big + + ".{0,300}" // We have to look in close range for the next part (docker lists a summary at top. If this range is too big // we'll find the latest listed version with download links that doesn't match the version we are looking for - + "href=https://desktop\\.docker\\.com" // Start of download link + + "href=(\")?%s" // Start of download link + ".*?" // We don't care if its windows or mac - match as least as possible characters + "(\\d{5,6})"; // Associated docker-version to readable version we are looking for @@ -60,14 +60,14 @@ protected void addVersion(UrlVersion urlVersion) { String version = urlVersion.getName().replaceAll("\\.", ""); // get Code for version String body = doGetResponseBodyAsString(getVersionUrl()); - String regexForDockerVersion = format(REGEX_FOR_DOCKER_VERSION, version); + String regexForDockerVersion = format(REGEX_FOR_DOCKER_VERSION, version, getDownloadBaseUrl()); Pattern patternForDockerVersion = Pattern.compile(regexForDockerVersion, Pattern.DOTALL); Matcher matcherForDockerVersion = patternForDockerVersion.matcher(body); String code; if (matcherForDockerVersion.find()) { - code = matcherForDockerVersion.group(1); - addVersionsForWindows(urlVersion, code, body); - boolean success = addVersionsForWindows(urlVersion, code, body); + code = matcherForDockerVersion.group(2); + boolean success; + success = addVersionsForWindows(urlVersion, code, body); if (!success) { return; } @@ -83,21 +83,21 @@ protected void addVersion(UrlVersion urlVersion) { * @param urlVersion the readable version e.g. 4332 (4.33.2) * @param dockerVersion the associated docker version to readable version e.g. 179689 * @param body the html body to search in + * @return {@code true} if version was added successfully, {@code false} if not. */ private boolean addVersionsForWindows(UrlVersion urlVersion, String dockerVersion, String body) { boolean versionExists = checkIfVersionExists(dockerVersion, body, WIN_VERSION, AMD_ARCH_TYPE); + boolean success = false; if (versionExists) { - String cs = getChecksum(WIN_AMD_URL + dockerVersion + "/" + CHECKSUM_FILE); - doAddVersion(urlVersion, WIN_AMD_URL + dockerVersion + "/" + WIN_FILE, WINDOWS, X64, cs); + String cs = getChecksum(getDownloadBaseUrl() + WIN_AMD_URL + dockerVersion + "/" + CHECKSUM_FILE); + success = doAddVersion(urlVersion, getDownloadBaseUrl() + WIN_AMD_URL + dockerVersion + "/" + WIN_FILE, WINDOWS, X64, cs); } versionExists = checkIfVersionExists(dockerVersion, body, WIN_VERSION, ARM_ARCH_TYPE); if (versionExists) { - String cs = getChecksum(WIN_ARM_URL + dockerVersion + "/" + CHECKSUM_FILE); - doAddVersion(urlVersion, WIN_ARM_URL + dockerVersion + "/" + WIN_FILE, WINDOWS, ARM64, cs); - } else { - return false; + String cs = getChecksum(getDownloadBaseUrl() + WIN_ARM_URL + dockerVersion + "/" + CHECKSUM_FILE); + success = doAddVersion(urlVersion, getDownloadBaseUrl() + WIN_ARM_URL + dockerVersion + "/" + WIN_FILE, WINDOWS, ARM64, cs); } - return true; + return success; } /** @@ -106,18 +106,21 @@ private boolean addVersionsForWindows(UrlVersion urlVersion, String dockerVersio * @param urlVersion the readable version e.g. 4332 (4.33.2) * @param dockerVersion the associated docker version to readable version e.g. 179689 * @param body the html body to search in + * @return {@code true} if version was added successfully, {@code false} if not. */ - private void addVersionsForMac(UrlVersion urlVersion, String dockerVersion, String body) { + private boolean addVersionsForMac(UrlVersion urlVersion, String dockerVersion, String body) { boolean versionExists = checkIfVersionExists(dockerVersion, body, MAC_VERSION, AMD_ARCH_TYPE); + boolean success = false; if (versionExists) { - String cs = getChecksum(MAC_AMD_URL + dockerVersion + "/" + CHECKSUM_FILE); - doAddVersion(urlVersion, MAC_AMD_URL + dockerVersion + "/" + MAC_FILE, MAC, X64, cs); + String cs = getChecksum(getDownloadBaseUrl() + MAC_AMD_URL + dockerVersion + "/" + CHECKSUM_FILE); + success = doAddVersion(urlVersion, getDownloadBaseUrl() + MAC_AMD_URL + dockerVersion + "/" + MAC_FILE, MAC, X64, cs); } versionExists = checkIfVersionExists(dockerVersion, body, MAC_VERSION, ARM_ARCH_TYPE); if (versionExists) { - String cs = getChecksum(MAC_ARM_URL + dockerVersion + "/" + CHECKSUM_FILE); - doAddVersion(urlVersion, MAC_ARM_URL + dockerVersion + "/" + MAC_FILE, MAC, ARM64, cs); + String cs = getChecksum(getDownloadBaseUrl() + MAC_ARM_URL + dockerVersion + "/" + CHECKSUM_FILE); + success = doAddVersion(urlVersion, getDownloadBaseUrl() + MAC_ARM_URL + dockerVersion + "/" + MAC_FILE, MAC, ARM64, cs); } + return success; } /** @@ -133,7 +136,7 @@ private void addVersionsForMac(UrlVersion urlVersion, String dockerVersion, Stri * @return true if the version exists - false if not */ private boolean checkIfVersionExists(String dockerVersion, String body, String osVersion, String archType) { - String regexForDownloadUrlS = format(REGEX_FOR_DOWNLOAD_URLS, osVersion, archType, dockerVersion); + String regexForDownloadUrlS = format(getDownloadBaseUrl() + REGEX_FOR_DOWNLOAD_URLS, osVersion, archType, dockerVersion); Pattern patternForDownloadUrls = Pattern.compile(regexForDownloadUrlS, Pattern.DOTALL); Matcher matcherForDownloadUrls = patternForDownloadUrls.matcher(body); return matcherForDownloadUrls.find(); diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdaterMock.java new file mode 100644 index 0000000000..cfd904825b --- /dev/null +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdaterMock.java @@ -0,0 +1,35 @@ +package com.devonfw.tools.ide.url.tool.docker; + +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; + +/** + * Mock of {@link DockerDesktopUrlUpdater} to allow integration testing with wiremock. + */ +public class DockerDesktopUrlUpdaterMock extends DockerDesktopUrlUpdater { + + private final String baseUrl; + + /** + * The constructor. + * + * @param wireMockRuntimeInfo wireMock server on a random port + */ + public DockerDesktopUrlUpdaterMock(WireMockRuntimeInfo wireMockRuntimeInfo) { + super(); + this.baseUrl = wireMockRuntimeInfo.getHttpBaseUrl(); + } + + @Override + public String getDownloadBaseUrl() { + + return baseUrl; + } + + @Override + protected String getVersionBaseUrl() { + + return this.baseUrl; + } + +} + diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdaterTest.java new file mode 100644 index 0000000000..f2f48298b2 --- /dev/null +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdaterTest.java @@ -0,0 +1,55 @@ +package com.devonfw.tools.ide.url.tool.docker; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.any; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import com.devonfw.tools.ide.url.model.folder.UrlRepository; +import com.devonfw.tools.ide.url.updater.AbstractUrlUpdaterTest; +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; +import com.github.tomakehurst.wiremock.junit5.WireMockTest; + +/** + * Test class for integrations of the {@link DockerDesktopUrlUpdater}. + */ +@WireMockTest +public class DockerDesktopUrlUpdaterTest extends AbstractUrlUpdaterTest { + + /** + * Integration test for {@link DockerDesktopUrlUpdater}: verifies that update creates expected files for DockerDesktop versions. + */ + @Test + void testDockerDesktopUpdaterCreatesDownloadUrlsAndChecksums(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) throws IOException { + // arrange + stubFor(get(urlMatching("/desktop/release-notes/")).willReturn(aResponse().withStatus(200) + .withBody(readAndResolve(PATH_INTEGRATION_TEST.resolve("DockerDesktopUrlUpdater").resolve("index.html"), wmRuntimeInfo)))); + stubFor( + any(urlMatching("/(win|mac)/main/(amd64|arm64)/[0-9.]+/D.*")) + .willReturn(aResponse().withStatus(200).withBody(DOWNLOAD_CONTENT))); + stubFor( + any(urlMatching("/.*/checksums.txt")) + .willReturn( + aResponse().withStatus(200).withBody(SHA_256))); + + UrlRepository urlRepository = UrlRepository.load(tempDir); + DockerDesktopUrlUpdater updater = new DockerDesktopUrlUpdaterMock(wmRuntimeInfo); + // act + updater.update(urlRepository); + + // assert + Path dockerDesktopEditionPath = tempDir.resolve("docker").resolve("docker"); + for (String version : new String[] { "4.30.0", "4.34.0" }) { + Path pgadminVersionPath = dockerDesktopEditionPath.resolve(version); + assertUrlVersion(pgadminVersionPath, List.of("windows_x64", "windows_arm64", "mac_x64", "mac_arm64")); + } + } +} diff --git a/url-updater/src/test/resources/integrationtest/DockerDesktopUrlUpdater/index.html b/url-updater/src/test/resources/integrationtest/DockerDesktopUrlUpdater/index.html new file mode 100644 index 0000000000..eb0354f5f4 --- /dev/null +++ b/url-updater/src/test/resources/integrationtest/DockerDesktopUrlUpdater/index.html @@ -0,0 +1,35 @@ +

4.34.0

2024-08-29

New

  • Host networking support on Docker Desktop is now generally available.
  • If you authenticate via the CLI, you can now authenticate through a browser-based flow, removing the need for manual PAT generation.
  • Windows now supports automatic reclamation of disk space in Docker Desktop for WSL2 installations + using a managed virtual hard disk.
  • Deploying Docker Desktop via the + MSI installer is now generally available.
  • Two new methods to + enforce sign-in (windows registry key and .plist file) are now generally available.
  • Fresh installations of Docker Desktop now use the containerd image store by default.
  • Compose Bridge (Experimental) is now available from the Compose file viewer. Easily convert and deploy your Compose project to a Kubernetes cluster.

Upgrades

Bug fixes and enhancements

For all platforms

  • Fixed a bug that caused the CLI to become idle when a container was started with AutoRemove (--rm) but whose port bindings would be rejected by Docker Desktop at start-up.
  • Fixed a bug where diagnostics collection would fail sporadically on the Support screen.
  • Fixed a bug where folders wouldn't expand in a container's File tab. Fixes docker/for-win#14204.
  • In-app updates now respect the proxy settings.
  • Extended the ECI Docker socket mount permissions feature to optionally child images derived from allowed images. This allows ECI to work with buildpacks (e.g., Paketo) that create ephemeral local images that use Docker socket mounts.
  • Fixed a bug that caused the Containers view to flash when using certain proxy settings. Fixes docker/for-win#13972.
  • Improved the output of docker image list to show multi-platform-related image information.

For Mac

  • Fixed a bug where a Partial repair error would occasionally appear when triggering the Configuration integrity check feature.
  • Configuration integrity check feature now shows information on why the Docker socket is mis-configured.
  • Fixed an issue where the Configuration integrity check feature would report the system path instead of the user path if Docker Desktop is installed as User.
  • Fixed a bug where applications trying to read extended attributes from bind mounted volumes could experience failures. Fixes docker/for-mac#7377.

For Windows

Known issues

  • Compose Bridge does not work automatically when you enable it within the Experimental settings tab. It takes a few minutes before you are notified that you must 'repair' Docker Desktop which then installs the compose-bridge binary.
  • The Convert and Deploy button in the Compose file viewer might be disabled even when Kubernetes is running and Compose Bridge is enabled. The workaround for this is to disable Compose Bridge in the Experimental settings tab, apply the change with Apply & restart, then re-enable and select Apply & restart again.
  • There is a known issue when authenticating against a registry in the Docker CLI (docker login [registry address]) where, if the provided registry address includes a repository/image name (such as docker login index.docker.io/docker/welcome-to-docker), the repository part (docker/welcome-to-docker) is not normalized and results in credentials being stored incorrectly, which causes subsequent pulls from the registry (docker pull index.docker.io/docker/welcome-to-docker) to not be authenticated. To prevent this, don't include any extraneous suffix in the registry address when running docker login.
    +Note

    Using docker login with an address that includes URL path segments is not a documented use case and is considered unsupported. The recommended usage is to specify only a registry hostname, and optionally a port, as the address for docker login.

  • When running docker compose up and Docker Desktop is in the Resource Saver mode, the command is unresponsive. As a workaround, manually exit the Resource Saving mode and Docker Compose becomes responsive again.
  • When + Enhanced Container Isolation (ECI) is enabled, Docker Desktop may not enter Resource Saver mode. This will be fixed in a future Docker Desktop release.
  • The new
+ +4.30.02024-05-06

Download Docker Desktop

Windows + (checksum) | + Windows ARM Beta + (checksum) | + Mac + with Apple chip + (checksum) | + Mac + with Intel chip + (checksum) + | + Debian + - + RPM + - + Arch + (checksum)

New

For all platforms

For Windows

  • Added support for