Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rudifa/goembed-demo
Embedding files in a go app
https://github.com/rudifa/goembed-demo
Last synced: 24 days ago
JSON representation
Embedding files in a go app
- Host: GitHub
- URL: https://github.com/rudifa/goembed-demo
- Owner: rudifa
- Created: 2023-06-18T21:28:32.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-06-19T15:07:47.000Z (over 1 year ago)
- Last Synced: 2024-10-06T01:41:29.298Z (about 1 month ago)
- Language: Go
- Size: 4.88 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Embedding files in the app
[How to Use go:embed in Go](https://blog.jetbrains.com/go/2021/06/09/how-to-use-go-embed-in-go-1-16/)
[embed](https://pkg.go.dev/embed) docs
[fs](https://pkg.go.dev/io/fs@master)
[example](https://www.reddit.com/r/golang/comments/kiuvbq/is_there_any_way_to_walk_an_embedfs_using_the/)
[fs walk](https://bitfieldconsulting.com/golang/filesystems)
## Discussions
[//go:embed \ doesn't work #46056](https://github.com/golang/go/issues/46056)
_The best practice here is to create a package in parent level with go:embed var in there; then reference to this var in the child level packages._
## `embed` lessons learned
```
// embedded.go//go:embed dir1
//go:embed dir2
var Dir12 embed.FS//go:embed dir3
var Dir3 embed.FS//go:embed A/B/C
var ABC embed.FS
```Above will embed the `dir1` and `dir2` in the `Dir12` variable, `dir3`in `Dir3` and `A/B/C` in `ABC`.
Note: dirs are relative to the directory where the file doing the embedding is found. It is not possible to embed dirs or files from the parent directiories (patterns starting with `.` or `..` are not allowed.
In the demo project `goembed-demo`, these dirs are, along with the file `embedded.go`, in the dir `pkg/embedded`.
```
goembed-demo % tree [main L|✚1…2]
.
├── pkg
│ └── embedded
│ ├── A
│ │ └── B
│ │ └── C
│ │ └── abra.txt
│ ├── dir1
│ │ ├── hello.txt
│ │ └── hello2.txt
│ ├── dir2
│ │ └── hello2.txt
│ ├── dir3
│ │ └── hello3.txt
│ └── embedded.go
├── README.md
├── go.mod
└── main.go
```In `main.go` we import the package `embedded`...
```
package mainimport (
"fmt"
"io/fs"
"log""github.com/rudifa/goembed-demo/pkg/embedded"
)func main() {
...
fmt.Println("Walk the embedded directory Dir12")
walkDir(embedded.Dir12)fmt.Println("Walk the embedded directory Dir3")
walkDir(embedded.Dir3)fmt.Println("Walk the embedded directory ABC")
walkDir(embedded.ABC)
...
}```
Above `walkDir` calls produce this:
```
Walk the embedded directory Dir12
. d
dir1 d
dir1/hello.txt
dir1/hello2.txt
dir2 d
dir2/hello2.txt
Walk the embedded directory Dir3
. d
dir3 d
dir3/hello3.txt
Walk the embedded directory ABC
. d
A d
A/B d
A/B/C d
A/B/C/abra.txt
```... with
```
// walkDir walks the file system, possibly embedded and prints the file names
func walkDir(fileSystem fs.FS) {
fs.WalkDir(fileSystem, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
log.Fatal(err)
}
isDir := ""
if d.IsDir() {
isDir = " d"
}
fmt.Println(path + isDir)
return nil
})
}```
Finally, we can read the contents of a file
```
// read the contents of the file dir3/file3.txtfile3, err := embedded.Dir3.ReadFile("dir3/hello3.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println("Contents of dir3/file3.txt:")
fmt.Println(string(file3))// read the contents of the file A/B/C/abra.txt
fileAbra, err := embedded.ABC.ReadFile("A/B/C/abra.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println("Contents of fileAbra:\n" + string(fileAbra))
```which yields
```
Contents of dir3/file3.txt:
hello3Contents of file A/B/C/abra.txt:
Ô flots abracadabrantesques
Prenez mon cœur, qu'il soit sauvé.
Ithyphalliques et pioupiesques
Leurs insultes l'ont dépravé !
A.Rimbaud
```