diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistribution.java b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistribution.java index 8afcd0b6c55a..3455e65e62eb 100644 --- a/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistribution.java +++ b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistribution.java @@ -38,29 +38,15 @@ public class WSLDistribution { private static final Key SUDO_LISTENER_KEY = Key.create("WSL sudo listener"); - static class Description { - @NotNull final String id; - @NotNull final String msId; - @NotNull final String exeName; - @NotNull final String presentableName; - - public Description(@NotNull String id, @NotNull String msId, @NotNull String exeName, @NotNull String presentableName) { - this.id = id; - this.msId = msId; - this.exeName = exeName; - this.presentableName = presentableName; - } - } - - @NotNull private final Description myDescription; + @NotNull private final WslDistributionDescriptor myDescriptor; @NotNull private final Path myExecutablePath; protected WSLDistribution(@NotNull WSLDistribution dist) { - this(dist.myDescription, dist.myExecutablePath); + this(dist.myDescriptor, dist.myExecutablePath); } - WSLDistribution(@NotNull Description description, @NotNull Path executablePath) { - myDescription = description; + WSLDistribution(@NotNull WslDistributionDescriptor descriptor, @NotNull Path executablePath) { + myDescriptor = descriptor; myExecutablePath = executablePath; } @@ -369,17 +355,17 @@ public class WSLDistribution { @NotNull public String getId() { - return myDescription.id; + return myDescriptor.getId(); } @NotNull public String getMsId() { - return myDescription.msId; + return myDescriptor.getMsId(); } @NotNull public String getPresentableName() { - return myDescription.presentableName; + return myDescriptor.getPresentableName(); } @Override diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionLegacy.java b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionLegacy.java index 6e253ee26ec5..5ac27746f0e0 100644 --- a/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionLegacy.java +++ b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionLegacy.java @@ -16,8 +16,8 @@ import java.nio.file.Paths; * Represents legacy bash.exe WSL, see RUBY-20359 */ public class WSLDistributionLegacy extends WSLDistribution { - private static final WSLDistribution.Description LEGACY_WSL = - new WSLDistribution.Description("UBUNTU_LEGACY", "ubuntu_bash", "bash.exe", "Ubuntu (Legacy)"); + private static final WslDistributionDescriptor LEGACY_WSL = + new WslDistributionDescriptor("UBUNTU_LEGACY", "ubuntu_bash", "bash.exe", "Ubuntu (Legacy)"); private static final String WSL_ROOT_CHUNK = "\\lxss\\rootfs"; @@ -40,7 +40,7 @@ public class WSLDistributionLegacy extends WSLDistribution { final Path executableRoot = getExecutableRootPath(); if (executableRoot == null) return null; - final Path executablePath = executableRoot.resolve(LEGACY_WSL.exeName); + final Path executablePath = executableRoot.resolve(LEGACY_WSL.getExeName()); if (Files.exists(executablePath, LinkOption.NOFOLLOW_LINKS)) { return new WSLDistributionLegacy(executablePath); } diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionService.java b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionService.java new file mode 100644 index 000000000000..66385fff09e8 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionService.java @@ -0,0 +1,68 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.execution.wsl; + + +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.xmlb.XmlSerializerUtil; +import com.intellij.util.xmlb.annotations.Tag; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Service responsible for keeping list of distributions in the external file, available for user modifications. + * To force IDE to store default values (as an example for users) we use empty list as default and initializing on + * first read. Configuration available at: {@code HOME\.IntelliJIdea2018.2\config\options\wsl.distributions.xml} + */ +@State( + name = "WslDistributionsService", + storages = @Storage(value = "wsl.distributions.xml") +) +class WSLDistributionService implements PersistentStateComponent { + @Tag("descriptors") + private final List myDescriptors = new ArrayList<>(); + + public List getDescriptors() { + if (myDescriptors.isEmpty()) { + init(); + } + return myDescriptors; + } + + private synchronized void init() { + if (!myDescriptors.isEmpty()) { + return; + } + ContainerUtil.addAll( + myDescriptors, + new WslDistributionDescriptor("DEBIAN", "Debian", "debian.exe", "Debian GNU/Linux"), + new WslDistributionDescriptor("KALI", "kali-linux", "kali.exe", "Kali Linux"), + new WslDistributionDescriptor("OPENSUSE42", "openSUSE-42", "opensuse-42.exe", "openSUSE Leap 42"), + new WslDistributionDescriptor("SLES12", "SLES-12", "sles-12.exe", "SUSE Linux Enterprise Server 12"), + new WslDistributionDescriptor("UBUNTU", "Ubuntu", "ubuntu.exe", "Ubuntu"), + new WslDistributionDescriptor("UBUNTU1604", "Ubuntu-16.04", "ubuntu1604.exe", "Ubuntu 16.04"), + new WslDistributionDescriptor("UBUNTU1804", "Ubuntu-18.04", "ubuntu1804.exe", "Ubuntu 18.04") + ); + } + + @Nullable + @Override + public WSLDistributionService getState() { + return this; + } + + @Override + public void loadState(@NotNull WSLDistributionService state) { + XmlSerializerUtil.copyBean(state, this); + } + + public static WSLDistributionService getInstance() { + return ServiceManager.getService(WSLDistributionService.class); + } +} diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/WSLUtil.java b/platform/platform-impl/src/com/intellij/execution/wsl/WSLUtil.java index 4cba9577a88d..d1c9d8606ee9 100644 --- a/platform/platform-impl/src/com/intellij/execution/wsl/WSLUtil.java +++ b/platform/platform-impl/src/com/intellij/execution/wsl/WSLUtil.java @@ -19,7 +19,6 @@ import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -49,16 +48,6 @@ public class WSLUtil { } }; - private static final List DISTRIBUTIONS = Arrays.asList( - new WSLDistribution.Description("DEBIAN", "Debian", "debian.exe", "Debian GNU/Linux"), - new WSLDistribution.Description("KALI", "kali-linux", "kali.exe", "Kali Linux"), - new WSLDistribution.Description("OPENSUSE42", "openSUSE-42", "opensuse-42.exe", "openSUSE Leap 42"), - new WSLDistribution.Description("SLES12", "SLES-12", "sles-12.exe", "SUSE Linux Enterprise Server 12"), - new WSLDistribution.Description("UBUNTU", "Ubuntu", "ubuntu.exe", "Ubuntu"), - new WSLDistribution.Description("UBUNTU1604", "Ubuntu-16.04", "ubuntu1604.exe", "Ubuntu 16.04"), - new WSLDistribution.Description("UBUNTU1804", "Ubuntu-18.04", "ubuntu1804.exe", "Ubuntu 18.04") - ); - /** * @return */ @@ -77,12 +66,13 @@ public class WSLUtil { final Path executableRoot = getExecutableRootPath(); if (executableRoot == null) return Collections.emptyList(); - final List result = new ArrayList<>(DISTRIBUTIONS.size() + 1 /* LEGACY_WSL */); + List descriptors = WSLDistributionService.getInstance().getDescriptors(); + final List result = new ArrayList<>(descriptors.size() + 1 /* LEGACY_WSL */); - for (WSLDistribution.Description description : DISTRIBUTIONS) { - final Path executablePath = executableRoot.resolve(description.exeName); + for (WslDistributionDescriptor descriptor: descriptors) { + final Path executablePath = executableRoot.resolve(descriptor.getExeName()); if (Files.exists(executablePath, LinkOption.NOFOLLOW_LINKS)) { - result.add(new WSLDistribution(description, executablePath)); + result.add(new WSLDistribution(descriptor, executablePath)); } } // add legacy WSL if it's available diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/WslDistributionDescriptor.java b/platform/platform-impl/src/com/intellij/execution/wsl/WslDistributionDescriptor.java new file mode 100644 index 000000000000..12ba14cf219f --- /dev/null +++ b/platform/platform-impl/src/com/intellij/execution/wsl/WslDistributionDescriptor.java @@ -0,0 +1,55 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.execution.wsl; + +import com.intellij.util.xmlb.annotations.Tag; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +/** + * Data class describing a WSL distribution + */ +@Tag("descriptor") +class WslDistributionDescriptor { + @Tag("jetbrains-id") + private String id; + @Tag("microsoft-id") + private String msId; + @Tag("executable-name") + private String exeName; + @Tag("presentable-name") + private String presentableName; + + /** + * Necessary for serializer + */ + public WslDistributionDescriptor() { + } + + public WslDistributionDescriptor(@NotNull String id, @NotNull String msId, @NotNull String exeName, @NotNull String presentableName) { + this.id = id; + this.msId = msId; + this.exeName = exeName; + this.presentableName = presentableName; + } + + @NotNull + public String getId() { + return Objects.requireNonNull(id); + } + + @NotNull + public String getMsId() { + return Objects.requireNonNull(msId); + } + + @NotNull + public String getExeName() { + return Objects.requireNonNull(exeName); + } + + @NotNull + public String getPresentableName() { + return Objects.requireNonNull(presentableName); + } +} diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index c5c3e1b3ade8..47b2bcf95808 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -12,6 +12,8 @@ + +