Skip to content

Commit 66ce91d

Browse files
MarvMahohwille
andauthored
#1750: implemented GoUrlUpdater (#1753)
Co-authored-by: Jörg Hohwiller <hohwille@users.noreply.github.com>
1 parent 19700bf commit 66ce91d

8 files changed

Lines changed: 198 additions & 44 deletions

File tree

url-updater/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ public class UpdateInitiator {
2020

2121
/**
2222
* @param args the command-line arguments. arg[0] points to the {@code ide-urls} repository. arg[1] defines a timeout for GitHub actions in Duration
23-
* string format.
23+
* string format and arg[2] can be used to specify a single tool to update instead of all tools. The timeout is used to prevent the GitHub action from
24+
* running into a timeout error due to too long execution time.
2425
*/
2526
public static void main(String[] args) {
2627

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.devonfw.tools.ide.url.tool.go;
2+
3+
import com.devonfw.tools.ide.url.model.folder.UrlVersion;
4+
import com.devonfw.tools.ide.url.updater.GithubUrlTagUpdater;
5+
import com.devonfw.tools.ide.version.VersionIdentifier;
6+
7+
/**
8+
* {@link GithubUrlTagUpdater} for Go programming language.
9+
*/
10+
public class GoUrlUpdater extends GithubUrlTagUpdater {
11+
12+
private static final String GO_BASE_URL = "https://go.dev";
13+
14+
private static final VersionIdentifier MIN_GO_VID = VersionIdentifier.of("1.2.2");
15+
16+
private static final VersionIdentifier MIN_WIN_ARM_VID = VersionIdentifier.of("1.17");
17+
18+
private static final VersionIdentifier MIN_MAC_ARM_VID = VersionIdentifier.of("1.16");
19+
20+
@Override
21+
public String getTool() {
22+
return "go";
23+
}
24+
25+
@Override
26+
protected String getGithubOrganization() {
27+
return "golang";
28+
}
29+
30+
@Override
31+
protected String getGithubRepository() {
32+
return "go";
33+
}
34+
35+
@Override
36+
protected String getVersionPrefixToRemove() {
37+
return "go";
38+
}
39+
40+
@Override
41+
protected String getDownloadBaseUrl() {
42+
return GO_BASE_URL;
43+
}
44+
45+
@Override
46+
protected void addVersion(UrlVersion urlVersion) {
47+
String baseUrl = getDownloadBaseUrl() + "/dl/go${version}.";
48+
VersionIdentifier vid = urlVersion.getVersionIdentifier();
49+
50+
if (vid.compareVersion(MIN_GO_VID).isGreater()) {
51+
doAddVersion(urlVersion, baseUrl + "windows-amd64.zip", WINDOWS, X64);
52+
if (vid.compareVersion(MIN_WIN_ARM_VID).isGreater()) {
53+
doAddVersion(urlVersion, baseUrl + "windows-arm64.zip", WINDOWS, ARM64);
54+
}
55+
doAddVersion(urlVersion, baseUrl + "linux-amd64.tar.gz", LINUX, X64);
56+
doAddVersion(urlVersion, baseUrl + "linux-arm64.tar.gz", LINUX, ARM64);
57+
doAddVersion(urlVersion, baseUrl + "darwin-amd64.tar.gz", MAC, X64);
58+
if (vid.compareVersion(MIN_MAC_ARM_VID).isGreater()) {
59+
doAddVersion(urlVersion, baseUrl + "darwin-arm64.tar.gz", MAC, ARM64);
60+
}
61+
}
62+
}
63+
64+
65+
@Override
66+
protected String getCustomVersionFilter() {
67+
return "rc";
68+
}
69+
}
70+

url-updater/src/main/java/com/devonfw/tools/ide/url/tool/node/NodeUrlUpdater.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,5 @@ public String mapVersion(String version) {
8080

8181
return super.mapVersion("v" + version);
8282
}
83-
83+
8484
}

url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ public abstract class AbstractUrlUpdater extends AbstractProcessorWithTimeout im
7070
protected static final SystemArchitecture ARM64 = SystemArchitecture.ARM64;
7171

7272
/** List of URL file names dependent on OS which need to be checked for existence */
73-
private static final Set<String> URL_FILENAMES_PER_OS = Set.of("linux_x64.urls", "mac_arm64.urls", "mac_x64.urls",
74-
"windows_x64.urls");
73+
private static final Set<String> URL_FILENAMES_PER_OS = Set.of("linux_x64.urls", "mac_arm64.urls", "mac_x64.urls", "windows_x64.urls");
7574

7675
/** List of URL file name independent of OS which need to be checked for existence */
7776
private static final Set<String> URL_FILENAMES_OS_INDEPENDENT = Set.of("urls");
@@ -255,8 +254,7 @@ protected boolean doAddVersion(String edition, UrlVersion urlVersion, String dow
255254
* @param architecture the optional {@link SystemArchitecture}.
256255
* @return {@code true} if the version was successfully added, {@code false} otherwise.
257256
*/
258-
protected boolean doAddVersion(UrlVersion urlVersion, String downloadUrl, OperatingSystem os,
259-
SystemArchitecture architecture) {
257+
protected boolean doAddVersion(UrlVersion urlVersion, String downloadUrl, OperatingSystem os, SystemArchitecture architecture) {
260258

261259
return doAddVersion(getEdition(), urlVersion, downloadUrl, os, architecture, "");
262260
}
@@ -271,8 +269,7 @@ protected boolean doAddVersion(UrlVersion urlVersion, String downloadUrl, Operat
271269
* @param architecture the optional {@link SystemArchitecture}.
272270
* @return {@code true} if the version was successfully added, {@code false} otherwise.
273271
*/
274-
protected boolean doAddVersion(String edition, UrlVersion urlVersion, String downloadUrl, OperatingSystem os,
275-
SystemArchitecture architecture) {
272+
protected boolean doAddVersion(String edition, UrlVersion urlVersion, String downloadUrl, OperatingSystem os, SystemArchitecture architecture) {
276273

277274
return doAddVersion(edition, urlVersion, downloadUrl, os, architecture, "");
278275
}
@@ -303,8 +300,7 @@ protected boolean doAddVersion(UrlVersion urlVersion, String url, OperatingSyste
303300
* @param checksum the existing checksum (e.g. from JSON metadata) or the empty {@link String} if not available and computation needed.
304301
* @return {@code true} if the version was successfully added, {@code false} otherwise.
305302
*/
306-
protected boolean doAddVersion(String edition, UrlVersion urlVersion, String url, OperatingSystem os, SystemArchitecture architecture,
307-
String checksum) {
303+
protected boolean doAddVersion(String edition, UrlVersion urlVersion, String url, OperatingSystem os, SystemArchitecture architecture, String checksum) {
308304

309305
UrlStatusFile status = urlVersion.getStatus();
310306
if ((status != null) && status.getStatusJson().isManual()) {
@@ -347,14 +343,13 @@ protected boolean isSuccess(HttpResponse<?> response) {
347343
* @param url the URL the checksum belongs to.
348344
* @return {@code true} if update of checksum was successful, {@code false} otherwise.
349345
*/
350-
private static boolean isChecksumStillValid(String checksum, UrlChecksum urlChecksum,
351-
String toolWithEdition, String version, String url) {
346+
private static boolean isChecksumStillValid(String checksum, UrlChecksum urlChecksum, String toolWithEdition, String version, String url) {
352347

353348
String existingChecksum = urlChecksum.getChecksum();
354349

355350
if ((existingChecksum != null) && !existingChecksum.equals(checksum)) {
356-
logger.error("For tool {} and version {} the download URL {} results in checksum {} but expected {}.",
357-
toolWithEdition, version, url, checksum, existingChecksum);
351+
logger.error("For tool {} and version {} the download URL {} results in checksum {} but expected {}.", toolWithEdition, version, url, checksum,
352+
existingChecksum);
358353
return false;
359354
} else {
360355
urlChecksum.setChecksum(checksum);
@@ -377,8 +372,8 @@ private boolean isValidDownload(String url, String toolWithEdition, String versi
377372
String contentType = response.headers().firstValue("content-type").orElse("undefined");
378373
boolean isValidContentType = isValidContentType(contentType);
379374
if (!isValidContentType) {
380-
logger.error("For toolWithEdition {} and version {} the download has an invalid content type {} for URL {}", toolWithEdition, version,
381-
contentType, url);
375+
logger.error("For toolWithEdition {} and version {} the download has an invalid content type {} for URL {}", toolWithEdition, version, contentType,
376+
url);
382377
return false;
383378
}
384379
return true;
@@ -412,8 +407,8 @@ protected boolean isValidContentType(String contentType) {
412407
* @param checksum the existing checksum (e.g. from JSON metadata) or the empty {@link String} if not available and computation needed.
413408
* @return {@code true} if the download was checked successfully, {@code false} otherwise.
414409
*/
415-
private boolean doAddVersionUrlIfNewAndValid(String edition, String url, UrlVersion urlVersion, OperatingSystem os,
416-
SystemArchitecture architecture, String checksum) {
410+
private boolean doAddVersionUrlIfNewAndValid(String edition, String url, UrlVersion urlVersion, OperatingSystem os, SystemArchitecture architecture,
411+
String checksum) {
417412

418413
UrlDownloadFile urlDownloadFile = urlVersion.getUrls(os, architecture);
419414
if (urlDownloadFile != null) {
@@ -471,8 +466,7 @@ private boolean doAddVersionUrlIfNewAndValid(String edition, String url, UrlVers
471466
* @param version the {@link UrlVersion version} identifier.
472467
* @return checksum of input stream as hex string
473468
*/
474-
private String doGenerateChecksum(HttpResponse<InputStream> response, String url, String edition, String version,
475-
String contentType) {
469+
private String doGenerateChecksum(HttpResponse<InputStream> response, String url, String edition, String version, String contentType) {
476470

477471
logger.info("Computing checksum for download with URL {}", url);
478472
try (InputStream inputStream = response.body()) {
@@ -490,9 +484,8 @@ private String doGenerateChecksum(HttpResponse<InputStream> response, String url
490484
}
491485
byte[] digestBytes = md.digest();
492486
String checksum = HexUtil.toHexString(digestBytes);
493-
logger.info(
494-
"For tool {} and version {} we received {} bytes with content-type {} and computed SHA256 {} from URL {}",
495-
getToolWithEdition(edition), version, Long.valueOf(size), contentType, checksum, url);
487+
logger.info("For tool {} and version {} we received {} bytes with content-type {} and computed SHA256 {} from URL {}", getToolWithEdition(edition),
488+
version, Long.valueOf(size), contentType, checksum, url);
496489
return checksum;
497490
} catch (IOException e) {
498491
throw new IllegalStateException("Failed to read body of download " + url, e);
@@ -513,8 +506,7 @@ protected HttpResponse<?> doCheckDownloadViaHeadRequest(String url) {
513506
HttpRequest request = null;
514507
try {
515508
uri = URI.create(url);
516-
request = HttpRequest.newBuilder().uri(uri)
517-
.method("HEAD", HttpRequest.BodyPublishers.noBody()).timeout(Duration.ofSeconds(5)).build();
509+
request = HttpRequest.newBuilder().uri(uri).method("HEAD", HttpRequest.BodyPublishers.noBody()).timeout(Duration.ofSeconds(5)).build();
518510

519511
return this.client.send(request, HttpResponse.BodyHandlers.ofString());
520512
} catch (Exception e) {
@@ -580,17 +572,15 @@ private void doUpdateStatusJson(boolean success, int statusCode, String edition,
580572
modified = true;
581573
}
582574

583-
logger.info("For tool {} and version {} the download verification succeeded with status code {} for URL {}.", tool,
584-
version, code, url);
575+
logger.info("For tool {} and version {} the download verification succeeded with status code {} for URL {}.", tool, version, code, url);
585576
getUrlUpdaterReport().incrementVerificationSuccess();
586577
} else {
587578
if (status != null) {
588579
if (errorStatus == null) {
589580
modified = true;
590581
} else {
591582
if (!Objects.equals(code, errorStatus.getCode())) {
592-
logger.warn("For tool {} and version {} the error status-code changed from {} to {} for URL {}.", tool,
593-
version, code, errorStatus.getCode(), url);
583+
logger.warn("For tool {} and version {} the error status-code changed from {} to {} for URL {}.", tool, version, code, errorStatus.getCode(), url);
594584
modified = true;
595585
} else if (isErrorCodeForAutomaticUrlRemoval(code)) {
596586
boolean urlBroken;
@@ -624,8 +614,7 @@ private void doUpdateStatusJson(boolean success, int statusCode, String edition,
624614
status.setError(errorStatus);
625615
}
626616
}
627-
logger.warn("For tool {} and version {} the download verification failed with status code {} for URL {}.", tool,
628-
version, code, url);
617+
logger.warn("For tool {} and version {} the download verification failed with status code {} for URL {}.", tool, version, code, url);
629618

630619
getUrlUpdaterReport().incrementVerificationFailure();
631620
}
@@ -639,13 +628,11 @@ private void doUpdateStatusJson(boolean success, int statusCode, String edition,
639628

640629
private static void removeUrl(String url, UrlDownloadFile downloadFile, String tool, String version, Integer code, UrlStatusFile urlStatusFile,
641630
UrlStatus status) {
642-
logger.warn("For tool {} and version {} the the URL {} is broken (status code {}) for a long time and will be removed.", tool,
643-
version, code, url);
631+
logger.warn("For tool {} and version {} the the URL {} is broken (status code {}) for a long time and will be removed.", tool, version, code, url);
644632
downloadFile.removeUrl(url);
645633
if (downloadFile.getUrls().isEmpty()) {
646634
Path downloadPath = downloadFile.getPath();
647-
logger.warn("For tool {} and version {} all URLs have been removed so the download file {} will be removed.", tool,
648-
version, downloadPath);
635+
logger.warn("For tool {} and version {} all URLs have been removed so the download file {} will be removed.", tool, version, downloadPath);
649636
downloadFile.delete();
650637
UrlChecksum urlChecksum = downloadFile.getParent().getChecksum(downloadFile.getName());
651638
if (urlChecksum == null) {
@@ -768,8 +755,7 @@ protected void updateExistingVersions(UrlEdition edition) {
768755
UrlStatusFile urlStatusFile = urlVersion.getOrCreateStatus();
769756
StatusJson statusJson = urlStatusFile.getStatusJson();
770757
if (statusJson.isManual()) {
771-
logger.info("For tool {} the version {} is set to manual, hence skipping update", getToolWithEdition(edition.getName()),
772-
version);
758+
logger.info("For tool {} the version {} is set to manual, hence skipping update", getToolWithEdition(edition.getName()), version);
773759
} else {
774760
updateExistingVersion(edition.getName(), version, urlVersion, statusJson, urlStatusFile);
775761
if (urlVersion.getChildren().isEmpty()) {
@@ -783,8 +769,7 @@ protected void updateExistingVersions(UrlEdition edition) {
783769
}
784770
}
785771

786-
private void updateExistingVersion(String edition, String version, UrlVersion urlVersion, StatusJson statusJson,
787-
UrlStatusFile urlStatusFile) {
772+
private void updateExistingVersion(String edition, String version, UrlVersion urlVersion, StatusJson statusJson, UrlStatusFile urlStatusFile) {
788773

789774
String toolWithEdition = getToolWithEdition(edition);
790775
Instant now = Instant.now();
@@ -844,18 +829,24 @@ public String mapVersion(String version) {
844829
if ((prefix != null) && version.startsWith(prefix)) {
845830
version = version.substring(prefix.length());
846831
}
832+
847833
String vLower = version.toLowerCase(Locale.ROOT);
848-
if (vLower.contains("alpha") || vLower.contains("beta") || vLower.contains("dev") || vLower.contains("snapshot")
849-
|| vLower.contains("preview") || vLower.contains("test") || vLower.contains("tech-preview") //
834+
if (vLower.contains("alpha") || vLower.contains("beta") || vLower.contains("dev") || vLower.contains("snapshot") || vLower.contains("preview")
835+
|| vLower.contains("test") || vLower.contains("tech-preview") //
850836
|| vLower.contains("-pre") || vLower.startsWith("ce-") || vLower.contains("-next") || vLower.contains("-rc")
851837
// vscode nonsense
852-
|| vLower.startsWith("bad") || vLower.contains("vsda-") || vLower.contains("translation/") || vLower.contains(
853-
"-insiders")) {
838+
|| vLower.startsWith("bad") || vLower.contains("vsda-") || vLower.contains("translation/") || vLower.contains("-insiders")) {
839+
return null;
840+
}
841+
842+
String filter = getCustomVersionFilter();
843+
if ((filter != null) && version.contains(filter)) {
854844
return null;
855845
}
856846
return version;
857847
}
858848

849+
859850
/**
860851
* @return the optional version prefix that has to be removed (e.g. "v").
861852
*/
@@ -864,6 +855,15 @@ protected String getVersionPrefixToRemove() {
864855
return null;
865856
}
866857

858+
859+
/**
860+
* @return the generic filters applied in {@link #filterVersion(String)}. Example: a tool might want to exclude versions containing "rc" or "beta".
861+
*/
862+
protected String getCustomVersionFilter() {
863+
864+
return null;
865+
}
866+
867867
/**
868868
* @param version the version to add (e.g. "1.0").
869869
* @param versions the {@link Collection} with the versions to collect.

url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.devonfw.tools.ide.url.tool.gcloud.GCloudUrlUpdater;
2323
import com.devonfw.tools.ide.url.tool.gcviewer.GcViewerUrlUpdater;
2424
import com.devonfw.tools.ide.url.tool.gh.GhUrlUpdater;
25+
import com.devonfw.tools.ide.url.tool.go.GoUrlUpdater;
2526
import com.devonfw.tools.ide.url.tool.graalvm.GraalVmCommunityUpdater;
2627
import com.devonfw.tools.ide.url.tool.graalvm.GraalVmOracleUrlUpdater;
2728
import com.devonfw.tools.ide.url.tool.gradle.GradleUrlUpdater;
@@ -67,7 +68,7 @@ public class UpdateManager extends AbstractProcessorWithTimeout {
6768
new AndroidStudioUrlUpdater(), new AwsUrlUpdater(), new AzureUrlUpdater(), new CorepackUrlUpdater(), new DockerDesktopUrlUpdater(),
6869
new DotNetUrlUpdater(),
6970
new EclipseCppUrlUpdater(), new EclipseJeeUrlUpdater(), new EclipseJavaUrlUpdater(), new GCloudUrlUpdater(),
70-
new GcViewerUrlUpdater(), new GhUrlUpdater(), new GraalVmCommunityUpdater(), new GraalVmOracleUrlUpdater(),
71+
new GcViewerUrlUpdater(), new GhUrlUpdater(), new GoUrlUpdater(), new GraalVmCommunityUpdater(), new GraalVmOracleUrlUpdater(),
7172
new GradleUrlUpdater(), new HelmUrlUpdater(), new IntellijUrlUpdater(), new JasyptUrlUpdater(),
7273
new JavaUrlUpdater(), new JenkinsUrlUpdater(), new JmcUrlUpdater(), new KotlincUrlUpdater(),
7374
new KotlincNativeUrlUpdater(), new LazyDockerUrlUpdater(), new MvnUrlUpdater(), new Mvn4UrlUpdater(),
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.devonfw.tools.ide.url.go;
2+
3+
import com.devonfw.tools.ide.url.tool.go.GoUrlUpdater;
4+
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
5+
6+
/**
7+
* Mock of {@link GoUrlUpdater} to allow integration testing with wiremock.
8+
*/
9+
public class GoUrlUpdaterMock extends GoUrlUpdater {
10+
11+
private final String baseUrl;
12+
13+
public GoUrlUpdaterMock(WireMockRuntimeInfo wireMockRuntimeInfo) {
14+
super();
15+
this.baseUrl = wireMockRuntimeInfo.getHttpBaseUrl();
16+
}
17+
18+
@Override
19+
protected String getDownloadBaseUrl() {
20+
21+
return this.baseUrl;
22+
}
23+
24+
@Override
25+
protected String doGetVersionUrl() {
26+
27+
return this.baseUrl + "/repos/golang/go/git/refs/tags";
28+
}
29+
}

0 commit comments

Comments
 (0)