kotlinx-resources icon indicating copy to clipboard operation
kotlinx-resources copied to clipboard

Walk directories

Open aSemy opened this issue 2 years ago • 6 comments

Currently I can only fetch one file directly, but I'd like to be able to fetch all resources within a directory.

Some use-cases:

  • I want to be able to fetch all files in a directory, and filter them (for example, to only get files with a prefix test-a, or only get JSON files
  • I have a very organised directory structure, so that all subdirectories represent a test case with the same 4 files. I want to be able to
    • fetch all directories in commonTest/resources/test-cases/
    • convert each one to a 'test case' class with 4 properties (one for each file)
    • pass each 'test case' to my test

So, I would like to be able to load an arbitrary file-system item, and be able to determine if it is a file or directory (for example, the returned object is in a sealed-interface hierarchy, so I can use a type-check).

aSemy avatar Jun 07 '23 14:06 aSemy

kotlinx-resources is modelled after Java's resources, so I'm tempted to approach it consistently… Boy, is it ugly. I'm tempted to not include it for this reason, but your second use-case is somewhat compelling. I'm not certain how to design an API that is elegant and consistent under the same design principle. Suggestions welcomed. 🙂 I'll think more about this one, too.

goncalossilva avatar Jun 09 '23 14:06 goncalossilva

I have two ideas:

  1. Code generation

    Define some interfaces to represent the file paths.

    sealed interface TestResource {
      val path: String
    
      interface Directory : TestResource {
        val contents: List<ResourceItem>
      }
    
      interface File: TestResource
    }
    

    Create a Gradle task that will generate some code for each discovered Directory, along with the file/dir contents.

  2. Network-based filesystem

    Create an implementation of Okio's FileSystem. Using Ktor, create a server and client to send and receive file data. Use a Gradle Build Service to run the Ktor server.

    This is less of an 'idea' and more of a 'total re-write'! But the advantage is that it's totally platform independent.

aSemy avatar Jun 12 '23 19:06 aSemy

Vouch for a FileSystem-like API. It doesn't have to be overly complex.
For example java.nio.FileSystem exposes the root path, and from that you can explore sub paths, and check if they're directories or files.

lppedd avatar Aug 08 '23 09:08 lppedd

@goncalossilva now that I've experimented with the current API I can share a better feedback.
It seems everything revolves around the Resource class. You create an instance of it, pointing to a path, and it lets you load the content.

I think a more fluent approach would be to provide a FileSystem entry point, from which you can obtain Resource instances. Much like in Java, where a Resource would be a Path.

Encapsulating the file handling code into a file system object would allow to extend it more easily in the future, instead of cluttering an expect class Resource. Plus, a platform-specific FileSystem could be reused not only in tests, but in the main code.

Edit: maybe FileSystem is not a appropriate name, as its scope is much restricted than that. ResourceManager, ResourceSystem are valid alternatives.

lppedd avatar Aug 08 '23 11:08 lppedd

@goncalossilva FYI https://github.com/Kotlin/kotlinx-io/pull/213, might be useful for this library's use cases.

lppedd avatar Sep 13 '23 09:09 lppedd

Nice! Thanks for sharing. It definitely adds to your case above. Consistency is important. 👍

goncalossilva avatar Sep 13 '23 16:09 goncalossilva