IDEA-242675 Opening folder without .idea creates corrupted project

GitOrigin-RevId: 651f094795162a40424e1577392347c7a202ce30
This commit is contained in:
Vladimir Krivosheev
2020-06-09 00:07:52 +03:00
committed by intellij-monorepo-bot
parent d9503820c9
commit 29c146ecf4
3 changed files with 65 additions and 67 deletions
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2019 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 com.intellij.openapi.fileTypes;
import com.intellij.openapi.options.Scheme;
@@ -27,13 +13,12 @@ import javax.swing.*;
/**
* Describes a filetype.
* <p/>
* Must be registered via {@code com.intellij.fileType} extension point or {@link com.intellij.openapi.fileTypes.FileTypeFactory}.
* Must be registered via {@code com.intellij.fileType} extension point.
* If file type depends on given file, {@link com.intellij.openapi.fileTypes.ex.FileTypeIdentifiableByVirtualFile}
* can be used for non-static mapping.
* <p/>
* Use {@link LanguageFileType} for files having {@link com.intellij.lang.Language} support.
*
* @see com.intellij.openapi.fileTypes.StdFileTypes
* @see com.intellij.openapi.fileTypes.FileTypes
* @see INativeFileType
*/
@@ -24,6 +24,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -38,8 +39,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import static com.intellij.ide.lightEdit.LightEditFeatureUsagesUtil.OpenPlace.LightEditOpenAction;
@@ -95,8 +96,8 @@ public class OpenFileAction extends AnAction implements DumbAware, LightEditComp
}
private static void doOpenFile(@Nullable Project project, @NotNull VirtualFile file) {
if (file.isDirectory()) {
Path filePath = Paths.get(file.getPath());
Path filePath = file.toNioPath();
if (Files.isDirectory(filePath)) {
boolean canAttach = ProjectAttachProcessor.canAttachToProject();
boolean preferAttach = PlatformUtils.isDataGrip() && project != null && canAttach && !ProjectUtil.isValidProjectPath(filePath);
Project openedProject;
@@ -104,10 +105,10 @@ public class OpenFileAction extends AnAction implements DumbAware, LightEditComp
return;
}
else if (canAttach) {
openedProject = PlatformProjectOpenProcessor.doOpenProject(filePath, OpenProjectTask.withProjectToClose(project));
openedProject = ProjectManagerEx.getInstanceEx().openProject(filePath, PlatformProjectOpenProcessor.createOptionsToOpenDotIdeaOrCreateNewIfNotExists(filePath, project));
}
else {
openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
openedProject = ProjectUtil.openOrImport(filePath, OpenProjectTask.withProjectToClose(project));
}
FileChooserUtil.setLastOpenedFile(openedProject, file);
return;
@@ -115,13 +116,12 @@ public class OpenFileAction extends AnAction implements DumbAware, LightEditComp
// try to open as a project - unless the file is an .ipr of the current one
if ((project == null || !file.equals(project.getProjectFile())) && OpenProjectFileChooserDescriptor.isProjectFile(file)) {
final int answer;
answer = shouldOpenNewProject(project, file);
if (answer == Messages.CANCEL) return;
if (answer == Messages.YES) {
Project openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
int answer = shouldOpenNewProject(project, file);
if (answer == Messages.CANCEL) {
return;
}
else if (answer == Messages.YES) {
Project openedProject = ProjectUtil.openOrImport(filePath, OpenProjectTask.withProjectToClose(project));
if (openedProject != null) {
FileChooserUtil.setLastOpenedFile(openedProject, file);
}
@@ -131,18 +131,18 @@ public class OpenFileAction extends AnAction implements DumbAware, LightEditComp
LightEditUtil.markUnknownFileTypeAsPlainTextIfNeeded(project, file);
FileType type = FileTypeChooser.getKnownFileTypeOrAssociate(file, project);
if (type == null) return;
if (type == null) {
return;
}
if (project != null && !project.isDefault()) {
openFile(file, project);
}
else if (LightEdit.openFile(file)) {
LightEditFeatureUsagesUtil.logFileOpen(WelcomeScreenOpenAction);
}
else {
if (LightEdit.openFile(file)) {
LightEditFeatureUsagesUtil.logFileOpen(WelcomeScreenOpenAction);
}
else {
PlatformProjectOpenProcessor.createTempProjectAndOpenFile(Paths.get(file.getPath()), new OpenProjectTask());
}
PlatformProjectOpenProcessor.createTempProjectAndOpenFile(filePath, OpenProjectTask.withProjectToClose(project));
}
}
@@ -112,36 +112,39 @@ class PlatformProjectOpenProcessor : ProjectOpenProcessor(), CommandLineProjectO
@JvmStatic
fun doOpenProject(file: Path, originalOptions: OpenProjectTask): Project? {
LOG.info("Opening $file")
var baseDir = file
if (Files.isDirectory(file)) {
return ProjectManagerEx.getInstanceEx().openProject(file, createOptionsToOpenDotIdeaOrCreateNewIfNotExists(file, projectToClose = null))
}
var options = originalOptions
if (!Files.isDirectory(file)) {
if (LightEditUtil.openFile(file)) {
return LightEditUtil.getProject()
if (LightEditUtil.openFile(file)) {
return LightEditUtil.getProject()
}
var baseDirCandidate = file.parent
while (baseDirCandidate != null && !Files.exists(baseDirCandidate.resolve(Project.DIRECTORY_STORE_FOLDER))) {
baseDirCandidate = baseDirCandidate.parent
}
val baseDir: Path
// no reasonable directory -> create new temp one or use parent
if (baseDirCandidate == null) {
LOG.info("No project directory found")
if (Registry.`is`("ide.open.file.in.temp.project.dir")) {
return createTempProjectAndOpenFile(file, options)
}
var baseDirCandidate = file.parent
while (baseDirCandidate != null && !Files.exists(baseDirCandidate.resolve(Project.DIRECTORY_STORE_FOLDER))) {
baseDirCandidate = baseDirCandidate.parent
}
// no reasonable directory -> create new temp one or use parent
if (baseDirCandidate == null) {
LOG.info("No project directory found")
if (Registry.`is`("ide.open.file.in.temp.project.dir")) {
return createTempProjectAndOpenFile(file, options)
}
baseDir = file.parent
options = options.copy(isNewProject = !Files.isDirectory(baseDir.resolve(Project.DIRECTORY_STORE_FOLDER)))
}
else {
baseDir = baseDirCandidate
LOG.info("Project directory found: $baseDir")
}
baseDir = file.parent
options = options.copy(isNewProject = !Files.isDirectory(baseDir.resolve(Project.DIRECTORY_STORE_FOLDER)))
}
else {
baseDir = baseDirCandidate
LOG.info("Project directory found: $baseDir")
}
val project = ProjectManagerEx.getInstanceEx().openProject(baseDir, if (baseDir == file) options else options.copy(projectName = file.fileName.toString()))
if (project != null && file != baseDir && !Files.isDirectory(file)) {
if (project != null && file != baseDir) {
openFileFromCommandLine(project, file, options.line, options.column)
}
return project
@@ -185,6 +188,22 @@ class PlatformProjectOpenProcessor : ProjectOpenProcessor(), CommandLineProjectO
processor.attachToProject(project, projectDir, callback)
} != null
}
/**
* If project file in IDEA format (.idea directory or .ipr file) exists, just open it.
* If doesn't exists, create a new project using default project template and run configurators (something that creates module).
* (at the moment of creation project file in IDEA format will be removed if any).
*/
@ApiStatus.Internal
@JvmStatic
fun createOptionsToOpenDotIdeaOrCreateNewIfNotExists(projectDir: Path, projectToClose: Project?): OpenProjectTask {
val validProjectPath = ProjectUtil.isValidProjectPath(projectDir)
// doesn't make sense to use default project as template in tests
return OpenProjectTask(runConfigurators = !validProjectPath,
isNewProject = !validProjectPath,
projectToClose = projectToClose,
useDefaultProjectAsTemplate = !ApplicationManager.getApplication().isUnitTestMode)
}
}
override fun canOpenProject(file: VirtualFile) = file.isDirectory
@@ -195,13 +214,7 @@ class PlatformProjectOpenProcessor : ProjectOpenProcessor(), CommandLineProjectO
override fun doOpenProject(virtualFile: VirtualFile, projectToClose: Project?, forceOpenInNewFrame: Boolean): Project? {
val baseDir = virtualFile.toNioPath()
// doesn't make sense to use default project in tests for heavy projects
val validProjectPath = ProjectUtil.isValidProjectPath(baseDir)
return doOpenProject(baseDir, OpenProjectTask(forceOpenInNewFrame = forceOpenInNewFrame,
projectToClose = projectToClose,
runConfigurators = !validProjectPath,
isNewProject = !validProjectPath,
useDefaultProjectAsTemplate = !ApplicationManager.getApplication().isUnitTestMode))
return doOpenProject(baseDir, createOptionsToOpenDotIdeaOrCreateNewIfNotExists(baseDir, projectToClose).copy(forceOpenInNewFrame = forceOpenInNewFrame))
}
override fun openProjectAndFile(file: Path, line: Int, column: Int, tempProject: Boolean): Project? {