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
  • Loading branch information
mholt committed Nov 30, 2016
1 parent 4a8a092 commit cdc68dd
Show file tree
Hide file tree
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
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion archiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions cmd/archiver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion tarbz2.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
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
Expand Up @@ -171,7 +171,9 @@ var compressedFormats = map[string]struct{}{
".mpg": {},
".png": {},
".rar": {},
".tbz2": {},
".tgz": {},
".txz": {},
".xz": {},
".zip": {},
".zipx": {},
Expand Down

0 comments on commit cdc68dd

Please sign in to comment.