gitee.com/h79/goutils@v1.22.10/common/archive/e7z/7z.go (about) 1 package e7z 2 3 import ( 4 "context" 5 "fmt" 6 fileconfig "gitee.com/h79/goutils/common/file/config" 7 "io" 8 "os" 9 "os/exec" 10 "runtime" 11 ) 12 13 // Archive as 7z. 14 type Archive struct { 15 Path string 16 Filename string 17 } 18 19 // New tar archive. 20 func New(target io.WriteCloser, path, filename string) Archive { 21 if target != nil { 22 target.Close() 23 os.Remove(filename) 24 } 25 return Archive{Path: path, Filename: filename} 26 } 27 28 // Close all closeables. 29 func (a Archive) Close() error { 30 return nil 31 } 32 33 // Add file to the archive. 34 func (a Archive) Add(f fileconfig.File, stream ...fileconfig.ReaderStream) error { 35 err := a.cmd(f) 36 if err != nil { 37 return err 38 } 39 return a.Stream(f, stream...) 40 } 41 42 func (a Archive) cmd(f fileconfig.File) error { 43 cmd := "7z" 44 switch runtime.GOOS { 45 case "windows": 46 cmd = "7z.exe" 47 } 48 return run(context.Background(), []string{cmd, "a", "-r", a.Filename, f.Source}, nil, "") 49 } 50 51 func (a Archive) Stream(f fileconfig.File, stream ...fileconfig.ReaderStream) error { 52 if len(stream) == 0 { 53 return nil 54 } 55 if f.Dir { 56 return nil 57 } 58 file, err := os.Open(f.Source) // #nosec 59 if err != nil { 60 return fmt.Errorf("%s: %w", f.Source, err) 61 } 62 defer func(file *os.File) { 63 err = file.Close() 64 if err != nil { 65 } 66 }(file) 67 for i := range stream { 68 stream[i].OnReader(file) 69 } 70 return nil 71 } 72 73 func run(ctx context.Context, command, env []string, dir string) error { 74 cmd := exec.CommandContext(ctx, command[0], command[1:]...) 75 cmd.Env = env 76 cmd.Dir = dir 77 out, err := cmd.CombinedOutput() 78 if err != nil { 79 return fmt.Errorf("%w: %s", err, string(out)) 80 } 81 return nil 82 }