Skip to content
This repository has been archived by the owner on Nov 19, 2024. It is now read-only.

Commit

Permalink
Add support for uncompressed .tar files
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt committed Oct 4, 2016
1 parent eb71e84 commit 90b9070
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The `archiver` command runs the same cross-platform and has no external dependen
Supported formats/extensions:

- .zip
- .tar
- .tar.gz
- .tgz
- .tar.bz2
Expand Down
6 changes: 4 additions & 2 deletions cmd/archiver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const usage = `Usage: archiver {make|open} <archive file> [files...]
The format of the archive is determined by its
file extension. Supported extensions:
.zip
.tar
.tar.gz
.tgz
.tar.bz2
Expand All @@ -83,10 +84,11 @@ const usage = `Usage: archiver {make|open} <archive file> [files...]

var fileFormats = []struct {
ext string
create archiver.CompressFunc
extract archiver.DecompressFunc
create archiver.MakeFunc
extract archiver.OpenFunc
}{
{ext: ".zip", create: archiver.Zip, extract: archiver.Unzip},
{ext: ".tar", create: archiver.Tar, extract: archiver.Untar},
{ext: ".tar.gz", create: archiver.TarGz, extract: archiver.UntarGz},
{ext: ".tgz", create: archiver.TarGz, extract: archiver.UntarGz},
{ext: ".tar.bz2", create: archiver.TarBz2, extract: archiver.UntarBz2},
Expand Down
33 changes: 30 additions & 3 deletions targz.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,27 @@ import (
"strings"
)

// TarGz creates a .tar.gz file at targzPath containing
// the contents of files listed in filePaths. File paths
// can be those of regular files or directories. Regular
// Tar creates a .tar file at tarPath containing the
// contents of files listed in filePaths. File paths can
// be those of regular files or directories. Regular
// files are stored at the 'root' of the archive, and
// directories are recursively added.
func Tar(tarPath string, filePaths []string) error {
out, err := os.Create(tarPath)
if err != nil {
return fmt.Errorf("error creating %s: %v", tarPath, err)
}
defer out.Close()

tarWriter := tar.NewWriter(out)
defer tarWriter.Close()

return tarball(filePaths, tarWriter, tarPath)
}

// TarGz creates a .tar.gz file at targzPath containing
// the contents of files listed in filePaths. It works
// the same way Tar does, but with gzip compression.
func TarGz(targzPath string, filePaths []string) error {
out, err := os.Create(targzPath)
if err != nil {
Expand Down Expand Up @@ -104,6 +120,17 @@ func tarFile(tarWriter *tar.Writer, source, dest string) error {
})
}

// Untar untars source and puts the contents into destination.
func Untar(source, destination string) error {
f, err := os.Open(source)
if err != nil {
return fmt.Errorf("%s: failed to open archive: %v", source, err)
}
defer f.Close()

return untar(tar.NewReader(f), destination)
}

// UntarGz untars source and decompresses the contents into destination.
func UntarGz(source, destination string) error {
f, err := os.Open(source)
Expand Down
4 changes: 4 additions & 0 deletions targz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package archiver

import "testing"

func TestTarAndUntar(t *testing.T) {
symmetricTest(t, ".tar", Tar, Untar)
}

func TestTarGzAndUntarGz(t *testing.T) {
symmetricTest(t, ".tar.gz", TarGz, UntarGz)
}
8 changes: 4 additions & 4 deletions zip.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ var CompressedFormats = map[string]struct{}{
}

type (
// CompressFunc is a function that makes an archive.
CompressFunc func(string, []string) error
// MakeFunc is a function that makes an archive.
MakeFunc func(string, []string) error

// DecompressFunc is a function that extracts an archive.
DecompressFunc func(string, string) error
// OpenFunc is a function that extracts an archive.
OpenFunc func(string, string) error
)
9 changes: 6 additions & 3 deletions zip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ func TestZipAndUnzip(t *testing.T) {
symmetricTest(t, ".zip", Zip, Unzip)
}

func symmetricTest(t *testing.T, ext string, cf CompressFunc, dcf DecompressFunc) {
// symmetricTest performs a symmetric test by using mf to make an archive
// from the test corpus, then using of to open the archive and comparing
// the contents to ensure they are equal.
func symmetricTest(t *testing.T, ext string, mf MakeFunc, of OpenFunc) {
tmp, err := ioutil.TempDir("", "archiver")
if err != nil {
t.Fatal(err)
Expand All @@ -21,7 +24,7 @@ func symmetricTest(t *testing.T, ext string, cf CompressFunc, dcf DecompressFunc

// Test creating archive
outfile := filepath.Join(tmp, "test"+ext)
err = cf(outfile, []string{"testdata"})
err = mf(outfile, []string{"testdata"})
if err != nil {
t.Fatalf("making archive: didn't expect an error, but got: %v", err)
}
Expand All @@ -35,7 +38,7 @@ func symmetricTest(t *testing.T, ext string, cf CompressFunc, dcf DecompressFunc
// Test extracting archive
dest := filepath.Join(tmp, "extraction_test")
os.Mkdir(dest, 0755)
err = dcf(outfile, dest)
err = of(outfile, dest)
if err != nil {
t.Fatalf("extracting archive: didn't expect an error, but got: %v", err)
}
Expand Down

0 comments on commit 90b9070

Please sign in to comment.