package main import ( "fmt" "os" "path/filepath" "text/template" ) func apply(conf *Conf, args []string) error { if len(args) != 0 { return applyFiles(conf, args) } names, err := getFileNames(conf) if err != nil { return err } return applyFiles(conf, names) } func applyFiles(conf *Conf, names []string) error { for _, name := range names { fmt.Printf("applying %s\n", name) if err := applyFile(conf, name); err != nil { return fmt.Errorf("could not apply %s: %v", name, err) } } return nil } func applyFile(conf *Conf, name string) error { src := filepath.Join(conf.Source, "templates", name) t, err := template.New(filepath.Base(name)).Funcs(buildFuncMap()).ParseFiles(src) if err != nil { return fmt.Errorf("could not build template: %v", err) } data, err := getTemplateData(conf) if err != nil { return err } dest := filepath.Join(conf.Dest, name) if err = os.MkdirAll(filepath.Dir(dest), 0700); err != nil { return err } srcInfo, err := os.Stat(src) if err != nil { return err } out, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, srcInfo.Mode()) if err != nil { return err } defer out.Close() if err = t.Execute(out, data); err != nil { return fmt.Errorf("could not execute template: %v", err) } return nil } func getFileNames(c *Conf) ([]string, error) { var names []string dir := filepath.Join(c.Source, "templates") err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { return nil } name, err := filepath.Rel(dir, path) if err != nil { return err } names = append(names, name) return nil }) if err != nil { return nil, err } return names, nil }