No request when glslify module is already downloaded

This commit is contained in:
Ricardo Matias
2020-02-29 14:27:59 +01:00
parent ad8d6632a9
commit 2b36b6f439
2 changed files with 61 additions and 54 deletions

View File

@@ -5,6 +5,7 @@ import org.rauschig.jarchivelib.ArchiverFactory
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
internal fun extractGzipStream(tarStream: InputStream, dest: File) { internal fun extractGzipStream(tarStream: InputStream, dest: File) {
@@ -13,8 +14,7 @@ internal fun extractGzipStream(tarStream: InputStream, dest: File) {
archiver.extract(tarStream, dest) archiver.extract(tarStream, dest)
} }
internal fun moveFilesUp(moduleDir: File) { internal fun moveFilesUp(modulePath: Path) {
val modulePath = Paths.get(moduleDir.path)
val packageFolder = modulePath.resolve("package") val packageFolder = modulePath.resolve("package")
val packageFiles = Files.list(packageFolder).filter { val packageFiles = Files.list(packageFolder).filter {
@@ -28,14 +28,14 @@ internal fun moveFilesUp(moduleDir: File) {
} }
} }
internal fun parseModule(module: String): Pair<String, String> { internal fun parseModule(module: String): Pair<String, Path> {
val path = Paths.get(module) val path = Paths.get(module)
val pathLen = path.nameCount val pathLen = path.nameCount
val moduleName = path.subpath(0, 1).toString() val moduleName = path.subpath(0, 1).toString()
var shaderPath = "index" var shaderPath = Paths.get("index")
if (pathLen > 1) { if (pathLen > 1) {
shaderPath = path.subpath(1, pathLen).toString() shaderPath = path.subpath(1, pathLen)
} }
return Pair(moduleName, shaderPath) return Pair(moduleName, shaderPath)

View File

@@ -5,16 +5,20 @@ import java.io.ByteArrayInputStream
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
import java.net.URL import java.net.URL
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
import kotlin.streams.toList
const val BASE_URL = "https://registry.npmjs.org" internal const val BASE_URL = "https://registry.npmjs.org"
const val GLSLIFY_PATH = "src/main/resources/glslify" internal const val GLSLIFY_PATH = "src/main/resources/glslify"
const val IMPORT_PATT = """#pragma\sglslify:\s*(.*)\s=\s*require\('([\w\-]+)'\)""" internal const val IMPORT_PATT = """#pragma\sglslify:\s*(.*)\s=\s*require\('?([\w\-\\/]+).*'?\)$"""
const val EXPORT_PATT = """#pragma\sglslify:\s*export\(([\w\-]+)\)""" internal const val EXPORT_PATT = """#pragma\sglslify:\s*export\(([\w\-]+)\)"""
internal val shaderExtensions = arrayOf("glsl", "frag") internal val shaderExtensions = arrayOf("glsl", "frag")
data class GlslifyImport( private data class GlslifyImport(
val functionName: String, val functionName: String,
val pkgName: String, val pkgName: String,
var exists: Boolean var exists: Boolean
@@ -23,64 +27,42 @@ data class GlslifyImport(
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
fun glslify(module: String, renameFunctionTo: String? = null): String { fun glslify(module: String, renameFunctionTo: String? = null): String {
val (moduleName: String, shaderPath: String) = parseModule(module) val (moduleName: String, shaderPath: Path) = parseModule(module)
val moduleDir = File("$GLSLIFY_PATH/$moduleName") val moduleDir = Paths.get("$GLSLIFY_PATH/$moduleName")
val packageUrl = getPackageUrl(moduleName) return glslifyImport(moduleName, moduleDir, shaderPath, renameFunctionTo)
}
if (packageUrl.isNullOrEmpty()) { private fun glslifyImport(moduleName: String, moduleDir: Path, shaderPath: Path, renameFunctionTo: String? = null): String {
throw error("[glslify] $moduleName not found") if (!Files.exists(moduleDir)) {
} fetchModule(moduleName, moduleDir)
if (!moduleDir.exists()) {
try {
moduleDir.mkdirs()
val url = URL(packageUrl)
val con = url.openConnection()
val tarStream: InputStream = ByteArrayInputStream(con.getInputStream().readBytes())
extractGzipStream(tarStream, moduleDir)
moveFilesUp(moduleDir)
File("$moduleDir/package").deleteRecursively()
logger.trace("[glslify] $moduleName downloaded")
(con as HttpsURLConnection).disconnect()
} catch (ex: Exception) {
logger.error(ex) { "[glslify]: There was an error getting $moduleName" }
return ""
}
} else { } else {
logger.trace("[glslify] $moduleName already exists.. Skipping download") logger.trace("[glslify] $moduleName already exists.. Skipping download")
} }
val shaderFile: File val shaderFile: Path
try { try {
shaderFile = shaderExtensions.map { shaderFile = shaderExtensions.map {
File("$GLSLIFY_PATH/$moduleName/$shaderPath.$it") moduleDir.resolve("$shaderPath.$it")
}.first { it.exists() } }.first { Files.exists(it) }
} catch (ex: NoSuchElementException) { } catch (ex: NoSuchElementException) {
logger.trace("[glslify] $moduleName: $shaderPath doesn't lead to any shader file") logger.trace("[glslify] $moduleName: $shaderPath doesn't lead to any shader file")
return "" return ""
} }
val shader = mutableListOf<String>()
val imports = mutableListOf<GlslifyImport>() val imports = mutableListOf<GlslifyImport>()
var exportName: String? = null var exportName: String? = null
shaderFile.useLines { sequence -> var shader = Files.lines(shaderFile).filter { line ->
for (line in sequence.iterator()) { line.contains("#pragma").let { isPragma ->
if (line.contains("#pragma")) { if (isPragma) {
Regex(IMPORT_PATT).find(line)?.let { Regex(IMPORT_PATT).find(line)?.let {
if (it.groupValues.size > 1) { if (it.groupValues.size > 1) {
val importExists = File("$GLSLIFY_PATH/${it.groupValues[2]}").exists() val importPath = Paths.get(GLSLIFY_PATH).resolve(it.groupValues[2])
imports.add(GlslifyImport(it.groupValues[1], it.groupValues[2], importExists)) imports.add(GlslifyImport(it.groupValues[1], it.groupValues[2], Files.exists(importPath)))
} }
} }
@@ -89,11 +71,11 @@ fun glslify(module: String, renameFunctionTo: String? = null): String {
exportName = it.groupValues[1] exportName = it.groupValues[1]
} }
} }
} else {
shader.add(line)
} }
!isPragma // we want to exclude any #pragma statements
} }
} }.toList().joinToString("\n")
val missingImports = imports.filter { !it.exists } val missingImports = imports.filter { !it.exists }
@@ -105,11 +87,36 @@ fun glslify(module: String, renameFunctionTo: String? = null): String {
throw error("[glslify] Please declare the missing imports") throw error("[glslify] Please declare the missing imports")
} }
var shaderString = shader.joinToString("\n")
if (renameFunctionTo != null && exportName != null) { if (renameFunctionTo != null && exportName != null) {
shaderString = shaderString.replace( exportName!!, renameFunctionTo) shader = shader.replace( exportName!!, renameFunctionTo)
} }
return shaderString return shader
}
internal fun fetchModule(moduleName: String, moduleDir: Path) {
val packageUrl = getPackageUrl(moduleName)
if (packageUrl.isNullOrEmpty()) {
throw error("[glslify] $moduleName not found")
}
try {
Files.createDirectories(moduleDir)
val url = URL(packageUrl)
val con = url.openConnection()
val tarStream: InputStream = ByteArrayInputStream(con.getInputStream().readBytes())
extractGzipStream(tarStream, moduleDir.toFile())
moveFilesUp(moduleDir)
moduleDir.resolve("package").toFile().deleteRecursively()
logger.trace("[glslify] $moduleName downloaded")
(con as HttpsURLConnection).disconnect()
} catch (ex: Exception) {
logger.error(ex) { "[glslify]: There was an error getting $moduleName" }
}
} }