diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 8237e2c626..2475adff3a 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -5,7 +5,8 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE
== 2026.07.001
Release with new features and bugfixes:
-
+* https://github.com/devonfw/IDEasy/issues/1943[#1943]: Create ruby commandlet
+* https://github.com/devonfw/IDEasy/issues/1942[#1942]: Create ruby url updater
* https://github.com/devonfw/IDEasy/issues/1063[#1063]: Improve IDEasy user specific configuration documentation
* https://github.com/devonfw/IDEasy/issues/1909[#1909]: add commandlet for Maven Daemon
* https://github.com/devonfw/IDEasy/issues/2068[#2068]: Isolate Claude Code configuration per IDEasy project
diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java
index 580534f0f7..08103f9dc9 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java
@@ -58,6 +58,7 @@
import com.devonfw.tools.ide.tool.pycharm.Pycharm;
import com.devonfw.tools.ide.tool.python.Python;
import com.devonfw.tools.ide.tool.quarkus.Quarkus;
+import com.devonfw.tools.ide.tool.ruby.Ruby;
import com.devonfw.tools.ide.tool.rust.Rust;
import com.devonfw.tools.ide.tool.sonar.Sonar;
import com.devonfw.tools.ide.tool.spring.Spring;
@@ -138,6 +139,7 @@ public CommandletManagerImpl(IdeContext context) {
add(new Terraform(context));
add(new Oc(context));
add(new Quarkus(context));
+ add(new Ruby(context));
add(new Rust(context));
add(new Kotlinc(context));
add(new KotlincNative(context));
diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/ruby/Ruby.java b/cli/src/main/java/com/devonfw/tools/ide/tool/ruby/Ruby.java
new file mode 100644
index 0000000000..10873b10a0
--- /dev/null
+++ b/cli/src/main/java/com/devonfw/tools/ide/tool/ruby/Ruby.java
@@ -0,0 +1,30 @@
+package com.devonfw.tools.ide.tool.ruby;
+
+import java.util.Set;
+
+import com.devonfw.tools.ide.common.Tag;
+import com.devonfw.tools.ide.context.IdeContext;
+import com.devonfw.tools.ide.tool.LocalToolCommandlet;
+import com.devonfw.tools.ide.tool.ToolCommandlet;
+
+/**
+ * {@link ToolCommandlet} for Ruby.
+ */
+public class Ruby extends LocalToolCommandlet {
+
+ /**
+ * The constructor.
+ *
+ * @param context the {@link IdeContext}.
+ */
+ public Ruby(IdeContext context) {
+
+ super(context, "ruby", Set.of(Tag.RUBY));
+ }
+
+ @Override
+ public String getToolHelpArguments() {
+
+ return "--help";
+ }
+}
diff --git a/cli/src/main/resources/nls/Help.properties b/cli/src/main/resources/nls/Help.properties
index 1e52f11056..ec95d1ec90 100644
--- a/cli/src/main/resources/nls/Help.properties
+++ b/cli/src/main/resources/nls/Help.properties
@@ -118,6 +118,8 @@ cmd.quarkus.detail=Quarkus is a Kubernetes-native Java framework for building cl
cmd.repository=Set up pre-configured git repositories using 'ide repository setup '
cmd.repository.detail=Without further arguments this will set up all pre-configured git repositories.\nAlso, you can provide an explicit git repo as `` argument and IDEasy will automatically clone, build and set up your project based on the existing property file.\nRepositories are configured in 'settings/repository/.properties' and can therefore be shared with your project team for automatic or optional setup.
cmd.repository.val.repository=The name of the properties file of the pre-configured git repository to set up, omit to set up all active repositories.
+cmd.ruby=Tool commandlet for Ruby (programming language).
+cmd.ruby.detail=Ruby is a dynamic, open-source programming language with a focus on simplicity and productivity. Detailed documentation can be found at https://www.ruby-lang.org/en/documentation/
cmd.rust=Tool commandlet for Rust (programming language).
cmd.rust.detail=Rust is a programming-language focused on safety and performance. Detailed documentation can be found at https://www.rust-lang.org/learn
cmd.set-edition=Set the edition of the selected tool.
diff --git a/cli/src/main/resources/nls/Help_de.properties b/cli/src/main/resources/nls/Help_de.properties
index 3c4f9787cf..c2dd76ba53 100644
--- a/cli/src/main/resources/nls/Help_de.properties
+++ b/cli/src/main/resources/nls/Help_de.properties
@@ -118,6 +118,8 @@ cmd.quarkus.detail=Quarkus ist ein Kubernetes-native Java-Framework zur Entwickl
cmd.repository=Richtet das vorkonfigurierte Git Repository ein mittels 'ide repository setup '.
cmd.repository.detail=Dies wird alle vorkonfigurierten Repositories einrichten. Rufen Sie einfach 'ide repository setup ' auf, ersetzen Sie durch den Namen Ihrer Projektkonfigurationsdatei, die sich in 'settings/repository/your_project_name' befindet und IDEasy wird Ihr Projekt basierend auf der vorhandenen Eigenschaftsdatei automatisch klonen, bauen und einrichten.\nWenn Sie den Projektnamen weglassen, werden alle im Repository-Verzeichnis gefundenen Projekte vorkonfiguriert.
cmd.repository.val.repository=Der Name der Properties-Datei des vorkonfigurierten Git Repositories zum Einrichten. Falls nicht angegeben, werden alle aktiven Projekte eingerichtet.
+cmd.ruby=Werkzeug Kommando für Ruby (Programmiersprache).
+cmd.ruby.detail=Ruby ist eine dynamische, quelloffene Programmiersprache mit Fokus auf Einfachheit und Produktivität. Detaillierte Dokumentation findet sich unter https://www.ruby-lang.org/de/documentation/
cmd.rust=Werkzeug Kommando für Rust (Programmiersprache).
cmd.rust.detail=Rust ist eine Programmiersprache mit Fokus auf Sicherheit und Performance. Detaillierte Dokumentation findet sich unter https://www.rust-lang.org/learn
cmd.set-edition=Setzt die Edition des selektierten Werkzeugs.
diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdater.java
new file mode 100644
index 0000000000..c2abe2bb50
--- /dev/null
+++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdater.java
@@ -0,0 +1,65 @@
+package com.devonfw.tools.ide.url.tool.ruby;
+
+import com.devonfw.tools.ide.url.model.folder.UrlVersion;
+import com.devonfw.tools.ide.url.updater.GithubUrlReleaseUpdater;
+import com.devonfw.tools.ide.version.VersionComparisonResult;
+import com.devonfw.tools.ide.version.VersionIdentifier;
+
+public class RubyUrlUpdater extends GithubUrlReleaseUpdater {
+
+ // Older RubyInstaller releases are ignored because releases before 2.5.3-1 use unsupported legacy tag naming.
+ private static final VersionIdentifier MIN_RUBY_VID = VersionIdentifier.of("2.5.3-1");
+
+ @Override
+ public String getTool() {
+ return "ruby";
+ }
+
+ @Override
+ protected String getGithubOrganization() {
+ return "oneclick";
+ }
+
+ @Override
+ protected String getGithubRepository() {
+ return "rubyinstaller2";
+ }
+
+ @Override
+ protected void addVersion(UrlVersion urlVersion) {
+
+ VersionIdentifier vid = urlVersion.getVersionIdentifier();
+ VersionComparisonResult result = vid.compareVersion(MIN_RUBY_VID);
+
+ if (result.isEqual() || result.isGreater()) {
+ String baseUrl = createGithubReleaseDownloadUrl("RubyInstaller-${version}", "rubyinstaller-${version}-");
+
+ doAddVersion(urlVersion, baseUrl + "x64.7z", WINDOWS, X64);
+ }
+ }
+
+ @Override
+ public String mapVersion(String version) {
+ int dateSeparator = version.indexOf(" - ");
+ if (dateSeparator >= 0) {
+ version = version.substring(0, dateSeparator);
+ }
+ return super.mapVersion(version);
+ }
+
+ @Override
+ protected String getVersionPrefixToRemove() {
+ return "RubyInstaller-";
+ }
+
+
+ @Override
+ public String getCpeVendor() {
+ return "ruby-lang";
+ }
+
+ @Override
+ public String getCpeProduct() {
+ return "ruby";
+ }
+}
diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java
index e3370dda23..def029b59f 100644
--- a/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java
+++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java
@@ -51,6 +51,7 @@
import com.devonfw.tools.ide.url.tool.pycharm.PycharmUrlUpdater;
import com.devonfw.tools.ide.url.tool.python.PythonUrlUpdater;
import com.devonfw.tools.ide.url.tool.quarkus.QuarkusUrlUpdater;
+import com.devonfw.tools.ide.url.tool.ruby.RubyUrlUpdater;
import com.devonfw.tools.ide.url.tool.rust.RustUrlUpdater;
import com.devonfw.tools.ide.url.tool.sonar.SonarUrlUpdater;
import com.devonfw.tools.ide.url.tool.squirrelsql.SquirrelSqlUrlUpdater;
@@ -82,7 +83,7 @@ public class UpdateManager extends AbstractProcessorWithTimeout {
new JavaUrlUpdater(), new JenkinsUrlUpdater(), new JmcUrlUpdater(), new KotlincUrlUpdater(),
new KotlincNativeUrlUpdater(), new LazyDockerUrlUpdater(), new MvnUrlUpdater(), new MvndUrlUpdater(),
new NgUrlUpdater(), new NodeUrlUpdater(), new NpmUrlUpdater(), new OcUrlUpdater(), new PgAdminUrlUpdater(), new PipUrlUpdater(), new PycharmUrlUpdater(),
- new PythonUrlUpdater(), new QuarkusUrlUpdater(), new RustUrlUpdater(), new DockerRancherDesktopUrlUpdater(), new SonarUrlUpdater(),
+ new PythonUrlUpdater(), new QuarkusUrlUpdater(), new RubyUrlUpdater(), new RustUrlUpdater(), new DockerRancherDesktopUrlUpdater(), new SonarUrlUpdater(),
new SquirrelSqlUrlUpdater(),
new TerraformUrlUpdater(), new TomcatUrlUpdater(), new UvUrlUpdater(), new VsCodeUrlUpdater(), new VsCodiumUrlUpdater());
diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdaterMock.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdaterMock.java
new file mode 100644
index 0000000000..b302e55722
--- /dev/null
+++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdaterMock.java
@@ -0,0 +1,29 @@
+package com.devonfw.tools.ide.url.tool.ruby;
+
+import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
+
+/**
+ * Mock of {@link RubyUrlUpdater} to allow integration testing with WireMock.
+ */
+public class RubyUrlUpdaterMock extends RubyUrlUpdater {
+
+ private final String baseUrl;
+
+ private final WireMockRuntimeInfo wmRuntimeInfo;
+
+ RubyUrlUpdaterMock(WireMockRuntimeInfo wireMockRuntimeInfo) {
+ super();
+ this.wmRuntimeInfo = wireMockRuntimeInfo;
+ this.baseUrl = wireMockRuntimeInfo.getHttpBaseUrl();
+ }
+
+ @Override
+ protected String getDownloadBaseUrl() {
+ return this.baseUrl;
+ }
+
+ @Override
+ protected String doGetVersionUrl() {
+ return this.baseUrl + "/repos/" + getGithubOrganization() + "/" + getGithubRepository() + "/releases";
+ }
+}
diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdaterTest.java
new file mode 100644
index 0000000000..43e385ab59
--- /dev/null
+++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/tool/ruby/RubyUrlUpdaterTest.java
@@ -0,0 +1,65 @@
+package com.devonfw.tools.ide.url.tool.ruby;
+
+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 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 of {@link RubyUrlUpdater}.
+ */
+@WireMockTest
+class RubyUrlUpdaterTest extends AbstractUrlUpdaterTest {
+
+ /**
+ * Test of {@link RubyUrlUpdater} for the creation of download URLs and checksums.
+ *
+ * @param tempDir path to a temporary directory
+ * @param wmRuntimeInfo the {@link WireMockRuntimeInfo}
+ * @throws IOException if the test fails
+ */
+ @Test
+ void testRubyUrlUpdater(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) throws IOException {
+
+ // arrange
+ stubFor(get(urlMatching("/repos/oneclick/rubyinstaller2/releases"))
+ .willReturn(aResponse()
+ .withStatus(200)
+ .withBody(readAndResolve(
+ PATH_INTEGRATION_TEST.resolve("RubyUrlUpdater").resolve("ruby-releases.json"),
+ wmRuntimeInfo))));
+
+ stubFor(any(urlMatching("/oneclick/rubyinstaller2/releases/download/.*"))
+ .willReturn(aResponse()
+ .withStatus(200)
+ .withBody(DOWNLOAD_CONTENT)));
+
+ UrlRepository urlRepository = UrlRepository.load(tempDir);
+ RubyUrlUpdaterMock updater = new RubyUrlUpdaterMock(wmRuntimeInfo);
+
+ // act
+ updater.update(urlRepository);
+
+ // assert
+ Path rubyVersionDir = tempDir.resolve("ruby").resolve("ruby").resolve("2.5.3-1");
+ assertThat(rubyVersionDir.resolve("status.json")).exists();
+ assertUrlVersionFile(rubyVersionDir, "windows_x64");
+
+ Path oldRubyVersionDir = tempDir.resolve("ruby").resolve("ruby").resolve("2.4.0-7");
+ assertThat(oldRubyVersionDir).doesNotExist();
+
+ }
+}
diff --git a/url-updater/src/test/resources/integrationtest/RubyUrlUpdater/ruby-releases.json b/url-updater/src/test/resources/integrationtest/RubyUrlUpdater/ruby-releases.json
new file mode 100644
index 0000000000..10ff8c9307
--- /dev/null
+++ b/url-updater/src/test/resources/integrationtest/RubyUrlUpdater/ruby-releases.json
@@ -0,0 +1,32 @@
+[
+ {
+ "url": "https://api.github.com/repos/oneclick/rubyinstaller2/releases/1",
+ "assets_url": "https://api.github.com/repos/oneclick/rubyinstaller2/releases/1/assets",
+ "html_url": "https://github.com/oneclick/rubyinstaller2/releases/tag/RubyInstaller-2.5.3-1",
+ "id": 1,
+ "tag_name": "RubyInstaller-2.5.3-1",
+ "target_commitish": "master",
+ "name": "RubyInstaller-2.5.3-1",
+ "draft": false,
+ "prerelease": true,
+ "assets": []
+ },
+ {
+ "url": "https://api.github.com/repos/oneclick/rubyinstaller2/releases/2",
+ "assets_url": "https://api.github.com/repos/oneclick/rubyinstaller2/releases/2/assets",
+ "html_url": "https://github.com/oneclick/rubyinstaller2/releases/tag/RubyInstaller-2.4.0-7",
+ "id": 2,
+ "tag_name": "RubyInstaller-2.4.0-7",
+ "target_commitish": "master",
+ "name": "RubyInstaller-2.4.0-7",
+ "draft": false,
+ "prerelease": true,
+ "assets": [
+ {
+ "name": "rubyinstaller-2.4.0-7-x64.7z",
+ "browser_download_url": "${testbaseurl}/oneclick/rubyinstaller2/releases/download/RubyInstaller-2.4.0-7/rubyinstaller-2.4.0-7-x64.7z"
+ }
+ ]
+ }
+]
+``