171 lines
3.0 KiB
Go
171 lines
3.0 KiB
Go
package template
|
|
|
|
import (
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"text/template"
|
|
|
|
"gitlab.com/wpetit/scaffold/internal/fs"
|
|
"gopkg.in/src-d/go-billy.v4"
|
|
|
|
"github.com/Masterminds/sprig"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func CopyDir(vfs billy.Filesystem, baseDir string, dst string, opts *Option) error {
|
|
if opts == nil {
|
|
opts = &Option{}
|
|
}
|
|
|
|
baseDir = filepath.Clean(baseDir)
|
|
dst = filepath.Clean(dst)
|
|
|
|
_, err := os.Stat(dst)
|
|
if err != nil && !os.IsNotExist(err) {
|
|
return err
|
|
}
|
|
|
|
if err := os.MkdirAll(dst, 0755); err != nil {
|
|
return errors.Wrapf(err, "could not create directory '%s'", dst)
|
|
}
|
|
|
|
err = fs.Walk(vfs, baseDir, func(srcPath string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if srcPath == baseDir {
|
|
return nil
|
|
}
|
|
|
|
for _, p := range opts.IgnorePatterns {
|
|
match, err := filepath.Match(p, srcPath)
|
|
if err != nil {
|
|
return errors.Wrap(err, "could not match ignored file")
|
|
}
|
|
if match {
|
|
log.Printf("Ignoring %s.", srcPath)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
relSrcPath, err := filepath.Rel(baseDir, srcPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dstPath := filepath.Join(dst, relSrcPath)
|
|
|
|
log.Printf("relSrcPath: %s, dstPath: %s", relSrcPath, dstPath)
|
|
|
|
if info.IsDir() {
|
|
log.Printf("creating dir '%s'", dstPath)
|
|
if err := os.MkdirAll(dstPath, 0755); err != nil {
|
|
return errors.Wrapf(err, "could not create directory '%s'", dstPath)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
err = CopyFile(vfs, srcPath, dstPath, opts)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "could not copy file '%s'", srcPath)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return errors.Wrapf(err, "could not walk source directory '%s'", baseDir)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func CopyFile(vfs billy.Filesystem, src, dst string, opts *Option) (err error) {
|
|
if opts == nil {
|
|
opts = &Option{}
|
|
}
|
|
|
|
if !strings.HasSuffix(src, opts.TemplateExt) {
|
|
return copyFile(vfs, src, dst)
|
|
}
|
|
|
|
in, err := vfs.Open(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer in.Close()
|
|
|
|
templateData, err := ioutil.ReadAll(in)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tmpl, err := template.New(filepath.Base(src)).Funcs(sprig.TxtFuncMap()).Parse(string(templateData))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dst = strings.TrimSuffix(dst, opts.TemplateExt)
|
|
|
|
log.Printf("templating file from '%s' to '%s'", src, dst)
|
|
|
|
out, err := os.Create(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
if e := out.Close(); e != nil {
|
|
err = e
|
|
}
|
|
}()
|
|
|
|
opts.TemplateData["SourceFile"] = src
|
|
opts.TemplateData["DestFile"] = dst
|
|
|
|
if err := tmpl.Execute(out, opts.TemplateData); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func copyFile(vfs billy.Filesystem, src, dst string) (err error) {
|
|
log.Printf("copying file '%s' to '%s'", src, dst)
|
|
|
|
in, err := vfs.Open(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer in.Close()
|
|
|
|
out, err := os.Create(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
if e := out.Close(); e != nil {
|
|
err = e
|
|
}
|
|
}()
|
|
|
|
_, err = io.Copy(out, in)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = out.Sync()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|