Add statistics for venv created from requirements.txt/setup.py/environment.yml/pipfil...
[idea/community.git] / platform / projectModel-api / src / com / intellij / openapi / project / ProjectUtilCore.kt
1 // 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.
2 @file:JvmName("ProjectUtilCore")
3 package com.intellij.openapi.project
4
5 import com.intellij.ide.highlighter.ProjectFileType
6 import com.intellij.openapi.application.ApplicationManager
7 import com.intellij.openapi.components.ServiceManager
8 import com.intellij.openapi.module.ModuleManager
9 import com.intellij.openapi.module.ModuleUtilCore
10 import com.intellij.openapi.roots.JdkOrderEntry
11 import com.intellij.openapi.roots.libraries.LibraryUtil
12 import com.intellij.openapi.util.io.FileUtil
13 import com.intellij.openapi.vfs.LocalFileProvider
14 import com.intellij.openapi.vfs.VirtualFile
15 import com.intellij.util.PathUtil
16 import com.intellij.util.PlatformUtils
17 import org.jetbrains.annotations.TestOnly
18
19 fun displayUrlRelativeToProject(file: VirtualFile, url: String, project: Project, isIncludeFilePath: Boolean, moduleOnTheLeft: Boolean): String {
20   var result = url
21
22   if (isIncludeFilePath) {
23     val projectHomeUrl = PathUtil.toSystemDependentName(project.basePath)
24     result = when {
25       projectHomeUrl != null && result.startsWith(projectHomeUrl) -> "...${result.substring(projectHomeUrl.length)}"
26       else -> FileUtil.getLocationRelativeToUserHome(file.presentableUrl)
27     }
28   }
29
30   val urlWithLibraryName = decorateWithLibraryName(file, project, result)
31   if (urlWithLibraryName != null) {
32     return urlWithLibraryName
33   }
34
35   // see PredefinedSearchScopeProviderImpl.getPredefinedScopes for the other place to fix.
36   if (PlatformUtils.isCidr() || PlatformUtils.isRider()) {
37     return result
38   }
39
40   return appendModuleName(file, project, result, moduleOnTheLeft)
41 }
42
43 fun decorateWithLibraryName(file: VirtualFile,
44                                     project: Project,
45                                     result: String): String? {
46   if (file.fileSystem is LocalFileProvider) {
47     @Suppress("DEPRECATION") val localFile = (file.fileSystem as LocalFileProvider).getLocalVirtualFileFor(file)
48     if (localFile != null) {
49       val libraryEntry = LibraryUtil.findLibraryEntry(file, project)
50       when {
51         libraryEntry is JdkOrderEntry -> return "$result [${libraryEntry.jdkName}]"
52         libraryEntry != null -> return "$result [${libraryEntry.presentableName}]"
53       }
54     }
55   }
56   return null
57 }
58
59 fun appendModuleName(file: VirtualFile,
60                      project: Project,
61                      result: String,
62                      moduleOnTheLeft: Boolean): String {
63   val module = ModuleUtilCore.findModuleForFile(file, project)
64   return when {
65     module == null || ModuleManager.getInstance(project).modules.size == 1 -> result
66     moduleOnTheLeft -> "[${module.name}] $result"
67     else -> "$result [${module.name}]"
68   }
69 }
70
71 private var enableExternalStorageByDefaultInTests = true
72
73 val Project.isExternalStorageEnabled: Boolean
74   get() {
75     if (projectFilePath?.endsWith(ProjectFileType.DOT_DEFAULT_EXTENSION) == true) {
76       return false
77     }
78
79     val manager = ServiceManager.getService(this, ExternalStorageConfigurationManager::class.java) ?: return false
80     if (manager.isEnabled) return true
81     val testMode = ApplicationManager.getApplication()?.isUnitTestMode ?: false
82     return testMode && enableExternalStorageByDefaultInTests
83   }
84
85 /**
86  * By default external storage is enabled in tests. Wrap code which loads the project into this call to always use explicit option value.
87  */
88 @TestOnly
89 fun doNotEnableExternalStorageByDefaultInTests(action: () -> Unit) {
90   enableExternalStorageByDefaultInTests = false
91   try {
92     action()
93   }
94   finally {
95     enableExternalStorageByDefaultInTests = true
96   }
97 }