Skip to content

Commit c11cdea

Browse files
develarintellij-monorepo-bot
authored andcommitted
state storage manager macro value as path instead of string
GitOrigin-RevId: b1411b4deb77099d564e3cdeb413a1fc37b16219
1 parent fffe74e commit c11cdea

File tree

50 files changed

+495
-467
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+495
-467
lines changed

java/java-tests/testSrc/com/intellij/codeInspection/ex/ProjectInspectionManagerTest.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// 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.
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.
22
package com.intellij.codeInspection.ex
33

44
import com.intellij.codeHighlighting.HighlightDisplayLevel
@@ -63,7 +63,7 @@ class ProjectInspectionManagerTest {
6363
</state>""".trimIndent()
6464
assertThat(projectInspectionProfileManager.state).isEqualTo(doNotUseProjectProfileState)
6565

66-
val inspectionDir = Paths.get(project.stateStore.projectConfigDir!!, PROFILE_DIR)
66+
val inspectionDir = project.stateStore.projectConfigDir!!.resolve(PROFILE_DIR)
6767
val file = inspectionDir.resolve("profiles_settings.xml")
6868
project.stateStore.save()
6969
assertThat(file).exists()
@@ -93,7 +93,7 @@ class ProjectInspectionManagerTest {
9393
@Test
9494
fun `do not save default project profile`() {
9595
doTest { project ->
96-
val inspectionDir = Paths.get(project.stateStore.projectConfigDir!!, PROFILE_DIR)
96+
val inspectionDir = project.stateStore.projectConfigDir!!.resolve(PROFILE_DIR)
9797
val profileFile = inspectionDir.resolve("Project_Default.xml")
9898
assertThat(profileFile).doesNotExist()
9999

@@ -127,7 +127,7 @@ class ProjectInspectionManagerTest {
127127

128128
project.stateStore.save()
129129

130-
val inspectionDir = Paths.get(project.stateStore.projectConfigDir!!, PROFILE_DIR)
130+
val inspectionDir = project.stateStore.projectConfigDir!!.resolve(PROFILE_DIR)
131131
val file = inspectionDir.resolve("profiles_settings.xml")
132132

133133
assertThat(file).doesNotExist()
@@ -166,7 +166,7 @@ class ProjectInspectionManagerTest {
166166
assertThat(profileManager.currentProfile.isProjectLevel).isTrue()
167167
assertThat(profileManager.currentProfile.name).isEqualTo("Project Default")
168168

169-
val projectConfigDir = Paths.get(project.stateStore.projectConfigDir!!)
169+
val projectConfigDir = project.stateStore.projectConfigDir!!
170170

171171
// test creation of .idea/inspectionProfiles dir, not .idea itself
172172
projectConfigDir.createDirectories()

platform/analysis-api/src/com/intellij/openapi/vfs/VfsUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,11 @@ public static VirtualFile copy(Object requestor, @NotNull VirtualFile file, @Not
194194
}
195195

196196
public static @Nullable VirtualFile findFile(@NotNull Path file, boolean refreshIfNeeded) {
197-
return findFile(FileUtil.toSystemIndependentName(file.toAbsolutePath().toString()), refreshIfNeeded);
197+
return findFile(file.toAbsolutePath().toString().replace(File.separatorChar, '/'), refreshIfNeeded);
198198
}
199199

200200
public static @Nullable VirtualFile findFileByIoFile(@NotNull File file, boolean refreshIfNeeded) {
201-
return findFile(FileUtil.toSystemIndependentName(file.getAbsolutePath()), refreshIfNeeded);
201+
return findFile(file.getAbsolutePath().replace(File.separatorChar, '/'), refreshIfNeeded);
202202
}
203203

204204
private static @Nullable VirtualFile findFile(@NotNull String filePath, boolean refreshIfNeeded) {

platform/configuration-store-impl/src/ApplicationStoreImpl.kt

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ import com.intellij.openapi.application.ApplicationManager
77
import com.intellij.openapi.application.PathManager
88
import com.intellij.openapi.application.appSystemDir
99
import com.intellij.openapi.components.*
10-
import com.intellij.openapi.components.impl.stores.FileStorageCoreUtil
1110
import com.intellij.openapi.diagnostic.runAndLogException
1211
import com.intellij.openapi.project.ex.ProjectManagerEx
1312
import com.intellij.openapi.util.NamedJDOMExternalizable
14-
import com.intellij.util.io.systemIndependentPath
1513
import kotlinx.coroutines.coroutineScope
1614
import kotlinx.coroutines.launch
1715
import org.jetbrains.jps.model.serialization.JpsGlobalLoader
@@ -22,20 +20,19 @@ internal class ApplicationPathMacroManager : PathMacroManager(null)
2220
const val APP_CONFIG = "\$APP_CONFIG$"
2321

2422
class ApplicationStoreImpl : ComponentStoreWithExtraComponents() {
25-
private val application = ApplicationManager.getApplication()
26-
27-
override val storageManager = ApplicationStorageManager(application, PathMacroManager.getInstance(ApplicationManager.getApplication()))
23+
override val storageManager = ApplicationStorageManager(ApplicationManager.getApplication(), PathMacroManager.getInstance(ApplicationManager.getApplication()))
2824

2925
// number of app components require some state, so, we load default state in test mode
3026
override val loadPolicy: StateLoadPolicy
31-
get() = if (application.isUnitTestMode) StateLoadPolicy.LOAD_ONLY_DEFAULT else StateLoadPolicy.LOAD
27+
get() = if (ApplicationManager.getApplication().isUnitTestMode) StateLoadPolicy.LOAD_ONLY_DEFAULT else StateLoadPolicy.LOAD
3228

3329
override fun setPath(path: Path) {
34-
val systemIndependentPath = path.systemIndependentPath
35-
// app config must be first, because collapseMacros collapse from fist to last, so, at first we must replace APP_CONFIG because it overlaps ROOT_CONFIG value
36-
storageManager.addMacro(APP_CONFIG, "$systemIndependentPath/${PathManager.OPTIONS_DIRECTORY}")
37-
storageManager.addMacro(ROOT_CONFIG, systemIndependentPath)
38-
storageManager.addMacro(StoragePathMacros.CACHE_FILE, appSystemDir.resolve("workspace").resolve("app.xml").systemIndependentPath)
30+
storageManager.setMacros(listOf(
31+
// app config must be first, because collapseMacros collapse from fist to last, so, at first we must replace APP_CONFIG because it overlaps ROOT_CONFIG value
32+
Macro(APP_CONFIG, path.resolve(PathManager.OPTIONS_DIRECTORY)),
33+
Macro(ROOT_CONFIG, path),
34+
Macro(StoragePathMacros.CACHE_FILE, appSystemDir.resolve("workspace").resolve("app.xml"))
35+
))
3936
}
4037

4138
override suspend fun doSave(result: SaveResult, forceSavingAllSettings: Boolean) {
@@ -71,12 +68,12 @@ internal val appFileBasedStorageConfiguration = object: FileBasedStorageConfigur
7168
}
7269

7370
class ApplicationStorageManager(application: Application?, pathMacroManager: PathMacroManager? = null)
74-
: StateStorageManagerImpl("application", pathMacroManager?.createTrackingSubstitutor(), application) {
71+
: StateStorageManagerImpl("application", pathMacroManager?.createTrackingSubstitutor (), application) {
7572
override fun getFileBasedStorageConfiguration(fileSpec: String) = appFileBasedStorageConfiguration
7673

7774
override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation): String? {
7875
return when (component) {
79-
is NamedJDOMExternalizable -> "${component.externalFileName}${FileStorageCoreUtil.DEFAULT_EXT}"
76+
is NamedJDOMExternalizable -> "${component.externalFileName}${PathManager.DEFAULT_EXT}"
8077
else -> PathManager.DEFAULT_OPTIONS_FILE
8178
}
8279
}
@@ -102,5 +99,8 @@ class ApplicationStorageManager(application: Application?, pathMacroManager: Pat
10299

103100
override fun normalizeFileSpec(fileSpec: String) = removeMacroIfStartsWith(super.normalizeFileSpec(fileSpec), APP_CONFIG)
104101

105-
override fun expandMacros(path: String) = if (path[0] == '$') super.expandMacros(path) else "${expandMacro(APP_CONFIG)}/$path"
102+
override fun expandMacro(collapsedPath: String): Path {
103+
// APP_CONFIG is the first macro
104+
return if (collapsedPath[0] == '$') super.expandMacro(collapsedPath) else macros.get(0).value.resolve(collapsedPath)
105+
}
106106
}

platform/configuration-store-impl/src/ComponentStoreImpl.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import org.jetbrains.annotations.ApiStatus
3737
import org.jetbrains.annotations.CalledInAwt
3838
import org.jetbrains.annotations.TestOnly
3939
import java.io.IOException
40-
import java.nio.file.Paths
4140
import java.util.*
4241
import java.util.concurrent.ConcurrentHashMap
4342
import java.util.concurrent.TimeUnit
@@ -246,7 +245,7 @@ abstract class ComponentStoreImpl : IComponentStore {
246245
LOG.debug { "saveComponent is called for ${stateSpec.name}" }
247246
val saveManager = createSaveSessionProducerManager()
248247
commitComponent(saveManager, ComponentInfoImpl(component, stateSpec), null, false)
249-
val absolutePath = Paths.get(storageManager.expandMacros(findNonDeprecated(getStorageSpecs(component, stateSpec, StateStorageOperation.WRITE)).path)).toAbsolutePath().toString()
248+
val absolutePath = storageManager.expandMacro(findNonDeprecated(getStorageSpecs(component, stateSpec, StateStorageOperation.WRITE)).path).toString()
250249
Disposer.newDisposable().use {
251250
VfsRootAccess.allowRootAccess(it, absolutePath)
252251
runBlocking {

platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import org.jdom.Element
99
import org.jetbrains.annotations.ApiStatus
1010
import java.io.Writer
1111
import java.nio.file.Path
12-
import java.nio.file.Paths
1312

1413
private const val FILE_SPEC = "${APP_CONFIG}/project.default.xml"
1514

@@ -64,7 +63,7 @@ class DefaultProjectStoreImpl(override val project: Project) : ChildlessComponen
6463
get() = if (ApplicationManager.getApplication().isUnitTestMode) StateLoadPolicy.NOT_LOAD else StateLoadPolicy.LOAD
6564

6665
private val storage by lazy {
67-
DefaultProjectStorage(Paths.get(ApplicationManager.getApplication().stateStore.storageManager.expandMacros(FILE_SPEC)), FILE_SPEC, PathMacroManager.getInstance(project))
66+
DefaultProjectStorage(ApplicationManager.getApplication().stateStore.storageManager.expandMacro(FILE_SPEC), FILE_SPEC, PathMacroManager.getInstance(project))
6867
}
6968

7069
override val storageManager = object : StateStorageManager {
@@ -77,12 +76,9 @@ class DefaultProjectStoreImpl(override val project: Project) : ChildlessComponen
7776
override fun removeStreamProvider(clazz: Class<out StreamProvider>) {
7877
}
7978

80-
override fun rename(path: String, newName: String) {
81-
}
82-
8379
override fun getStateStorage(storageSpec: Storage) = storage
8480

85-
override fun expandMacros(path: String) = throw UnsupportedOperationException()
81+
override fun expandMacro(path: String) = throw UnsupportedOperationException()
8682

8783
override fun getOldStorage(component: Any, componentName: String, operation: StateStorageOperation) = storage
8884
}

platform/configuration-store-impl/src/ExportSettingsAction.kt

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,18 @@ import com.intellij.openapi.options.SchemeManagerFactory
2121
import com.intellij.openapi.project.DumbAware
2222
import com.intellij.openapi.ui.Messages
2323
import com.intellij.openapi.ui.showOkCancelDialog
24-
import com.intellij.openapi.util.io.FileUtil
2524
import com.intellij.serviceContainer.ComponentManagerImpl
2625
import com.intellij.serviceContainer.processAllImplementationClasses
2726
import com.intellij.util.ArrayUtil
2827
import com.intellij.util.ReflectionUtil
28+
import com.intellij.util.SmartList
2929
import com.intellij.util.containers.CollectionFactory
3030
import com.intellij.util.containers.putValue
3131
import com.intellij.util.io.*
3232
import java.io.IOException
3333
import java.io.OutputStream
3434
import java.io.StringWriter
3535
import java.nio.file.Path
36-
import java.nio.file.Paths
3736
import java.util.*
3837

3938
internal fun isImportExportActionApplicable(): Boolean {
@@ -49,7 +48,7 @@ open class ExportSettingsAction : AnAction(), DumbAware {
4948
protected open fun exportSettings(saveFile: Path, markedComponents: Set<ExportableItem>) {
5049
val exportFiles = markedComponents.mapTo(CollectionFactory.createSmallMemoryFootprintSet()) { it.file }
5150
saveFile.outputStream().use {
52-
exportSettings(exportFiles, it, FileUtil.toSystemIndependentName(PathManager.getConfigPath()))
51+
exportSettings(exportFiles, it, PathManager.getConfigDir())
5352
}
5453
}
5554

@@ -92,24 +91,26 @@ open class ExportSettingsAction : AnAction(), DumbAware {
9291
}
9392
}
9493

95-
fun exportSettings(exportFiles: Set<Path>, out: OutputStream, configPath: String) {
96-
val filter = CollectionFactory.createSmallMemoryFootprintSet<String>()
97-
Compressor.Zip(out).filter { entryName, _ -> filter.add(entryName) }.use { zip ->
98-
for (file in exportFiles) {
99-
val fileInfo = file.basicAttributesIfExists() ?: continue
100-
val relativePath = FileUtil.getRelativePath(configPath, file.toAbsolutePath().systemIndependentPath, '/')!!
101-
if (fileInfo.isDirectory) {
102-
zip.addDirectory(relativePath, file.toFile())
103-
}
104-
else {
105-
zip.addFile(relativePath, file.inputStream())
94+
fun exportSettings(exportFiles: Set<Path>, out: OutputStream, configPath: Path) {
95+
val filter = HashSet<String>()
96+
Compressor.Zip(out)
97+
.nioFilter { entryName, _ -> filter.add(entryName) }
98+
.use { zip ->
99+
for (file in exportFiles) {
100+
val fileInfo = file.basicAttributesIfExists() ?: continue
101+
val relativePath = configPath.relativize(file).toString()
102+
if (fileInfo.isDirectory) {
103+
zip.addDirectory(relativePath, file)
104+
}
105+
else {
106+
zip.addFile(relativePath, file)
107+
}
106108
}
107-
}
108109

109-
exportInstalledPlugins(zip)
110+
exportInstalledPlugins(zip)
110111

111-
zip.addFile(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER, ArrayUtil.EMPTY_BYTE_ARRAY)
112-
}
112+
zip.addFile(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER, ArrayUtil.EMPTY_BYTE_ARRAY)
113+
}
113114
}
114115

115116
data class ExportableItem(val file: Path, val presentableName: String, val roamingType: RoamingType = RoamingType.DEFAULT)
@@ -133,7 +134,7 @@ fun getExportableComponentsMap(isOnlyExisting: Boolean,
133134
val processor = { component: ExportableComponent ->
134135
for (file in component.exportFiles) {
135136
val item = ExportableItem(file.toPath(), component.presentableName, RoamingType.DEFAULT)
136-
result.putValue(item.file, item)
137+
result.computeIfAbsent(item.file) { SmartList() }.add(item)
137138
}
138139
}
139140

@@ -144,11 +145,16 @@ fun getExportableComponentsMap(isOnlyExisting: Boolean,
144145
@Suppress("DEPRECATION")
145146
ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent::class.java).forEach(processor)
146147

147-
val configPath = storageManager.expandMacros(ROOT_CONFIG)
148+
val configPath = storageManager.expandMacro(ROOT_CONFIG)
148149

149150
fun isSkipFile(file: Path): Boolean {
150151
if (onlyPaths != null) {
151-
var relativePath = FileUtil.getRelativePath(configPath, file.systemIndependentPath, '/')!!
152+
// maybe in tests where in memory fs is used
153+
if (configPath.fileSystem != file.fileSystem) {
154+
return true
155+
}
156+
157+
var relativePath = configPath.relativize(file).systemIndependentPath
152158
if (!file.fileName.toString().contains('.') && !file.isFile()) {
153159
relativePath += '/'
154160
}
@@ -184,7 +190,7 @@ fun getExportableComponentsMap(isOnlyExisting: Boolean,
184190

185191
try {
186192
additionalExportFile = getAdditionalExportFile(stateAnnotation, storageManager, ::isSkipFile)
187-
file = Paths.get(storageManager.expandMacros(storage.path))
193+
file = storageManager.expandMacro(storage.path)
188194
}
189195
catch (e: UnknownMacroException) {
190196
LOG.error("Cannot expand macro for component \"${stateAnnotation.name}\"", e)
@@ -214,7 +220,7 @@ fun getExportableComponentsMap(isOnlyExisting: Boolean,
214220
// must be in the end - because most of SchemeManager clients specify additionalExportFile in the State spec
215221
(SchemeManagerFactory.getInstance() as SchemeManagerFactoryBase).process {
216222
if (it.roamingType != RoamingType.DISABLED && it.fileSpec.getOrNull(0) != '$') {
217-
val file = Paths.get(storageManager.expandMacros(ROOT_CONFIG), it.fileSpec)
223+
val file = storageManager.expandMacro(ROOT_CONFIG).resolve(it.fileSpec)
218224
if (!result.containsKey(file) && !isSkipFile(file)) {
219225
result.putValue(file, ExportableItem(file, it.presentableName ?: "", it.roamingType))
220226
}
@@ -232,10 +238,11 @@ private inline fun getAdditionalExportFile(stateAnnotation: State, storageManage
232238
val additionalExportFile: Path?
233239
// backward compatibility - path can contain macro
234240
if (additionalExportPath[0] == '$') {
235-
additionalExportFile = Paths.get(storageManager.expandMacros(additionalExportPath))
241+
additionalExportFile = storageManager.expandMacro(additionalExportPath)
236242
}
237243
else {
238-
additionalExportFile = Paths.get(storageManager.expandMacros(ROOT_CONFIG), additionalExportPath)
244+
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
245+
additionalExportFile = storageManager.expandMacro(ROOT_CONFIG).resolve(additionalExportPath)!!
239246
}
240247
return if (isSkipFile(additionalExportFile)) null else additionalExportFile
241248
}

platform/configuration-store-impl/src/ModuleStateStorageManager.kt

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,64 @@
1-
// 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.
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.
22
package com.intellij.configurationStore
33

4+
import com.intellij.ide.highlighter.ModuleFileType
45
import com.intellij.openapi.components.*
56
import com.intellij.openapi.module.Module
67
import com.intellij.openapi.module.ModuleManager
78
import com.intellij.openapi.module.impl.ModuleEx
89
import com.intellij.openapi.module.impl.ModuleManagerImpl
9-
import com.intellij.openapi.module.impl.getModuleNameByFilePath
1010
import com.intellij.openapi.project.isExternalStorageEnabled
1111
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
1212
import org.jdom.Element
1313
import org.jetbrains.annotations.ApiStatus
1414
import java.io.FileNotFoundException
15+
import java.io.IOException
1516
import java.nio.file.Path
16-
import java.nio.file.Paths
17+
import kotlin.concurrent.write
1718

1819
@ApiStatus.Internal
19-
open class ModuleStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, module: Module) : StateStorageManagerImpl("module", macroSubstitutor, module) {
20+
open class ModuleStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, module: Module) : StateStorageManagerImpl("module", macroSubstitutor, module), RenameableStateStorageManager {
2021
override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation) = StoragePathMacros.MODULE_FILE
2122

22-
override fun pathRenamed(oldPath: String, newPath: String, event: VFileEvent?) {
23+
// the only macro is supported by ModuleStateStorageManager
24+
final override fun expandMacro(collapsedPath: String): Path {
25+
if (collapsedPath != StoragePathMacros.MODULE_FILE) {
26+
throw IllegalStateException("Cannot resolve $collapsedPath in $macros")
27+
}
28+
return macros.get(0).value
29+
}
30+
31+
final override fun rename(newName: String) {
32+
storageLock.write {
33+
val storage = getOrCreateStorage(StoragePathMacros.MODULE_FILE, RoamingType.DEFAULT) as FileBasedStorage
34+
val file = storage.getVirtualFile(StateStorageOperation.WRITE)
35+
try {
36+
if (file != null) {
37+
file.rename(storage, newName)
38+
}
39+
else if (storage.file.fileName.toString() != newName) {
40+
// old file didn't exist or renaming failed
41+
val newFile = storage.file.parent.resolve(newName)
42+
storage.setFile(null, newFile)
43+
pathRenamed(newFile, null)
44+
}
45+
}
46+
catch (e: IOException) {
47+
LOG.debug(e)
48+
}
49+
}
50+
}
51+
52+
override fun pathRenamed(newPath: Path, event: VFileEvent?) {
2353
try {
24-
super.pathRenamed(oldPath, newPath, event)
54+
setMacros(listOf(Macro(StoragePathMacros.MODULE_FILE, newPath)))
2555
}
2656
finally {
2757
val requestor = event?.requestor
2858
if (requestor == null || requestor !is StateStorage /* not renamed as result of explicit rename */) {
2959
val module = componentManager as ModuleEx
3060
val oldName = module.name
31-
module.rename(getModuleNameByFilePath(newPath), false)
61+
module.rename(newPath.fileName.toString().removeSuffix(ModuleFileType.DOT_DEFAULT_EXTENSION), false)
3262
(ModuleManager.getInstance(module.project) as? ModuleManagerImpl)?.fireModuleRenamedByVfsEvent(module, oldName)
3363
}
3464
}
@@ -66,8 +96,8 @@ open class ModuleStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitu
6696
override val isExternalSystemStorageEnabled: Boolean
6797
get() = (componentManager as Module?)?.project?.isExternalStorageEnabled ?: false
6898

69-
override fun createFileBasedStorage(path: String, collapsedPath: String, roamingType: RoamingType, rootTagName: String?): StateStorage {
70-
return ModuleFileStorage(this, Paths.get(path), collapsedPath, rootTagName, roamingType, getMacroSubstitutor(collapsedPath), if (roamingType == RoamingType.DISABLED) null else compoundStreamProvider)
99+
override fun createFileBasedStorage(path: Path, collapsedPath: String, roamingType: RoamingType, rootTagName: String?): StateStorage {
100+
return ModuleFileStorage(this, path, collapsedPath, rootTagName, roamingType, getMacroSubstitutor(collapsedPath), if (roamingType == RoamingType.DISABLED) null else compoundStreamProvider)
71101
}
72102

73103
override fun getFileBasedStorageConfiguration(fileSpec: String) = moduleFileBasedStorageConfiguration

0 commit comments

Comments
 (0)