Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#37: Tool commandlet for visual studio code #538

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
124e6b8
#37: Added Plugin Installation
aBega2000 Aug 12, 2024
0e14ff6
#37: Added tests for Vscode
aBega2000 Aug 14, 2024
7c173b3
Merge branch 'devonfw:main' into feature/37-tool-commandlet-for-visua…
aBega2000 Aug 14, 2024
80a76b0
#37: Changes in Tests
aBega2000 Aug 19, 2024
16ac352
#37: Small Change
aBega2000 Aug 19, 2024
048944b
Merge branch 'devonfw:main' into feature/37-tool-commandlet-for-visua…
aBega2000 Aug 20, 2024
3963a7c
#37: Changed the PluginDescriptor location
aBega2000 Aug 20, 2024
431d4f2
Merge branch 'devonfw:main' into feature/37-tool-commandlet-for-visua…
aBega2000 Aug 23, 2024
8136609
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
hohwille Aug 26, 2024
67845af
Merge branch 'devonfw:main' into feature/37-tool-commandlet-for-visua…
aBega2000 Aug 27, 2024
e3a8e06
#37: Changes after review
aBega2000 Aug 28, 2024
9b3d8f5
#37: Small change in tests
aBega2000 Aug 28, 2024
41579cf
Merge branch 'devonfw:main' into feature/37-tool-commandlet-for-visua…
aBega2000 Aug 29, 2024
c68e67f
#37: Changes in implementation
aBega2000 Sep 3, 2024
e6634de
Merge branch 'devonfw:main' into feature/37-tool-commandlet-for-visua…
aBega2000 Sep 3, 2024
bcefb1b
Merge branch 'feature/37-tool-commandlet-for-visual-studio-code' of h…
aBega2000 Sep 3, 2024
ecbecdc
#37: Added extensions.json file in test resources
aBega2000 Sep 3, 2024
f28fc4a
#37: Changes after review
aBega2000 Sep 9, 2024
d32f67a
#37: Small change in test resources
aBega2000 Sep 9, 2024
dbf786c
Merge branch 'devonfw:main' into feature/37-tool-commandlet-for-visua…
aBega2000 Sep 9, 2024
65392fb
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
jan-vcapgemini Sep 10, 2024
4d53850
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
jan-vcapgemini Sep 11, 2024
5f50a5c
#37: Changes after review
aBega2000 Sep 11, 2024
1e9f96d
Merge branch 'feature/37-tool-commandlet-for-visual-studio-code' of h…
aBega2000 Sep 11, 2024
49d67b4
#37: Changes after review
aBega2000 Sep 12, 2024
64ac951
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
jan-vcapgemini Sep 16, 2024
8c7e8ac
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
hohwille Sep 16, 2024
11ece7e
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
jan-vcapgemini Sep 18, 2024
2731553
#37: implemented requested changes
jan-vcapgemini Sep 18, 2024
e713306
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
jan-vcapgemini Sep 19, 2024
221569d
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
jan-vcapgemini Sep 20, 2024
06aa9af
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
jan-vcapgemini Sep 23, 2024
53329a0
Merge branch 'main' into feature/37-tool-commandlet-for-visual-studio…
hohwille Sep 24, 2024
83a22b2
Update CHANGELOG.adoc
hohwille Sep 24, 2024
5ccc977
Update CHANGELOG.adoc
hohwille Sep 24, 2024
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
3 changes: 2 additions & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE
Release with new features and bugfixes:

* https://github.com/devonfw/IDEasy/issues/628[#638]: Fixed update fails on first error
* https://github.com/devonfw/IDEasy/issues/553[#554]: Missmatch of IDE_ROOT
* https://github.com/devonfw/IDEasy/issues/37[#37]: Added Visual Studio Code (vscode) with plugin installation and plugin recommendation support
* https://github.com/devonfw/IDEasy/issues/553[#553]: Mismatch of IDE_ROOT
* https://github.com/devonfw/IDEasy/issues/556[#556]: ProcessContext should compute PATH on run and not in constructor
* https://github.com/devonfw/IDEasy/issues/557[#557]: Failed to update tomcat: Cannot find a (Map) Key deserializer for type VersionRange
* https://github.com/devonfw/IDEasy/issues/623[#623]: CliArgument prepand and append methods inconsistent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Set;

Expand Down Expand Up @@ -151,19 +152,35 @@ protected boolean doInstall(boolean silent) {
} else if (!Files.isDirectory(pluginsInstallationPath)) {
installPlugins = true;
}
createExtensionFolder();
if (installPlugins) {
PluginMaps pluginMaps = getPluginsMap();
for (PluginDescriptor plugin : pluginMaps.getPlugins()) {
if (plugin.isActive()) {
installPlugin(plugin);
} else {
handleInstall4InactivePlugin(plugin);
}
}
Collection<PluginDescriptor> plugins = pluginMaps.getPlugins();
installPlugins(plugins);
}
return newlyInstalled;
}

private void createExtensionFolder() {
Path extensionFolder = this.context.getIdeHome().resolve("plugins").resolve(this.tool);
this.context.getFileAccess().mkdirs(extensionFolder);
}

/**
* Method to install active plugins or to handle install for inactive plugins
*
* @param plugins as {@link Collection} of plugins to install.
*/
protected void installPlugins(Collection<PluginDescriptor> plugins) {
hohwille marked this conversation as resolved.
Show resolved Hide resolved
for (PluginDescriptor plugin : plugins) {
if (plugin.isActive()) {
installPlugin(plugin);
} else {
handleInstall4InactivePlugin(plugin);
}
}
}

