Skip to content

Commit 8fa3bff

Browse files
#1492: Add Spring-Boot-CLI Commandlet (#1496)
Co-authored-by: Jörg Hohwiller <hohwille@users.noreply.github.com>
1 parent 8749d60 commit 8fa3bff

21 files changed

Lines changed: 279 additions & 11 deletions

File tree

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The full list of changes for this release can be found in https://github.com/dev
1414

1515
Release with new features and bugfixes:
1616

17+
* https://github.com/devonfw/IDEasy/issues/1492[#1492]: Add spring-boot CLI Commandlet.
1718
* https://github.com/devonfw/IDEasy/issues/1545[#1545]: Yarn can not be installed after corepack
1819

1920
The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/36?closed=1[milestone 2025.10.002].

cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.devonfw.tools.ide.tool.python.Python;
4646
import com.devonfw.tools.ide.tool.quarkus.Quarkus;
4747
import com.devonfw.tools.ide.tool.sonar.Sonar;
48+
import com.devonfw.tools.ide.tool.spring.Spring;
4849
import com.devonfw.tools.ide.tool.terraform.Terraform;
4950
import com.devonfw.tools.ide.tool.tomcat.Tomcat;
5051
import com.devonfw.tools.ide.tool.uv.Uv;
@@ -133,6 +134,7 @@ public CommandletManagerImpl(IdeContext context) {
133134
add(new LazyDocker(context));
134135
add(new Python(context));
135136
add(new Pycharm(context));
137+
add(new Spring(context));
136138
add(new Uv(context));
137139
add(new Yarn(context));
138140
add(new Corepack(context));

cli/src/main/java/com/devonfw/tools/ide/tool/mvn/MvnArtifact.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/**
1111
* Simple type representing a maven artifact.
1212
*/
13-
public final class MvnArtifact extends SoftwareArtifact {
13+
public class MvnArtifact extends SoftwareArtifact {
1414

1515
/** {@link #getGroupId() Group ID} of IDEasy. */
1616
public static final String GROUP_ID_IDEASY = "com.devonfw.tools.IDEasy";
@@ -260,12 +260,16 @@ public String getBaseVersion() {
260260
*/
261261
public String getDownloadUrl() {
262262
if (this.downloadUrl == null) {
263-
String baseUrl = isSnapshot() ? MvnRepository.MAVEN_SNAPSHOTS : MvnRepository.MAVEN_CENTRAL;
263+
String baseUrl = getMvnBaseUrl();
264264
this.downloadUrl = baseUrl + "/" + getPath();
265265
}
266266
return this.downloadUrl;
267267
}
268268

269+
public String getMvnBaseUrl() {
270+
return isSnapshot() ? MvnRepository.MAVEN_SNAPSHOTS : MvnRepository.MAVEN_CENTRAL;
271+
}
272+
269273
@Override
270274
public int hashCode() {
271275
return Objects.hash(this.groupId, this.artifactId, this.version);

cli/src/main/java/com/devonfw/tools/ide/tool/repository/MvnRepository.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,26 @@ public MvnArtifactMetadata getMetadata(MvnArtifact artifact, String tool, String
127127
}
128128
artifact = artifact.withClassifier(resolvedClassifier);
129129
}
130-
UrlChecksums chekcsums = null;
130+
UrlChecksums checksums = getChecksums(artifact);
131+
return new MvnArtifactMetadata(artifact, tool, edition, checksums, os, arch);
132+
}
133+
134+
/**
135+
* Method is required to disable checksum checks in tests.
136+
*
137+
* @param artifact the {@link MvnArtifact} to use.
138+
* @return the {@link UrlChecksums}.
139+
*/
140+
protected UrlChecksums getChecksums(MvnArtifact artifact) {
141+
142+
UrlChecksums checksums = null;
131143
if (!artifact.isMavenMetadata()) {
132-
chekcsums = new UrlLazyChecksums(artifact);
144+
checksums = new UrlLazyChecksums(artifact);
133145
}
134-
return new MvnArtifactMetadata(artifact, tool, edition, chekcsums, os, arch);
146+
return checksums;
135147
}
136148

137-
private UrlGenericChecksum getChecksum(MvnArtifact artifact, String hashAlgorithm) {
149+
protected UrlGenericChecksum getChecksum(MvnArtifact artifact, String hashAlgorithm) {
138150

139151
MvnArtifact checksumArtifact = artifact.withType(artifact.getType() + "." + hashAlgorithm.toLowerCase(Locale.ROOT));
140152
Path checksumFile = getDownloadedArtifact(checksumArtifact, null);
@@ -147,7 +159,7 @@ private Path getDownloadedArtifact(MvnArtifact artifact, UrlChecksums checksums)
147159
Path file = this.localMavenRepository.resolve(artifact.getPath());
148160
if (isNotUpToDateInLocalRepo(file)) {
149161
this.context.getFileAccess().mkdirs(file.getParent());
150-
download(artifact.getDownloadUrl(), file, artifact.getVersion(), checksums);
162+
download(getMavenUrl(artifact), file, artifact.getVersion(), checksums);
151163
}
152164
return file;
153165
}
@@ -190,15 +202,16 @@ public VersionIdentifier resolveVersion(MvnArtifact artifact, GenericVersionRang
190202
versionString = resolvedVersion.toString();
191203
if (versionString.endsWith("-SNAPSHOT")) {
192204
artifact = artifact.withVersion(versionString);
193-
return resolveSnapshotVersion(artifact.getDownloadUrl(), versionString);
205+
return resolveSnapshotVersion(getMavenUrl(artifact), versionString);
194206
}
195207
return resolvedVersion;
196208
}
197209

198210
@Override
199211
protected List<VersionIdentifier> fetchVersions(MvnArtifact artifact) {
200212

201-
String metadataUrl = artifact.withMavenMetadata().getDownloadUrl();
213+
String metadataUrl = getMavenUrl(artifact.withMavenMetadata());
214+
202215
Document metadata = fetchXmlMetadata(metadataUrl);
203216
return fetchVersions(metadata, metadataUrl);
204217
}
@@ -274,6 +287,16 @@ private Document fetchXmlMetadata(String url) {
274287
}
275288
}
276289

290+
/**
291+
* Used for tests to overwrite Maven base url.
292+
*
293+
* @param artifact the {@link MvnArtifact} to use
294+
* @return the Maven url
295+
*/
296+
protected String getMavenUrl(MvnArtifact artifact) {
297+
return artifact.getDownloadUrl();
298+
}
299+
277300
private class UrlLazyChecksums implements UrlChecksums {
278301

279302
private final MvnArtifact artifact;
@@ -301,5 +324,4 @@ public Iterator<UrlGenericChecksum> iterator() {
301324
return this.checksums.iterator();
302325
}
303326
}
304-
305327
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.devonfw.tools.ide.tool.spring;
2+
3+
import java.util.Set;
4+
5+
import com.devonfw.tools.ide.common.Tag;
6+
import com.devonfw.tools.ide.context.IdeContext;
7+
import com.devonfw.tools.ide.tool.ToolCommandlet;
8+
import com.devonfw.tools.ide.tool.mvn.MvnArtifact;
9+
import com.devonfw.tools.ide.tool.mvn.MvnBasedLocalToolCommandlet;
10+
11+
/**
12+
* {@link ToolCommandlet} for <a href="https://github.com/spring-projects/spring-boot">Spring-Boot-CLI</a>.
13+
*/
14+
public class Spring extends MvnBasedLocalToolCommandlet {
15+
16+
/** The {@link MvnArtifact} for Spring. */
17+
public static final MvnArtifact ARTIFACT = new MvnArtifact("org/springframework/boot", "spring-boot-cli", "*", "tar.gz", "bin");
18+
19+
/**
20+
* The constructor.
21+
*
22+
* @param context the {@link IdeContext}.
23+
*/
24+
public Spring(IdeContext context) {
25+
26+
super(context, "spring", ARTIFACT, Set.of(Tag.JAVA, Tag.ARCHITECTURE, Tag.FRAMEWORK));
27+
}
28+
}

cli/src/main/resources/nls/Help.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ cmd.shell.detail=The interactive shell offers console users a new user experienc
103103
cmd.sonar=Tool commandlet for SonarQube.
104104
cmd.sonar.detail=SonarQube is a platform for continuous inspection of code quality. Detailed documentation can be found at https://docs.sonarqube.org/
105105
cmd.sonar.val.command=Action to perform (START|STOP|ANALYZE)
106+
cmd.spring=Tool commandlet for Spring-Boot-CLI.
107+
cmd.spring.detail=Spring Boot is an extension of the Spring framework that simplifies the initial configuration of Spring applications. Detailed documentation can be found at https://spring.io/projects/spring-boot
106108
cmd.status=Prints the status report about your IDEasy.
107109
cmd.status.detail=To check your IDE-status (e.g. duplicated or legacy variables) as well as potential information about updates to settings you should apply\nwith ide update, run the following command: 'ide status'.
108110
cmd.terraform=Tool commandlet for Terraform.

cli/src/main/resources/nls/Help_de.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ cmd.shell.detail=Die integrierte Shell bietet Konsolenbenutzer*Innen eine neue B
103103
cmd.sonar=Werkzeug Kommando für SonarQube.
104104
cmd.sonar.detail=SonarQube ist eine Plattform für die kontinuierliche Code-Qualitätsprüfung. Detaillierte Dokumentation ist zu finden unter https://docs.sonarqube.org/
105105
cmd.sonar.val.command=Auszuführende Aktion (START|STOP|ANALYZE)
106+
cmd.spring=Werkzeug Kommando für Spring-Boot-CLI.
107+
cmd.spring.detail=Spring Boot ist eine Erweiterung des Spring frameworks das die initiale Konfiguration von Spring Anwendungen vereinfacht. Detaillierte Dokumentation ist zu finden unter https://spring.io/projects/spring-boot
106108
cmd.status=Gibt einen Statusbericht über IDEasy aus
107109
cmd.status.detail=Um den Status Ihrer IDE zu überprüfen (z.B. doppelte oder veraltete Variablen) sowie potenzielle Informationen über Updates zu den Einstellungen,\ndie Sie mit dem Befehl 'ide update' anwenden sollten, führen Sie den folgenden Befehl aus: 'ide status'.
108110
cmd.terraform=Werkzeug Kommando für Terraform.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
echo "Running install spring (spring-boot-cli) integration test"
2+
ide -d install spring
3+
4+
assertThat "${IDE_ROOT}/${TEST_PROJECT_NAME}/software/spring/bin/spring" exists

cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class AbstractIdeTestContext extends AbstractIdeContext {
6161
*
6262
* @param logger the {@link IdeLogger}.
6363
* @param workingDirectory the optional {@link Path} to current working directory.
64-
* @param wireMockRuntimeInfo wireMock server on a random port
64+
* @param wireMockRuntimeInfo wireMock server on a random port.
6565
*/
6666
public AbstractIdeTestContext(IdeStartContextImpl logger, Path workingDirectory, WireMockRuntimeInfo wireMockRuntimeInfo) {
6767

cli/src/test/java/com/devonfw/tools/ide/context/IdeTestContext.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.devonfw.tools.ide.log.IdeLogLevel;
1010
import com.devonfw.tools.ide.log.IdeTestLogger;
1111
import com.devonfw.tools.ide.process.ProcessContext;
12+
import com.devonfw.tools.ide.tool.repository.MvnRepository;
1213
import com.devonfw.tools.ide.tool.repository.NpmRepository;
1314
import com.devonfw.tools.ide.tool.repository.ToolRepositoryMock;
1415
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
@@ -119,4 +120,14 @@ protected NpmRepository createNpmRepository() {
119120
}
120121
return super.createNpmRepository();
121122
}
123+
124+
@Override
125+
protected MvnRepository createMvnRepository() {
126+
if (this.wireMockRuntimeInfo != null) {
127+
return new MvnRepositoryMock(this, this.wireMockRuntimeInfo);
128+
}
129+
return super.createMvnRepository();
130+
}
131+
132+
122133
}

0 commit comments

Comments
 (0)