From 42a10ea1326cdff2d0992a131867bcf64dea4be4 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 18 Jun 2020 17:14:42 +0200 Subject: [PATCH] =?UTF-8?q?cleanup=20=E2=80=94=20use=20Path=20instead=20of?= =?UTF-8?q?=20String=20as=20return=20type=20of=20getDirectoryStorePath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitOrigin-RevId: 65db4eb7d0af6df4ddce48e96db8f55c5b0c2d78 --- .../compiler/BaseCompilerTestCase.java | 9 ++- .../jsonSchema/extension/JsonSchemaInfo.java | 47 ++++++++--- .../src/ProjectStoreBase.kt | 4 +- .../src/ProjectStoreImpl.kt | 2 +- .../AbstractConvertLineSeparatorsAction.java | 8 +- .../ExternalSystemStorageTest.kt | 28 ++++--- .../actions/ModuleDeleteProvider.java | 9 ++- .../components/impl/stores/IProjectStore.java | 7 +- .../vcs/impl/DefaultVcsRootPolicy.java | 20 +---- .../vcs/impl/ModuleDefaultVcsRootPolicy.java | 6 +- .../ignore/GitIgnoredFileContentProvider.kt | 78 +++++++++++-------- .../git4idea/ignore/GitIgnoredFileTest.kt | 33 ++++---- 12 files changed, 143 insertions(+), 108 deletions(-) diff --git a/java/compiler/tests/com/intellij/compiler/BaseCompilerTestCase.java b/java/compiler/tests/com/intellij/compiler/BaseCompilerTestCase.java index 0ca56511f8f9..b996409b74f2 100644 --- a/java/compiler/tests/com/intellij/compiler/BaseCompilerTestCase.java +++ b/java/compiler/tests/com/intellij/compiler/BaseCompilerTestCase.java @@ -39,6 +39,7 @@ import org.junit.Assert; import javax.swing.*; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.*; import java.util.function.Consumer; @@ -322,12 +323,12 @@ public abstract class BaseCompilerTestCase extends JavaModuleTestCase { @Override protected Module doCreateRealModule(@NotNull String moduleName) { //todo[nik] reuse code from PlatformTestCase - final VirtualFile baseDir = getOrCreateProjectBaseDir(); - final File moduleFile = new File(baseDir.getPath().replace('/', File.separatorChar), moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION); - myFilesToDelete.add(moduleFile); + VirtualFile baseDir = getOrCreateProjectBaseDir(); + Path moduleFile = baseDir.toNioPath().resolve(moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION); + myFilesToDelete.add(moduleFile.toFile()); return WriteAction.computeAndWait(() -> { Module module = ModuleManager.getInstance(myProject) - .newModule(FileUtil.toSystemIndependentName(moduleFile.getAbsolutePath()), getModuleType().getId()); + .newModule(FileUtil.toSystemIndependentName(moduleFile.toString()), getModuleType().getId()); module.getModuleFile(); return module; }); diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaInfo.java b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaInfo.java index 2545bee89988..b52261ea2881 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaInfo.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaInfo.java @@ -1,8 +1,11 @@ -// 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. +// 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.jetbrains.jsonSchema.extension; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.text.Strings; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; @@ -14,6 +17,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Map; import java.util.Set; @@ -136,17 +141,35 @@ public class JsonSchemaInfo { @NotNull public static String getRelativePath(@NotNull Project project, @NotNull String text) { text = text.trim(); - if (project.isDefault() || project.getBasePath() == null) return text; - if (StringUtil.isEmptyOrSpaces(text)) return text; - final File ioFile = new File(text); - if (!ioFile.isAbsolute()) return text; - VirtualFile file = VfsUtil.findFileByIoFile(ioFile, false); - if (file == null) return text; - final String relativePath = VfsUtilCore.getRelativePath(file, project.getBaseDir()); - if (relativePath != null) return relativePath; - if (isMeaningfulAncestor(VfsUtilCore.getCommonAncestor(file, project.getBaseDir()))) { - String path = VfsUtilCore.findRelativePath(project.getBaseDir(), file, File.separatorChar); - if (path != null) return path; + if (project.isDefault() || project.getBasePath() == null || Strings.isEmptyOrSpaces(text)) { + return text; + } + + Path ioFile = Paths.get(text); + if (!ioFile.isAbsolute()) { + return text; + } + + String relativePath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(ioFile.toString()), project.getBasePath(), '/'); + if (relativePath != null) { + return relativePath; + } + + VirtualFile file = LocalFileSystem.getInstance().findFileByNioFile(ioFile); + if (file == null) { + return text; + } + + VirtualFile projectBaseDir = LocalFileSystem.getInstance().findFileByPath(project.getBasePath()); + if (projectBaseDir == null) { + return text; + } + + if (isMeaningfulAncestor(VfsUtilCore.getCommonAncestor(file, projectBaseDir))) { + String path = VfsUtilCore.findRelativePath(projectBaseDir, file, File.separatorChar); + if (path != null) { + return path; + } } return text; } diff --git a/platform/configuration-store-impl/src/ProjectStoreBase.kt b/platform/configuration-store-impl/src/ProjectStoreBase.kt index 18796166b0f4..47bef851e907 100644 --- a/platform/configuration-store-impl/src/ProjectStoreBase.kt +++ b/platform/configuration-store-impl/src/ProjectStoreBase.kt @@ -60,7 +60,7 @@ abstract class ProjectStoreBase(final override val project: Project) : Component loadPolicy = if (value) StateLoadPolicy.NOT_LOAD else StateLoadPolicy.LOAD } - override fun getProjectFilePath() = storageManager.expandMacro(PROJECT_FILE) + final override fun getProjectFilePath() = storageManager.expandMacro(PROJECT_FILE) /** * `null` for default or non-directory based project. @@ -268,7 +268,7 @@ abstract class ProjectStoreBase(final override val project: Project) : Component return if (!ignoreProjectStorageScheme && !isDirectoryBased) null else PathUtil.getParentPath(projectFilePath).nullize() } - override fun getDirectoryStoreFile(): VirtualFile? = directoryStorePath?.let { LocalFileSystem.getInstance().findFileByPath(it) } + override fun getDirectoryStoreFile(): VirtualFile? = directoryStorePath?.let { LocalFileSystem.getInstance().findFileByNioFile(it) } override fun getDirectoryStorePathOrBase(): String = PathUtil.getParentPath(projectFilePath) diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt index 03e0b416be32..e237d4c949d4 100644 --- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt @@ -32,7 +32,7 @@ import java.nio.file.Path import java.nio.file.Paths internal val IProjectStore.nameFile: Path - get() = Paths.get(directoryStorePath, ProjectImpl.NAME_FILE) + get() = directoryStorePath.resolve(ProjectImpl.NAME_FILE) @ApiStatus.Internal open class ProjectStoreImpl(project: Project) : ProjectStoreBase(project) { diff --git a/platform/editor-ui-ex/src/com/intellij/codeStyle/AbstractConvertLineSeparatorsAction.java b/platform/editor-ui-ex/src/com/intellij/codeStyle/AbstractConvertLineSeparatorsAction.java index a1857330b537..3ac3c7e9cd01 100644 --- a/platform/editor-ui-ex/src/com/intellij/codeStyle/AbstractConvertLineSeparatorsAction.java +++ b/platform/editor-ui-ex/src/com/intellij/codeStyle/AbstractConvertLineSeparatorsAction.java @@ -14,7 +14,9 @@ import com.intellij.openapi.fileTypes.FileTypeRegistry; import com.intellij.openapi.fileTypes.InternalFileType; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.StandardFileSystems; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileVisitor; @@ -24,6 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.nio.file.Path; import java.util.function.Supplier; /** @@ -78,8 +81,9 @@ public abstract class AbstractConvertLineSeparatorsAction extends AnAction imple return; } - VirtualFile projectVirtualDirectory = ProjectKt.getStateStore(project).getDirectoryStoreFile(); - final FileTypeRegistry fileTypeManager = FileTypeRegistry.getInstance(); + Path directoryStorePath = ProjectKt.getStateStore(project).getDirectoryStorePath(); + VirtualFile projectVirtualDirectory = directoryStorePath == null ? null : StandardFileSystems.local().findFileByPath(FileUtil.toSystemIndependentName(directoryStorePath.toString())); + FileTypeRegistry fileTypeManager = FileTypeRegistry.getInstance(); for (VirtualFile file : virtualFiles) { VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() { @NotNull diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorageTest.kt b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorageTest.kt index d98d56b28c72..7fd2a4be5b9d 100644 --- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorageTest.kt +++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorageTest.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2019 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. +// 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.externalSystem.configurationStore import com.intellij.facet.FacetManager @@ -47,9 +47,11 @@ import com.intellij.util.ui.UIUtil import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.annotations.NotNull -import org.junit.* import org.junit.Assert.assertFalse +import org.junit.Before +import org.junit.ClassRule +import org.junit.Rule +import org.junit.Test import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths @@ -323,21 +325,23 @@ class ExternalSystemStorageTest { runBlocking { createProjectAndUseInLoadComponentStateMode(tempDirManager, directoryBased = true, useDefaultProjectSettings = false) { project -> ExternalProjectsManagerImpl.getInstance(project).setStoreExternally(storeExternally) - val projectDir = Paths.get(project.stateStore.directoryStorePath).parent + val projectDir = project.stateStore.directoryStorePath.parent val cacheDir = ExternalProjectsDataStorage.getProjectConfigurationDir(project) cacheDir.delete() Disposer.register(disposableRule.disposable, Disposable { cacheDir.delete() }) - withContext(AppUIExecutor.onUiThread().coroutineDispatchingContext()) { - runWriteAction { - //we need to set language level explicitly because otherwise if some tests modifies language level in the default project, we'll - // get different content in misc.xml - LanguageLevelProjectExtension.getInstance(project)!!.languageLevel = LanguageLevel.JDK_1_8 - setupProject(project, projectDir) + runBlocking { + withContext(AppUIExecutor.onWriteThread().coroutineDispatchingContext()) { + runWriteAction { + //we need to set language level explicitly because otherwise if some tests modifies language level in the default project, we'll + // get different content in misc.xml + LanguageLevelProjectExtension.getInstance(project)!!.languageLevel = LanguageLevel.JDK_1_8 + setupProject(project, projectDir) + } } - } - project.stateStore.save() + project.stateStore.save() + } val expectedDir = tempDirManager.newPath("expectedStorage") FileUtil.copyDir(testDataRoot.resolve("common").toFile(), expectedDir.toFile()) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java index 92f702496b5b..8fa4dd6800a0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/actions/ModuleDeleteProvider.java @@ -1,4 +1,4 @@ -// 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. +// 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.roots.ui.configuration.actions; @@ -11,7 +11,6 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.module.Module; import com.intellij.openapi.module.*; import com.intellij.openapi.module.impl.LoadedModuleDescriptionImpl; import com.intellij.openapi.project.Project; @@ -22,6 +21,7 @@ import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.impl.ModifiableModelCommitter; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.project.ProjectKt; import com.intellij.projectImport.ProjectAttachProcessor; @@ -30,6 +30,7 @@ import com.intellij.util.PlatformUtils; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; @@ -53,8 +54,8 @@ public class ModuleDeleteProvider implements DeleteProvider, TitledHandler { continue; } - String ideaDir = ProjectKt.getStateStore(project).getDirectoryStorePath(); - if (PathUtilRt.getParentPath(moduleFile).equals(ideaDir)) { + Path ideaDir = ProjectKt.getStateStore(project).getDirectoryStorePath(); + if (ideaDir != null && PathUtilRt.getParentPath(moduleFile).equals(FileUtil.toSystemIndependentName(ideaDir.toString()))) { return true; } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/IProjectStore.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/IProjectStore.java index cb841921d94e..e0719e1d74a3 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/IProjectStore.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/IProjectStore.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.SystemIndependent; import java.nio.file.Path; +import java.nio.file.Paths; public interface IProjectStore extends IComponentStore { @SystemIndependent @@ -59,9 +60,9 @@ public interface IProjectStore extends IComponentStore { /** * Directory of project configuration files for directory-based project. Or null. */ - @SystemIndependent - default String getDirectoryStorePath() { - return getDirectoryStorePath(false); + default Path getDirectoryStorePath() { + String result = getDirectoryStorePath(false); + return result == null ? null : Paths.get(result); } @NotNull diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultVcsRootPolicy.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultVcsRootPolicy.java index 05cea2a3ad21..e1c170a61890 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultVcsRootPolicy.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultVcsRootPolicy.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2016 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.vcs.impl; import com.intellij.openapi.components.ServiceManager; @@ -22,7 +8,6 @@ import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.project.ProjectKt; -import com.intellij.util.PathUtilRt; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -49,9 +34,8 @@ public abstract class DefaultVcsRootPolicy { @Nls public String getProjectConfigurationMessage() { boolean isDirectoryBased = ProjectKt.isDirectoryBased(myProject); - if (isDirectoryBased) { - String fileName = PathUtilRt.getFileName(ProjectKt.getStateStore(myProject).getDirectoryStorePath()); + String fileName = ProjectKt.getStateStore(myProject).getDirectoryStorePath().getFileName().toString(); return VcsBundle.message("settings.vcs.mapping.project.description.with.idea.directory", fileName); } return VcsBundle.getString("settings.vcs.mapping.project.description"); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleDefaultVcsRootPolicy.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleDefaultVcsRootPolicy.java index ea5da3eea278..b4ba03f9c64b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleDefaultVcsRootPolicy.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleDefaultVcsRootPolicy.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 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. +// 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.vcs.impl; @@ -11,6 +11,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.project.ProjectKt; import com.intellij.util.messages.MessageBusConnection; @@ -36,13 +37,12 @@ public class ModuleDefaultVcsRootPolicy extends DefaultVcsRootPolicy { Set result = new HashSet<>(); VirtualFile baseDir = myProject.getBaseDir(); - if (baseDir != null) { result.add(baseDir); } if (ProjectKt.isDirectoryBased(myProject) && baseDir != null) { - final VirtualFile ideaDir = ProjectKt.getStateStore(myProject).getDirectoryStoreFile(); + VirtualFile ideaDir = LocalFileSystem.getInstance().findFileByNioFile(ProjectKt.getStateStore(myProject).getDirectoryStorePath()); if (ideaDir != null) { result.add(ideaDir); } diff --git a/plugins/git4idea/src/git4idea/ignore/GitIgnoredFileContentProvider.kt b/plugins/git4idea/src/git4idea/ignore/GitIgnoredFileContentProvider.kt index f5e78b252692..5ad61cb921fd 100644 --- a/plugins/git4idea/src/git4idea/ignore/GitIgnoredFileContentProvider.kt +++ b/plugins/git4idea/src/git4idea/ignore/GitIgnoredFileContentProvider.kt @@ -1,4 +1,4 @@ -// 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. +// 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 git4idea.ignore import com.intellij.openapi.diagnostic.logger @@ -14,7 +14,6 @@ import com.intellij.openapi.vcs.changes.IgnoreSettingsType.* import com.intellij.openapi.vcs.changes.IgnoredFileContentProvider import com.intellij.openapi.vcs.changes.IgnoredFileDescriptor import com.intellij.openapi.vcs.changes.IgnoredFileProvider -import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.project.stateStore import com.intellij.vcsUtil.VcsUtil @@ -22,13 +21,13 @@ import git4idea.GitUtil import git4idea.GitVcs import git4idea.repo.GitRepositoryFiles.GITIGNORE import git4idea.repo.GitRepositoryManager -import java.io.File import java.lang.System.lineSeparator +import java.nio.file.Files +import java.nio.file.Paths private val LOG = logger() open class GitIgnoredFileContentProvider(private val project: Project) : IgnoredFileContentProvider { - private val gitIgnoreChecker = GitIgnoreChecker(project) override fun getSupportedVcs(): VcsKey = GitVcs.getKey() @@ -46,8 +45,10 @@ open class GitIgnoredFileContentProvider(private val project: Project) : Ignored if (untrackedFiles.isEmpty()) return "" //if there is no untracked files this mean nothing to ignore for (provider in ignoredFileProviders) { - val ignoredFiles = provider.getIgnoredFiles(project).ignoreBeansToRelativePaths(ignoreFileVcsRoot, ignoreFileRoot, untrackedFiles) - if (ignoredFiles.isEmpty()) continue + val ignoredFiles = ignoreBeansToRelativePaths(provider.getIgnoredFiles(project), ignoreFileVcsRoot, ignoreFileRoot, untrackedFiles) + if (ignoredFiles.isEmpty()) { + continue + } if (content.isNotEmpty()) { content.append(lineSeparator).append(lineSeparator) @@ -74,45 +75,55 @@ open class GitIgnoredFileContentProvider(private val project: Project) : Ignored } } - private fun Iterable.ignoreBeansToRelativePaths(ignoreFileVcsRoot: VirtualFile, ignoreFileRoot: VirtualFile, untrackedFiles: Set): List { + private fun ignoreBeansToRelativePaths(iterable: Iterable, ignoreFileVcsRoot: VirtualFile, ignoreFileRoot: VirtualFile, untrackedFiles: Set): List { val vcsContextFactory = VcsContextFactory.SERVICE.getInstance() - return filter { ignoredBean -> - when (ignoredBean.type) { - UNDER_DIR -> shouldIgnoreUnderDir(ignoredBean, untrackedFiles, ignoreFileRoot, ignoreFileVcsRoot, vcsContextFactory) - FILE -> shouldIgnoreFile(ignoredBean, untrackedFiles, ignoreFileRoot, ignoreFileVcsRoot, vcsContextFactory) - MASK -> shouldIgnoreByMask(ignoredBean, untrackedFiles) + return iterable + .asSequence() + .filter { ignoredBean -> + when (ignoredBean.type) { + UNDER_DIR -> shouldIgnoreUnderDir(ignoredBean, untrackedFiles, ignoreFileRoot, ignoreFileVcsRoot, vcsContextFactory) + FILE -> shouldIgnoreFile(ignoredBean, untrackedFiles, ignoreFileRoot, ignoreFileVcsRoot, vcsContextFactory) + MASK -> shouldIgnoreByMask(ignoredBean, untrackedFiles) + } } - }.map { ignoredBean -> - when (ignoredBean.type) { - MASK -> ignoredBean.mask!! - UNDER_DIR -> buildIgnoreEntryContent(ignoreFileRoot, ignoredBean) - FILE -> buildIgnoreEntryContent(ignoreFileRoot, ignoredBean) + .map { ignoredBean -> + when (ignoredBean.type) { + MASK -> ignoredBean.mask!! + UNDER_DIR -> buildIgnoreEntryContent(ignoreFileRoot, ignoredBean) + FILE -> buildIgnoreEntryContent(ignoreFileRoot, ignoredBean) + } } - } + .toList() } private fun shouldIgnoreUnderDir(ignoredBean: IgnoredFileDescriptor, untrackedFiles: Set, ignoreFileRoot: VirtualFile, ignoreFileVcsRoot: VirtualFile, - vcsContextFactory: VcsContextFactory) = - FileUtil.exists(ignoredBean.path) - && untrackedFiles.any { FileUtil.isAncestor(ignoredBean.path!!, it.path, true) } - && FileUtil.isAncestor(ignoreFileRoot.path, ignoredBean.path!!, false) - && Comparing.equal(ignoreFileVcsRoot, VcsUtil.getVcsRootFor(project, vcsContextFactory.createFilePath(ignoredBean.path!!, true))) - && gitIgnoreChecker.isIgnored(ignoreFileVcsRoot, File(ignoredBean.path!!)) is NotIgnored - && shouldNotConsiderInternalIgnoreFile(ignoredBean, ignoreFileRoot) + vcsContextFactory: VcsContextFactory): Boolean { + val path = ignoredBean.path ?: return false + val file = Paths.get(path) + return Files.exists(file) + && untrackedFiles.any { FileUtil.isAncestor(path, it.path, true) } + && FileUtil.isAncestor(ignoreFileRoot.path, path, false) + && Comparing.equal(ignoreFileVcsRoot, + VcsUtil.getVcsRootFor(project, vcsContextFactory.createFilePath(path, true))) + && gitIgnoreChecker.isIgnored(ignoreFileVcsRoot, file.toFile()) is NotIgnored + && shouldNotConsiderInternalIgnoreFile(ignoredBean, ignoreFileRoot) + } private fun shouldIgnoreFile(ignoredBean: IgnoredFileDescriptor, untrackedFiles: Set, ignoreFileRoot: VirtualFile, ignoreFileVcsRoot: VirtualFile, - vcsContextFactory: VcsContextFactory) = - FileUtil.exists(ignoredBean.path) - && untrackedFiles.any { ignoredBean.matchesFile(it) } - && FileUtil.isAncestor(ignoreFileRoot.path, ignoredBean.path!!, false) - && Comparing.equal(ignoreFileVcsRoot, VcsUtil.getVcsRootFor(project, vcsContextFactory.createFilePath(ignoredBean.path!!, false))) - && shouldNotConsiderInternalIgnoreFile(ignoredBean, ignoreFileRoot) + vcsContextFactory: VcsContextFactory): Boolean { + return FileUtil.exists(ignoredBean.path) + && untrackedFiles.any { ignoredBean.matchesFile(it) } + && FileUtil.isAncestor(ignoreFileRoot.path, ignoredBean.path!!, false) + && Comparing.equal(ignoreFileVcsRoot, + VcsUtil.getVcsRootFor(project, vcsContextFactory.createFilePath(ignoredBean.path!!, false))) + && shouldNotConsiderInternalIgnoreFile(ignoredBean, ignoreFileRoot) + } private fun shouldIgnoreByMask(ignoredBean: IgnoredFileDescriptor, untrackedFiles: Set) = untrackedFiles.any { ignoredBean.matchesFile(it) } @@ -120,9 +131,8 @@ open class GitIgnoredFileContentProvider(private val project: Project) : Ignored private fun shouldNotConsiderInternalIgnoreFile(ignoredBean: IgnoredFileDescriptor, ignoreFileRoot: VirtualFile): Boolean { val insideDirectoryStore = ignoredBean.path?.contains(Project.DIRECTORY_STORE_FOLDER) ?: false if (insideDirectoryStore) { - val directoryStoreOrProjectFileLocation = project.stateStore.directoryStoreFile ?: project.projectFile?.parent ?: return false - return FileUtil.isAncestor(VfsUtilCore.virtualToIoFile(directoryStoreOrProjectFileLocation), - VfsUtilCore.virtualToIoFile(ignoreFileRoot), false) + val directoryStoreOrProjectFileLocation = project.stateStore.directoryStorePath ?: project.projectFilePath?.let { Paths.get(it).parent } ?: return false + return FileUtil.isAncestor(directoryStoreOrProjectFileLocation.toString(), FileUtil.toSystemDependentName(ignoreFileRoot.path), false) } return true } diff --git a/plugins/git4idea/tests/git4idea/ignore/GitIgnoredFileTest.kt b/plugins/git4idea/tests/git4idea/ignore/GitIgnoredFileTest.kt index 980ebf35b537..ce3032a0fa03 100644 --- a/plugins/git4idea/tests/git4idea/ignore/GitIgnoredFileTest.kt +++ b/plugins/git4idea/tests/git4idea/ignore/GitIgnoredFileTest.kt @@ -1,4 +1,4 @@ -// 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. +// 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 git4idea.ignore import com.intellij.configurationStore.saveComponentManager @@ -19,15 +19,16 @@ import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.encoding.EncodingProjectManager import com.intellij.project.stateStore -import com.intellij.testFramework.HeavyPlatformTestCase import com.intellij.testFramework.PlatformTestUtil import com.intellij.testFramework.UsefulTestCase -import com.intellij.util.ui.UIUtil +import com.intellij.testFramework.runInEdtAndWait +import com.intellij.util.io.systemIndependentPath import git4idea.GitUtil import git4idea.repo.GitRepositoryFiles.GITIGNORE import git4idea.test.GitSingleRepoTest +import org.assertj.core.api.Assertions.assertThat +import org.junit.Assert.assertFalse import java.io.File -import java.nio.file.Paths const val OUT = "out" const val EXCLUDED = "excluded" @@ -69,17 +70,21 @@ class GitIgnoredFileTest : GitSingleRepoTest() { val shelf = File(ShelveChangesManager.getShelfPath(project)) val shelfExist = if (shelf.exists()) true else shelf.mkdir() - if (!shelfExist) fail("Shelf doesn't exist and cannot be created") - FileUtil.createIfDoesntExist(File(shelf, "some.patch")) //create file inside shelf dir because we don't add empty (without unversioned files) dirs to gitignore + if (!shelfExist) { + fail("Shelf doesn't exist and cannot be created") + } + // create file inside shelf dir because we don't add empty (without unversioned files) dirs to gitignore + FileUtil.createIfDoesntExist(File(shelf, "some.patch")) val workspaceFilePath = project.stateStore.workspaceFilePath if (workspaceFilePath == null) fail("Cannot detect workspace file path") val workspaceFile = File(workspaceFilePath!!) val workspaceFileExist = FileUtil.createIfNotExists(workspaceFile) - if (!workspaceFileExist || VfsUtil.findFileByIoFile(workspaceFile, true) == null) + if (!workspaceFileExist || VfsUtil.findFileByIoFile(workspaceFile, true) == null) { fail("Workspace file doesn't exist and cannot be created") + } - GitUtil.generateGitignoreFileIfNeeded(project, VfsUtil.findFile(Paths.get("$projectPath/$DIRECTORY_STORE_FOLDER"), true)!!) + GitUtil.generateGitignoreFileIfNeeded(project, LocalFileSystem.getInstance().refreshAndFindFileByPath(project.stateStore.directoryStorePath.systemIndependentPath)!!) assertGitignoreValid(gitIgnore, """ @@ -535,13 +540,15 @@ class GitIgnoredFileTest : GitSingleRepoTest() { internal fun assertGitignoreValid(ignoreFile: File, gitIgnoreExpectedContent: String) { val gitIgnoreExpectedContentList = gitIgnoreExpectedContent.trimIndent().lines() - UIUtil.invokeAndWaitIfNeeded(Runnable { PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() }) + runInEdtAndWait { + PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue() + } - UsefulTestCase.assertExists(ignoreFile) + assertThat(ignoreFile).exists() val generatedGitIgnoreContent = ignoreFile.readText() - HeavyPlatformTestCase.assertFalse("Generated ignore file is empty", generatedGitIgnoreContent.isBlank()) - HeavyPlatformTestCase.assertFalse("Generated ignore file content should be system-independent", generatedGitIgnoreContent.contains('\\')) - HeavyPlatformTestCase.assertContainsOrdered(generatedGitIgnoreContent.lines(), gitIgnoreExpectedContentList) + assertFalse("Generated ignore file is empty", generatedGitIgnoreContent.isBlank()) + assertFalse("Generated ignore file content should be system-independent", generatedGitIgnoreContent.contains('\\')) + UsefulTestCase.assertContainsOrdered(generatedGitIgnoreContent.lines(), gitIgnoreExpectedContentList) } internal fun VirtualFile.findOrCreateDir(dirName: String) = this.findChild(dirName) ?: createChildDirectory(this, dirName) \ No newline at end of file