mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
Path remapping when reading JPS projects inside WSL
GitOrigin-RevId: cfcd6059b38cf12c885dbc229468bdfd63ec7414
This commit is contained in:
committed by
intellij-monorepo-bot
parent
697acd6687
commit
fdffd34bf1
@@ -1,12 +1,14 @@
|
||||
// Copyright 2000-2020 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 org.jetbrains.jps.model.serialization;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface JpsPathMapper {
|
||||
String mapUrl(String url);
|
||||
@Nullable String mapUrl(@Nullable String url);
|
||||
|
||||
JpsPathMapper IDENTITY = new JpsPathMapper() {
|
||||
@Override
|
||||
public String mapUrl(String url) {
|
||||
public @Nullable String mapUrl(@Nullable String url) {
|
||||
return url;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,6 +19,10 @@ import java.util.stream.Stream;
|
||||
|
||||
public final class JpsPathUtil {
|
||||
|
||||
public static final String FILE_URL_PREFIX = "file://";
|
||||
public static final String JAR_URL_PREFIX = "jar://";
|
||||
public static final String JAR_SEPARATOR = "!/";
|
||||
|
||||
public static boolean isUnder(Set<File> ancestors, File file) {
|
||||
if (ancestors.isEmpty()) {
|
||||
return false; // optimization
|
||||
@@ -47,12 +51,13 @@ public final class JpsPathUtil {
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
if (url.startsWith("file://")) {
|
||||
return url.substring("file://".length());
|
||||
if (url.startsWith(FILE_URL_PREFIX)) {
|
||||
return url.substring(FILE_URL_PREFIX.length());
|
||||
}
|
||||
else if (url.startsWith("jar://")) {
|
||||
url = url.substring("jar://".length());
|
||||
url = Strings.trimEnd(url, "!/");
|
||||
else if (url.startsWith(JAR_URL_PREFIX)) {
|
||||
url = url.substring(JAR_URL_PREFIX
|
||||
.length());
|
||||
url = Strings.trimEnd(url, JAR_SEPARATOR);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
@@ -76,12 +81,13 @@ public final class JpsPathUtil {
|
||||
}
|
||||
|
||||
public static String pathToUrl(String path) {
|
||||
return "file://" + path;
|
||||
return FILE_URL_PREFIX + path;
|
||||
}
|
||||
|
||||
public static String getLibraryRootUrl(File file) {
|
||||
String path = FileUtilRt.toSystemIndependentName(file.getAbsolutePath());
|
||||
return file.isDirectory() ? "file://" + path : "jar://" + path + "!/";
|
||||
return file.isDirectory() ? FILE_URL_PREFIX + path : JAR_URL_PREFIX
|
||||
+ path + "!/";
|
||||
}
|
||||
|
||||
public static boolean isJrtUrl(@NotNull String url) {
|
||||
|
||||
@@ -113,7 +113,7 @@ public final class JpsGlobalLoader extends JpsLoaderBase {
|
||||
|
||||
@Override
|
||||
public void loadExtension(@NotNull JpsGlobal global, @NotNull Element componentTag) {
|
||||
JpsLibraryTableSerializer.loadLibraries(componentTag, global.getLibraryCollection());
|
||||
JpsLibraryTableSerializer.loadLibraries(componentTag, global.getPathMapper(), global.getLibraryCollection());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,12 +63,18 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
|
||||
private final JpsProject myProject;
|
||||
private final Map<String, String> myPathVariables;
|
||||
private final JpsPathMapper myPathMapper;
|
||||
private final boolean myLoadUnloadedModules;
|
||||
|
||||
private JpsProjectLoader(JpsProject project, Map<String, String> pathVariables, Path baseDir, boolean loadUnloadedModules) {
|
||||
private JpsProjectLoader(JpsProject project,
|
||||
Map<String, String> pathVariables,
|
||||
@NotNull JpsPathMapper pathMapper,
|
||||
Path baseDir,
|
||||
boolean loadUnloadedModules) {
|
||||
super(createProjectMacroExpander(pathVariables, baseDir));
|
||||
myProject = project;
|
||||
myPathVariables = pathVariables;
|
||||
myPathMapper = pathMapper;
|
||||
myProject.getContainer().setChild(JpsProjectSerializationDataExtensionImpl.ROLE, new JpsProjectSerializationDataExtensionImpl(baseDir));
|
||||
myLoadUnloadedModules = loadUnloadedModules;
|
||||
}
|
||||
@@ -80,13 +86,13 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
}
|
||||
|
||||
public static void loadProject(JpsProject project, Map<String, String> pathVariables, String projectPath) throws IOException {
|
||||
loadProject(project, pathVariables, projectPath, false);
|
||||
loadProject(project, pathVariables, JpsPathMapper.IDENTITY, projectPath, false);
|
||||
}
|
||||
|
||||
public static void loadProject(JpsProject project, Map<String, String> pathVariables, String projectPath, boolean loadUnloadedModules) throws IOException {
|
||||
public static void loadProject(JpsProject project, Map<String, String> pathVariables, @NotNull JpsPathMapper pathMapper, String projectPath, boolean loadUnloadedModules) throws IOException {
|
||||
Path file = Paths.get(FileUtil.toCanonicalPath(projectPath));
|
||||
if (Files.isRegularFile(file) && projectPath.endsWith(".ipr")) {
|
||||
new JpsProjectLoader(project, pathVariables, file.getParent(), loadUnloadedModules).loadFromIpr(file);
|
||||
new JpsProjectLoader(project, pathVariables, pathMapper, file.getParent(), loadUnloadedModules).loadFromIpr(file);
|
||||
}
|
||||
else {
|
||||
Path dotIdea = file.resolve(PathMacroUtil.DIRECTORY_STORE_NAME);
|
||||
@@ -100,7 +106,7 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
else {
|
||||
throw new IOException("Cannot find IntelliJ IDEA project files at " + projectPath);
|
||||
}
|
||||
new JpsProjectLoader(project, pathVariables, directory.getParent(), loadUnloadedModules).loadFromDirectory(directory);
|
||||
new JpsProjectLoader(project, pathVariables, pathMapper, directory.getParent(), loadUnloadedModules).loadFromDirectory(directory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +299,7 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
}
|
||||
|
||||
private void loadProjectLibraries(@Nullable Element libraryTableElement) {
|
||||
JpsLibraryTableSerializer.loadLibraries(libraryTableElement, myProject.getLibraryCollection());
|
||||
JpsLibraryTableSerializer.loadLibraries(libraryTableElement, myPathMapper, myProject.getLibraryCollection());
|
||||
}
|
||||
|
||||
private void loadModules(@Nullable Element componentElement, final @Nullable JpsSdkType<?> projectSdkType, @NotNull Path workspaceFile) {
|
||||
@@ -322,7 +328,7 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
List<JpsModule> modules = loadModules(moduleFiles, projectSdkType, myPathVariables);
|
||||
List<JpsModule> modules = loadModules(moduleFiles, projectSdkType, myPathVariables, myPathMapper);
|
||||
for (JpsModule module : modules) {
|
||||
myProject.addModule(module);
|
||||
}
|
||||
@@ -338,7 +344,8 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
@NotNull
|
||||
public static List<JpsModule> loadModules(@NotNull List<? extends Path> moduleFiles,
|
||||
@Nullable JpsSdkType<?> projectSdkType,
|
||||
@NotNull Map<String, String> pathVariables) {
|
||||
@NotNull Map<String, String> pathVariables,
|
||||
@NotNull JpsPathMapper pathMapper) {
|
||||
List<JpsModule> modules = new ArrayList<>();
|
||||
List<Future<Pair<Path, Element>>> futureModuleFilesContents = new ArrayList<>();
|
||||
Path externalModuleDir = resolveExternalProjectConfig("modules");
|
||||
@@ -389,7 +396,7 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
final Pair<Path, Element> moduleFile = futureModuleFile.get();
|
||||
if (moduleFile.getSecond() != null) {
|
||||
futures.add(ourThreadPool.submit(
|
||||
() -> loadModule(moduleFile.getFirst(), moduleFile.getSecond(), classpathDirs, projectSdkType, pathVariables)));
|
||||
() -> loadModule(moduleFile.getFirst(), moduleFile.getSecond(), classpathDirs, projectSdkType, pathVariables, pathMapper)));
|
||||
}
|
||||
}
|
||||
for (Future<JpsModule> future : futures) {
|
||||
@@ -407,7 +414,7 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
|
||||
@NotNull
|
||||
private static JpsModule loadModule(@NotNull Path file, @NotNull Element moduleRoot, List<String> paths,
|
||||
@Nullable JpsSdkType<?> projectSdkType, Map<String, String> pathVariables) {
|
||||
@Nullable JpsSdkType<?> projectSdkType, Map<String, String> pathVariables, @NotNull JpsPathMapper pathMapper) {
|
||||
String name = getModuleName(file);
|
||||
final String typeId = moduleRoot.getAttributeValue("type");
|
||||
final JpsModulePropertiesSerializer<?> serializer = getModulePropertiesSerializer(typeId);
|
||||
@@ -424,7 +431,7 @@ public final class JpsProjectLoader extends JpsLoaderBase {
|
||||
if (classpath == null) {
|
||||
try {
|
||||
JpsModuleRootModelSerializer.loadRootModel(module, JDomSerializationUtil.findComponent(moduleRoot, "NewModuleRootManager"),
|
||||
projectSdkType);
|
||||
projectSdkType, pathMapper);
|
||||
}
|
||||
catch (JpsSerializationFormatException e) {
|
||||
LOG.warn("Failed to load module configuration from " + file.toString() + ": " + e.getMessage(), e);
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
// Copyright 2000-2020 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 org.jetbrains.jps.model.serialization;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class JpsWslPathMapper implements JpsPathMapper {
|
||||
private static final String WSL_PREFIX = "//wsl$/";
|
||||
private @Nullable String myWslRootPrefix;
|
||||
|
||||
@Override
|
||||
public String mapUrl(String url) {
|
||||
public @Nullable String mapUrl(@Nullable String url) {
|
||||
if (url == null) return null;
|
||||
if (url.contains(WSL_PREFIX)) {
|
||||
int startPos = url.indexOf(WSL_PREFIX);
|
||||
int endPos = url.indexOf('/', startPos + WSL_PREFIX.length());
|
||||
@@ -13,6 +25,43 @@ public class JpsWslPathMapper implements JpsPathMapper {
|
||||
return url.substring(0, startPos) + url.substring(endPos);
|
||||
}
|
||||
}
|
||||
if (url.startsWith(JpsPathUtil.FILE_URL_PREFIX)) {
|
||||
return JpsPathUtil.FILE_URL_PREFIX + mapPath(url.substring(JpsPathUtil.FILE_URL_PREFIX.length()));
|
||||
}
|
||||
if (url.startsWith(JpsPathUtil.JAR_URL_PREFIX)) {
|
||||
int index = url.indexOf(JpsPathUtil.JAR_SEPARATOR);
|
||||
if (index >= 0) {
|
||||
return JpsPathUtil.JAR_URL_PREFIX + mapPath(url.substring(JpsPathUtil.JAR_URL_PREFIX.length(), index)) + url.substring(index);
|
||||
}
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String mapPath(@NotNull String path) {
|
||||
if (myWslRootPrefix == null || path.indexOf(':') != 1) {
|
||||
String wslPath;
|
||||
try {
|
||||
wslPath = runWslPath(path);
|
||||
}
|
||||
catch (IOException | InterruptedException e) {
|
||||
return path;
|
||||
}
|
||||
if (path.indexOf(':') == 1) {
|
||||
int pathLengthAfterDriveLetter = path.length() - 2;
|
||||
myWslRootPrefix = wslPath.substring(0, wslPath.length() - pathLengthAfterDriveLetter - 2 /* slash and drive letter */);
|
||||
}
|
||||
return wslPath;
|
||||
}
|
||||
|
||||
return myWslRootPrefix + Character.toLowerCase(path.charAt(0)) + FileUtil.toSystemIndependentName(path.substring(2));
|
||||
}
|
||||
|
||||
private static String runWslPath(String path) throws IOException, InterruptedException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder("/usr/bin/wslpath", path);
|
||||
Process process = processBuilder.start();
|
||||
process.waitFor();
|
||||
return StreamUtil.readText(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public final class JpsSerializationManagerImpl extends JpsSerializationManager {
|
||||
JpsGlobalLoader.loadGlobalSettings(model.getGlobal(), optionsPath);
|
||||
}
|
||||
Map<String, String> pathVariables = JpsModelSerializationDataService.computeAllPathVariables(model.getGlobal());
|
||||
JpsProjectLoader.loadProject(model.getProject(), pathVariables, projectPath, loadUnloadedModules);
|
||||
JpsProjectLoader.loadProject(model.getProject(), pathVariables, model.getGlobal().getPathMapper(), projectPath, loadUnloadedModules);
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,17 @@ package org.jetbrains.jps.model.serialization.library;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.*;
|
||||
import org.jetbrains.jps.model.java.JpsJavaLibraryType;
|
||||
import org.jetbrains.jps.model.library.*;
|
||||
import org.jetbrains.jps.model.library.JpsLibrary;
|
||||
import org.jetbrains.jps.model.library.JpsLibraryCollection;
|
||||
import org.jetbrains.jps.model.library.JpsLibraryRoot;
|
||||
import org.jetbrains.jps.model.library.JpsOrderRootType;
|
||||
import org.jetbrains.jps.model.module.JpsModuleReference;
|
||||
import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension;
|
||||
import org.jetbrains.jps.model.serialization.JpsPathMapper;
|
||||
|
||||
public final class JpsLibraryTableSerializer {
|
||||
private static final JpsLibraryRootTypeSerializer[] PREDEFINED_ROOT_TYPES_SERIALIZERS = {
|
||||
@@ -36,17 +41,19 @@ public final class JpsLibraryTableSerializer {
|
||||
public static final String PROJECT_LEVEL = "project";
|
||||
public static final String APPLICATION_LEVEL = "application";
|
||||
|
||||
public static void loadLibraries(@Nullable Element libraryTableElement, JpsLibraryCollection result) {
|
||||
public static void loadLibraries(@Nullable Element libraryTableElement,
|
||||
@NotNull JpsPathMapper pathMapper,
|
||||
JpsLibraryCollection result) {
|
||||
for (Element libraryElement : JDOMUtil.getChildren(libraryTableElement, LIBRARY_TAG)) {
|
||||
result.addLibrary(loadLibrary(libraryElement));
|
||||
result.addLibrary(loadLibrary(libraryElement, pathMapper));
|
||||
}
|
||||
}
|
||||
|
||||
public static JpsLibrary loadLibrary(Element libraryElement) {
|
||||
return loadLibrary(libraryElement, libraryElement.getAttributeValue(NAME_ATTRIBUTE));
|
||||
public static JpsLibrary loadLibrary(Element libraryElement, @NotNull JpsPathMapper pathMapper) {
|
||||
return loadLibrary(libraryElement, libraryElement.getAttributeValue(NAME_ATTRIBUTE), pathMapper);
|
||||
}
|
||||
|
||||
public static JpsLibrary loadLibrary(Element libraryElement, String name) {
|
||||
public static JpsLibrary loadLibrary(Element libraryElement, String name, @NotNull JpsPathMapper pathMapper) {
|
||||
String typeId = libraryElement.getAttributeValue(TYPE_ATTRIBUTE);
|
||||
final JpsLibraryPropertiesSerializer<?> loader = getLibraryPropertiesSerializer(typeId);
|
||||
JpsLibrary library = createLibrary(name, loader, libraryElement.getChild(PROPERTIES_TAG));
|
||||
@@ -54,7 +61,7 @@ public final class JpsLibraryTableSerializer {
|
||||
MultiMap<JpsOrderRootType, String> jarDirectories = new MultiMap<>();
|
||||
MultiMap<JpsOrderRootType, String> recursiveJarDirectories = new MultiMap<>();
|
||||
for (Element jarDirectory : JDOMUtil.getChildren(libraryElement, JAR_DIRECTORY_TAG)) {
|
||||
String url = jarDirectory.getAttributeValue(URL_ATTRIBUTE);
|
||||
String url = pathMapper.mapUrl(jarDirectory.getAttributeValue(URL_ATTRIBUTE));
|
||||
String rootTypeId = jarDirectory.getAttributeValue(TYPE_ATTRIBUTE);
|
||||
final JpsOrderRootType rootType = rootTypeId != null ? getRootType(rootTypeId) : JpsOrderRootType.COMPILED;
|
||||
boolean recursive = Boolean.parseBoolean(jarDirectory.getAttributeValue(RECURSIVE_ATTRIBUTE));
|
||||
@@ -68,7 +75,7 @@ public final class JpsLibraryTableSerializer {
|
||||
if (!rootTypeId.equals(JAR_DIRECTORY_TAG) && !rootTypeId.equals(PROPERTIES_TAG)) {
|
||||
final JpsOrderRootType rootType = getRootType(rootTypeId);
|
||||
for (Element rootElement : JDOMUtil.getChildren(rootsElement, ROOT_TAG)) {
|
||||
String url = rootElement.getAttributeValue(URL_ATTRIBUTE);
|
||||
String url = pathMapper.mapUrl(rootElement.getAttributeValue(URL_ATTRIBUTE));
|
||||
JpsLibraryRoot.InclusionOptions options;
|
||||
if (jarDirectories.get(rootType).contains(url)) {
|
||||
final boolean recursive = recursiveJarDirectories.get(rootType).contains(url);
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.jps.model.library.JpsLibrary;
|
||||
import org.jetbrains.jps.model.library.sdk.JpsSdkType;
|
||||
import org.jetbrains.jps.model.module.*;
|
||||
import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension;
|
||||
import org.jetbrains.jps.model.serialization.JpsPathMapper;
|
||||
import org.jetbrains.jps.model.serialization.impl.JpsSerializationFormatException;
|
||||
import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer;
|
||||
import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer;
|
||||
@@ -48,7 +49,7 @@ public final class JpsModuleRootModelSerializer {
|
||||
public static final String JAVA_TEST_ROOT_TYPE_ID = "java-test";
|
||||
private static final String GENERATED_LIBRARY_NAME_PREFIX = "#";
|
||||
|
||||
public static void loadRootModel(JpsModule module, @Nullable Element rootModelComponent, @Nullable JpsSdkType<?> projectSdkType) {
|
||||
public static void loadRootModel(JpsModule module, @Nullable Element rootModelComponent, @Nullable JpsSdkType<?> projectSdkType, @NotNull JpsPathMapper pathMapper) {
|
||||
if (rootModelComponent == null) return;
|
||||
|
||||
for (Element contentElement : getChildren(rootModelComponent, CONTENT_TAG)) {
|
||||
@@ -108,7 +109,7 @@ public final class JpsModuleRootModelSerializer {
|
||||
name = GENERATED_LIBRARY_NAME_PREFIX;
|
||||
}
|
||||
String uniqueName = nameGenerator.generateUniqueName(name);
|
||||
final JpsLibrary library = JpsLibraryTableSerializer.loadLibrary(moduleLibraryElement, uniqueName);
|
||||
final JpsLibrary library = JpsLibraryTableSerializer.loadLibrary(moduleLibraryElement, uniqueName, pathMapper);
|
||||
module.addModuleLibrary(library);
|
||||
|
||||
final JpsLibraryDependency dependency = dependenciesList.addLibraryDependency(library);
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
import org.jetbrains.jps.model.module.JpsModuleDependency
|
||||
import org.jetbrains.jps.model.serialization.JpsGlobalLoader
|
||||
import org.jetbrains.jps.model.serialization.JpsPathMapper
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectLoader
|
||||
import java.nio.file.Paths
|
||||
|
||||
@@ -45,7 +46,7 @@ class UnloadedModuleDescriptionImpl(val modulePath: ModulePath,
|
||||
@JvmStatic
|
||||
fun createFromPaths(paths: Collection<ModulePath>, parentDisposable: Disposable): List<UnloadedModuleDescriptionImpl> {
|
||||
val pathVariables = JpsGlobalLoader.computeAllPathVariables(PathManager.getOptionsPath())
|
||||
val modules = JpsProjectLoader.loadModules(paths.map { Paths.get(it.path) }, null, pathVariables)
|
||||
val modules = JpsProjectLoader.loadModules(paths.map { Paths.get(it.path) }, null, pathVariables, JpsPathMapper.IDENTITY)
|
||||
val pathsByName = paths.associateBy { it.moduleName }
|
||||
return modules.map { create(pathsByName[it.name]!!, it, parentDisposable) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user