예제 #1
0
파일: scanner.go 프로젝트: glyn/bloblets
func doScan(appDir, path string) (*directory, error) {
	fullPath := filepath.Join(appDir, path)
	fi, err := os.Lstat(fullPath)
	if err != nil {
		return nil, fmt.Errorf("Scan of %s for path %s failed: %s", appDir, path, err)
	}

	if !fi.IsDir() {
		return nil, fmt.Errorf("Not a directory: %s", path)
	}

	dir := directory{
		path:     path,
		hash:     filehash.Zero(),
		size:     0,
		files:    make(map[string]*models.AppFileFields, 50),
		children: make(map[string]*directory, 10),
	}

	f, err := os.Open(fullPath)
	if err != nil {
		return nil, fmt.Errorf("Scan of %s failed on Open: %s", fullPath, err)
	}
	fis, err := f.Readdir(-1)
	if err != nil {
		return nil, fmt.Errorf("Scan of %s failed on Readdir: %s", fullPath, err)
	}

	for _, fi := range fis {
		fp := filepath.Join(fullPath, fi.Name())
		fpRelative := filepath.Join(path, fi.Name())
		if !fi.IsDir() {
			h := filehash.New(fp)
			dir.files[fp] = &models.AppFileFields{
				Sha1: h.String(),
				Size: fi.Size(),
				Path: fpRelative,
				Mode: fmt.Sprintf("%#o", fi.Mode()),
			}
			dir.size += fi.Size()
			dir.hash.Combine(h)
		} else {
			s, err := doScan(appDir, fpRelative)
			if err != nil {
				return nil, fmt.Errorf("Scan of %s failed to scan subdirectory %s: %s", fullPath, fp, err)
			}
			dir.children[fp] = s
		}
	}

	return &dir, nil
}
예제 #2
0
	"github.com/cloudfoundry/cli/cf/models"
	"github.com/glyn/bloblets/bloblet/filehash"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Scanner", func() {
	It("should correctly scan an empty directory", func() {
		d, err := ioutil.TempDir("", "empty")
		Expect(err).NotTo(HaveOccurred())

		dir, err := Scan(d)
		Expect(err).NotTo(HaveOccurred())
		Expect(dir.path).To(Equal("."))
		Expect(dir.hash).To(Equal(filehash.Zero()))
		Expect(dir.size).To(Equal(int64(0)))
		Expect(dir.files).To(BeEmpty())
		Expect(dir.children).To(BeEmpty())
		Expect(dir.bloblet).To(BeNil())
	})

	It("should correctly scan a directory with no children", func() {
		dir, err := Scan("./test/nochildren")
		Expect(err).NotTo(HaveOccurred())
		Expect(dir.path).To(Equal("."))
		Expect(dir.hash.String()).To(Equal("6fbf71631414af6ab45c4508bc4bc030ae12f891"))
		Expect(dir.size).To(Equal(int64(3218)))
		Expect(hashes(dir.files)).To(Equal(map[string]string{"test/nochildren/file1": filehash.New("./test/nochildren/file1").String(),
			"test/nochildren/file2": filehash.New("./test/nochildren/file2").String()}))
		Expect(dir.children).To(BeEmpty())
예제 #3
0
파일: condenser.go 프로젝트: glyn/bloblets
	"strings"

	"github.com/cloudfoundry/cli/cf/models"
	"github.com/glyn/bloblets/bloblet/filehash"
)

type Condensate interface {
	Bloblets([]models.AppFileFields) ([]Bloblet, []models.AppFileFields)
}

const BlobletFileName = "com-github-glyn-bloblet.zip"

var BlobletFileNamePathTerminator = filepath.Join("", BlobletFileName)

var noFiles = make(map[string]*models.AppFileFields)
var zeroHash = filehash.Zero()

// Condenses the files in the given directory and returns details of (a) files which
// are already larger than minCompressedBlobletSize, and (b) bloblets.
func (dir *directory) Condense(minBlobletSize, minCompressedBlobletSize int64) []models.AppFileFields {
	affs := make([]models.AppFileFields, 0, 100)
	for _, child := range dir.children {
		caffs := child.Condense(minBlobletSize, minCompressedBlobletSize)
		affs = appendAll(affs, caffs)
		// If the child has not been condensed, copy its files to its parent (this directory).
		if child.bloblet == nil {
			addAll(dir.files, child.files)
			dir.size += child.size
			dir.hash.Combine(child.hash)

			// Show child has been condensed into parent - only for use in testing.