From 07d0c7c107e01e05c037b304b684428bd2d5f659 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Mon, 15 Apr 2024 13:42:00 -0400 Subject: [PATCH 1/8] Initial APIs for FileSystem extensions Closes: https://github.com/square/okio/issues/1466 --- okio/build.gradle.kts | 2 +- okio/src/commonMain/kotlin/okio/FileSystem.kt | 6 ++ .../kotlin/okio/FileSystemExtension.kt | 21 +++++++ .../kotlin/okio/ForwardingFileSystem.kt | 18 +++++- okio/src/commonMain/kotlin/okio/Okio.kt | 8 +++ .../kotlin/okio/internal/FileSystem.kt | 19 +++++++ .../kotlin/okio/FileSystemExtensionsTest.kt | 55 +++++++++++++++++++ okio/src/jsMain/kotlin/okio/FileSystem.kt | 9 +++ okio/src/jvmMain/kotlin/okio/FileSystem.kt | 9 +++ okio/src/nativeMain/kotlin/okio/FileSystem.kt | 9 +++ okio/src/wasmMain/kotlin/okio/FileSystem.kt | 9 +++ 11 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 okio/src/commonMain/kotlin/okio/FileSystemExtension.kt create mode 100644 okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt diff --git a/okio/build.gradle.kts b/okio/build.gradle.kts index eea0f82119..d3f215639b 100644 --- a/okio/build.gradle.kts +++ b/okio/build.gradle.kts @@ -66,6 +66,7 @@ kotlin { dependencies { implementation(libs.kotlin.test) implementation(projects.okioTestingSupport) + implementation(projects.okioFakefilesystem) } } @@ -80,7 +81,6 @@ kotlin { val nonWasmTest by creating { dependencies { implementation(libs.kotlin.time) - implementation(projects.okioFakefilesystem) } } diff --git a/okio/src/commonMain/kotlin/okio/FileSystem.kt b/okio/src/commonMain/kotlin/okio/FileSystem.kt index 9535880b62..23b8e096e6 100644 --- a/okio/src/commonMain/kotlin/okio/FileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/FileSystem.kt @@ -15,6 +15,8 @@ */ package okio +import kotlin.reflect.KClass + /** * Read and write access to a hierarchical collection of files, addressed by [paths][Path]. This * is a natural interface to the current computer's local file system. @@ -376,6 +378,10 @@ expect abstract class FileSystem() { @Throws(IOException::class) abstract fun createSymlink(source: Path, target: Path) + open fun extend(extensionType: KClass, extension: E): FileSystem + + open fun extension(type: KClass): E? + companion object { /** * Returns a writable temporary directory on [SYSTEM]. diff --git a/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt b/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt new file mode 100644 index 0000000000..89900f5421 --- /dev/null +++ b/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 Square, Inc. + * + * 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. + */ +package okio + +/** + * + */ +interface FileSystemExtension diff --git a/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt b/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt index 2fe5cd4f06..0be07f40fd 100644 --- a/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt @@ -16,6 +16,8 @@ package okio import kotlin.jvm.JvmName +import kotlin.reflect.KClass +import kotlin.reflect.cast /** * A [FileSystem] that forwards calls to another, intended for subclassing. @@ -101,11 +103,15 @@ import kotlin.jvm.JvmName * other functions of this class. If desired, subclasses may override non-abstract functions to * forward them. */ -abstract class ForwardingFileSystem( +open class ForwardingFileSystem internal constructor( /** [FileSystem] to which this instance is delegating. */ @get:JvmName("delegate") val delegate: FileSystem, + extensions: Map, Any>, ) : FileSystem() { + internal val extensions = extensions.toMap() + + constructor(delegate: FileSystem) : this(delegate, emptyMap()) /** * Invoked each time a path is passed as a parameter to this file system. This returns the path to @@ -142,6 +148,8 @@ abstract class ForwardingFileSystem( */ open fun onPathResult(path: Path, functionName: String): Path = path + open fun onExtension(type: KClass, extension: T): T = extension + @Throws(IOException::class) override fun canonicalize(path: Path): Path { val path = onPathParameter(path, "canonicalize", "path") @@ -238,5 +246,13 @@ abstract class ForwardingFileSystem( delegate.createSymlink(source, target) } + override fun extension(type: KClass): E? { + val result = extensions[type]?.let { type.cast(it) } + ?: delegate.extension(type) + ?: return null + + return onExtension(type, result) + } + override fun toString() = "${this::class.simpleName}($delegate)" } diff --git a/okio/src/commonMain/kotlin/okio/Okio.kt b/okio/src/commonMain/kotlin/okio/Okio.kt index a0a420bbc3..d019d5ee65 100644 --- a/okio/src/commonMain/kotlin/okio/Okio.kt +++ b/okio/src/commonMain/kotlin/okio/Okio.kt @@ -72,3 +72,11 @@ inline fun T.use(block: (T) -> R): R { @Suppress("UNCHECKED_CAST") return result as R } + +inline fun FileSystem.extend(extension: E): FileSystem { + return extend(E::class, extension) +} + +inline fun FileSystem.extension(): E? { + return extension(E::class) +} diff --git a/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt b/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt index 72c541d12d..b722304f8e 100644 --- a/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt @@ -18,9 +18,11 @@ package okio.internal import kotlin.jvm.JvmName +import kotlin.reflect.KClass import okio.FileMetadata import okio.FileNotFoundException import okio.FileSystem +import okio.ForwardingFileSystem import okio.IOException import okio.Path import okio.buffer @@ -69,6 +71,23 @@ internal fun FileSystem.commonCopy(source: Path, target: Path) { } } +fun FileSystem.commonExtend(extensionType: KClass, extension: T): FileSystem { + // If this file system is already an extension wrapper, replace it rather than wrapping again. + // Note that this optimization doesn't apply to ForwardingFileSystem subclasses, only to the + // ForwardingFileSystem base class. + if (this::class === ForwardingFileSystem::class) { + this as ForwardingFileSystem + val newExtensions = extensions.toMutableMap() + newExtensions[extensionType] = extension + return ForwardingFileSystem(delegate, newExtensions) + } + + return ForwardingFileSystem( + delegate = this, + extensions = mapOf(extensionType to extension) + ) +} + @Throws(IOException::class) internal fun FileSystem.commonDeleteRecursively(fileOrDirectory: Path, mustExist: Boolean) { val sequence = sequence { diff --git a/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt b/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt new file mode 100644 index 0000000000..dab0d16f4e --- /dev/null +++ b/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 Square, Inc. + * + * 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. + */ + +package okio + +import kotlin.test.Test +import kotlin.test.assertEquals +import okio.fakefilesystem.FakeFileSystem + +class FileSystemExtensionsTest { + @Test + fun happyPath() { + val fakeFileSystem = FakeFileSystem() + val extension = FooExtension(fakeFileSystem) + val fileSystemWithExtension = fakeFileSystem.extend(extension) + assertEquals(fileSystemWithExtension.extension(), extension) + } + + @Test + fun absentExtension() { + } + + @Test + fun overrideExtension() { + } + + @Test + fun forwardingFileSystemCoalesced() { + } + + @Test + fun customForwardingFileSystemNotCoalesced() { + } + + class FooExtension( + val target: FileSystem, + ) : FileSystemExtension + + class BarExtension( + val target: FileSystem, + ) : FileSystemExtension +} diff --git a/okio/src/jsMain/kotlin/okio/FileSystem.kt b/okio/src/jsMain/kotlin/okio/FileSystem.kt index ea1bb4bf30..7f11e4a890 100644 --- a/okio/src/jsMain/kotlin/okio/FileSystem.kt +++ b/okio/src/jsMain/kotlin/okio/FileSystem.kt @@ -15,11 +15,13 @@ */ package okio +import kotlin.reflect.KClass import okio.Path.Companion.toPath import okio.internal.commonCopy import okio.internal.commonCreateDirectories import okio.internal.commonDeleteRecursively import okio.internal.commonExists +import okio.internal.commonExtend import okio.internal.commonListRecursively import okio.internal.commonMetadata @@ -84,6 +86,13 @@ actual abstract class FileSystem { actual abstract fun createSymlink(source: Path, target: Path) + actual open fun extend( + extensionType: KClass, + extension: E, + ): FileSystem = commonExtend(extensionType, extension) + + actual open fun extension(type: KClass): E? = null + actual companion object { actual val SYSTEM_TEMPORARY_DIRECTORY: Path = tmpdir.toPath() } diff --git a/okio/src/jvmMain/kotlin/okio/FileSystem.kt b/okio/src/jvmMain/kotlin/okio/FileSystem.kt index 7a552cc551..e55805cfad 100644 --- a/okio/src/jvmMain/kotlin/okio/FileSystem.kt +++ b/okio/src/jvmMain/kotlin/okio/FileSystem.kt @@ -16,12 +16,14 @@ package okio import java.nio.file.FileSystem as JavaNioFileSystem +import kotlin.reflect.KClass import okio.Path.Companion.toPath import okio.internal.ResourceFileSystem import okio.internal.commonCopy import okio.internal.commonCreateDirectories import okio.internal.commonDeleteRecursively import okio.internal.commonExists +import okio.internal.commonExtend import okio.internal.commonListRecursively import okio.internal.commonMetadata @@ -125,6 +127,13 @@ actual abstract class FileSystem { @Throws(IOException::class) actual abstract fun createSymlink(source: Path, target: Path) + actual open fun extend( + extensionType: KClass, + extension: E, + ): FileSystem = commonExtend(extensionType, extension) + + actual open fun extension(type: KClass): E? = null + actual companion object { /** * The current process's host file system. Use this instance directly, or dependency inject a diff --git a/okio/src/nativeMain/kotlin/okio/FileSystem.kt b/okio/src/nativeMain/kotlin/okio/FileSystem.kt index 7672c919b3..568ead3ac6 100644 --- a/okio/src/nativeMain/kotlin/okio/FileSystem.kt +++ b/okio/src/nativeMain/kotlin/okio/FileSystem.kt @@ -15,10 +15,12 @@ */ package okio +import kotlin.reflect.KClass import okio.internal.commonCopy import okio.internal.commonCreateDirectories import okio.internal.commonDeleteRecursively import okio.internal.commonExists +import okio.internal.commonExtend import okio.internal.commonListRecursively import okio.internal.commonMetadata @@ -102,6 +104,13 @@ actual abstract class FileSystem { @Throws(IOException::class) actual abstract fun createSymlink(source: Path, target: Path) + actual open fun extend( + extensionType: KClass, + extension: E, + ): FileSystem = commonExtend(extensionType, extension) + + actual open fun extension(type: KClass): E? = null + actual companion object { /** * The current process's host file system. Use this instance directly, or dependency inject a diff --git a/okio/src/wasmMain/kotlin/okio/FileSystem.kt b/okio/src/wasmMain/kotlin/okio/FileSystem.kt index 2152a91b0c..add85050a9 100644 --- a/okio/src/wasmMain/kotlin/okio/FileSystem.kt +++ b/okio/src/wasmMain/kotlin/okio/FileSystem.kt @@ -15,11 +15,13 @@ */ package okio +import kotlin.reflect.KClass import okio.Path.Companion.toPath import okio.internal.commonCopy import okio.internal.commonCreateDirectories import okio.internal.commonDeleteRecursively import okio.internal.commonExists +import okio.internal.commonExtend import okio.internal.commonListRecursively import okio.internal.commonMetadata @@ -84,6 +86,13 @@ actual abstract class FileSystem { actual abstract fun createSymlink(source: Path, target: Path) + actual open fun extend( + extensionType: KClass, + extension: E, + ): FileSystem = commonExtend(extensionType, extension) + + actual open fun extension(type: KClass): E? = null + actual companion object { actual val SYSTEM_TEMPORARY_DIRECTORY: Path = "/tmp".toPath() } From e054205c04f66f96731f41b106600bfada9169ba Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Mon, 15 Apr 2024 21:02:31 -0400 Subject: [PATCH 2/8] Fill in docs and tests --- okio/src/commonMain/kotlin/okio/FileSystem.kt | 8 ++++ .../kotlin/okio/FileSystemExtension.kt | 3 +- okio/src/commonMain/kotlin/okio/Okio.kt | 17 +++++--- .../kotlin/okio/internal/FileSystem.kt | 2 +- .../kotlin/okio/FileSystemExtensionsTest.kt | 43 ++++++++++++++++++- 5 files changed, 64 insertions(+), 9 deletions(-) diff --git a/okio/src/commonMain/kotlin/okio/FileSystem.kt b/okio/src/commonMain/kotlin/okio/FileSystem.kt index 23b8e096e6..74e780679c 100644 --- a/okio/src/commonMain/kotlin/okio/FileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/FileSystem.kt @@ -378,8 +378,16 @@ expect abstract class FileSystem() { @Throws(IOException::class) abstract fun createSymlink(source: Path, target: Path) + /** + * Returns a new file system that forwards all calls to this, and that also returns [extension] + * when it is requested. + * + * When [extensionType] is requested on the returned file system, it will return [extension], + * regardless of what is returned by this file system. + */ open fun extend(extensionType: KClass, extension: E): FileSystem + /** Returns the extension for [type] if it exists, and null otherwise. */ open fun extension(type: KClass): E? companion object { diff --git a/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt b/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt index 89900f5421..073d459320 100644 --- a/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt +++ b/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt @@ -16,6 +16,7 @@ package okio /** - * + * Marks an object that can be attached to a [FileSystem], and that supplements the file system's + * capabilities. */ interface FileSystemExtension diff --git a/okio/src/commonMain/kotlin/okio/Okio.kt b/okio/src/commonMain/kotlin/okio/Okio.kt index d019d5ee65..9d29eb1daf 100644 --- a/okio/src/commonMain/kotlin/okio/Okio.kt +++ b/okio/src/commonMain/kotlin/okio/Okio.kt @@ -73,10 +73,15 @@ inline fun T.use(block: (T) -> R): R { return result as R } -inline fun FileSystem.extend(extension: E): FileSystem { - return extend(E::class, extension) -} +/** + * Returns a new file system that forwards all calls to this, and that also returns [extension] + * when it is requested. + * + * When [E] is requested on the returned file system, it will return [extension], regardless of what + * is returned by this file system. + */ +inline fun FileSystem.extend(extension: E): FileSystem = + extend(E::class, extension) -inline fun FileSystem.extension(): E? { - return extension(E::class) -} +/** Returns the extension for [E] if it exists, and null otherwise. */ +inline fun FileSystem.extension(): E? = extension(E::class) diff --git a/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt b/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt index b722304f8e..83c79464b4 100644 --- a/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt @@ -75,7 +75,7 @@ fun FileSystem.commonExtend(extensionType: KClass, extension: T): F // If this file system is already an extension wrapper, replace it rather than wrapping again. // Note that this optimization doesn't apply to ForwardingFileSystem subclasses, only to the // ForwardingFileSystem base class. - if (this::class === ForwardingFileSystem::class) { + if (this::class == ForwardingFileSystem::class) { this as ForwardingFileSystem val newExtensions = extensions.toMutableMap() newExtensions[extensionType] = extension diff --git a/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt b/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt index dab0d16f4e..15072554ee 100644 --- a/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt +++ b/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package okio import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertNotEquals +import kotlin.test.assertNull import okio.fakefilesystem.FakeFileSystem class FileSystemExtensionsTest { @@ -31,18 +32,58 @@ class FileSystemExtensionsTest { @Test fun absentExtension() { + val fakeFileSystem = FakeFileSystem() + val extension = FooExtension(fakeFileSystem) + val fileSystemWithExtension = fakeFileSystem.extend(extension) + assertNull(fileSystemWithExtension.extension()) } @Test fun overrideExtension() { + val fakeFileSystem = FakeFileSystem() + val extension1 = FooExtension(fakeFileSystem) + val fileSystemWithExtension1 = fakeFileSystem.extend(extension1) + + val extension2 = FooExtension(fakeFileSystem) + val fileSystemWithExtension2 = fileSystemWithExtension1.extend(extension2) + assertEquals(fileSystemWithExtension2.extension(), extension2) + + // Doesn't interfere with any of the wrapped layers. + assertEquals(fileSystemWithExtension1.extension(), extension1) + assertNull(fakeFileSystem.extension(), null) } @Test fun forwardingFileSystemCoalesced() { + val fakeFileSystem = FakeFileSystem() + val fooExtension = FooExtension(fakeFileSystem) + val fileSystemWithFoo = fakeFileSystem.extend(fooExtension) + + val barExtension = BarExtension(fakeFileSystem) + val fileSystemWithFooAndBar = fileSystemWithFoo.extend(barExtension) + + assertEquals(fileSystemWithFooAndBar.extension(), fooExtension) + assertEquals(fileSystemWithFooAndBar.extension(), barExtension) + assertEquals((fileSystemWithFooAndBar as ForwardingFileSystem).delegate, fakeFileSystem) } @Test fun customForwardingFileSystemNotCoalesced() { + val fakeFileSystem = FakeFileSystem() + val fooExtension = FooExtension(fakeFileSystem) + val fileSystemWithFoo = object : ForwardingFileSystem( + delegate = fakeFileSystem, + extensions = mapOf(FooExtension::class to fooExtension), + ) { + // This extends ForwardingFileSystem. Usually this would be to add new capabilities. + } + + val barExtension = BarExtension(fakeFileSystem) + val fileSystemWithFooAndBar = fileSystemWithFoo.extend(barExtension) + + assertEquals(fileSystemWithFooAndBar.extension(), fooExtension) + assertEquals(fileSystemWithFooAndBar.extension(), barExtension) + assertNotEquals((fileSystemWithFooAndBar as ForwardingFileSystem).delegate, fakeFileSystem) } class FooExtension( From b0f4ebba31aaaf3c5c58597b5b5c3b4f42c4c4da Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Mon, 15 Apr 2024 21:07:42 -0400 Subject: [PATCH 3/8] apiDump and spotlessApply --- okio/api/okio.api | 13 ++++++++++++- .../commonMain/kotlin/okio/internal/FileSystem.kt | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/okio/api/okio.api b/okio/api/okio.api index e124cd36a2..5236ff5220 100644 --- a/okio/api/okio.api +++ b/okio/api/okio.api @@ -477,6 +477,8 @@ public abstract class okio/FileSystem { public fun deleteRecursively (Lokio/Path;Z)V public static synthetic fun deleteRecursively$default (Lokio/FileSystem;Lokio/Path;ZILjava/lang/Object;)V public final fun exists (Lokio/Path;)Z + public fun extend (Lkotlin/reflect/KClass;Lokio/FileSystemExtension;)Lokio/FileSystem; + public fun extension (Lkotlin/reflect/KClass;)Lokio/FileSystemExtension; public static final fun get (Ljava/nio/file/FileSystem;)Lokio/FileSystem; public abstract fun list (Lokio/Path;)Ljava/util/List; public abstract fun listOrNull (Lokio/Path;)Ljava/util/List; @@ -499,7 +501,10 @@ public final class okio/FileSystem$Companion { public final fun get (Ljava/nio/file/FileSystem;)Lokio/FileSystem; } -public abstract class okio/ForwardingFileSystem : okio/FileSystem { +public abstract interface class okio/FileSystemExtension { +} + +public class okio/ForwardingFileSystem : okio/FileSystem { public fun (Lokio/FileSystem;)V public fun appendingSink (Lokio/Path;Z)Lokio/Sink; public fun atomicMove (Lokio/Path;Lokio/Path;)V @@ -508,10 +513,12 @@ public abstract class okio/ForwardingFileSystem : okio/FileSystem { public fun createSymlink (Lokio/Path;Lokio/Path;)V public final fun delegate ()Lokio/FileSystem; public fun delete (Lokio/Path;Z)V + public fun extension (Lkotlin/reflect/KClass;)Lokio/FileSystemExtension; public fun list (Lokio/Path;)Ljava/util/List; public fun listOrNull (Lokio/Path;)Ljava/util/List; public fun listRecursively (Lokio/Path;Z)Lkotlin/sequences/Sequence; public fun metadataOrNull (Lokio/Path;)Lokio/FileMetadata; + public fun onExtension (Lkotlin/reflect/KClass;Ljava/lang/Object;)Ljava/lang/Object; public fun onPathParameter (Lokio/Path;Ljava/lang/String;Ljava/lang/String;)Lokio/Path; public fun onPathResult (Lokio/Path;Ljava/lang/String;)Lokio/Path; public fun openReadOnly (Lokio/Path;)Lokio/FileHandle; @@ -819,6 +826,10 @@ public final class okio/_JvmPlatformKt { public static final fun withLock (Ljava/util/concurrent/locks/ReentrantLock;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object; } +public final class okio/internal/-FileSystem { + public static final fun commonExtend (Lokio/FileSystem;Lkotlin/reflect/KClass;Ljava/lang/Object;)Lokio/FileSystem; +} + public final class okio/internal/_Utf8Kt { public static final fun commonAsUtf8ToByteArray (Ljava/lang/String;)[B public static final fun commonToUtf8String ([BII)Ljava/lang/String; diff --git a/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt b/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt index 83c79464b4..9d2618128f 100644 --- a/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/internal/FileSystem.kt @@ -84,7 +84,7 @@ fun FileSystem.commonExtend(extensionType: KClass, extension: T): F return ForwardingFileSystem( delegate = this, - extensions = mapOf(extensionType to extension) + extensions = mapOf(extensionType to extension), ) } From a4f71a1c863d28c98b1b83dffdb45d5b4b8b5a36 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Tue, 16 Apr 2024 09:11:05 -0400 Subject: [PATCH 4/8] Experiment with path mapping --- .../kotlin/okio/FileSystemExtension.kt | 32 ++++++++++++++++++- okio/src/commonMain/kotlin/okio/Okio.kt | 27 ++++++++++++++++ okio/src/commonMain/kotlin/okio/PathMapper.kt | 13 ++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 okio/src/commonMain/kotlin/okio/PathMapper.kt diff --git a/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt b/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt index 073d459320..219e3d8334 100644 --- a/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt +++ b/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt @@ -18,5 +18,35 @@ package okio /** * Marks an object that can be attached to a [FileSystem], and that supplements the file system's * capabilities. + * + * Implementations must support transforms to input and output paths with [PathMapper]. To simplify + * implementation, use [PathMapper.NONE] by default and use [chain] to combine mappers. + * + * ```kotlin + * class DiskUsageExtension private constructor( + * private val pathMapper: PathMapper, + * ) : FileSystemExtension { + * constructor() : this(PathMapper.NONE) + * + * override fun map(pathMapper: PathMapper): FileSystemExtension { + * return DiskUsageExtension(chain(pathMapper, this.pathMapper)) + * } + * + * fun sizeOnDisk(path: Path): Long { + * val mappedPath = pathMapper.onPathParameter(path, "sizeOnDisk", "path") + * return lookUpSizeOnDisk(mappedPath) + * } + * + * fun largestFiles(): Sequence { + * val largestFiles: Sequence = lookUpLargestFiles() + * return largestFiles.map { + * pathMapper.onPathResult(it, "largestFiles") + * } + * } + * } + * ``` */ -interface FileSystemExtension +interface FileSystemExtension { + /** Returns a file system of the same type, that applies [pathMapper] to all paths. */ + fun map(pathMapper: PathMapper) : FileSystemExtension +} diff --git a/okio/src/commonMain/kotlin/okio/Okio.kt b/okio/src/commonMain/kotlin/okio/Okio.kt index 9d29eb1daf..071ab7b840 100644 --- a/okio/src/commonMain/kotlin/okio/Okio.kt +++ b/okio/src/commonMain/kotlin/okio/Okio.kt @@ -85,3 +85,30 @@ inline fun FileSystem.extend(extension: E): Fi /** Returns the extension for [E] if it exists, and null otherwise. */ inline fun FileSystem.extension(): E? = extension(E::class) + + +fun chain(outer: PathMapper, inner: PathMapper): PathMapper { + return object : PathMapper { + override fun onPathParameter(path: Path, functionName: String, parameterName: String): Path { + return inner.onPathParameter( + outer.onPathParameter( + path, + functionName, + parameterName, + ), + functionName, + parameterName, + ) + } + + override fun onPathResult(path: Path, functionName: String): Path { + return outer.onPathResult( + inner.onPathResult( + path, + functionName, + ), + functionName, + ) + } + } +} diff --git a/okio/src/commonMain/kotlin/okio/PathMapper.kt b/okio/src/commonMain/kotlin/okio/PathMapper.kt new file mode 100644 index 0000000000..ecca2cc201 --- /dev/null +++ b/okio/src/commonMain/kotlin/okio/PathMapper.kt @@ -0,0 +1,13 @@ +package okio + +interface PathMapper { + fun onPathParameter(path: Path, functionName: String, parameterName: String): Path + fun onPathResult(path: Path, functionName: String): Path + + companion object { + val NONE = object : PathMapper { + override fun onPathParameter(path: Path, functionName: String, parameterName: String) = path + override fun onPathResult(path: Path, functionName: String) = path + } + } +} From 9c05d2fa484fb945f0891b19a4be89966ab7b261 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Wed, 17 Apr 2024 09:43:56 -0400 Subject: [PATCH 5/8] Copyright --- okio/src/commonMain/kotlin/okio/PathMapper.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/okio/src/commonMain/kotlin/okio/PathMapper.kt b/okio/src/commonMain/kotlin/okio/PathMapper.kt index ecca2cc201..4f5b9f28ad 100644 --- a/okio/src/commonMain/kotlin/okio/PathMapper.kt +++ b/okio/src/commonMain/kotlin/okio/PathMapper.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2024 Square, Inc. + * + * 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. + */ package okio interface PathMapper { From 0bf63eba7a0847a46d9323a62107073306737d22 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Sat, 20 Apr 2024 15:13:00 -0400 Subject: [PATCH 6/8] Finish the mapping API and write some tests --- .../kotlin/okio/FileSystemExtension.kt | 61 +++++- .../kotlin/okio/ForwardingFileSystem.kt | 20 +- okio/src/commonMain/kotlin/okio/Okio.kt | 31 +-- okio/src/commonMain/kotlin/okio/PathMapper.kt | 28 --- .../okio/FileSystemExtensionMappingTest.kt | 193 ++++++++++++++++++ .../kotlin/okio/FileSystemExtensionsTest.kt | 9 +- 6 files changed, 272 insertions(+), 70 deletions(-) delete mode 100644 okio/src/commonMain/kotlin/okio/PathMapper.kt create mode 100644 okio/src/commonTest/kotlin/okio/FileSystemExtensionMappingTest.kt diff --git a/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt b/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt index 219e3d8334..79bab5b93e 100644 --- a/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt +++ b/okio/src/commonMain/kotlin/okio/FileSystemExtension.kt @@ -15,38 +15,79 @@ */ package okio +import okio.FileSystemExtension.Mapping + /** * Marks an object that can be attached to a [FileSystem], and that supplements the file system's * capabilities. * - * Implementations must support transforms to input and output paths with [PathMapper]. To simplify - * implementation, use [PathMapper.NONE] by default and use [chain] to combine mappers. + * Implementations must support transforms to input and output paths with [Mapping]. To simplify + * implementation, use [Mapping.NONE] by default and use [Mapping.chain] to combine mappings. * * ```kotlin * class DiskUsageExtension private constructor( - * private val pathMapper: PathMapper, + * private val mapping: Mapping, * ) : FileSystemExtension { - * constructor() : this(PathMapper.NONE) + * constructor() : this(Mapping.NONE) * - * override fun map(pathMapper: PathMapper): FileSystemExtension { - * return DiskUsageExtension(chain(pathMapper, this.pathMapper)) + * override fun map(outer: Mapping): FileSystemExtension { + * return DiskUsageExtension(mapping.chain(outer)) * } * * fun sizeOnDisk(path: Path): Long { - * val mappedPath = pathMapper.onPathParameter(path, "sizeOnDisk", "path") + * val mappedPath = mapping.mapParameter(path, "sizeOnDisk", "path") * return lookUpSizeOnDisk(mappedPath) * } * * fun largestFiles(): Sequence { * val largestFiles: Sequence = lookUpLargestFiles() * return largestFiles.map { - * pathMapper.onPathResult(it, "largestFiles") + * mapping.mapResult(it, "largestFiles") * } * } * } * ``` */ interface FileSystemExtension { - /** Returns a file system of the same type, that applies [pathMapper] to all paths. */ - fun map(pathMapper: PathMapper) : FileSystemExtension + /** Returns a file system of the same type, that applies [outer] to all paths. */ + fun map(outer: Mapping): FileSystemExtension + + abstract class Mapping { + abstract fun mapParameter(path: Path, functionName: String, parameterName: String): Path + abstract fun mapResult(path: Path, functionName: String): Path + + fun chain(outer: Mapping): Mapping { + val inner = this + return object : Mapping() { + override fun mapParameter(path: Path, functionName: String, parameterName: String): Path { + return inner.mapParameter( + outer.mapParameter( + path, + functionName, + parameterName, + ), + functionName, + parameterName, + ) + } + + override fun mapResult(path: Path, functionName: String): Path { + return outer.mapResult( + inner.mapResult( + path, + functionName, + ), + functionName, + ) + } + } + } + + companion object { + val NONE = object : Mapping() { + override fun mapParameter(path: Path, functionName: String, parameterName: String) = path + override fun mapResult(path: Path, functionName: String) = path + } + } + } } diff --git a/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt b/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt index 0be07f40fd..69b5b45cb2 100644 --- a/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt +++ b/okio/src/commonMain/kotlin/okio/ForwardingFileSystem.kt @@ -109,8 +109,18 @@ open class ForwardingFileSystem internal constructor( val delegate: FileSystem, extensions: Map, Any>, ) : FileSystem() { + /** Extensions added at this layer. Additional extensions may exist in [delegate]. */ internal val extensions = extensions.toMap() + /** Maps paths with [onPathParameter] and [onPathResult]. */ + val extensionMapping: FileSystemExtension.Mapping = object : FileSystemExtension.Mapping() { + override fun mapParameter(path: Path, functionName: String, parameterName: String) = + onPathParameter(path, functionName, parameterName) + + override fun mapResult(path: Path, functionName: String) = + onPathResult(path, functionName) + } + constructor(delegate: FileSystem) : this(delegate, emptyMap()) /** @@ -148,7 +158,15 @@ open class ForwardingFileSystem internal constructor( */ open fun onPathResult(path: Path, functionName: String): Path = path - open fun onExtension(type: KClass, extension: T): T = extension + /** + * Invoked each time an extension is returned from [ForwardingFileSystem.extension]. + * + * Overrides of this function must call [FileSystemExtension.map] with [extensionMapping], + * otherwise path mapping will not be applied. Or call `super.onExtension()` to do this. + */ + open fun onExtension(type: KClass, extension: T): T { + return type.cast(extension.map(extensionMapping)) + } @Throws(IOException::class) override fun canonicalize(path: Path): Path { diff --git a/okio/src/commonMain/kotlin/okio/Okio.kt b/okio/src/commonMain/kotlin/okio/Okio.kt index 071ab7b840..1b0464fb8e 100644 --- a/okio/src/commonMain/kotlin/okio/Okio.kt +++ b/okio/src/commonMain/kotlin/okio/Okio.kt @@ -77,38 +77,11 @@ inline fun T.use(block: (T) -> R): R { * Returns a new file system that forwards all calls to this, and that also returns [extension] * when it is requested. * - * When [E] is requested on the returned file system, it will return [extension], regardless of what - * is returned by this file system. + * When [E] is requested on the returned file system, it will return [extension]. If this file + * system already has an extension of this type, [extension] takes precedence. */ inline fun FileSystem.extend(extension: E): FileSystem = extend(E::class, extension) /** Returns the extension for [E] if it exists, and null otherwise. */ inline fun FileSystem.extension(): E? = extension(E::class) - - -fun chain(outer: PathMapper, inner: PathMapper): PathMapper { - return object : PathMapper { - override fun onPathParameter(path: Path, functionName: String, parameterName: String): Path { - return inner.onPathParameter( - outer.onPathParameter( - path, - functionName, - parameterName, - ), - functionName, - parameterName, - ) - } - - override fun onPathResult(path: Path, functionName: String): Path { - return outer.onPathResult( - inner.onPathResult( - path, - functionName, - ), - functionName, - ) - } - } -} diff --git a/okio/src/commonMain/kotlin/okio/PathMapper.kt b/okio/src/commonMain/kotlin/okio/PathMapper.kt deleted file mode 100644 index 4f5b9f28ad..0000000000 --- a/okio/src/commonMain/kotlin/okio/PathMapper.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2024 Square, Inc. - * - * 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. - */ -package okio - -interface PathMapper { - fun onPathParameter(path: Path, functionName: String, parameterName: String): Path - fun onPathResult(path: Path, functionName: String): Path - - companion object { - val NONE = object : PathMapper { - override fun onPathParameter(path: Path, functionName: String, parameterName: String) = path - override fun onPathResult(path: Path, functionName: String) = path - } - } -} diff --git a/okio/src/commonTest/kotlin/okio/FileSystemExtensionMappingTest.kt b/okio/src/commonTest/kotlin/okio/FileSystemExtensionMappingTest.kt new file mode 100644 index 0000000000..537a7a1da5 --- /dev/null +++ b/okio/src/commonTest/kotlin/okio/FileSystemExtensionMappingTest.kt @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2024 Square, Inc. + * + * 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. + */ +package okio + +import kotlin.test.Test +import kotlin.test.assertEquals +import okio.FileSystemExtension.Mapping +import okio.Path.Companion.toPath +import okio.fakefilesystem.FakeFileSystem + +class FileSystemExtensionMappingTest { + private val rawFileSystem = FakeFileSystem() + + @Test + fun happyPath() { + // Create a bunch of files in the /monday directory. + val mondayExtension = ChefExtension(rawFileSystem) + val mondayFs = rawFileSystem.extend(mondayExtension) + mondayFs.createDirectory("/monday".toPath()) + mondayFs.write("/monday/breakfast.txt".toPath()) { writeUtf8("croissant") } + mondayFs.write("/monday/lunch.txt".toPath()) { writeUtf8("peanut butter sandwich") } + mondayFs.write("/monday/dinner.txt".toPath()) { writeUtf8("pizza") } + + // Associate data with these files in the extension. + mondayExtension.setChef("/monday/dinner.txt".toPath(), "jesse") + mondayExtension.setChef("/monday/breakfast.txt".toPath(), "benoit") + mondayExtension.setChef("/monday/lunch.txt".toPath(), "jesse") + + // Confirm we can query the extension. + assertEquals( + listOf( + "/monday/dinner.txt".toPath(), + "/monday/lunch.txt".toPath(), + ), + mondayExtension.listForChef("/monday".toPath(), "jesse"), + ) + assertEquals( + listOf( + "/monday/breakfast.txt".toPath(), + ), + mondayExtension.listForChef("/monday".toPath(), "benoit"), + ) + + // Apply a path mapping transformation and confirm we can read the metadata. + val tuesdayFs = TuesdayFileSystem(mondayFs) + val tuesdayExtension = tuesdayFs.extension()!! + assertEquals( + listOf( + "/tuesday/dinner.txt".toPath(), + "/tuesday/lunch.txt".toPath(), + ), + tuesdayExtension.listForChef("/tuesday".toPath(), "jesse"), + ) + assertEquals( + listOf( + "/tuesday/breakfast.txt".toPath(), + ), + tuesdayExtension.listForChef("/tuesday".toPath(), "benoit"), + ) + + // We should also be able to write through the extension... + tuesdayFs.write("/tuesday/snack.txt".toPath()) { writeUtf8("doritos") } + tuesdayExtension.setChef("/tuesday/snack.txt".toPath(), "jake") + assertEquals( + listOf( + "/tuesday/snack.txt".toPath(), + ), + tuesdayExtension.listForChef("/tuesday".toPath(), "jake"), + ) + + // ...And the extension data should map all the way through to the source file system. + assertEquals( + listOf( + "/monday/snack.txt".toPath(), + ), + mondayExtension.listForChef("/monday".toPath(), "jake"), + ) + } + + @Test + fun chainTransformations() { + val mondayExtension = ChefExtension(rawFileSystem) + val mondayFs = rawFileSystem.extend(mondayExtension) + mondayFs.createDirectory("/monday".toPath()) + mondayFs.write("/monday/breakfast.txt".toPath()) { writeUtf8("croissant") } + mondayExtension.setChef("/monday/breakfast.txt".toPath(), "benoit") + + // Map /monday to /tuesday. + val tuesdayFs = TuesdayFileSystem(mondayFs) + + // Map / to /menu. + val menuFs = MenuFileSystem(tuesdayFs) + val menuExtension = menuFs.extension()!! + + // Confirm we can read through the mappings. + assertEquals( + listOf( + "/menu/tuesday/breakfast.txt".toPath(), + ), + menuExtension.listForChef("/menu/tuesday".toPath(), "benoit"), + ) + + // Confirm we can write through also. + menuFs.write("/menu/tuesday/lunch.txt".toPath()) { writeUtf8("tomato soup") } + menuExtension.setChef("/menu/tuesday/lunch.txt".toPath(), "jesse") + assertEquals( + "tomato soup", + mondayFs.read("/monday/lunch.txt".toPath()) { readUtf8() }, + ) + assertEquals( + listOf( + "/monday/lunch.txt".toPath(), + ), + mondayExtension.listForChef("/monday".toPath(), "jesse"), + ) + + // Each extension gets its own mapping. + assertEquals( + "tomato soup", + tuesdayFs.read("/tuesday/lunch.txt".toPath()) { readUtf8() }, + ) + assertEquals( + listOf( + "/tuesday/lunch.txt".toPath(), + ), + tuesdayFs.extension()!!.listForChef("/tuesday".toPath(), "jesse"), + ) + } + + /** + * This test extension associates paths with optional metadata: the chef of a file. + * + * When tests run there will be multiple instances of this extension, all sharing one [chefs] + * store, and each with its own [mapping]. The contents of [chefs] uses mapped paths for its keys. + * + * Real world extensions will have similar obligations for path mapping, but they'll likely do + * real things with the paths such as passing them to system APIs. + */ + class ChefExtension( + private val target: FileSystem, + private val chefs: MutableMap = mutableMapOf(), + private val mapping: Mapping = Mapping.NONE, + ) : FileSystemExtension { + override fun map(outer: Mapping) = ChefExtension(target, chefs, mapping.chain(outer)) + + fun setChef(path: Path, chef: String) { + val mappedPath = mapping.mapParameter(path, "set", "path") + chefs[mappedPath] = chef + } + + fun listForChef(dir: Path, chef: String): List { + val mappedDir = mapping.mapParameter(dir, "listForChef", "dir") + return target.list(mappedDir) + .filter { chefs[it] == chef } + .map { mapping.mapResult(it, "listForChef") } + } + } + + class TuesdayFileSystem(delegate: FileSystem) : ForwardingFileSystem(delegate) { + private val monday = "/monday".toPath() + private val tuesday = "/tuesday".toPath() + + override fun onPathParameter(path: Path, functionName: String, parameterName: String) = + monday / path.relativeTo(tuesday) + + override fun onPathResult(path: Path, functionName: String) = + tuesday / path.relativeTo(monday) + } + + class MenuFileSystem(delegate: FileSystem) : ForwardingFileSystem(delegate) { + private val root = "/".toPath() + private val menu = "/menu".toPath() + + override fun onPathParameter(path: Path, functionName: String, parameterName: String) = + root / path.relativeTo(menu) + + override fun onPathResult(path: Path, functionName: String) = + menu / path.relativeTo(root) + } +} diff --git a/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt b/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt index 15072554ee..7a27d676e0 100644 --- a/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt +++ b/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt @@ -19,6 +19,7 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals import kotlin.test.assertNull +import okio.FileSystemExtension.Mapping import okio.fakefilesystem.FakeFileSystem class FileSystemExtensionsTest { @@ -88,9 +89,13 @@ class FileSystemExtensionsTest { class FooExtension( val target: FileSystem, - ) : FileSystemExtension + ) : FileSystemExtension { + override fun map(outer: Mapping) = this + } class BarExtension( val target: FileSystem, - ) : FileSystemExtension + ) : FileSystemExtension { + override fun map(outer: Mapping) = this + } } From 7a0425e391c8fa8ddc6d0c234ab90e37671784d2 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Sat, 20 Apr 2024 15:13:58 -0400 Subject: [PATCH 7/8] apiDump --- okio/api/okio.api | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/okio/api/okio.api b/okio/api/okio.api index 5236ff5220..d112bfc9aa 100644 --- a/okio/api/okio.api +++ b/okio/api/okio.api @@ -502,6 +502,19 @@ public final class okio/FileSystem$Companion { } public abstract interface class okio/FileSystemExtension { + public abstract fun map (Lokio/FileSystemExtension$Mapping;)Lokio/FileSystemExtension; +} + +public abstract class okio/FileSystemExtension$Mapping { + public static final field Companion Lokio/FileSystemExtension$Mapping$Companion; + public fun ()V + public final fun chain (Lokio/FileSystemExtension$Mapping;)Lokio/FileSystemExtension$Mapping; + public abstract fun mapParameter (Lokio/Path;Ljava/lang/String;Ljava/lang/String;)Lokio/Path; + public abstract fun mapResult (Lokio/Path;Ljava/lang/String;)Lokio/Path; +} + +public final class okio/FileSystemExtension$Mapping$Companion { + public final fun getNONE ()Lokio/FileSystemExtension$Mapping; } public class okio/ForwardingFileSystem : okio/FileSystem { @@ -514,11 +527,12 @@ public class okio/ForwardingFileSystem : okio/FileSystem { public final fun delegate ()Lokio/FileSystem; public fun delete (Lokio/Path;Z)V public fun extension (Lkotlin/reflect/KClass;)Lokio/FileSystemExtension; + public final fun getExtensionMapping ()Lokio/FileSystemExtension$Mapping; public fun list (Lokio/Path;)Ljava/util/List; public fun listOrNull (Lokio/Path;)Ljava/util/List; public fun listRecursively (Lokio/Path;Z)Lkotlin/sequences/Sequence; public fun metadataOrNull (Lokio/Path;)Lokio/FileMetadata; - public fun onExtension (Lkotlin/reflect/KClass;Ljava/lang/Object;)Ljava/lang/Object; + public fun onExtension (Lkotlin/reflect/KClass;Lokio/FileSystemExtension;)Lokio/FileSystemExtension; public fun onPathParameter (Lokio/Path;Ljava/lang/String;Ljava/lang/String;)Lokio/Path; public fun onPathResult (Lokio/Path;Ljava/lang/String;)Lokio/Path; public fun openReadOnly (Lokio/Path;)Lokio/FileHandle; From 5325b962ba5964c4ea21df5a92e4b7c067701e38 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Sat, 20 Apr 2024 15:32:12 -0400 Subject: [PATCH 8/8] No FS tests on Wasm --- okio/build.gradle.kts | 3 ++- .../kotlin/okio/FileSystemExtensionMappingTest.kt | 0 .../kotlin/okio/FileSystemExtensionsTest.kt | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename okio/src/{commonTest => nonWasmTest}/kotlin/okio/FileSystemExtensionMappingTest.kt (100%) rename okio/src/{commonTest => nonWasmTest}/kotlin/okio/FileSystemExtensionsTest.kt (100%) diff --git a/okio/build.gradle.kts b/okio/build.gradle.kts index d3f215639b..ed0c66d1ab 100644 --- a/okio/build.gradle.kts +++ b/okio/build.gradle.kts @@ -66,7 +66,6 @@ kotlin { dependencies { implementation(libs.kotlin.test) implementation(projects.okioTestingSupport) - implementation(projects.okioFakefilesystem) } } @@ -80,7 +79,9 @@ kotlin { val nonWasmTest by creating { dependencies { + implementation(libs.kotlin.test) implementation(libs.kotlin.time) + implementation(projects.okioFakefilesystem) } } diff --git a/okio/src/commonTest/kotlin/okio/FileSystemExtensionMappingTest.kt b/okio/src/nonWasmTest/kotlin/okio/FileSystemExtensionMappingTest.kt similarity index 100% rename from okio/src/commonTest/kotlin/okio/FileSystemExtensionMappingTest.kt rename to okio/src/nonWasmTest/kotlin/okio/FileSystemExtensionMappingTest.kt diff --git a/okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt b/okio/src/nonWasmTest/kotlin/okio/FileSystemExtensionsTest.kt similarity index 100% rename from okio/src/commonTest/kotlin/okio/FileSystemExtensionsTest.kt rename to okio/src/nonWasmTest/kotlin/okio/FileSystemExtensionsTest.kt