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 opening .rar files (and fix build script)
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt committed Jul 5, 2016
1 parent ea17366 commit dbc8e5d
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 18 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
archiver [![archiver GoDoc](https://img.shields.io/badge/reference-godoc-blue.svg?style=flat-square)](https://godoc.org/github.com/mholt/archiver) [![Linux Build Status](https://img.shields.io/travis/mholt/archiver.svg?style=flat-square&label=linux+build)](https://travis-ci.org/mholt/archiver) [![Windows Build Status](https://img.shields.io/appveyor/ci/mholt/archiver.svg?style=flat-square&label=windows+build)](https://ci.appveyor.com/project/mholt/archiver)
========

Package archiver makes it trivially easy to make and extract common archive formats such as .zip, .tar.gz, and .tar.bz2. Simply name the input and output file(s).
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.

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

Supported formats/extensions:

- .zip
- .tar.gz (.tgz)
- .tar.gz
- .tgz
- .tar.bz2
- .rar (open)


## Install
Expand Down Expand Up @@ -70,7 +72,7 @@ Working with other file formats is exactly the same, but with [their own functio

#### Can I list a file in one folder to go into a different folder in the archive?

No. This works just like your OS would make an archive in Finder or File Explorer: organize your input files to mirror the structure you want in the archive.
No. This works just like your OS would make an archive in the file explorer: organize your input files to mirror the structure you want in the archive.


#### Can it add files to an existing archive?
Expand Down
28 changes: 14 additions & 14 deletions build.bash
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ set -ex

export CGO_ENABLED=0

cd archiver
GOOS=linux GOARCH=386 go build -o ../builds/archiver_linux_386
GOOS=linux GOARCH=amd64 go build -o ../builds/archiver_linux_amd64
GOOS=linux GOARCH=arm go build -o ../builds/archiver_linux_arm7
GOOS=linux GOARCH=arm64 go build -o ../builds/archiver_linux_arm64
GOOS=darwin GOARCH=amd64 go build -o ../builds/archiver_mac_amd64
GOOS=windows GOARCH=386 go build -o ../builds/archiver_windows_386.exe
GOOS=windows GOARCH=amd64 go build -o ../builds/archiver_windows_amd64.exe
GOOS=freebsd GOARCH=386 go build -o ../builds/archiver_freebsd_386
GOOS=freebsd GOARCH=amd64 go build -o ../builds/archiver_freebsd_amd64
GOOS=freebsd GOARCH=arm go build -o ../builds/archiver_freebsd_arm7
GOOS=openbsd GOARCH=386 go build -o ../builds/archiver_openbsd_386
GOOS=openbsd GOARCH=amd64 go build -o ../builds/archiver_openbsd_amd64
cd ..
cd cmd/archiver
GOOS=linux GOARCH=386 go build -o ../../builds/archiver_linux_386
GOOS=linux GOARCH=amd64 go build -o ../../builds/archiver_linux_amd64
GOOS=linux GOARCH=arm go build -o ../../builds/archiver_linux_arm7
GOOS=linux GOARCH=arm64 go build -o ../../builds/archiver_linux_arm64
GOOS=darwin GOARCH=amd64 go build -o ../../builds/archiver_mac_amd64
GOOS=windows GOARCH=386 go build -o ../../builds/archiver_windows_386.exe
GOOS=windows GOARCH=amd64 go build -o ../../builds/archiver_windows_amd64.exe
GOOS=freebsd GOARCH=386 go build -o ../../builds/archiver_freebsd_386
GOOS=freebsd GOARCH=amd64 go build -o ../../builds/archiver_freebsd_amd64
GOOS=freebsd GOARCH=arm go build -o ../../builds/archiver_freebsd_arm7
GOOS=openbsd GOARCH=386 go build -o ../../builds/archiver_openbsd_386
GOOS=openbsd GOARCH=amd64 go build -o ../../builds/archiver_openbsd_amd64
cd ../..
2 changes: 2 additions & 0 deletions cmd/archiver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const usage = `Usage: archiver {make|open} <archive file> [files...]
.tar.gz
.tgz
.tar.bz2
.rar (open only)
Existing files:
When creating an archive file that already exists,
Expand All @@ -89,4 +90,5 @@ var fileFormats = []struct {
{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},
{ext: ".rar", create: archiver.Rar, extract: archiver.Unrar},
}
56 changes: 56 additions & 0 deletions rar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package archiver

import (
"fmt"
"io"
"os"
"path/filepath"

"github.com/nwaples/rardecode"
)

// Rar makes a .rar archive, but this is not implemented because
// RAR is a proprietary format. It is here only for symmetry with
// the other archive formats in this package.
func Rar(rarPath string, filePaths []string) error {
return fmt.Errorf("make %s: RAR not implemented (proprietary format)", rarPath)
}

// Unrar extracts the RAR file at source and puts the contents
// into destination.
func Unrar(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()

rr, err := rardecode.NewReader(f, "")
if err != nil {
return fmt.Errorf("%s: failed to create reader: %v", source, err)
}

for {
header, err := rr.Next()
if err == io.EOF {
break
} else if err != nil {
return err
}

if header.IsDir {
err = mkdir(filepath.Join(destination, header.Name))
if err != nil {
return err
}
continue
}

err = writeNewFile(filepath.Join(destination, header.Name), rr, header.Mode())
if err != nil {
return err
}
}

return nil
}

0 comments on commit dbc8e5d

Please sign in to comment.