{"id":37126916,"url":"https://github.com/maxmcd/archiver","last_synced_at":"2026-01-14T14:47:01.622Z","repository":{"id":57586872,"uuid":"298825209","full_name":"maxmcd/archiver","owner":"maxmcd","description":"Easily create \u0026 extract archives, and compress \u0026 decompress files of various formats","archived":false,"fork":true,"pushed_at":"2021-09-23T00:46:33.000Z","size":344,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-11T03:15:23.112Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://godoc.org/github.com/mholt/archiver","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"mholt/archiver","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maxmcd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["mholt"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-09-26T13:56:38.000Z","updated_at":"2021-09-23T00:46:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/maxmcd/archiver","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/maxmcd/archiver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxmcd%2Farchiver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxmcd%2Farchiver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxmcd%2Farchiver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxmcd%2Farchiver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maxmcd","download_url":"https://codeload.github.com/maxmcd/archiver/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxmcd%2Farchiver/sbom","scorecard":{"id":629742,"data":{"date":"2025-08-11","repo":{"name":"github.com/maxmcd/archiver","commit":"06ef4f8f175b9c878f53c3ef26ecf2c708f250ac"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T07:30:01.686Z","repository_id":57586872,"created_at":"2025-08-21T07:30:01.686Z","updated_at":"2025-08-21T07:30:01.686Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28423988,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T13:30:50.153Z","status":"ssl_error","status_checked_at":"2026-01-14T13:29:08.907Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-14T14:47:01.026Z","updated_at":"2026-01-14T14:47:01.616Z","avatar_url":"https://github.com/maxmcd.png","language":"Go","funding_links":["https://github.com/sponsors/mholt"],"categories":[],"sub_categories":[],"readme":"# archiver [![archiver GoDoc](https://img.shields.io/badge/reference-godoc-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/mholt/archiver?tab=doc) \u003ca href=\"https://dev.azure.com/mholt-dev/Archiver/_build\"\u003e\u003cimg src=\"https://img.shields.io/azure-devops/build/mholt-dev/1e14e7f7-f929-4fec-a1db-fa5a3c0d4ca9/2/master.svg?label=cross-platform%20tests\u0026style=flat-square\"\u003e\u003c/a\u003e\n\nIntroducing **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 platform-specific or format-specific archive utilities.\n\n## Features\n\nPackage archiver makes it trivially easy to make and extract common archive formats such as tarball (and its compressed variants) and zip. 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.\n\nFiles are put into the root of the archive; directories are recursively added, preserving structure.\n\n- Make whole archives from a list of files\n- Open whole archives to a folder\n- Extract specific files/folders from archives\n- Stream files in and out of archives without needing actual files on disk\n- Traverse archive contents without loading them\n- Compress files\n- Decompress files\n- Streaming compression and decompression\n- Several archive and compression formats supported\n\n### Format-dependent features\n\n- Gzip is multithreaded\n- Optionally create a top-level folder to avoid littering a directory or archive root with files\n- Toggle overwrite existing files\n- Adjust compression level\n- Zip: store (not compress) already-compressed files\n- Make all necessary directories\n- Open password-protected RAR archives\n- Optionally continue with other files after an error\n\n### Supported compression formats\n\n- brotli (br)\n- bzip2 (bz2)\n- flate (zip)\n- gzip (gz)\n- lz4\n- snappy (sz)\n- xz\n- zstandard (zstd)\n\n### Supported archive formats\n\n- .zip\n- .tar (including any compressed variants like .tar.gz)\n- .rar (read-only)\n\nTar files can optionally be compressed using any of the above compression formats.\n\n## GoDoc\n\nSee \u003chttps://pkg.go.dev/github.com/mholt/archiver/v3\u003e\n\n## Install\n\n### With webi\n\n[`webi`](https://webinstall.dev/arc) will install `webi` and `arc` to `~/.local/bin/` and update your `PATH`.\n\n#### Mac, Linux, Raspberry Pi\n\n```bash\ncurl -fsS https://webinstall.dev/arc | bash\n```\n\n#### Windows 10\n\n```pwsh\ncurl.exe -fsS -A MS https://webinstall.dev/arc | powershell\n```\n\n### With Go\n\nTo install the runnable binary to your \\$GOPATH/bin:\n\n```bash\ngo get github.com/mholt/archiver/cmd/arc\n```\n\n### Manually\n\nTo install manually\n\n1. Download the binary for your platform from the [Github Releases](https://github.com/mholt/archiver/releases) page.\n2. Move the binary to a location in your path, for example:\n   - without `sudo`:\n     ```bash\n     chmod a+x ~/Downloads/arc_*\n     mkdir -p ~/.local/bin\n     mv ~/Downloads/arc_* ~/.local/bin/arc\n     ```\n   - as `root`:\n     ```bash\n     chmod a+x ~/Downloads/arc_*\n     sudo mkdir -p /usr/local/bin\n     sudo mv ~/Downloads/arc_* /usr/local/bin/arc\n     ```\n3. If needed, update `~/.bashrc` or `~/.profile` to include add `arc` in your `PATH`, for example:\n   ```\n   echo 'PATH=\"$HOME:/.local/bin:$PATH\"' \u003e\u003e ~/.bashrc\n   ```\n\n## Build from Source\n\nYou can successfully build `arc` with just the go tooling, or with `goreleaser`.\n\n### With `go`\n\n```bash\ngo build cmd/arc/*.go\n```\n\n### Multi-platform with `goreleaser`\n\nBuilds with `goreleaser` will also include version info.\n\n```bash\ngoreleaser --snapshot --skip-publish --rm-dist\n```\n\n## Command Use\n\n### Make new archive\n\n```bash\n# Syntax: arc archive [archive name] [input files...]\n\narc archive test.tar.gz file1.txt images/file2.jpg folder/subfolder\n```\n\n(At least one input file is required.)\n\n### Extract entire archive\n\n```bash\n# Syntax: arc unarchive [archive name] [destination]\n\narc unarchive test.tar.gz\n```\n\n(The destination path is optional; default is current directory.)\n\nThe archive name must end with a supported file extension\u0026mdash;this is how it knows what kind of archive to make. Run `arc help` for more help.\n\n### List archive contents\n\n```bash\n# Syntax: arc ls [archive name]\n\narc ls caddy_dist.tar.gz\n```\n\n```txt\ndrwxr-xr-x  matt    staff   0       2018-09-19 15:47:18 -0600 MDT   dist/\n-rw-r--r--  matt    staff   6148    2017-08-07 18:34:22 -0600 MDT   dist/.DS_Store\n-rw-r--r--  matt    staff   22481   2018-09-19 15:47:18 -0600 MDT   dist/CHANGES.txt\n-rw-r--r--  matt    staff   17189   2018-09-19 15:47:18 -0600 MDT   dist/EULA.txt\n-rw-r--r--  matt    staff   25261   2016-03-07 16:32:00 -0700 MST   dist/LICENSES.txt\n-rw-r--r--  matt    staff   1017    2018-09-19 15:47:18 -0600 MDT   dist/README.txt\n-rw-r--r--  matt    staff   288     2016-03-21 11:52:38 -0600 MDT   dist/gitcookie.sh.enc\n...\n```\n\n### Extract a specific file or folder from an archive\n\n```bash\n# Syntax: arc extract [archive name] [path in archive] [destination on disk]\n\narc extract test.tar.gz foo/hello.txt extracted/hello.txt\n```\n\n### Compress a single file\n\n```bash\n# Syntax: arc compress [input file] [output file]\n\narc compress test.txt compressed_test.txt.gz\narc compress test.txt gz\n```\n\nFor 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.\n\n### Decompress a single file\n\n```bash\n# Syntax: arc decompress [input file] [output file]\n\narc decompress test.txt.gz original_test.txt\narc decompress test.txt.gz\n```\n\nFor 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.\n\n### Flags\n\nFlags are specified before the subcommand. Use `arc help` or `arc -h` to get usage help and a description of flags with their default values.\n\n## Library Use\n\nThe 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.\n\nTo use as a dependency in your project:\n\n```bash\ngo get github.com/mholt/archiver/v3\n```\n\n```go\nimport \"github.com/mholt/archiver/v3\"\n```\n\n[See the package's GoDoc](https://pkg.go.dev/github.com/mholt/archiver?tab=doc) for full API documentation.\n\nFor example, creating or unpacking an archive file:\n\n```go\nerr := archiver.Archive([]string{\"testdata\", \"other/file.txt\"}, \"test.zip\")\n// ...\nerr = archiver.Unarchive(\"test.tar.gz\", \"test\")\n```\n\nThe archive format is determined by file extension. (There are [several functions in this package](https://pkg.go.dev/github.com/mholt/archiver?tab=doc) which perform a task by inferring the format from file extension or file header, including `Archive()`, `Unarchive()`, `CompressFile()`, and `DecompressFile()`.)\n\nTo configure the archiver used or perform, create an instance of the format's type:\n\n```go\nz := archiver.Zip{\n\tCompressionLevel:       flate.DefaultCompression,\n\tMkdirAll:               true,\n\tSelectiveCompression:   true,\n\tContinueOnError:        false,\n\tOverwriteExisting:      false,\n\tImplicitTopLevelFolder: false,\n}\n\nerr := z.Archive([]string{\"testdata\", \"other/file.txt\"}, \"/Users/matt/Desktop/test.zip\")\n```\n\nInspecting an archive:\n\n```go\nerr = z.Walk(\"/Users/matt/Desktop/test.zip\", func(f archiver.File) error {\n\tzfh, ok := f.Header.(zip.FileHeader)\n\tif ok {\n\t\tfmt.Println(\"Filename:\", zfh.Name)\n\t}\n\treturn nil\n})\n```\n\nStreaming files into an archive that is being written to the HTTP response:\n\n```go\nerr = z.Create(responseWriter)\nif err != nil {\n\treturn err\n}\ndefer z.Close()\n\nfor _, fname := range filenames {\n\tinfo, err := os.Stat(fname)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// get file's name for the inside of the archive\n\tinternalName, err := archiver.NameInArchive(info, fname, fname)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// open the file\n\tfile, err := os.Open(f)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// write it to the archive\n\terr = z.Write(archiver.File{\n\t\tFileInfo: archiver.FileInfo{\n\t\t\tFileInfo:   info,\n\t\t\tCustomName: internalName,\n\t\t},\n\t\tReadCloser: file,\n\t})\n\tfile.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n}\n```\n\nThe `archiver.File` type allows you to use actual files with archives, or to mimic files when you only have streams.\n\nThere's a lot more that can be done, too. [See the GoDoc](https://pkg.go.dev/github.com/mholt/archiver?tab=doc) for full API documentation.\n\n**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.\n\n## Project Values\n\nThis project has a few principle-based goals that guide its development:\n\n- **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.)\n\n- **Have good tests.** Changes should be covered by tests.\n\n- **Limit dependencies.** Keep the package lightweight.\n\n- **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.\n\n- **Idiomatic Go.** Keep interfaces small, variable names semantic, vet shows no errors, the linter is generally quiet, etc.\n\n- **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.\n\n- **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.\n\n- **Keep it efficient.** This often means keep it simple. Fast code is valuable.\n\n- **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.\n\n- **Have fun contributing.** Coding is awesome!\n\nWe 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!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxmcd%2Farchiver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxmcd%2Farchiver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxmcd%2Farchiver/lists"}