• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.github/ISSUE_TEMPLATE/H04-Dec-2018-

cmd/arc/H04-Dec-2018-

testdata/proverbs/extra/H03-May-2022-

.gitignoreH A D04-Dec-201858

.travis.ymlH A D04-Dec-2018293

LICENSEH A D04-Dec-20181 KiB

README.mdH A D04-Dec-20189.7 KiB

appveyor.ymlH A D04-Dec-2018445

archiver.goH A D04-Dec-201814.5 KiB

archiver_test.goH A D04-Dec-20189.6 KiB

build.bashH A D04-Dec-2018670

bz2.goH A D04-Dec-20181.4 KiB

doc_test.goH A D04-Dec-20187.2 KiB

filecompressor.goH A D04-Dec-20181.4 KiB

filecompressor_test.goH A D04-Dec-20184.5 KiB

gz.goH A D04-Dec-20181.3 KiB

lz4.goH A D04-Dec-20181.3 KiB

rar.goH A D04-Dec-201810.1 KiB

sz.goH A D04-Dec-20181.2 KiB

tar.goH A D04-Dec-201815 KiB

tarbz2.goH A D04-Dec-20183.3 KiB

targz.goH A D04-Dec-20183.1 KiB

tarlz4.goH A D04-Dec-20183.3 KiB

tarsz.goH A D04-Dec-20182.9 KiB

tarxz.goH A D04-Dec-20183 KiB

xz.goH A D04-Dec-20181.2 KiB

zip.goH A D04-Dec-201814.3 KiB

README.md

