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  }