func (zipper *DropletArtifactZipper) Zip(srcDir string, cfIgnore cf_ignore.CFIgnore) (string, error) { tmpPath, err := ioutil.TempDir(os.TempDir(), "droplet-artifact-zipper") if err != nil { return "", err } fileWriter, err := os.OpenFile(filepath.Join(tmpPath, "artifact.zip"), os.O_CREATE|os.O_WRONLY, 0600) if err != nil { return "", err } defer fileWriter.Close() zipWriter := zip.NewWriter(fileWriter) defer zipWriter.Close() contentsFileInfo, err := os.Stat(srcDir) if err != nil { return "", err } if !contentsFileInfo.IsDir() { return "", fmt.Errorf("%s must be a directory", srcDir) } if ignoreFile, err := os.Open(filepath.Join(srcDir, ".cfignore")); err == nil { defer ignoreFile.Close() if err := cfIgnore.Parse(ignoreFile); err != nil { return "", err } } err = filepath.Walk(srcDir, func(fullPath string, info os.FileInfo, err error) error { if err != nil { return err } relativePath, err := filepath.Rel(srcDir, fullPath) if err != nil { return err } if cfIgnore.ShouldIgnore(relativePath) { return nil } if relativePath == fileWriter.Name() || relativePath == "." || relativePath == ".." { return nil } if h, err := zip.FileInfoHeader(info); err == nil { h.Name = filepath.ToSlash(relativePath) if info.IsDir() { h.Name = h.Name + "/" } h.SetMode(info.Mode()) writer, err := zipWriter.CreateHeader(h) if err != nil { return err } if info.IsDir() { return nil } li, err := os.Lstat(fullPath) if err != nil { return err } if li.Mode()&os.ModeSymlink == os.ModeSymlink { dest, err := os.Readlink(fullPath) if err != nil { return err } if _, err := io.Copy(writer, strings.NewReader(dest)); err != nil { return err } } else { fr, err := os.Open(fullPath) if err != nil { return err } defer fr.Close() if _, err := io.Copy(writer, fr); err != nil { return err } } } return nil }) return fileWriter.Name(), err }
package cf_ignore_test import ( "errors" "strings" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/cloudfoundry-incubator/ltc/droplet_runner/command_factory/cf_ignore" ) var _ = Describe("CF Ignore", func() { var cfIgnore cf_ignore.CFIgnore BeforeEach(func() { cfIgnore = cf_ignore.New() }) It("excludes files based on exact path matches", func() { Expect(cfIgnore.Parse(strings.NewReader("the-dir/the-path"))).To(Succeed()) Expect(cfIgnore.ShouldIgnore("the-dir/the-path")).To(BeTrue()) }) It("excludes the contents of directories based on exact path matches", func() { Expect(cfIgnore.Parse(strings.NewReader("dir1/dir2"))).To(Succeed()) Expect(cfIgnore.ShouldIgnore("dir1/dir2/the-file")).To(BeTrue()) Expect(cfIgnore.ShouldIgnore("dir1/dir2/dir3/the-file")).To(BeTrue()) }) It("excludes files based on star patterns", func() {