1archiver [![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)
2========
3
4Introducing **Archiver 3.1** - a cross-platform, multi-format archive utility and Go library. A powerful and flexible library meets an elegant CLI in this generic replacement for several of platform-specific, format-specific archive utilities.
5
6## Features
7
8Package archiver makes it trivially easy to make and extract common archive formats such as zip and tarball (and its compressed variants). Simply name the input and output file(s). The `arc` command runs the same on all platforms and has no external dependencies (not even libc). It is powered by the Go standard library and several third-party, pure-Go libraries.
9
10Files are put into the root of the archive; directories are recursively added, preserving structure.
11
12- Make whole archives from a list of files
13- Open whole archives to a folder
14- Extract specific files/folders from archives
15- Stream files in and out of archives without needing actual files on disk
16- Traverse archive contents without loading them
17- Compress files
18- Decompress files
19- Streaming compression and decompression
20- Several archive and compression formats supported
21
22### Format-dependent features
23
24- Optionally create a top-level folder to avoid littering a directory or archive root with files
25- Toggle overwrite existing files
26- Adjust compression level
27- Zip: store (not compress) already-compressed files
28- Make all necessary directories
29- Open password-protected RAR archives
30- Optionally continue with other files after an error
31
32### Supported archive formats
33
34- .zip
35- .tar
36- .tar.gz or .tgz
37- .tar.bz2 or .tbz2
38- .tar.xz or .txz
39- .tar.lz4 or .tlz4
40- .tar.sz or .tsz
41- .rar (open only)
42
43### Supported compression formats
44
45- bzip2
46- gzip
47- lz4
48- snappy (sz)
49- xz
50
51
52## Install
53
54```bash
55go get -u github.com/mholt/archiver/cmd/arc
56```
57
58Or download binaries from the [releases](https://github.com/mholt/archiver/releases) page.
59
60
61## Command Use
62
63### Make new archive
64
65```bash
66# Syntax: arc archive [archive name] [input files...]
67
68$ arc archive test.tar.gz file1.txt images/file2.jpg folder/subfolder
69```
70
71(At least one input file is required.)
72
73### Extract entire archive
74
75```bash
76# Syntax: arc unarchive [archive name] [destination]
77
78$ arc unarchive test.tar.gz
79```
80
81(The destination path is optional; default is current directory.)
82
83The archive name must end with a supported file extension—this is how it knows what kind of archive to make. Run `arc help` for more help.
84
85### List archive contents
86
87```bash
88# Syntax: arc ls [archive name]
89
90$ arc ls caddy_dist.tar.gz
91drwxr-xr-x  matt    staff   0       2018-09-19 15:47:18 -0600 MDT   dist/
92-rw-r--r--  matt    staff   6148    2017-08-07 18:34:22 -0600 MDT   dist/.DS_Store
93-rw-r--r--  matt    staff   22481   2018-09-19 15:47:18 -0600 MDT   dist/CHANGES.txt
94-rw-r--r--  matt    staff   17189   2018-09-19 15:47:18 -0600 MDT   dist/EULA.txt
95-rw-r--r--  matt    staff   25261   2016-03-07 16:32:00 -0700 MST   dist/LICENSES.txt
96-rw-r--r--  matt    staff   1017    2018-09-19 15:47:18 -0600 MDT   dist/README.txt
97-rw-r--r--  matt    staff   288     2016-03-21 11:52:38 -0600 MDT   dist/gitcookie.sh.enc
98...
99```
100
101### Extract a specific file or folder from an archive
102
103```bash
104# Syntax: arc extract [archive name] [path in archive] [destination on disk]
105
106$ arc extract test.tar.gz foo/hello.txt extracted/hello.txt
107```
108
109### Compress a single file
110
111```bash
112# Syntax: arc compress [input file] [output file]
113
114$ arc compress test.txt compressed_test.txt.gz
115$ arc compress test.txt gz
116```
117
118For convenience, the output file (second argument) may simply be a compression format (without leading dot), in which case the output filename will be the same as the input filename but with the format extension appended, and the input file will be deleted if successful.
119
120### Decompress a single file
121
122```bash
123# Syntax: arc decompress [input file] [output file]
124
125$ arc decompress test.txt.gz original_test.txt
126$ arc decompress test.txt.gz
127```
128
129For convenience, the output file (second argument) may be omitted. In that case, the output filename will have the same name as the input filename, but with the compression extension stripped from the end; and the input file will be deleted if successful.
130
131### Flags
132
133Flags are specified before the subcommand. Use `arc help` or `arc -h` to get usage help and a description of flags with their default values.
134
135## Library Use
136
137The archiver package allows you to easily create and open archives, walk their contents, extract specific files, compress and decompress files, and even stream archives in and out using pure io.Reader and io.Writer interfaces, without ever needing to touch the disk.
138
139```go
140import "github.com/mholt/archiver"
141```
142
143[See the package's GoDoc](https://godoc.org/github.com/mholt/archiver) for full API documentation.
144
145For example, creating or unpacking an archive file:
146
147```go
148err := archiver.Archive([]string{"testdata", "other/file.txt"}, "test.zip")
149// ...
150err = archiver.Unarchive("test.tar.gz", "test")
151```
152
153The archive format is determined by file extension. (There are [several functions in this package](https://godoc.org/github.com/mholt/archiver) which perform a task by inferring the format from file extension or file header, including `Archive()`, `Unarchive()`, `CompressFile()`, and `DecompressFile()`.)
154
155To configure the archiver used or perform, create an instance of the format's type:
156
157```go
158z := archiver.Zip{
159	CompressionLevel:       flate.DefaultCompression,
160	MkdirAll:               true,
161	SelectiveCompression:   true,
162	ContinueOnError:        false,
163	OverwriteExisting:      false,
164	ImplicitTopLevelFolder: false,
165}
166
167err := z.Archive([]string{"testdata", "other/file.txt"}, "/Users/matt/Desktop/test.zip")
168```
169
170Inspecting an archive:
171
172```go
173err = z.Walk("/Users/matt/Desktop/test.zip", func(f archiver.File) error {
174	zfh, ok := f.Header.(zip.FileHeader)
175	if ok {
176		fmt.Println("Filename:", zfh.Name)
177	}
178	return nil
179})
180```
181
182Streaming files into an archive that is being written to the HTTP response:
183
184```go
185err = z.Create(responseWriter)
186if err != nil {
187	return err
188}
189defer z.Close()
190
191for _, fname := range filenames {
192	info, err := os.Stat(fname)
193	if err != nil {
194		return err
195	}
196
197	// get file's name for the inside of the archive
198	internalName, err := archiver.NameInArchive(info, fname, fname)
199	if err != nil {
200		return err
201	}
202
203	// open the file
204	file, err := os.Open(f)
205	if err != nil {
206		return err
207	}
208
209	// write it to the archive
210	err = z.Write(archiver.File{
211		FileInfo: archiver.FileInfo{
212			FileInfo:   info,
213			CustomName: internalName,
214		},
215		ReadCloser: file,
216	})
217	file.Close()
218	if err != nil {
219		return err
220	}
221}
222```
223
224The `archiver.File` type allows you to use actual files with archives, or to mimic files when you only have streams.
225
226There's a lot more that can be done, too. [See the GoDoc](https://godoc.org/github.com/mholt/archiver) for full API documentation.
227
228**Security note: This package does NOT attempt to mitigate zip-slip attacks.** It is [extremely difficult](https://github.com/rubyzip/rubyzip/pull/376) [to do properly](https://github.com/mholt/archiver/pull/65#issuecomment-395988244) and [seemingly impossible to mitigate effectively across platforms](https://github.com/golang/go/issues/20126). [Attempted fixes have broken processing of legitimate files in production](https://github.com/mholt/archiver/pull/70#issuecomment-423267320), rendering the program unusable. Our recommendation instead is to inspect the contents of an untrusted archive before extracting it (this package provides `Walkers`) and decide if you want to proceed with extraction.
229
230
231## Project Values
232
233This project has a few principle-based goals that guide its development:
234
235- **Do our thing really well.** Our thing is creating, opening, inspecting, compressing, and streaming archive files. It is not meant to be a replacement for specific archive format tools like tar, zip, etc. that have lots of features and customizability. (Some customizability is OK, but not to the extent that it becomes overly complicated or error-prone.)
236
237- **Have good tests.** Changes should be covered by tests.
238
239- **Limit dependencies.** Keep the package lightweight.
240
241- **Pure Go.** This means no cgo or other external/system dependencies. This package should be able to stand on its own and cross-compile easily to any platform -- and that includes its library dependencies.
242
243- **Idiomatic Go.** Keep interfaces small, variable names semantic, vet shows no errors, the linter is generally quiet, etc.
244
245- **Be elegant.** This package should be elegant to use and its code should be elegant when reading and testing. If it doesn't feel good, fix it up.
246
247- **Well-documented.** Use comments prudently; explain why non-obvious code is necessary (and use tests to enforce it). Keep the docs updated, and have examples where helpful.
248
249- **Keep it efficient.** This often means keep it simple. Fast code is valuable.
250
251- **Consensus.** Contributions should ideally be approved by multiple reviewers before being merged. Generally, avoid merging multi-chunk changes that do not go through at least one or two iterations/reviews. Except for trivial changes, PRs are seldom ready to merge right away.
252
253- **Have fun contributing.** Coding is awesome!
254
255We welcome contributions and appreciate your efforts! However, please open issues to discuss any changes before spending the time preparing a pull request. This will save time, reduce frustration, and help coordinate the work. Thank you!
256