github.com/apex/up@v1.7.1/internal/zip/zip.go (about)

     1  package zip
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"strings"
     9  
    10  	"github.com/pkg/errors"
    11  	archive "github.com/tj/go-archive"
    12  )
    13  
    14  var transform = archive.TransformFunc(func(r io.Reader, i os.FileInfo) (io.Reader, os.FileInfo) {
    15  	name := strings.Replace(i.Name(), "\\", "/", -1)
    16  
    17  	i = archive.Info{
    18  		Name:     name,
    19  		Size:     i.Size(),
    20  		Mode:     i.Mode() | 0555,
    21  		Modified: i.ModTime(),
    22  		Dir:      i.IsDir(),
    23  	}.FileInfo()
    24  
    25  	return r, i
    26  })
    27  
    28  // Build the given `dir`.
    29  func Build(dir string) (io.ReadCloser, *archive.Stats, error) {
    30  	upignore, err := read(".upignore")
    31  	if err != nil {
    32  		return nil, nil, errors.Wrap(err, "reading .upignore")
    33  	}
    34  	defer upignore.Close()
    35  
    36  	r := io.MultiReader(
    37  		strings.NewReader(".*\n"),
    38  		strings.NewReader("\n!vendor\n!node_modules/**\n!.pypath/**\n"),
    39  		upignore,
    40  		strings.NewReader("\n!main\n!server\n!_proxy.js\n!up.json\n!pom.xml\n!build.gradle\n!project.clj\ngin-bin\nup\n"))
    41  
    42  	filter, err := archive.FilterPatterns(r)
    43  	if err != nil {
    44  		return nil, nil, errors.Wrap(err, "parsing ignore patterns")
    45  	}
    46  
    47  	buf := new(bytes.Buffer)
    48  	zip := archive.NewZip(buf).
    49  		WithFilter(filter).
    50  		WithTransform(transform)
    51  
    52  	if err := zip.Open(); err != nil {
    53  		return nil, nil, errors.Wrap(err, "opening")
    54  	}
    55  
    56  	if err := zip.AddDir(dir); err != nil {
    57  		return nil, nil, errors.Wrap(err, "adding dir")
    58  	}
    59  
    60  	if err := zip.Close(); err != nil {
    61  		return nil, nil, errors.Wrap(err, "closing")
    62  	}
    63  
    64  	return ioutil.NopCloser(buf), zip.Stats(), nil
    65  }
    66  
    67  // read file.
    68  func read(path string) (io.ReadCloser, error) {
    69  	f, err := os.Open(path)
    70  
    71  	if os.IsNotExist(err) {
    72  		return ioutil.NopCloser(bytes.NewReader(nil)), nil
    73  	}
    74  
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  
    79  	return f, nil
    80  }