Skip to content

Commit

Permalink
refactor: move header name computation to file
Browse files Browse the repository at this point in the history
  • Loading branch information
ybirader committed Sep 3, 2023
1 parent 6211c92 commit 9d9e500
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 66 deletions.
24 changes: 7 additions & 17 deletions archiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,10 @@ func (a *Archiver) populateHeader(file *pool.File) error {
header := file.Header

if a.dirArchive() {
relativeToRoot, err := a.relativeToChRoot(file.Path)
err := file.SetNameRelativeTo(a.chroot)
if err != nil {
return errors.Wrapf(err, "ERROR: could not find path relative to directory root %s", file.Path)
return errors.Wrapf(err, "ERROR: could not set path relative to chroot %s", file.Path)
}
header.Name = relativeToRoot
}

utf8ValidName, utf8RequireName := detectUTF8(header.Name)
Expand Down Expand Up @@ -252,25 +251,16 @@ func (a *Archiver) dirArchive() bool {
return a.chroot != ""
}

func (a *Archiver) relativeToChRoot(path string) (string, error) {
relativeToRoot, err := filepath.Rel(a.chroot, path)
func (a *Archiver) archive(file *pool.File) error {
fileWriter, err := a.w.CreateRaw(file.Header)
if err != nil {
return "", errors.Errorf("ERROR: could not find relative path of %s to root %s", path, a.chroot)
return errors.Errorf("ERROR: could not write raw header for %s", file.Path)
}

return filepath.Join(filepath.Base(a.chroot), relativeToRoot), nil
}

func (a *Archiver) archive(f *pool.File) error {
fileWriter, err := a.w.CreateRaw(f.Header)
if err != nil {
return errors.Errorf("ERROR: could not write raw header for %s", f.Path)
}

_, err = io.Copy(fileWriter, &f.CompressedData)
_, err = io.Copy(fileWriter, &file.CompressedData)

if err != nil {
return errors.Errorf("ERROR: could not write content for %s", f.Path)
return errors.Errorf("ERROR: could not write content for %s", file.Path)
}

return nil
Expand Down
73 changes: 24 additions & 49 deletions archiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func TestCompressToBuffer(t *testing.T) {

archiver, err := NewArchiver(archive)
assert.NoError(t, err)

info := testutils.GetFileInfo(t, helloTxtFileFixture)
file, err := pool.NewFile(helloTxtFileFixture, info)
assert.NoError(t, err)
Expand All @@ -140,60 +141,36 @@ func TestCompressToBuffer(t *testing.T) {

func TestFileWriter(t *testing.T) {
t.Run("writes correct header", func(t *testing.T) {
t.Run("with file name relative to archive root when file path is absolute", func(t *testing.T) {
archive, cleanup := testutils.CreateTempArchive(t, archivePath)
defer cleanup()

archiver, err := NewArchiver(archive)
assert.NoError(t, err)

t.Run("with file name relative to archive root when file path is relative", func(t *testing.T) {
info := testutils.GetFileInfo(t, helloTxtFileFixture)

absPath, err := filepath.Abs(helloTxtFileFixture)
assert.NoError(t, err)
file, err := pool.NewFile(absPath, info)
file, err := pool.NewFile(helloTxtFileFixture, info)
assert.NoError(t, err)

archiver.populateHeader(&file)

assert.Equal(t, "hello.txt", file.Header.Name)
})

t.Run("with file name relative to archive root when file path is relative", func(t *testing.T) {
archive, cleanup := testutils.CreateTempArchive(t, archivePath)
defer cleanup()

archiver, err := NewArchiver(archive)
t.Run("with file name relative to archive root when file path is absolute", func(t *testing.T) {
absFilePath, err := filepath.Abs(helloTxtFileFixture)
assert.NoError(t, err)

info := testutils.GetFileInfo(t, helloTxtFileFixture)
file, err := pool.NewFile(helloTxtFileFixture, info)
info := testutils.GetFileInfo(t, absFilePath)
file, err := pool.NewFile(absFilePath, info)
assert.NoError(t, err)

archiver.populateHeader(&file)

assert.Equal(t, "hello.txt", file.Header.Name)
})

t.Run("with file names relative to archive root for directories", func(t *testing.T) {
archive, cleanup := testutils.CreateTempArchive(t, archivePath)
defer cleanup()

archiver, err := NewArchiver(archive)
assert.NoError(t, err)

archiver.changeRoot(helloDirectoryFixture)
filePath := filepath.Join(archiver.chroot, "nested/hello.md")

t.Run("with file name relative to archive root for directories", func(t *testing.T) {
filePath := filepath.Join(helloDirectoryFixture, "nested/hello.md")
info := testutils.GetFileInfo(t, filePath)

file, err := pool.NewFile(filePath, info)
assert.NoError(t, err)

archiver.populateHeader(&file)
err = file.SetNameRelativeTo(helloDirectoryFixture)
assert.NoError(t, err)

assert.Equal(t, "hello/nested/hello.md", file.Header.Name)
})

t.Run("with deflate method and correct mod time, mode, data descriptor and extended timestamp for files", func(t *testing.T) {
archive, cleanup := testutils.CreateTempArchive(t, archivePath)
defer cleanup()
Expand All @@ -206,17 +183,14 @@ func TestFileWriter(t *testing.T) {
assert.NoError(t, err)

archiver.compress(&file)

archiver.populateHeader(&file)

assert.Equal(t, zip.Deflate, file.Header.Method)
assertMatchingTimes(t, info.ModTime(), file.Header.Modified)
assert.Equal(t, info.Mode(), file.Header.Mode())

assert.NotZero(t, file.Header.CRC32)
assert.Equal(t, uint64(file.CompressedData.Len()), file.Header.CompressedSize64)
assert.Equal(t, uint64(info.Size()), file.Header.UncompressedSize64)

assertExtendedTimestamp(t, file.Header)
})

Expand All @@ -226,13 +200,14 @@ func TestFileWriter(t *testing.T) {

archiver, err := NewArchiver(archive)
assert.NoError(t, err)
archiver.changeRoot(helloDirectoryFixture)

filePath := filepath.Join(archiver.chroot, "nested")
info := testutils.GetFileInfo(t, filepath.Join(helloDirectoryFixture, "/nested"))
filePath := filepath.Join(helloDirectoryFixture, "nested")
info := testutils.GetFileInfo(t, filePath)
file, err := pool.NewFile(filePath, info)
assert.NoError(t, err)
file.SetNameRelativeTo(helloDirectoryFixture)

archiver.compress(&file)
archiver.populateHeader(&file)

assert.Equal(t, "hello/nested/", file.Header.Name)
Expand All @@ -251,6 +226,14 @@ func assertExtendedTimestamp(t testing.TB, hdr *zip.FileHeader) {
assert.Equal(t, want, got, "expected header to contain extended timestamp")
}

func assertMatchingTimes(t testing.TB, t1, t2 time.Time) {
t.Helper()

assert.True(t,
t1.Year() == t2.Year() && t1.YearDay() == t2.YearDay() && t1.Second() == t2.Second(),
fmt.Sprintf("expected %+v to match %+v but didn't", t1, t2))
}

func BenchmarkArchive(b *testing.B) {
archive, cleanup := testutils.CreateTempArchive(b, archivePath)
defer cleanup()
Expand All @@ -264,11 +247,3 @@ func BenchmarkArchive(b *testing.B) {
archiver.Archive([]string{helloTxtFileFixture, helloMarkdownFileFixture})
}
}

func assertMatchingTimes(t testing.TB, t1, t2 time.Time) {
t.Helper()

assert.True(t,
t1.Year() == t2.Year() && t1.YearDay() == t2.YearDay() && t1.Second() == t2.Second(),
fmt.Sprintf("expected %+v to match %+v but didn't", t1, t2))
}
10 changes: 10 additions & 0 deletions pool/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"archive/zip"
"bytes"
"io/fs"
"path/filepath"

"github.com/pkg/errors"
)
Expand All @@ -23,3 +24,12 @@ func NewFile(path string, info fs.FileInfo) (File, error) {

return File{Path: path, Info: info, Header: hdr}, nil
}

func (f *File) SetNameRelativeTo(root string) error {
relativeToRoot, err := filepath.Rel(root, f.Path)
if err != nil {
return errors.Errorf("ERROR: could not find relative path of %s to root %s", f.Path, root)
}
f.Header.Name = filepath.Join(filepath.Base(root), relativeToRoot)
return nil
}

0 comments on commit 9d9e500

Please sign in to comment.