DEV Community

Juan C. Muller
Juan C. Muller

Posted on

Quick and dirty copy embed.FS to another directory

// CopyDir copies the contents of an embedded FS in your binary
// to some directory on disk.
// f is the //go:embed attribute
// origin is the name of the directory in the embed call
// target is the target directory to write into
func CopyDir(f embed.FS, origin, target string) error {
    if _, err := os.Stat(target); os.IsNotExist(err) {
        if err := os.MkdirAll(target, os.ModePerm); err != nil {
            err = fmt.Errorf("error creating directory: %v", err)
            return err
        }
    }

    files, err := f.ReadDir(origin)
    if err != nil {
        err = fmt.Errorf("error reading directory: %v", err)
        return err
    }

    for _, file := range files {
        sourceFileName := filepath.Join(origin, file.Name())
        destFileName := filepath.Join(target, file.Name())

        if file.IsDir() {
            if err := copyDir(f, sourceFileName, destFileName); err != nil {
                err = fmt.Errorf("error copying subdirectory: %v", err)
                return err
            }
            continue
        }

        fileContent, err := f.ReadFile(sourceFileName)
        if err != nil {
            err = fmt.Errorf("error reading file: %v", err)
            return err
        }

        if err := os.WriteFile(destFileName, fileContent, 0644); err != nil { // nolint: gosec
            log.Printf("error os.WriteFile error: %v", err)
            err = fmt.Errorf("error writing file: %w", err)
            return err
        }
    }

    return nil
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)