Skip to content

Commit

Permalink
#44 add FilesGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex009 committed May 4, 2020
1 parent 83e4231 commit cf5aeb0
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package dev.icerock.gradle
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.LibraryPlugin
import com.android.build.gradle.api.AndroidSourceSet
import dev.icerock.gradle.generator.FilesGenerator
import dev.icerock.gradle.generator.FontsGenerator
import dev.icerock.gradle.generator.GenerateMultiplatformResourcesTask
import dev.icerock.gradle.generator.ImagesGenerator
Expand Down Expand Up @@ -85,7 +86,8 @@ class MultiplatformResourcesPlugin : Plugin<Project> {
StringsGenerator.Feature(sourceInfo, iosLocalizationRegion),
PluralsGenerator.Feature(sourceInfo, iosLocalizationRegion),
ImagesGenerator.Feature(sourceInfo),
FontsGenerator.Feature(sourceInfo)
FontsGenerator.Feature(sourceInfo),
FilesGenerator.Feature(sourceInfo)
)
val targets: List<KotlinTarget> = multiplatformExtension.targets.toList()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright 2020 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.gradle.generator

import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeSpec
import dev.icerock.gradle.generator.android.AndroidFilesGenerator
import dev.icerock.gradle.generator.common.CommonFilesGenerator
import dev.icerock.gradle.generator.ios.IosFilesGenerator
import org.gradle.api.file.FileTree
import java.io.File