/**
* @param plugin the in{@link PluginDescriptor#isActive() active} {@link PluginDescriptor} that is skipped for regular plugin installation.
*/
Expand Down
119 changes: 117 additions & 2 deletions cli/src/main/java/com/devonfw/tools/ide/tool/vscode/Vscode.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
package com.devonfw.tools.ide.tool.vscode;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
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.process.ProcessContext;
import com.devonfw.tools.ide.process.ProcessErrorHandling;
import com.devonfw.tools.ide.process.ProcessMode;
import com.devonfw.tools.ide.tool.ToolCommandlet;
import com.devonfw.tools.ide.tool.ide.IdeToolCommandlet;
import com.devonfw.tools.ide.tool.plugin.PluginDescriptor;
import com.devonfw.tools.ide.version.VersionIdentifier;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
* {@link ToolCommandlet} for <a href="https://code.visualstudio.com/">vscode</a>.
*/
public class Vscode extends LocalToolCommandlet {
public class Vscode extends IdeToolCommandlet {

/**
* The constructor.
Expand All @@ -28,4 +45,102 @@ protected String getBinaryName() {
return "code";
}

@Override
public void installPlugin(PluginDescriptor plugin) {
jan-vcapgemini marked this conversation as resolved.
Show resolved Hide resolved
hohwille marked this conversation as resolved.
Show resolved Hide resolved

}

@Override
protected void installPlugins(Collection<PluginDescriptor> plugins) {

List<PluginDescriptor> pluginsToInstall = new ArrayList<>();
List<PluginDescriptor> pluginsToRecommend = new ArrayList<>();

for (PluginDescriptor plugin : plugins) {
if (plugin.isActive()) {
pluginsToInstall.add(plugin);
} else {
pluginsToRecommend.add(plugin);
}
}
doAddRecommendations(pluginsToRecommend);
doInstallPlugins(pluginsToInstall);

}

private void doInstallPlugins(List<PluginDescriptor> pluginsToInstall) {

List<String> extensionsCommands = new ArrayList<>();

if (pluginsToInstall.isEmpty()) {
this.context.info("No plugins to be installed");
} else {

for (PluginDescriptor plugin : pluginsToInstall) {
extensionsCommands.add("--install-extension");
extensionsCommands.add(plugin.getId());
}
}
runTool(ProcessMode.DEFAULT, null, extensionsCommands.toArray(new String[0]));
}

private void doAddRecommendations(List<PluginDescriptor> recommendations) {
Path extensionsJsonPath = this.context.getWorkspacePath().resolve(".vscode/extensions.json");

ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> recommendationsMap;

if (Files.exists(extensionsJsonPath)) {
try (BufferedReader reader = Files.newBufferedReader(extensionsJsonPath)) {
recommendationsMap = objectMapper.readValue(reader, Map.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
recommendationsMap = new HashMap<>();
}

List<String> existingRecommendations = (List<String>) recommendationsMap.getOrDefault("recommendations", new ArrayList<>());

try {
int addedRecommendations = 0;
Set<String> existingRecommendationsSet = new HashSet<>(existingRecommendations);
for (PluginDescriptor recommendation : recommendations) {
String recommendationId = recommendation.getId();
if (existingRecommendationsSet.add(recommendationId)) {
existingRecommendations.add(recommendationId);
addedRecommendations++;
}
}

if (addedRecommendations > 0) {
objectMapper.writeValue(extensionsJsonPath.toFile(), recommendationsMap);
}
hohwille marked this conversation as resolved.
Show resolved Hide resolved

} catch (IOException e) {
this.context.error(e);
}
}

@Override
public void runTool(ProcessMode processMode, VersionIdentifier toolVersion, String... args) {

install(true);

Path vsCodeConf = this.context.getWorkspacePath().resolve(".vscode/.userdata");
Path vsCodeExtensionFolder = this.context.getIdeHome().resolve("plugins/vscode");

List<String> command = new ArrayList<>();
command.add("--new-window");
command.add("--user-data-dir=" + vsCodeConf);
command.add("--extensions-dir=" + vsCodeExtensionFolder);

command.addAll(Arrays.asList(args));

Path binaryPath;
binaryPath = Path.of(getBinaryName());
ProcessContext pc = this.context.newProcess().errorHandling(ProcessErrorHandling.THROW).executable(binaryPath).addArgs(command.toArray());
pc.run(processMode);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.devonfw.tools.ide.tool.vscode;

import org.junit.jupiter.api.Test;

import com.devonfw.tools.ide.context.AbstractIdeContextTest;
import com.devonfw.tools.ide.context.IdeTestContext;

/**
* Test of {@link Vscode} class.
*/
public class VscodeTest extends AbstractIdeContextTest {
hohwille marked this conversation as resolved.
Show resolved Hide resolved

private static final String PROJECT_VSCODE = "vscode";


@Test
public void testVscodeInstall() {

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

// install
vscodeCommandlet.install();

// assert
checkInstallation(context);
}

private void checkInstallation(IdeTestContext context) {

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

assertThat(context.getSoftwarePath().resolve("vscode/.ide.software.version")).exists().hasContent("1.92.1");
assertThat(context).logAtSuccess().hasMessage("Successfully installed vscode in version 1.92.1");

//check plugins folder
assertThat(context.getIdeHome().resolve("plugins").resolve("vscode")).exists();

//check Recommendations
assertThat(context.getWorkspacePath().resolve(".vscode").resolve("extensions.json")).exists()
.hasContent("{\"recommendations\":[\"esbenp.prettier-vscode\",\"mockedPlugin2\"]}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VSCODE_VERSION=1.92.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugin_id=mockedPlugin2
plugin_active=false
tags=mocking
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugin_id=mockedPlugin
plugin_active=true
tags=mocking
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
Loading