Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
60bb713
https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Do…
mbilda Mar 7, 2025
c638a15
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Mar 10, 2025
ebc9908
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Mar 11, 2025
1c3b98e
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Mar 11, 2025
3310471
https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Do…
mbilda Mar 11, 2025
2037ae2
https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Do…
mbilda Mar 11, 2025
be49cea
https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Do…
mbilda Mar 12, 2025
56f1c73
https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Do…
mbilda Mar 13, 2025
a45edbc
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
mbilda Mar 13, 2025
a1046cc
https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Do…
mbilda Mar 13, 2025
ff8fe15
https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Do…
mbilda Mar 13, 2025
1d76b49
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
mbilda Mar 17, 2025
c2d0e2b
https://github.com/devonfw/IDEasy/issues/692 : "Latest" version of Do…
mbilda Mar 17, 2025
9394d51
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Mar 26, 2025
20652d3
https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater f…
mbilda Mar 27, 2025
d954a5a
https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater f…
mbilda Mar 27, 2025
340a149
https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater f…
mbilda Mar 27, 2025
97f4083
https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater f…
mbilda Mar 27, 2025
0af8fa2
https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater f…
mbilda Mar 27, 2025
33c07dd
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Mar 31, 2025
2d97315
https://github.com/devonfw/IDEasy/issues/1181 : Improve url updater f…
mbilda Apr 7, 2025
74ee70a
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
mbilda Apr 7, 2025
51f7f7e
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Apr 7, 2025
3fa4236
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Apr 28, 2025
76a93a8
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini May 12, 2025
55dbbfe
#692: fixed checksum detection
jan-vcapgemini May 12, 2025
844faa6
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Aug 12, 2025
e54e8f9
#692: Optimized DockerDesktopUrlUpdater for tests
jan-vcapgemini Aug 12, 2025
8bc9b3c
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Aug 15, 2025
066ff7f
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Oct 14, 2025
72e716e
Merge branch 'main' into fix/692-fixing-url-updater-for-docker
jan-vcapgemini Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -19,6 +21,32 @@ public class DockerDesktopUrlUpdater extends WebsiteUrlUpdater {

private static final Pattern VERSION_PATTERN = Pattern.compile("(4\\.\\d{1,4}+\\.\\d+)");

private final static String AMD_ARCH_TYPE = "amd64";
private final static String ARM_ARCH_TYPE = "arm64";
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";
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 = "/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 = "/%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 too big
// we'll find the latest listed version with download links that doesn't match the version we are looking for
+ "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


@Override
protected String getTool() {

Expand All @@ -32,26 +60,100 @@ protected void addVersion(UrlVersion urlVersion) {
String version = urlVersion.getName().replaceAll("\\.", "");
// get Code for version
String body = doGetResponseBodyAsString(getVersionUrl());
String regex = "href=#" + version
// .......1.........................................................2.................
+ ".{8,12}(\r\n|\r|\n).{0,350}href=https://desktop\\.docker\\.com.*?(\\d{5,6}).*\\.exe";
Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
Matcher matcher = pattern.matcher(body);
String regexForDockerVersion = format(REGEX_FOR_DOCKER_VERSION, version, getDownloadBaseUrl());
Pattern patternForDockerVersion = Pattern.compile(regexForDockerVersion, Pattern.DOTALL);
Matcher matcherForDockerVersion = patternForDockerVersion.matcher(body);
String code;
if (matcher.find()) {
code = matcher.group(2);
boolean success = doAddVersion(urlVersion,
getDownloadBaseUrl() + "/win/main/amd64/" + code + "/Docker%20Desktop%20Installer.exe", WINDOWS);
if (matcherForDockerVersion.find()) {
code = matcherForDockerVersion.group(2);
boolean success;
success = addVersionsForWindows(urlVersion, code, body);
if (!success) {
return;
}
if (WINDOWS_ONLY_VERSIONS.stream().noneMatch(i -> vid.compareVersion(i).isEqual())) {
doAddVersion(urlVersion, getDownloadBaseUrl() + "/mac/main/amd64/" + code + "/Docker.dmg", MAC, X64);
doAddVersion(urlVersion, getDownloadBaseUrl() + "/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
* @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(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(getDownloadBaseUrl() + WIN_ARM_URL + dockerVersion + "/" + CHECKSUM_FILE);
success = doAddVersion(urlVersion, getDownloadBaseUrl() + WIN_ARM_URL + dockerVersion + "/" + WIN_FILE, WINDOWS, ARM64, cs);
}
return success;
}

/**
* 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
* @return {@code true} if version was added successfully, {@code false} if not.
*/
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(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(getDownloadBaseUrl() + MAC_ARM_URL + dockerVersion + "/" + CHECKSUM_FILE);
success = doAddVersion(urlVersion, getDownloadBaseUrl() + MAC_ARM_URL + dockerVersion + "/" + MAC_FILE, MAC, ARM64, cs);
}
return success;
}

/**
* 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- <a href="https://docs.docker.com/desktop/release-notes/#4241">4.24.1</a> E.g. for no
* download links provided - <a href="https://docs.docker.com/desktop/release-notes/#4242">4.24.2</a> E.g. for only mac download links provided - <a
* href="https://docs.docker.com/desktop/release-notes/#4361">4.36.1</a>
*
* @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(getDownloadBaseUrl() + REGEX_FOR_DOWNLOAD_URLS, osVersion, archType, dockerVersion);
Pattern patternForDownloadUrls = Pattern.compile(regexForDownloadUrlS, Pattern.DOTALL);
Matcher matcherForDownloadUrls = patternForDownloadUrls.matcher(body);
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 getDownloadBaseUrl() {

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}

}

Original file line number Diff line number Diff line change
@@ -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"));
}
}
}
Loading