Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Release with new features and bugfixes:
* https://github.com/devonfw/IDEasy/issues/1904[#1904]: Add Inso CLI to IDEasy commandlets
* https://github.com/devonfw/IDEasy/issues/1952[#1952]: Ability for platform specific dependencies
* https://github.com/devonfw/IDEasy/issues/1950[#1950]: Fix exit autocompletion
* https://github.com/devonfw/IDEasy/issues/1849[#1849]: Add VSCodium support

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

Expand Down
41 changes: 34 additions & 7 deletions cli/src/main/java/com/devonfw/tools/ide/tool/vscode/Vscode.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.devonfw.tools.ide.io.IdeProgressBar;
import com.devonfw.tools.ide.log.IdeLogLevel;
import com.devonfw.tools.ide.process.ProcessContext;
import com.devonfw.tools.ide.process.ProcessErrorHandling;
import com.devonfw.tools.ide.process.ProcessMode;
import com.devonfw.tools.ide.process.ProcessResult;
import com.devonfw.tools.ide.step.Step;
Expand All @@ -28,6 +29,12 @@ public class Vscode extends IdeToolCommandlet {

private static final Logger LOG = LoggerFactory.getLogger(Vscode.class);

/** The {@link #getConfiguredEdition() edition} for VSCodium. */
private static final String EDITION_VSCODIUM = "vscodium";

/** Plugin IDs collected during {@link #installPlugins} that the VSCodium build refused to install. */
private final List<String> vscodiumUnavailablePlugins = new ArrayList<>();

/**
* The constructor.
*
Expand All @@ -41,11 +48,20 @@ public Vscode(IdeContext context) {
@Override
protected String getBinaryName() {

if (EDITION_VSCODIUM.equals(getConfiguredEdition())) {
return "codium";
}
return "code";
}

@Override
protected void installPlugins(Collection<ToolPluginDescriptor> plugins, ProcessContext pc) {
boolean isVscodium = EDITION_VSCODIUM.equals(getConfiguredEdition());
if (isVscodium) {
this.vscodiumUnavailablePlugins.clear();
pc.errorHandling(ProcessErrorHandling.NONE);
}
IdeLogLevel suppressLevel = isVscodium ? IdeLogLevel.WARNING : IdeLogLevel.STEP;
this.context.runWithoutLogging(() -> {
IdeProgressBar pb = this.context.newProgressBarForPlugins(plugins.size());
pc.setOutputListener((msg, err) -> {
Expand All @@ -55,7 +71,14 @@ protected void installPlugins(Collection<ToolPluginDescriptor> plugins, ProcessC
});
super.installPlugins(plugins, pc);
pb.close();
});
}, suppressLevel);
if (isVscodium && !this.vscodiumUnavailablePlugins.isEmpty()) {
LOG.warn("{} plugin(s) could not be installed on VSCodium due to not being available on open-vsx or other errors:\n - {}\n"
+ "For full plugin support, set VSCODE_EDITION=vscode to use Microsoft's distribution.\n"
+ "For more detailed information on why plugins failed to install, check the IDEasy logfile at $IDE_ROOT/_ide/logs/.",
this.vscodiumUnavailablePlugins.size(),
String.join("\n - ", this.vscodiumUnavailablePlugins));
}
Comment on lines +74 to +81
Copy link
Copy Markdown
Contributor Author

@laert-ll laert-ll May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: VSCodium does not support all the plugins that VSCode does.

I figured it would be better to suppress the very large red error messages that normally come when not being able to install the plugins, since it gives the impression that this is unexpected behavior. This is a temporary workaround for potentially a future story where we would have a separate list of plugins that are compatible with VSCodium.

}

@Override
Expand All @@ -80,13 +103,17 @@ public boolean installPlugin(ToolPluginDescriptor plugin, Step step, ProcessCont
}
step.success();
return true;
}
if (EDITION_VSCODIUM.equals(getConfiguredEdition())) {
this.vscodiumUnavailablePlugins.add(plugin.id());
return false;
} else {
if (versionSpecified) {
IdeLogLevel.ERROR.log(LOG, "Failed to install plugin: {} with version: {}", plugin.name(), plugin.version());
} else {
IdeLogLevel.ERROR.log(LOG, "Failed to install plugin: {}", plugin.name());
}
return false;
if (versionSpecified) {
IdeLogLevel.ERROR.log(LOG, "Failed to install plugin: {} with version: {}", plugin.name(), plugin.version());
} else {
IdeLogLevel.ERROR.log(LOG, "Failed to install plugin: {}", plugin.name());
}
return false;
}
}

Expand Down
2 changes: 1 addition & 1 deletion cli/src/main/resources/nls/Help.properties
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ cmd.uv.detail=uv is a Python package and project manager. Used by IDEasy interna
cmd.version=Print the version of IDEasy.
cmd.version.detail=To print the current version of IDEasy simply type: 'ide --version'.
cmd.vscode=Tool commandlet for Visual Studio Code (IDE).
cmd.vscode.detail=Visual Studio Code (VS Code) is a popular code editor developed by Microsoft. Detailed documentation can be found at https://code.visualstudio.com/docs/
cmd.vscode.detail=Visual Studio Code (VS Code) is a popular code editor developed by Microsoft. VSCodium is also supported as an open-source alternative edition. Detailed documentation can be found at https://code.visualstudio.com/docs/
cmd.yarn=Tool commandlet for Yarn (NPM alternative, JavaScript package manager).
cmd.yarn.detail=Yarn is a package manager and build tool for JavaScript. Detailed documentation can be found at https://yarnpkg.com/
commandlets=Available commandlets:
Expand Down
2 changes: 1 addition & 1 deletion cli/src/main/resources/nls/Help_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ cmd.uv.detail=uv ist ein Paket- und Projektmanager für Python. Intern nutzt es
cmd.version=Gibt die Version von IDEasy aus.
cmd.version.detail=Um die aktuelle Version von IDEasy auszugeben, brauchen Sie einfach nur 'ide --version' in die Konsole eingeben.
cmd.vscode=Werkzeug Kommando für Visual Studio Code (IDE).
cmd.vscode.detail=Visual Studio Code (VS Code) ist ein beliebter Code-Editor, der von Microsoft entwickelt wurde. Detaillierte Dokumentation ist zu finden unter https://code.visualstudio.com/docs/
cmd.vscode.detail=Visual Studio Code (VS Code) ist ein beliebter Code-Editor, der von Microsoft entwickelt wurde. VSCodium wird ebenfalls als Open-Source-Alternative (Edition) unterstützt. Detaillierte Dokumentation ist zu finden unter https://code.visualstudio.com/docs/
cmd.yarn=Werkzeug Kommando für Yarn (NPM Alternative, JavaScript Package Manager).
cmd.yarn.detail=Yarn ist ein Package Manager und Build-Werkzeug für JavaScript. Detaillierte Dokumentation ist zu finden unter https://yarnpkg.com/
commandlets=Verfügbare Kommandos:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class VscodeTest extends AbstractIdeContextTest {

private static final String PROJECT_VSCODE = "vscode";

private static final String PROJECT_VSCODIUM = "vscodium";

@Test
void testVscodeInstall() {

Expand Down Expand Up @@ -146,6 +148,35 @@ void testConfigureToolArgsDoesNotSetWslEnvVarOnNonWsl() {
assertThat(pc.getEnvVar("DONT_PROMPT_WSL_INSTALL")).isNull();
}

@Test
void testVscodiumInstall() {

// arrange
IdeTestContext context = newContext(PROJECT_VSCODIUM);
Vscode vscodeCommandlet = new Vscode(context);

// install
vscodeCommandlet.install();

// assert
checkVscodiumInstallation(context);
}

@Test
void testVscodiumRun() {

// arrange
IdeTestContext context = newContext(PROJECT_VSCODIUM);
Vscode vscodeCommandlet = new Vscode(context);

// install
vscodeCommandlet.run();

// assert
checkVscodiumInstallation(context);
}


/**
* Test double for {@link Vscode} that captures CLI arguments passed to {@link #runTool(ProcessContext, ProcessMode, List)}
* so tests can assert command construction without spawning an external process.
Expand Down Expand Up @@ -194,4 +225,13 @@ String getEnvVar(String key) {
return this.capturedEnvVars.get(key);
}
}
}

private void checkVscodiumInstallation(IdeTestContext context) {

assertThat(context.getSoftwarePath().resolve("vscode/bin/codium.cmd")).exists().hasContent("@echo test for windows");
assertThat(context.getSoftwarePath().resolve("vscode/bin/codium")).exists().hasContent("#!/bin/bash\n" + "echo \"Test for linux and Mac\"");

assertThat(context.getSoftwarePath().resolve("vscode/.ide.software.version")).exists().hasContent("1.116.02821");
assertThat(context).logAtSuccess().hasMessageContaining("Successfully installed vscode/vscodium in version 1.116.02821");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
${testbaseurl}/download/vscode/vscodium/1.116.02821/VSCodium-1.116.02821.tgz
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VSCODE_EDITION=vscodium
VSCODE_VERSION=1.116.02821
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"esbenp.prettier-vscode"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
echo "Test for linux and Mac"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@echo test for windows
1 change: 1 addition & 0 deletions documentation/LICENSE.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ The column `inclusion` indicates the way the component is included:
|https://github.com/anthropics/claude-code/tree/main[Claude Code CLI]|Optional|https://github.com/anthropics/claude-code/blob/main/LICENSE.md[Proprietary]
|https://maven.apache.org/[Maven]|Default Setup|https://www.apache.org/licenses/LICENSE-2.0[Apache 2.0]
|https://code.visualstudio.com/[VS Code]|Optional|https://github.com/Microsoft/vscode/blob/master/LICENSE.txt[MIT] (https://code.visualstudio.com/License/[Terms])
|https://vscodium.com/[VSCodium]|Optional|https://github.com/VSCodium/vscodium/blob/master/LICENSE[MIT]
|https://github.com/devonfw/extension-pack-vscode[extension-pack-vscode] |Optional|https://github.com/devonfw/extension-pack-vscode/blob/master/LICENSE[Apache 2.0]
|https://www.eclipse.org/[Eclipse] |Optional|https://www.eclipse.org/legal/epl-2.0/[EPL 2.0]
|https://marketplace.eclipse.org/content/tm-terminal[TM Terminal] |Optional|https://www.eclipse.org/legal/epl-2.0/[EPL 2.0] (see https://marketplace.eclipse.org/content/tm-terminal[here])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.devonfw.tools.ide.url.tool.vscode;

import com.devonfw.tools.ide.url.model.folder.UrlVersion;
import com.devonfw.tools.ide.url.updater.GithubUrlTagUpdater;

/**
* {@link GithubUrlTagUpdater} for the "vscodium" edition of vscode (<a href="https://vscodium.com/">VSCodium</a>).
*/
public class VsCodiumUrlUpdater extends GithubUrlTagUpdater {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are GitHub releases available for VSCodium:
https://github.com/VSCodium/vscodium/releases/

As we already discussed in such case GithubUrlReleaseUpdater should be preferred.
See also #1949


private static final String DOWNLOAD_BASE_URL = "https://github.com/VSCodium/vscodium/releases/download";

@Override
public String getTool() {

return "vscode";
}

@Override
protected String getEdition() {

return "vscodium";
}

@Override
protected String getGithubOrganization() {

return "VSCodium";
}

@Override
protected String getGithubRepository() {

return "vscodium";
}

@Override
protected String getDownloadBaseUrl() {

return DOWNLOAD_BASE_URL;
}

@Override
protected void addVersion(UrlVersion urlVersion) {

String baseUrl = getDownloadBaseUrl() + "/${version}/VSCodium-";
doAddVersion(urlVersion, baseUrl + "linux-x64-${version}.tar.gz", LINUX, X64);
doAddVersion(urlVersion, baseUrl + "linux-arm64-${version}.tar.gz", LINUX, ARM64);
doAddVersion(urlVersion, baseUrl + "darwin-x64-${version}.zip", MAC, X64);
doAddVersion(urlVersion, baseUrl + "darwin-arm64-${version}.zip", MAC, ARM64);
doAddVersion(urlVersion, baseUrl + "win32-x64-${version}.zip", WINDOWS, X64);
doAddVersion(urlVersion, baseUrl + "win32-arm64-${version}.zip", WINDOWS, ARM64);
}

@Override
public String mapVersion(String version) {

// VSCodium tag schemes seen in history: 3-segment "1.55.0", 4-segment "1.84.2.23319", and current 3-segment with
// build-encoded patch like "1.116.02821". Accept any 3- or 4-segment numeric tag.
if (version.matches("\\d+\\.\\d+\\.\\d+(\\.\\d+)?")) {
return super.mapVersion(version);
} else {
return null;
}
}

@Override
public String getCpeVendor() {
return "vscodium";
}

@Override
public String getCpeProduct() {
return "vscodium";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import com.devonfw.tools.ide.url.tool.tomcat.TomcatUrlUpdater;
import com.devonfw.tools.ide.url.tool.uv.UvUrlUpdater;
import com.devonfw.tools.ide.url.tool.vscode.VsCodeUrlUpdater;
import com.devonfw.tools.ide.url.tool.vscode.VsCodiumUrlUpdater;

/**
* The {@code UpdateManager} class manages the update process for various tools by using a list of {@link AbstractUrlUpdater}s to update the
Expand All @@ -83,7 +84,7 @@ public class UpdateManager extends AbstractProcessorWithTimeout {
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 SquirrelSqlUrlUpdater(),
new TerraformUrlUpdater(), new TomcatUrlUpdater(), new UvUrlUpdater(), new VsCodeUrlUpdater());
new TerraformUrlUpdater(), new TomcatUrlUpdater(), new UvUrlUpdater(), new VsCodeUrlUpdater(), new VsCodiumUrlUpdater());

/**
* The constructor.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.devonfw.tools.ide.url.tool.vscode;

import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;

/**
* Mock of {@link VsCodiumUrlUpdater} to allow integration testing with wiremock.
*/
public class VsCodiumUrlUpdaterMock extends VsCodiumUrlUpdater {

private final String baseUrl;

VsCodiumUrlUpdaterMock(WireMockRuntimeInfo wireMockRuntimeInfo) {
super();
this.baseUrl = wireMockRuntimeInfo.getHttpBaseUrl();
}

@Override
protected String getDownloadBaseUrl() {
return this.baseUrl;
}

@Override
protected String doGetVersionUrl() {

return this.baseUrl + "/repos/" + getGithubOrganization() + "/" + getGithubRepository() + "/git/refs/tags";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.devonfw.tools.ide.url.tool.vscode;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.head;
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.Files;
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 VsCodiumUrlUpdater}.
*/
@WireMockTest
class VsCodiumUrlUpdaterTest extends AbstractUrlUpdaterTest {

/**
* verifies that update creates expected files for VSCodium versions.
*/
@Test
void testVsCodiumUrlUpdaterCreatesDownloadUrlsAndChecksums(@TempDir Path tempDir, WireMockRuntimeInfo wmRuntimeInfo) throws IOException {
// given
stubFor(get(urlMatching("/repos/VSCodium/vscodium/git/refs/tags")).willReturn(aResponse().withStatus(200)
.withBody(Files.readAllBytes(PATH_INTEGRATION_TEST.resolve("VsCodiumUrlUpdater").resolve("vscodium-tags.json")))));
stubFor(head(urlMatching("/.*/VSCodium-(linux|darwin|win32)-(x64|arm64)-.*\\.(tar\\.gz|zip)")).willReturn(aResponse().withStatus(200)));
stubFor(get(urlMatching("/.*/VSCodium-(linux|darwin|win32)-(x64|arm64)-.*\\.(tar\\.gz|zip)")).willReturn(aResponse().withStatus(200).withBody(DOWNLOAD_CONTENT)));

UrlRepository urlRepository = UrlRepository.load(tempDir);
VsCodiumUrlUpdaterMock updater = new VsCodiumUrlUpdaterMock(wmRuntimeInfo);
// when
updater.update(urlRepository);

Path vscodium1 = tempDir.resolve("vscode").resolve("vscodium").resolve("1.92.1.24228");
Path vscodium2 = tempDir.resolve("vscode").resolve("vscodium").resolve("1.116.02821");

// then
assertUrlVersionOsArch(vscodium1);
assertUrlVersionOsArch(vscodium2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"ref": "refs/tags/1.92.1.24228"
},
{
"ref": "refs/tags/1.116.02821"
}
]
Loading