I need to modify fragment of code which needs to take argument instead of use hardcoded path in go:embed
My code:
package main
import (
"embed"
"log"
"github.com/golang-migrate/migrate/v4/source/iofs"
)
// Instead of use hardcoded `migrations/*.sql` I need to pass
// `path` to `migrations/*.sql` as a argument to `migrate` function
//go:embed migrations/*.sql
var fs embed.FS
func main() {
const path = "migrations/*.sql"
if err := migrate(path); err != nil {
log.Fatal(err)
}
log.Println("done")
}
func migrate(path string) error {
d, err := iofs.New(fs, "migrations")
if err != nil {
return err
}
// rest of the code...
return nil
}
I already tried to use os.DirFS
however result of this function only contains data with dir
parameter without actual files from folder migrations/*.sql
CodePudding user response:
I'm not entirely sure I understand the question. You've created an embedded filesystem that contains multiple files (everything matching *.sql
in the migrations
directory). You can load files from this embedded filesystem by name.
Let's assume that your migrations
directory looks like:
migrations/
├── bar.sql
└── foo.sql
Where foo.sql
contains this is foo.sql
, and similarly for bar.sql
.
If we write code like this:
func main() {
const path = "migrations/foo.sql"
if err := migrate(path); err != nil {
log.Fatal(err)
}
log.Println("done")
}
func migrate(path string) error {
data, err := fs.ReadFile(path)
if err != nil {
panic(err)
}
fmt.Println(string(data))
// rest of the code...
return nil
}
You'd get the output:
this is foo.sql
If you want to iterate over files in your embedded filesystem, you can use the ReadDir
method:
func main() {
const path = "migrations"
if err := migrate(path); err != nil {
log.Fatal(err)
}
log.Println("done")
}
func migrate(path string) error {
items, err := fs.ReadDir(path)
if err != nil {
panic(err)
}
for _, ent := range items {
fmt.Println(ent.Name())
}
// rest of the code...
return nil
}
This would print:
bar.sql
foo.sql
Does that help?