nim-wasm-test/src/lib/embeddedfs.nim

90 lines
2.3 KiB
Nim
Raw Normal View History

# vim: set et sta sw=4 ts=4 :
#
# This module exposes an "embeddedFs" object, that can
# return file handles for either native use (extracted on first run)
# or wasm (via preload-files).
import
std/os,
std/files,
std/paths,
std/strformat,
2025-08-22 11:47:04 -07:00
std/strutils,
std/tempfiles
2025-08-22 11:47:04 -07:00
import
constants
type
EmbeddedFS* = object
EmbeddedFSError* = object of CatchableError
when not defined( emscripten ):
import zippy/tarballs
const ROOT = Path( currentSourcePath() ).parentDir.parentDir.parentDir
const RESOURCES = staticRead( $(ROOT / Path("resources.tgz")) )
let appname = extractFilename( getAppFileName() )
let dataDir = Path(getDataDir()) / Path( appname )
let confDir = Path(getConfigDir()) / Path( appname )
let confFile* = confDir / Path("config.ini")
else:
let dataDir = Path( "resources" )
let confDir = Path( "resources" )
let confFile* = confDir / Path("config.ini")
2025-08-22 11:47:04 -07:00
proc path*( data: EmbeddedFS, path: string ): Path =
## Returns the path of an embedded file.
return dataDir / Path( path )
proc `[]`*( data: EmbeddedFS, path: string ): string =
## Returns the contents of an embedded file.
if not fileExists( data.path(path) ):
raise newException( EmbeddedFSError, "No such file: {path}".fmt )
let f = open( $data.path(path) )
defer: f.close
return f.readAll
2025-08-22 11:47:04 -07:00
proc newEmbeddedFS(): EmbeddedFS =
## Initialize the embedded filesystem.
##
## If the current runtime version is different than the binary version,
## re-extract the embedded filesystem to disk.
result = EmbeddedFS()
when defined( emscripten ): return
try:
var fsVersion = readFile( $result.path(".version") )
fsVersion.removeSuffix
if fsVersion == VERSION: return
except:
discard
echo "Extracting embedded resources for v{VERSION}".fmt
createDir( getDataDir() )
createDir( $confDir )
let ( tarball, path ) = createTempFile( "{appname}_resources_".fmt, ".tgz" )
tarball.write( RESOURCES )
tarball.close
2025-08-22 11:47:04 -07:00
removeDir( $dataDir )
extractAll( path, $dataDir )
removeFile( path )
2025-08-22 11:47:04 -07:00
let source = dataDir / Path( "config.ini" )
if not fileExists( confFile ): copyFile( $source, $confFile )
2025-08-22 11:47:04 -07:00
let embeddedFs* = newEmbeddedFS()