package sync import ( "bufio" "fmt" "io/ioutil" "os" "path" ) // LocalImporter implements an Importer, where files to imports are located // inside a local directory from your filesystem. type LocalImporter struct { // Base is the root directory used by the LocalImporter. It should contains all themes. Base string // Symlink changes the normal file copy/concatenate behaviour to symlink/concatenate. // If enable, your base directory must be accessible by the frontend processus as it will follow the symlink. Symlink bool } func (i LocalImporter) Kind() string { if i.Symlink { return "local file importer (through symlink): " + i.Base } else { return "local file importer: " + i.Base } } func (i LocalImporter) Id() *string { return nil } func (i LocalImporter) Init() error { if f, err := os.Stat(i.Base); os.IsNotExist(err) { if err = os.Mkdir(i.Base, 0751); err != nil { return err } } else if err != nil { return err } else if !f.IsDir() { return fmt.Errorf("%q exists and is not a directory", i.Base) } return nil } func (i LocalImporter) Sync() error { return nil } func (i LocalImporter) exists(filename string) bool { _, err := os.Stat(i.toURL(filename)) return !os.IsNotExist(err) } func (i LocalImporter) toURL(filename string) string { return path.Join(i.Base, filename) } func (i LocalImporter) importFile(URI string, next func(string, string) (interface{}, error)) (interface{}, error) { if i.Symlink { dest := getDestinationFilePath(URI) if err := os.MkdirAll(path.Dir(dest), 0755); err != nil { return nil, err } if i.exists(URI) { os.Symlink(i.toURL(URI), dest) return next(dest, URI) } else { os.Symlink(i.toURL(URI)+"_MERGED", dest) return ImportFile(i, URI, next) } } else { return ImportFile(i, URI, next) } } func (i LocalImporter) getFile(filename string, writer *bufio.Writer) error { if fd, err := os.Open(path.Join(i.Base, filename)); err != nil { return err } else { defer fd.Close() reader := bufio.NewReader(fd) reader.WriteTo(writer) writer.Flush() return nil } } func (i LocalImporter) listDir(filename string) ([]string, error) { if files, err := ioutil.ReadDir(path.Join(i.Base, filename)); err != nil { return nil, err } else { res := make([]string, 0) for _, file := range files { res = append(res, file.Name()) } return res, nil } } func (i LocalImporter) stat(filename string) (os.FileInfo, error) { return os.Stat(path.Join(i.Base, filename)) }