Compare commits
1 Commits
master
..
954d71cb3f
| Author | SHA1 | Date | |
|---|---|---|---|
| 954d71cb3f |
@@ -9,12 +9,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup V
|
- name: Setup V
|
||||||
run: |
|
run: |
|
||||||
git clone --depth=1 https://github.com/vlang/v /tmp/v && cd /tmp/v && make
|
wget -qO /tmp/v.zip https://github.com/vlang/v/releases/latest/download/v_linux.zip
|
||||||
/tmp/v/v symlink
|
unzip -q /tmp/v.zip -d /tmp
|
||||||
|
echo /tmp/v >> "$GITHUB_PATH"
|
||||||
|
|
||||||
- name: Build docs
|
- name: Build docs
|
||||||
run: |
|
run: |
|
||||||
@@ -39,7 +40,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
id: deployment
|
id: deployment
|
||||||
uses: actions/deploy-pages@v5
|
uses: actions/deploy-pages@v4
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup V
|
- name: Setup V
|
||||||
run: |
|
run: |
|
||||||
git clone --depth=1 https://github.com/vlang/v /tmp/v && cd /tmp/v && make
|
wget -qO /tmp/v.zip https://github.com/vlang/v/releases/latest/download/v_linux.zip
|
||||||
/tmp/v/v symlink
|
unzip -q /tmp/v.zip -d /tmp
|
||||||
|
echo /tmp/v >> "$GITHUB_PATH"
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
SRC_DIR ?= src
|
||||||
|
DOC_DIR ?= doc
|
||||||
|
TESTS_DIR ?= .
|
||||||
|
|
||||||
|
all: test
|
||||||
|
|
||||||
|
test:
|
||||||
|
v test $(TESTS_DIR)
|
||||||
|
|
||||||
|
doc:
|
||||||
|
v doc -f html -m ./$(SRC_DIR) -o $(DOC_DIR)
|
||||||
|
|
||||||
|
serve: clean doc
|
||||||
|
v -e "import net.http.file; file.serve(folder: '$(DOC_DIR)')"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -r $(DOC_DIR) || true
|
||||||
|
|
||||||
|
cli:
|
||||||
|
v cmd/mkembedfs -o mkembedfs
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
# Embedding Directories into Executables
|
## Code generator for embedding directories with files into executables
|
||||||
|
|
||||||
The `$embed_file()` call in V embeds only a single file. This module makes it
|
The `$embed_file` statement in V embeds only a single file. This module makes
|
||||||
easy to embed entire directories into the final executable.
|
it easy to embed entire directories into the final executable.
|
||||||
|
|
||||||
File embedding in V is done at compile time, and there is no way to dynamically
|
File embedding in V is done at compile time, and unfortunately there is no way
|
||||||
embed arbitrary files into an application. The `embedfs` module is a simple
|
to dynamically embed arbitrary files into an application. The `embedfs` module
|
||||||
code generator that creates a separate `.v` file with the code for embedding
|
is a simple code generator that creates a separate `.v` file with the code for
|
||||||
files.
|
embedding files. That is, the embedfs call must be made before the code is
|
||||||
|
compiled. So embedfs is a build dependency.
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
```
|
||||||
v install https://github.com/gechandesu/embedfs
|
v install --git https://github.com/gechandesu/embedfs
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -19,30 +18,28 @@ v install https://github.com/gechandesu/embedfs
|
|||||||
For example you have following file structure:
|
For example you have following file structure:
|
||||||
|
|
||||||
```
|
```
|
||||||
./
|
v.mod
|
||||||
├── src/
|
src/
|
||||||
│ ├── assets/
|
main.v
|
||||||
│ │ ├── css/
|
assets/
|
||||||
│ │ │ └── style.css
|
css/style.css
|
||||||
│ │ └── js/
|
js/app.js
|
||||||
│ │ └── app.js
|
|
||||||
│ └── main.v
|
|
||||||
└── v.mod
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Lets embed the `assets` directory.
|
Lets embed the `assets` directory.
|
||||||
|
|
||||||
Create `embed_assets.vsh` next to v.mod:
|
Create `embed_assets.vsh` next to your v.mod:
|
||||||
|
|
||||||
```v
|
```v
|
||||||
#!/usr/bin/env v
|
#!/usr/bin/env -S v
|
||||||
|
|
||||||
import os
|
|
||||||
import embedfs
|
import embedfs
|
||||||
|
|
||||||
os.chdir('src')!
|
chdir('src')!
|
||||||
assets := embedfs.generate('assets')!
|
assets := embedfs.CodeGenerator{
|
||||||
os.write_file('assets_generated.v', assets)!
|
path: 'assets'
|
||||||
|
}
|
||||||
|
write_file('assets_generated.v', assets.generate())!
|
||||||
```
|
```
|
||||||
|
|
||||||
Run it:
|
Run it:
|
||||||
@@ -51,40 +48,46 @@ Run it:
|
|||||||
v run embed_assets.vsh
|
v run embed_assets.vsh
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you have `src/assets_generated.v`. Take a look inside it:
|
Now you have `src/assets_generated.v`. Take a look inside it. So you can use
|
||||||
|
`embedfs` const in `src/main.v` in this way:
|
||||||
```v
|
|
||||||
module main
|
|
||||||
|
|
||||||
const embed_files = {
|
|
||||||
'assets/css/style.css': $embed_file('assets/css/style.css')
|
|
||||||
'assets/js/app.js': $embed_file('assets/js/app.js')
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can use it in `src/main.v` in this way:
|
|
||||||
|
|
||||||
```v
|
```v
|
||||||
module main
|
module main
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
style := unsafe { embed_files['assets/css/style.css'].to_string() }
|
style := embedfs.files['assets/css/style.css']!
|
||||||
println(style)
|
// If `bare_map` parameter is set to `true` use:
|
||||||
|
// style := embedfs['assets/css/style.css']!
|
||||||
|
println(style.data.to_string())
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The map type is `map[string]embed_file.EmbedFileData`, see the
|
The generated `embedfs` const value example (from `tests/`):
|
||||||
[v.embed_file](https://modules.vlang.io/v.embed_file.html#EmbedFileData)
|
|
||||||
module docs for details.
|
|
||||||
|
|
||||||
## `bin2v` tool
|
```v okfmt
|
||||||
|
EmbedFileSystem{
|
||||||
Also there is `v bin2v` utility that generates the V modules with embedded
|
files: {'assets/example.json': EmbedFile{
|
||||||
files. See:
|
data: embed_file.EmbedFileData{ len: 22, path: "assets/example.json", apath: "", uncompressed: 846284 }
|
||||||
|
meta: EmbedFileMetadata{
|
||||||
```
|
key: 'assets/example.json'
|
||||||
v help bin2v
|
name: 'example.json'
|
||||||
|
ext: 'json'
|
||||||
|
mimetype: 'application/json'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In contrast with embedfs, bin2v generates constants into which it writes
|
The generated const value if `bare_map` parameter is `true`:
|
||||||
files as fixed-length byte arrays.
|
|
||||||
|
```v okfmt
|
||||||
|
{'assets/example.json': EmbedFile{
|
||||||
|
data: embed_file.EmbedFileData{ len: 22, path: "assets/example.json", apath: "", uncompressed: 845da4 }
|
||||||
|
meta: EmbedFileMetadata{
|
||||||
|
key: 'assets/example.json'
|
||||||
|
name: 'example.json'
|
||||||
|
ext: 'json'
|
||||||
|
mimetype: 'application/json'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
```
|
||||||
|
|||||||
+8
-10
@@ -1,13 +1,11 @@
|
|||||||
mkembedfs - generate V code to embed directories into executables.
|
mkembedfs - generate V code for embed directories with files into executable.
|
||||||
usage: mkembedfs [flags] [<path>]
|
usage: mkembedfs [flags] [<path>]
|
||||||
flags:
|
flags:
|
||||||
-help print this help message and exit.
|
-help print this help message and exit
|
||||||
-chdir <string> change working directory before codegen.
|
-chdir <string> change working directory before codegen
|
||||||
|
-prefix <string> path prefix for file keys, none by default
|
||||||
-ignore <string> path globs to ignore (allowed multiple times)
|
-ignore <string> path globs to ignore (allowed multiple times)
|
||||||
-prefix <string> path prefix for file keys, none by default.
|
-module-name <string> generated module name, 'main' by default
|
||||||
-path-prefix <string> path prefix for files in $embed_file() calls.
|
-const-name <string> generated constant name with data, 'embedfs' by default
|
||||||
-compression apply zlib compression to $embed_file().
|
-no-pub do not make symbols in generated module public
|
||||||
-module-name <string> generated module name, 'main' by default.
|
-force-mimetype set 'application/octet-stream' mime type for unknown files
|
||||||
-const-name <string> generated const name, 'embed_files' by default.
|
|
||||||
-no-pub do not make symbols in generated module public.
|
|
||||||
-notice <string> notice comment text, set empty to disable.
|
|
||||||
|
|||||||
+21
-28
@@ -5,9 +5,9 @@ import flag
|
|||||||
import embedfs
|
import embedfs
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
mut path := '.'
|
mut path := os.getwd()
|
||||||
mut flags, no_matches := flag.to_struct[FlagConfig](os.args, skip: 1, style: .go_flag) or {
|
mut flags, no_matches := flag.to_struct[FlagConfig](os.args, skip: 1, style: .v) or {
|
||||||
println('cmdline parsing error, see -help for info')
|
eprintln('cmdline parsing error, see -help for info')
|
||||||
exit(2)
|
exit(2)
|
||||||
}
|
}
|
||||||
if no_matches.len > 1 {
|
if no_matches.len > 1 {
|
||||||
@@ -26,32 +26,25 @@ fn main() {
|
|||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dump(flags)
|
generator := embedfs.CodeGenerator{
|
||||||
dump(path)
|
path: path
|
||||||
code := embedfs.generate(path,
|
prefix: flags.prefix
|
||||||
key_path_prefix: flags.prefix
|
ignore_patterns: flags.ignore
|
||||||
file_path_prefix: flags.path_prefix
|
module_name: flags.module_name
|
||||||
ignore: flags.ignore
|
const_name: flags.const_name
|
||||||
module_name: flags.module_name
|
make_pub: if flags.no_pub { false } else { true }
|
||||||
const_name: flags.const_name
|
force_mimetype: flags.force_mimetype
|
||||||
const_public: !flags.no_pub
|
}
|
||||||
notice: flags.notice
|
println(generator.generate())
|
||||||
compression: flags.compression
|
|
||||||
)!
|
|
||||||
print(code)
|
|
||||||
flush_stdout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FlagConfig {
|
struct FlagConfig {
|
||||||
mut:
|
help bool
|
||||||
help bool
|
chdir string
|
||||||
chdir string
|
prefix string
|
||||||
ignore []string
|
ignore []string
|
||||||
prefix string
|
module_name string = 'main'
|
||||||
path_prefix string
|
const_name string = 'embedfs'
|
||||||
module_name string = 'main'
|
no_pub bool
|
||||||
const_name string = 'embed_files'
|
force_mimetype bool
|
||||||
no_pub bool
|
|
||||||
notice string = 'This file is generated by embedfs module, DO NOT EDIT!'
|
|
||||||
compression bool
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
module ${module_name}
|
|
||||||
|
|
||||||
@if !skip_notice
|
|
||||||
/*
|
|
||||||
${notice}
|
|
||||||
*/
|
|
||||||
|
|
||||||
@endif
|
|
||||||
@if const_public
|
|
||||||
pub const ${const_name} = {
|
|
||||||
@else
|
|
||||||
const ${const_name} = {
|
|
||||||
@endif
|
|
||||||
@for key, value in files
|
|
||||||
@if compression
|
|
||||||
'${key}': $embed_file('${value}', .zlib)
|
|
||||||
@else
|
|
||||||
'${key}': $embed_file('${value}')
|
|
||||||
@endif
|
|
||||||
@endfor
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
module embedfs
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
@[params]
|
|
||||||
pub struct EmbedFsParams {
|
|
||||||
pub:
|
|
||||||
module_name string = 'main' // name of the generated V module.
|
|
||||||
const_name string = 'embed_files' // name of the constant that will store the embedded data.
|
|
||||||
const_public bool // if true make the const public.
|
|
||||||
key_path_prefix string // path prefix for all embedded files, will be added to data map key.
|
|
||||||
file_path_prefix string // path prefix for files used in $embed_file() call in generated file.
|
|
||||||
compression bool // add zlib compression flag to $embed_file() call in generated file.
|
|
||||||
notice string = 'This file is generated by embedfs module, DO NOT EDIT!'
|
|
||||||
}
|
|
||||||
|
|
||||||
@[params]
|
|
||||||
pub struct GenerateParams {
|
|
||||||
EmbedFsParams
|
|
||||||
pub:
|
|
||||||
ignore []string // glob expressions for files that should not be embedded.
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate generates the V code that embeds the contents of directory `dir`.
|
|
||||||
pub fn generate(dir string, params GenerateParams) !string {
|
|
||||||
files := collect_files(dir, params.ignore)
|
|
||||||
return generate_with(files, params.EmbedFsParams)!
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate_with generates the V code that embeds the files listed in `paths`.
|
|
||||||
pub fn generate_with(paths []string, params EmbedFsParams) !string {
|
|
||||||
module_name := params.module_name
|
|
||||||
const_name := params.const_name
|
|
||||||
const_public := params.const_public
|
|
||||||
compression := params.compression
|
|
||||||
notice := params.notice
|
|
||||||
skip_notice := params.notice == ''
|
|
||||||
mut files := map[string]string{}
|
|
||||||
for file in paths {
|
|
||||||
file_path := if params.file_path_prefix == '' {
|
|
||||||
file
|
|
||||||
} else {
|
|
||||||
os.join_path_single(params.file_path_prefix, file)
|
|
||||||
}
|
|
||||||
files[os.join_path_single(params.key_path_prefix, file)] = file_path
|
|
||||||
}
|
|
||||||
result := $tmpl('embedfs.template')
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collect_files(path string, ignore []string) []string {
|
|
||||||
mut file_list := &[]string{}
|
|
||||||
os.walk(path, fn [mut file_list, ignore] (file string) {
|
|
||||||
for globexpr in ignore {
|
|
||||||
if file.match_glob(globexpr) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_list << file
|
|
||||||
})
|
|
||||||
return *file_list
|
|
||||||
}
|
|
||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
module embedfs
|
||||||
|
|
||||||
|
import os
|
||||||
|
import strings
|
||||||
|
import net.http.mime
|
||||||
|
|
||||||
|
pub struct CodeGenerator {
|
||||||
|
pub:
|
||||||
|
// Path to file or directory to embed
|
||||||
|
path string @[required]
|
||||||
|
// Path prefix if you want to add extra prefix for file paths
|
||||||
|
prefix string
|
||||||
|
// Glob patterns to match files the must be ignored when generating the code
|
||||||
|
ignore_patterns []string
|
||||||
|
// If true set the default MIME-type for files if no MIME-type detected
|
||||||
|
force_mimetype bool
|
||||||
|
// Default MIME-type for files. See https://www.iana.org/assignments/media-types/media-types.xhtml
|
||||||
|
default_mimetype string = 'application/octet-stream'
|
||||||
|
// Name of generated module
|
||||||
|
module_name string = 'main'
|
||||||
|
// Name of constant which will contain embedded files
|
||||||
|
const_name string = 'embedfs'
|
||||||
|
// If true make constant public
|
||||||
|
make_const_pub bool
|
||||||
|
// If true make all symbols in generated module public
|
||||||
|
make_pub bool
|
||||||
|
// Generate map[string]EmbedFile instead of EmbedFileSystem instance
|
||||||
|
bare_map bool
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EmbedFileSpec {
|
||||||
|
key string
|
||||||
|
path string
|
||||||
|
name string
|
||||||
|
ext string
|
||||||
|
mimetype string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (g CodeGenerator) generate() string {
|
||||||
|
visible := if g.make_pub == true { 'pub ' } else { '' }
|
||||||
|
const_visible := if g.make_pub == true || g.make_const_pub == true { 'pub ' } else { '' }
|
||||||
|
mut b := strings.new_builder(1024 * 4)
|
||||||
|
b.writeln('// !WARNING! This file is generated by embedfs module, do not edit it.')
|
||||||
|
b.writeln('')
|
||||||
|
b.writeln('module ${g.module_name}')
|
||||||
|
b.writeln('')
|
||||||
|
b.writeln('import v.embed_file { EmbedFileData }')
|
||||||
|
b.writeln('')
|
||||||
|
b.writeln('${visible}struct EmbedFileMetadata {')
|
||||||
|
b.writeln('\tkey string')
|
||||||
|
b.writeln('\tname string')
|
||||||
|
b.writeln('\text string')
|
||||||
|
b.writeln('\tmimetype string')
|
||||||
|
b.writeln('}')
|
||||||
|
b.writeln('')
|
||||||
|
b.writeln('${visible}struct EmbedFile {')
|
||||||
|
b.writeln('\tdata EmbedFileData')
|
||||||
|
b.writeln('\tmeta EmbedFileMetadata')
|
||||||
|
b.writeln('}')
|
||||||
|
b.writeln('')
|
||||||
|
b.writeln('${visible}struct EmbedFileSystem {')
|
||||||
|
b.writeln('\tfiles map[string]EmbedFile')
|
||||||
|
b.writeln('}')
|
||||||
|
b.writeln('')
|
||||||
|
if g.bare_map {
|
||||||
|
b.writeln('${const_visible}const ${g.const_name} = {')
|
||||||
|
g.write_embed_file_map_item(mut b)
|
||||||
|
b.writeln('}')
|
||||||
|
} else {
|
||||||
|
b.writeln('${const_visible}const ${g.const_name} = EmbedFileSystem{')
|
||||||
|
b.writeln('\tfiles: {')
|
||||||
|
g.write_embed_file_map_item(mut b)
|
||||||
|
b.writeln('\t}')
|
||||||
|
b.writeln('}')
|
||||||
|
}
|
||||||
|
return b.str()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (g CodeGenerator) get_files() []EmbedFileSpec {
|
||||||
|
mut file_list := &[]string{}
|
||||||
|
os.walk(g.path, fn [mut file_list] (file string) {
|
||||||
|
file_list << file
|
||||||
|
})
|
||||||
|
mut files := []EmbedFileSpec{}
|
||||||
|
outer: for file in file_list {
|
||||||
|
for glob in g.ignore_patterns {
|
||||||
|
if file.match_glob(glob) {
|
||||||
|
continue outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_key := os.join_path_single(g.prefix, file)
|
||||||
|
file_path := file // the actual path used in $embed_file() statement
|
||||||
|
file_name := os.file_name(file_path)
|
||||||
|
file_ext := os.file_ext(file_name).replace_once('.', '')
|
||||||
|
mut mimetype := mime.get_mime_type(file_ext)
|
||||||
|
if g.force_mimetype && mimetype == '' {
|
||||||
|
mimetype = g.default_mimetype
|
||||||
|
}
|
||||||
|
files << EmbedFileSpec{
|
||||||
|
key: file_key
|
||||||
|
path: file_path
|
||||||
|
name: file_name
|
||||||
|
ext: file_ext
|
||||||
|
mimetype: mimetype
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (g CodeGenerator) write_embed_file_map_item(mut b strings.Builder) {
|
||||||
|
for filespec in g.get_files() {
|
||||||
|
b.writeln("\t\t'${filespec.key}': EmbedFile{")
|
||||||
|
b.writeln("\t\t\tdata: \$embed_file('${filespec.path}')")
|
||||||
|
b.writeln('\t\t\tmeta: EmbedFileMetadata{')
|
||||||
|
b.writeln("\t\t\t\tkey: '${filespec.key}'")
|
||||||
|
b.writeln("\t\t\t\tname: '${filespec.name}'")
|
||||||
|
b.writeln("\t\t\t\text: '${filespec.ext}'")
|
||||||
|
b.writeln("\t\t\t\tmimetype: '${filespec.mimetype}'")
|
||||||
|
b.writeln('\t\t\t}')
|
||||||
|
b.writeln('\t\t},')
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import embedfs
|
|
||||||
|
|
||||||
fn test_generate() {
|
|
||||||
expected := r"module main
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is generated by embedfs module, DO NOT EDIT!
|
|
||||||
*/
|
|
||||||
|
|
||||||
const embed_files = {
|
|
||||||
'cmd/mkembedfs/mkembedfs.v': $embed_file('cmd/mkembedfs/mkembedfs.v')
|
|
||||||
}
|
|
||||||
"
|
|
||||||
data := embedfs.generate('cmd', ignore: ['*.txt'])!
|
|
||||||
assert data == expected
|
|
||||||
}
|
|
||||||
+8
-2
@@ -1,6 +1,12 @@
|
|||||||
module main
|
module main
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
json_file := unsafe { embed_files['assets/example.json'] }
|
println(embedfs)
|
||||||
println(json_file.to_string().trim_space())
|
$if bare_map ? {
|
||||||
|
json_file := embedfs['assets/example.json'] or { EmbedFile{} }
|
||||||
|
println(json_file.data.to_string().trim_space())
|
||||||
|
} $else {
|
||||||
|
json_file := embedfs.files['assets/example.json'] or { EmbedFile{} }
|
||||||
|
println(json_file.data.to_string().trim_space())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
EmbedFileSystem{
|
||||||
|
files: {'assets/example.json': EmbedFile{
|
||||||
|
data: embed_file.EmbedFileData{ len: 22, path: "assets/example.json", apath: "", uncompressed: 846284 }
|
||||||
|
meta: EmbedFileMetadata{
|
||||||
|
key: 'assets/example.json'
|
||||||
|
name: 'example.json'
|
||||||
|
ext: 'json'
|
||||||
|
mimetype: 'application/json'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
{"some": "JSON data"}
|
||||||
+23
-4
@@ -1,15 +1,34 @@
|
|||||||
module main
|
module main
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import v.util.diff
|
||||||
import embedfs
|
import embedfs
|
||||||
|
|
||||||
fn test_mymod() {
|
fn test_mymod() {
|
||||||
oldpwd := os.getwd()
|
oldpwd := os.getwd()
|
||||||
expected := '{"some": "JSON data"}\n'
|
expected_out := os.read_file('tests/mymod_test.out')!
|
||||||
os.chdir('tests/mymod')!
|
os.chdir('tests/mymod')!
|
||||||
gen := embedfs.generate('assets')!
|
gen := embedfs.CodeGenerator{
|
||||||
os.write_file('assets_generated.v', gen)!
|
path: 'assets'
|
||||||
|
}
|
||||||
|
os.write_file('assets_generated.v', gen.generate())!
|
||||||
ret := os.execute('${os.quoted_path(@VEXE)} run .')
|
ret := os.execute('${os.quoted_path(@VEXE)} run .')
|
||||||
assert ret.output == expected
|
dump(diff.compare_text(ret.output, expected_out)!)
|
||||||
|
assert ret.output == expected_out
|
||||||
|
os.chdir(oldpwd)!
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_mymod_bare_map() {
|
||||||
|
oldpwd := os.getwd()
|
||||||
|
expected_out := os.read_file('tests/mymod_test_bare_map.out')!
|
||||||
|
os.chdir('tests/mymod')!
|
||||||
|
gen := embedfs.CodeGenerator{
|
||||||
|
path: 'assets'
|
||||||
|
bare_map: true
|
||||||
|
}
|
||||||
|
os.write_file('assets_generated.v', gen.generate())!
|
||||||
|
ret := os.execute('${os.quoted_path(@VEXE)} -d bare_map run .')
|
||||||
|
dump(diff.compare_text(ret.output, expected_out)!)
|
||||||
|
assert ret.output == expected_out
|
||||||
os.chdir(oldpwd)!
|
os.chdir(oldpwd)!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{'assets/example.json': EmbedFile{
|
||||||
|
data: embed_file.EmbedFileData{ len: 22, path: "assets/example.json", apath: "", uncompressed: 845da4 }
|
||||||
|
meta: EmbedFileMetadata{
|
||||||
|
key: 'assets/example.json'
|
||||||
|
name: 'example.json'
|
||||||
|
ext: 'json'
|
||||||
|
mimetype: 'application/json'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{"some": "JSON data"}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
Module {
|
Module {
|
||||||
name: 'embedfs'
|
name: 'embedfs'
|
||||||
description: 'Embed directories into executables'
|
description: 'Code generator for embedding directories with files into executables'
|
||||||
version: '1.0.0'
|
version: '0.0.2'
|
||||||
license: 'Unlicense'
|
license: 'Unlicense'
|
||||||
dependencies: []
|
dependencies: []
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user