Skip to content

Commit

Permalink
Import projects by configurations (#2913)
Browse files Browse the repository at this point in the history
Signed-off-by: Sheng Chen <sheche@microsoft.com>
  • Loading branch information
jdneo authored Nov 22, 2023
1 parent 9dcc017 commit 58fc1d6
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,20 @@ public void initialize(File rootFolder) {
public abstract boolean applies(IProgressMonitor monitor) throws OperationCanceledException, CoreException;

@Override
public boolean isResolved(File folder) throws OperationCanceledException, CoreException {
return directories != null && directories.contains(folder.toPath());
public boolean isResolved(File file) throws OperationCanceledException, CoreException {
if (directories == null) {
return false;
}
// if input is a directory (usually the root folder),
// check if the importer has imported it.
if (file.isDirectory()) {
return directories.contains(file.toPath());
}

// if the input is a file, check if the parent directory is imported.
return directories.stream().anyMatch((directory) -> {
return file.toPath().getParent().equals(directory);
});
};

@Override
Expand Down Expand Up @@ -82,6 +94,10 @@ protected Collection<Path> findProjectPathByConfigurationName(Collection<IPath>
return filteredPaths;
}

return eliminateNestedPaths(filteredPaths);
}

protected List<Path> eliminateNestedPaths(List<Path> filteredPaths) {
Path parentDir = null;
List<Path> result = new LinkedList<>();
for (Path path : filteredPaths) {
Expand All @@ -95,7 +111,6 @@ protected Collection<Path> findProjectPathByConfigurationName(Collection<IPath>
parentDir = path;
}
}

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public class GradleProjectImporter extends AbstractProjectImporter {
.replaceAll("\n", System.lineSeparator());
//@formatter:on

/**
* A flag whether this importer is activated by manual selection mode.
*/
private boolean manualSelection = false;

/* (non-Javadoc)
* @see org.eclipse.jdt.ls.core.internal.managers.IProjectImporter#applies(org.eclipse.core.runtime.IProgressMonitor)
*/
Expand Down Expand Up @@ -158,6 +163,7 @@ public boolean applies(IProgressMonitor monitor) throws CoreException {

@Override
public boolean applies(Collection<IPath> buildFiles, IProgressMonitor monitor) {
manualSelection = true;
if (!getPreferences().isImportGradleEnabled()) {
return false;
}
Expand All @@ -167,7 +173,7 @@ public boolean applies(Collection<IPath> buildFiles, IProgressMonitor monitor) {
SETTINGS_GRADLE_DESCRIPTOR,
BUILD_GRADLE_KTS_DESCRIPTOR,
SETTINGS_GRADLE_KTS_DESCRIPTOR
), false /*includeNested*/);
), true /*includeNested*/);
if (configurationDirs == null || configurationDirs.isEmpty()) {
return false;
}
Expand Down Expand Up @@ -199,16 +205,20 @@ public void importToWorkspace(IProgressMonitor monitor) throws CoreException {
if (!applies(monitor)) {
return;
}
int projectSize = directories.size();
List<Path> directoriesToImport = new ArrayList<>(this.directories);
if (manualSelection) {
directoriesToImport = eliminateNestedPaths(directoriesToImport);
}
int projectSize = directoriesToImport.size();
SubMonitor subMonitor = SubMonitor.convert(monitor, projectSize + 1);
subMonitor.setTaskName(IMPORTING_GRADLE_PROJECTS);
JavaLanguageServerPlugin.logInfo(IMPORTING_GRADLE_PROJECTS);
subMonitor.worked(1);
// run just once at the first project, assuming that all projects are using the same gradle version.
inferGradleJavaHome(directories.iterator().next(), monitor);
inferGradleJavaHome(directoriesToImport.iterator().next(), monitor);
MultiStatus compatibilityStatus = new MultiStatus(IConstants.PLUGIN_ID, -1, "Compatibility issue occurs when importing Gradle projects", null);
MultiStatus gradleUpgradeWrapperStatus = new MultiStatus(IConstants.PLUGIN_ID, -1, "Gradle upgrade wrapper", null);
for (Path directory : directories) {
for (Path directory : directoriesToImport) {
IStatus importStatus = importDir(directory, subMonitor.newChild(1));
if (isFailedStatus(importStatus) && importStatus instanceof GradleCompatibilityStatus) {
compatibilityStatus.add(importStatus);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -173,11 +174,14 @@ protected void importProjectsFromConfigurationFiles(Collection<IPath> rootPaths,
MultiStatus importStatusCollection = new MultiStatus(IConstants.PLUGIN_ID, -1, "Failed to import projects", null);
for (IPath rootPath : rootPaths) {
File rootFolder = rootPath.toFile();
Set<IPath> buildFiles = projectConfigurations.stream()
.filter(rootPath::isPrefixOf).collect(Collectors.toSet());
try {
for (IProjectImporter importer : importers()) {
importer.initialize(rootFolder);
if (importer.applies(projectConfigurations, subMonitor.split(1))) {
if (importer.applies(buildFiles, subMonitor.split(1))) {
importer.importToWorkspace(subMonitor.split(70));
buildFiles = removeImportedConfigurations(buildFiles, importer);
}
}
} catch (CoreException e) {
Expand All @@ -191,6 +195,18 @@ protected void importProjectsFromConfigurationFiles(Collection<IPath> rootPaths,
}
}

private Set<IPath> removeImportedConfigurations(Set<IPath> configurations, IProjectImporter importer) {
return configurations.stream()
.filter(config -> {
try {
return !importer.isResolved(config.toFile());
} catch (OperationCanceledException | CoreException e) {
return true;
}
})
.collect(Collectors.toSet());
}

public void importProjects(IProgressMonitor monitor) {
WorkspaceJob job = new WorkspaceJob("Importing projects in workspace...") {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,14 @@ public void dontFilterGitLikePackages() throws Exception {

@Test
public void testImportMavenSubModule() throws IOException, OperationCanceledException, CoreException {
Path projectDir = copyFiles("maven/multimodule", true).toPath();
File projectDir = copyFiles("maven/multimodule", true);
Path projectDirPath = projectDir.toPath();
Collection<IPath> configurationPaths = new ArrayList<>();
Path subModuleConfiguration = projectDir.resolve("module1/pom.xml");
Path subModuleConfiguration = projectDirPath.resolve("module1/pom.xml");
IPath filePath = ResourceUtils.canonicalFilePathFromURI(subModuleConfiguration.toUri().toString());
configurationPaths.add(filePath);
preferenceManager.getPreferences().setProjectConfigurations(configurationPaths);
projectsManager.initializeProjects(Collections.singleton(new org.eclipse.core.runtime.Path(projectDir.toString())), monitor);
projectsManager.initializeProjects(Collections.singleton(new org.eclipse.core.runtime.Path(projectDir.getAbsolutePath())), monitor);
IProject[] allProjects = ProjectUtils.getAllProjects();
Set<String> expectedProjects = new HashSet<>(Arrays.asList(
"module1",
Expand All @@ -252,13 +253,14 @@ public void testImportMavenSubModule() throws IOException, OperationCanceledExce

@Test
public void testImportMixedProjects() throws IOException, OperationCanceledException, CoreException {
Path projectDir = copyFiles("mixed", true).toPath();
File projectDir = copyFiles("mixed", true);
Path projectDirPath = projectDir.toPath();
Collection<IPath> configurationPaths = new ArrayList<>();
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDir.resolve("hello/.project").toUri().toString()));
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDir.resolve("simple-gradle/build.gradle").toUri().toString()));
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDir.resolve("salut/pom.xml").toUri().toString()));
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDirPath.resolve("hello/.project").toUri().toString()));
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDirPath.resolve("simple-gradle/build.gradle").toUri().toString()));
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDirPath.resolve("salut/pom.xml").toUri().toString()));
preferenceManager.getPreferences().setProjectConfigurations(configurationPaths);
projectsManager.initializeProjects(Collections.singleton(new org.eclipse.core.runtime.Path(projectDir.toString())), monitor);
projectsManager.initializeProjects(Collections.singleton(new org.eclipse.core.runtime.Path(projectDir.getAbsolutePath())), monitor);
IProject[] allProjects = ProjectUtils.getAllProjects();
Set<String> expectedProjects = new HashSet<>(Arrays.asList(
"jdt.ls-java-project",
Expand All @@ -274,12 +276,13 @@ public void testImportMixedProjects() throws IOException, OperationCanceledExcep

@Test
public void testImportMixedProjectsPartially() throws IOException, OperationCanceledException, CoreException {
Path projectDir = copyFiles("mixed", true).toPath();
File projectDir = copyFiles("mixed", true);
Path projectDirPath = projectDir.toPath();
Collection<IPath> configurationPaths = new ArrayList<>();
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDir.resolve("simple-gradle/build.gradle").toUri().toString()));
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDir.resolve("salut/pom.xml").toUri().toString()));
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDirPath.resolve("simple-gradle/build.gradle").toUri().toString()));
configurationPaths.add(ResourceUtils.canonicalFilePathFromURI(projectDirPath.resolve("salut/pom.xml").toUri().toString()));
preferenceManager.getPreferences().setProjectConfigurations(configurationPaths);
projectsManager.initializeProjects(Collections.singleton(new org.eclipse.core.runtime.Path(projectDir.toString())), monitor);
projectsManager.initializeProjects(Collections.singleton(new org.eclipse.core.runtime.Path(projectDir.getAbsolutePath())), monitor);
IProject[] allProjects = ProjectUtils.getAllProjects();
Set<String> expectedProjects = new HashSet<>(Arrays.asList(
"jdt.ls-java-project",
Expand Down

0 comments on commit 58fc1d6

Please sign in to comment.