package main import ( "io/ioutil" "os" "path/filepath" ) type Index struct { Files map[string][]byte Dirs map[string][]string } func NewIndex() *Index { return &Index{ Files: map[string][]byte{}, Dirs: map[string][]string{}, } } // ReadDir reads a directory and indexes the files and directories within it. func (index *Index) ReadDir(srcDir string, dstDir string) error { entries, err := ioutil.ReadDir(srcDir) if err != nil { return err } for _, entry := range entries { name := entry.Name() srcPath := filepath.Join(srcDir, name) dstPath := filepath.Join(dstDir, name) if entry.IsDir() { index.Dirs[dstPath] = []string{} index.ReadDir(srcPath, dstPath) } else { content, err := ioutil.ReadFile(srcPath) if err != nil { return err } index.Files[dstPath] = content index.Dirs[dstDir] = append(index.Dirs[dstDir], dstPath) } } return nil } // Write writes the contents of the Index to the provided destination directory. func (index *Index) Write(dstDir string) error { // Empty the destination directory if err := os.RemoveAll(dstDir); err != nil { return err } if err := os.MkdirAll(dstDir, 0755); err != nil { return err } for path := range index.Files { // Create any parent directories if dir := filepath.Dir(path); dir != "." { dstPath := filepath.Join(dstDir, dir) if err := os.MkdirAll(dstPath, 0755); err != nil { return err } } // Write the file dstPath := filepath.Join(dstDir, path) f, err := os.Create(dstPath) if err != nil { return err } data := index.Files[path] if _, err := f.Write(data); err != nil { return err } } return nil }