Skip to content

tar

stable

Read, write, and inspect tar and tar.gz archives — listing entries, extracting to disk, creating archives from string data, and appending files.

use plugin tar::{list, extract, create, …}
10 functions Data Formats
/ filter jk navigate Esc clear
Functions (10)
  1. list List entries in a .tar archive
  2. extract Extract a .tar archive to a directory
  3. create Create a .tar archive from string entries
  4. read_entry Read a specific entry as a string
  5. read_entry_bytes Read a specific entry as raw bytes
  6. add_file Append a file from disk to an archive
  7. entry_count Count entries in an archive
  8. list_gz List entries in a .tar.gz archive
  9. extract_gz Extract a .tar.gz archive to a directory
  10. create_gz Create a .tar.gz archive from string entries

Overview

tar is a small toolkit for working with Unix tape archives (.tar) and their gzip-compressed variant (.tar.gz / .tgz). Every function is stateless and path-based: you hand it the path to an archive on disk, and it opens, reads, or rewrites that file in place — there is no archive handle to keep around. Archive contents can be inspected without unpacking (list, entry_count, read_entry), extracted to a directory, or built from scratch out of in-memory string data.

Reach for it whenever you need to bundle several pieces of generated content into one file, ship a release tarball, or pull a single configuration entry out of an archive without extracting the whole thing. Each .tar operation has a matching *_gz form that transparently handles gzip compression, so the workflow is the same whether or not the archive is compressed.

Common patterns

Build an archive from generated content, then verify it by listing its entries:

use plugin tar::{tar}

tar.create("bundle.tar", [
    #{"path": "readme.txt", "data_str": "Hello from Zolo"},
    #{"path": "config.json", "data_str": '{"version": 1}'}
])

print("{tar.entry_count("bundle.tar")} entries:")
for _, entry in tar.list("bundle.tar") {
    print("  {entry["path"]} ({entry["size"]} bytes)")
}

Pull a single entry out of an archive without extracting everything to disk:

use plugin tar::{tar}

let settings = tar.read_entry("release.tar", "config/settings.json")
print(settings)

Ship a compressed release: create a .tar.gz, then unpack it elsewhere:

use plugin tar::{tar}

tar.create_gz("release.tar.gz", [
    #{"path": "bin/app", "data_str": "#!/bin/sh\necho hello"},
    #{"path": "README.md", "data_str": "# My App"}
])

tar.extract_gz("release.tar.gz", "dist/")
print("unpacked release into dist/")

List entries in a .tar archive

Lists all entries in a .tar file. Each entry is a table with path, size (bytes), and modified (Unix timestamp).

use plugin tar::{tar}

let entries = tar.list("archive.tar")
for _, entry in entries {
    print("{entry["path"]} ({entry["size"]} bytes)")
}

Because each entry carries its modified timestamp, you can scan an archive for its newest member:

use plugin tar::{tar}

let newest = 0
for _, entry in tar.list("archive.tar") {
    if entry["modified"] > newest {
        newest = entry["modified"]
    }
}
print("most recent entry mtime: {newest}")

Extract a .tar archive to a directory

Extracts all contents of a .tar file into the dest directory. Creates directories as needed.

use plugin tar::{tar}

tar.extract("archive.tar", "output/")
print("extracted to output/")

Create a .tar archive from string entries

Creates a new .tar file at output_path from a table of entries. Each entry must have a path (archive path) and data_str (file content as string). A missing data_str is treated as an empty file. Entries are written with mode 0644.

use plugin tar::{tar}

tar.create("bundle.tar", [
    #{"path": "readme.txt", "data_str": "Hello from Zolo"},
    #{"path": "config.json", "data_str": '{"version": 1}'}
])

The entries table can be assembled programmatically — for example, snapshotting a set of named documents into one archive:

use plugin tar::{tar}

let docs = #{"intro.md": "# Intro", "guide.md": "# Guide"}

let entries = []
for name, body in docs {
    entries.push(#{"path": name, "data_str": body})
}
tar.create("docs.tar", entries)

Read a specific entry as a string

Reads the content of a specific entry inside the archive as a UTF-8 string. The whole archive is scanned until the matching entry_path is found, and an error is raised if no such entry exists.

use plugin tar::{tar}

let content = tar.read_entry("archive.tar", "config/settings.json")
print(content)

Combine it with list to read back every text entry in an archive:

use plugin tar::{tar}

for _, entry in tar.list("docs.tar") {
    print("--- {entry["path"]} ---")
    print(tar.read_entry("docs.tar", entry["path"]))
}

Read a specific entry as raw bytes

Reads the content of a specific entry as raw bytes rather than a UTF-8 string. The value is a byte buffer (the plugin's signature reports it as any). Use this for binary members such as images or compiled artifacts, where decoding as text would be lossy. Like read_entry, it raises an error if the entry is not present.

use plugin tar::{tar}

let logo = tar.read_entry_bytes("archive.tar", "assets/logo.png")
print(logo.len())

Append a file from disk to an archive

Appends a file from disk into an existing .tar archive under the given archive_name. The existing entries are read back and rewritten alongside the new file, so the archive is rebuilt rather than appended in place. If the archive does not exist yet, a new one is created containing just the added file.

use plugin tar::{tar}

tar.add_file("bundle.tar", "dist/app.js", "app.js")
tar.add_file("bundle.tar", "dist/styles.css", "styles.css")
print("bundle now has {tar.entry_count("bundle.tar")} files")

Count entries in an archive

Returns the number of entries in the archive without reading their content.

use plugin tar::{tar}

let n = tar.entry_count("archive.tar")
print("{n} entries in archive")

List entries in a .tar.gz archive

Same as list but transparently decompresses a .tar.gz (or .tgz) file first.

use plugin tar::{tar}

let entries = tar.list_gz("archive.tar.gz")
for _, entry in entries {
    print("{entry["path"]}")
}

Extract a .tar.gz archive to a directory

Extracts all contents of a .tar.gz file into the dest directory.

use plugin tar::{tar}

tar.extract_gz("release.tar.gz", "dist/")

Create a .tar.gz archive from string entries

Creates a new compressed .tar.gz file from a table of {path, data_str} entries, using the same entry format as create. Uses the default gzip compression level.

use plugin tar::{tar}

tar.create_gz("release.tar.gz", [
    #{"path": "bin/app", "data_str": "#!/bin/sh\necho hello"},
    #{"path": "README.md", "data_str": "# My App\nSee docs."}
])

The compressed archive can be inspected with the *_gz readers without ever writing it to disk uncompressed:

use plugin tar::{tar}

for _, entry in tar.list_gz("release.tar.gz") {
    print("{entry["path"]}: {entry["size"]} bytes")
}
enespt-br