github.com/qxnw/lib4go@v0.0.0-20180426074627-c80c7e84b925/archiver/archiver.go (about) 1 package archiver 2 3 import ( 4 "fmt" 5 "io" 6 "log" 7 "os" 8 "path/filepath" 9 "runtime" 10 ) 11 12 // Archiver represent a archive format 13 type Archiver interface { 14 // Match checks supported files 15 Match(filename string) bool 16 // Make makes an archive file on disk. 17 Make(destination string, sources []string) error 18 // Open extracts an archive file on disk. 19 Open(source, destination string) error 20 // Write writes an archive to a Writer. 21 Write(output io.Writer, sources []string) error 22 // Read reads an archive from a Reader. 23 Read(input io.Reader, destination string) error 24 } 25 26 // SupportedFormats contains all supported archive formats 27 var SupportedFormats = map[string]Archiver{} 28 29 // RegisterFormat adds a supported archive format 30 func RegisterFormat(name string, format Archiver) { 31 if _, ok := SupportedFormats[name]; ok { 32 log.Printf("Format %s already exists, skip!\n", name) 33 return 34 } 35 SupportedFormats[name] = format 36 } 37 38 // MatchingFormat returns the first archive format that matches 39 // the given file, or nil if there is no match 40 func MatchingFormat(fpath string) Archiver { 41 for _, fmt := range SupportedFormats { 42 if fmt.Match(fpath) { 43 return fmt 44 } 45 } 46 return nil 47 } 48 49 func writeNewFile(fpath string, in io.Reader, fm os.FileMode) error { 50 err := os.MkdirAll(filepath.Dir(fpath), 0755) 51 if err != nil { 52 return fmt.Errorf("%s: making directory for file: %v", fpath, err) 53 } 54 55 out, err := os.Create(fpath) 56 if err != nil { 57 return fmt.Errorf("%s: creating new file: %v", fpath, err) 58 } 59 defer out.Close() 60 61 err = out.Chmod(fm) 62 if err != nil && runtime.GOOS != "windows" { 63 return fmt.Errorf("%s: changing file mode: %v", fpath, err) 64 } 65 66 _, err = io.Copy(out, in) 67 if err != nil { 68 return fmt.Errorf("%s: writing file: %v", fpath, err) 69 } 70 return nil 71 } 72 73 func writeNewSymbolicLink(fpath string, target string) error { 74 err := os.MkdirAll(filepath.Dir(fpath), 0755) 75 if err != nil { 76 return fmt.Errorf("%s: making directory for file: %v", fpath, err) 77 } 78 79 err = os.Symlink(target, fpath) 80 if err != nil { 81 return fmt.Errorf("%s: making symbolic link for: %v", fpath, err) 82 } 83 84 return nil 85 } 86 87 func writeNewHardLink(fpath string, target string) error { 88 err := os.MkdirAll(filepath.Dir(fpath), 0755) 89 if err != nil { 90 return fmt.Errorf("%s: making directory for file: %v", fpath, err) 91 } 92 93 err = os.Link(target, fpath) 94 if err != nil { 95 return fmt.Errorf("%s: making hard link for: %v", fpath, err) 96 } 97 98 return nil 99 } 100 101 func mkdir(dirPath string) error { 102 err := os.MkdirAll(dirPath, 0755) 103 if err != nil { 104 return fmt.Errorf("%s: making directory: %v", dirPath, err) 105 } 106 return nil 107 }