abstract class FilesGenerator(
private val inputFileTree: FileTree
) : MRGenerator.Generator {

private val resourceClass = ClassName("dev.icerock.moko.resources", "FileResource")

override fun generate(resourcesGenerationDir: File): TypeSpec {
val fileSpecs = inputFileTree.map { file ->
FileSpec(
key = file.nameWithoutExtension,
file = file
)
}.sortedBy { it.key }
val typeSpec = createTypeSpec(fileSpecs.map { it.key })
generateResources(resourcesGenerationDir, fileSpecs)
return typeSpec
}

private fun createTypeSpec(keys: List<String>): TypeSpec {
val classBuilder = TypeSpec.objectBuilder("files")
@Suppress("SpreadOperator")
classBuilder.addModifiers(*getClassModifiers())

keys.forEach { classBuilder.addProperty(generateFileProperty(fileName = it)) }
return classBuilder.build()
}

override fun getImports(): List<ClassName> = emptyList()

private fun generateFileProperty(
fileName: String
): PropertySpec {
@Suppress("SpreadOperator")
return PropertySpec.builder(fileName, resourceClass)
.addModifiers(*getPropertyModifiers())
.apply {
getPropertyInitializer(fileName)?.let { initializer(it) }
}
.build()
}

protected open fun generateResources(
resourcesGenerationDir: File,
files: List<FileSpec>
) {
}

abstract fun getClassModifiers(): Array<KModifier>

abstract fun getPropertyModifiers(): Array<KModifier>

abstract fun getPropertyInitializer(fileName: String): CodeBlock?

data class FileSpec(
val key: String,
val file: File
)

class Feature(private val info: SourceInfo) : ResourceGeneratorFeature<FilesGenerator> {
private val fileTree = info.commonResources.matching {
include("MR/files/**")
}

override fun createCommonGenerator(): FilesGenerator {
return CommonFilesGenerator(fileTree)
}

override fun createIosGenerator(): FilesGenerator {
return IosFilesGenerator(fileTree)
}

override fun createAndroidGenerator(): FilesGenerator {
return AndroidFilesGenerator(
fileTree,
info.androidRClassPackage
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2020 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.gradle.generator.android

import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.KModifier
import dev.icerock.gradle.generator.FilesGenerator
import org.gradle.api.file.FileTree
import java.io.File
import java.util.Locale

class AndroidFilesGenerator(
inputFileTree: FileTree,
private val androidRClassPackage: String
) : FilesGenerator(
inputFileTree = inputFileTree
) {
override fun getClassModifiers(): Array<KModifier> = arrayOf(KModifier.ACTUAL)

override fun getPropertyModifiers(): Array<KModifier> = arrayOf(KModifier.ACTUAL)

override fun getPropertyInitializer(fileName: String): CodeBlock? {
return CodeBlock.of("FileResource(rawResId = R.raw.%L)", keyToResourceId(fileName))
}

override fun getImports(): List<ClassName> = listOf(
ClassName(androidRClassPackage, "R")
)

override fun generateResources(
resourcesGenerationDir: File,
files: List<FileSpec>
) {
val targetDir = File(resourcesGenerationDir, "raw")
targetDir.mkdirs()

files.forEach { (key, file) ->
val fileName = keyToResourceId(key) + "." + file.extension
file.copyTo(File(targetDir, fileName))
}
}

private fun keyToResourceId(key: String): String {
return key.replace("-", "_").toLowerCase(Locale.ROOT)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2020 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.gradle.generator.common

import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.KModifier
import dev.icerock.gradle.generator.FilesGenerator
import dev.icerock.gradle.generator.FontsGenerator
import org.gradle.api.file.FileTree

class CommonFilesGenerator(
inputFileTree: FileTree
) : FilesGenerator(
inputFileTree = inputFileTree
) {
override fun getClassModifiers(): Array<KModifier> = emptyArray()

override fun getPropertyModifiers(): Array<KModifier> = emptyArray()

override fun getPropertyInitializer(fileName: String): CodeBlock? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2020 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.gradle.generator.ios

import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.KModifier
import dev.icerock.gradle.generator.FilesGenerator
import org.gradle.api.file.FileTree
import java.io.File

class IosFilesGenerator(
inputFileTree: FileTree
) : FilesGenerator(
inputFileTree = inputFileTree
) {
override fun getClassModifiers(): Array<KModifier> = arrayOf(KModifier.ACTUAL)

override fun getPropertyModifiers(): Array<KModifier> = arrayOf(KModifier.ACTUAL)

override fun getPropertyInitializer(fileName: String): CodeBlock? {
return CodeBlock.of(
"FileResource(fileName = %S, bundle = ${IosMRGenerator.BUNDLE_PROPERTY_NAME})",
fileName
)
}

override fun generateResources(
resourcesGenerationDir: File,
files: List<FileSpec>
) {
val targetDir = File(resourcesGenerationDir, "files")
targetDir.mkdirs()

files.forEach { (_, file) ->
file.copyTo(File(targetDir, file.name))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@

package dev.icerock.moko.resources

import java.io.File
import java.net.URI
import android.content.Context
import android.content.res.Resources
import androidx.annotation.RawRes
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader

actual class FileResource(
val assetsPath: String
@RawRes
val rawResId: Int
) {
actual fun readText(): String {
val assetUri: URI = URI.create("file:///android_asset/$assetsPath")
val file: File = File(assetUri)
return file.readText()
fun readText(context: Context): String {
val resources: Resources = context.resources
val inputStream: InputStream = resources.openRawResource(rawResId)
val bufferedReader = BufferedReader(InputStreamReader(inputStream))
return bufferedReader.readText()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

package dev.icerock.moko.resources

expect class FileResource {
fun readText(): String
}
expect class FileResource
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ actual class FileResource(
val path: String get() = bundle.pathForResource(name = fileName, ofType = null, inDirectory = "files")!!
val url: NSURL get() = bundle.URLForResource(name = fileName, withExtension = null, subdirectory = "files")!!

actual fun readText(): String {
fun readText(): String {
val (result: String?, error: NSError?) = memScoped {
val p = alloc<ObjCObjectVar<NSError?>>()
val result: String? = runCatching {
Expand All @@ -36,7 +36,7 @@ actual class FileResource(
result to p.value
}

if (error != null) throw RuntimeException(error.localizedDescription)
if (error != null) throw ReadFileTextException(fileResource = this, error = error)
else return result!!
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright 2020 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.resources

import platform.Foundation.NSError

class ReadFileTextException(
val fileResource: FileResource,
val info: String
) : Exception("can't read file $fileResource text ($info)") {
constructor(fileResource: FileResource, error: NSError) : this(fileResource, error.localizedDescription)
}

0 comments on commit cf5aeb0

Please sign in to comment.