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

Commit

Permalink
Add .tar.xz support
Browse files Browse the repository at this point in the history
mholt committed Nov 30, 2016

Verified

This commit was signed with the committer’s verified signature.
mholt Matt Holt
1 parent 4a8a092 commit cdc68dd
Showing 6 changed files with 80 additions and 8 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -3,18 +3,18 @@ archiver [![archiver GoDoc](https://img.shields.io/badge/reference-godoc-blue.sv

Package archiver makes it trivially easy to make and extract common archive formats such as .zip, and .tar.gz. Simply name the input and output file(s).

Files are put into the root of the archive; directories are recursively added.
Files are put into the root of the archive; directories are recursively added, preserving structure.

The `archiver` command runs the same cross-platform and has no external dependencies (not even libc); powered by the Go standard library, [dsnet/compress](https://github.com/dsnet/compress), and [nwaples/rardecode](https://github.com/nwaples/rardecode). Enjoy!
The `archiver` command runs the same cross-platform and has no external dependencies (not even libc); powered by the Go standard library, [dsnet/compress](https://github.com/dsnet/compress), [nwaples/rardecode](https://github.com/nwaples/rardecode), and [ulikunitz/xz](https://github.com/ulikunitz/xz). Enjoy!

Supported formats/extensions:

- .zip
- .tar
- .tar.gz
- .tgz
- .tar.bz2
- .rar (open)
- .tar.gz & .tgz
- .tar.bz2 & .tbz2
- .tar.xz & .txz
- .rar (open only)


## Install
2 changes: 1 addition & 1 deletion archiver_test.go
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ func symmetricTest(t *testing.T, name string, ar Archiver) {
os.Mkdir(dest, 0755)
err = ar.Open(outfile, dest)
if err != nil {
t.Fatalf("extracting archive: didn't expect an error, but got: %v", err)
t.Fatalf("extracting archive [%s -> %s]: didn't expect an error, but got: %v", outfile, dest, err)
}

// If outputs equals inputs, we're good; traverse output files
3 changes: 3 additions & 0 deletions cmd/archiver/main.go
Original file line number Diff line number Diff line change
@@ -71,6 +71,9 @@ const usage = `Usage: archiver {make|open} <archive file> [files...]
.tar.gz
.tgz
.tar.bz2
.tbz2
.tar.xz
.txz
.rar (open only)
Existing files:
3 changes: 2 additions & 1 deletion tarbz2.go
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ type tarBz2Format struct{}

func (tarBz2Format) Match(filename string) bool {
// TODO: read file header to identify the format
return strings.HasSuffix(strings.ToLower(filename), ".tar.bz2")
return strings.HasSuffix(strings.ToLower(filename), ".tar.bz2") ||
strings.HasSuffix(strings.ToLower(filename), ".tbz2")
}

// Make creates a .tar.bz2 file at tarbz2Path containing
66 changes: 66 additions & 0 deletions tarxz.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package archiver

import (
"archive/tar"
"fmt"
"os"
"strings"

"github.com/ulikunitz/xz"
)

// TarXZ is for TarXZ format
var TarXZ xzFormat

func init() {
RegisterFormat("TarXZ", TarXZ)
}

type xzFormat struct{}

// Match returns whether filename matches this format.
func (xzFormat) Match(filename string) bool {
// TODO: read file header to identify the format
return strings.HasSuffix(strings.ToLower(filename), ".tar.xz") ||
strings.HasSuffix(strings.ToLower(filename), ".txz")
}

// Make creates a .tar.xz file at xzPath 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 (xzFormat) Make(xzPath string, filePaths []string) error {
out, err := os.Create(xzPath)
if err != nil {
return fmt.Errorf("error creating %s: %v", xzPath, err)
}
defer out.Close()

xzWriter, err := xz.NewWriter(out)
if err != nil {
return fmt.Errorf("error compressing %s: %v", xzPath, err)
}
defer xzWriter.Close()

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

return tarball(filePaths, tarWriter, xzPath)
}

// Open untars source and decompresses the contents into destination.
func (xzFormat) Open(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()

xzReader, err := xz.NewReader(f)
if err != nil {
return fmt.Errorf("error decompressing %s: %v", source, err)
}

return untar(tar.NewReader(xzReader), destination)
}
2 changes: 2 additions & 0 deletions zip.go
Original file line number Diff line number Diff line change
@@ -171,7 +171,9 @@ var compressedFormats = map[string]struct{}{
".mpg": {},
".png": {},
".rar": {},
".tbz2": {},
".tgz": {},
".txz": {},
".xz": {},
".zip": {},
".zipx": {},

0 comments on commit cdc68dd

Please sign in to comment.