Documentation
¶
Overview ¶
Package pack turns a kage mirror on disk into a distributable artifact: a ZIM archive, or a self-contained executable that serves the mirror offline. It is the only pack-side package that touches the filesystem and the running executable; the byte-level format work lives in the zim package.
Index ¶
- func BuildApp(zimBytes []byte, opts AppOptions) (string, int64, error)
- func BuildAppDir(zimBytes []byte, opts LinuxAppOptions) (path string, size int64, hasIcon bool, err error)
- func BuildBinary(zimBytes []byte, opts BinaryOptions) (string, int64, error)
- func BuildZIM(mirrorDir string, opts ZIMOptions) (string, int64, error)
- func BuildZIMBytes(mirrorDir string, opts ZIMOptions) ([]byte, error)
- func DecodeIcon(path string) (image.Image, error)
- func Embedded() (ra io.ReaderAt, size int64, ok bool)
- func EncodeICNS(img image.Image) ([]byte, error)
- func Favicon48(mirrorDir string) ([]byte, bool)
- func FindIcon(mirrorDir string) (image.Image, string, bool)
- func Handler(r *zim.Reader) http.Handler
- func MimeForExt(p string) string
- func SniffOS(path string) string
- type AppOptions
- type BinaryOptions
- type LinuxAppOptions
- type PackStats
- type ZIMOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildApp ¶ added in v0.2.0
func BuildApp(zimBytes []byte, opts AppOptions) (string, int64, error)
BuildApp writes a double-clickable macOS application bundle that serves the packed site. Finder runs Contents/MacOS/<ExecName> with no terminal attached, which is the whole point: the bare appended binary opens a Terminal window when double-clicked, a .app does not. The executable is the same base++zim++trailer image BuildBinary produces, so Embedded finds the archive at runtime exactly as it does for a plain viewer.
It returns the bundle path and the size of the executable inside it (the part that dominates, since the plist and icon are tiny).
func BuildAppDir ¶ added in v0.2.0
func BuildAppDir(zimBytes []byte, opts LinuxAppOptions) (path string, size int64, hasIcon bool, err error)
BuildAppDir writes an AppImage-style application directory. The layout follows the AppDir convention so `appimagetool` can fold it into a single double-clickable .AppImage, but it is useful on its own: AppRun is the packed viewer, the .desktop file launches it with Terminal=false (no console), and the icon gives it a face in the file manager and menus.
It returns the AppDir path, the size of the executable inside it, and whether an icon was written (the caller needs that to decide if an .AppImage can be built, since AppImage requires one).
func BuildBinary ¶
func BuildBinary(zimBytes []byte, opts BinaryOptions) (string, int64, error)
BuildBinary writes baseExe ++ zimBytes ++ trailer to opts.Out and marks it executable. The base must be a kage binary, since the viewer behaviour lives in kage's own startup hook (see Embedded); appending a ZIM to an arbitrary executable would only produce a broken file. It returns the output path and the total byte size.
func BuildZIM ¶
func BuildZIM(mirrorDir string, opts ZIMOptions) (string, int64, error)
BuildZIM walks mirrorDir, turns every file into a C/ content entry, infers the MIME from the extension, picks a main page, adds M/ metadata and a W/mainPage redirect, and writes a .zim to opts.Out. It returns the output path and the number of bytes written.
func BuildZIMBytes ¶
func BuildZIMBytes(mirrorDir string, opts ZIMOptions) ([]byte, error)
BuildZIMBytes is the buffer-returning sibling of BuildZIM: it runs the same walk and returns the archive in memory, which the binary path appends to a base executable without writing the ZIM to disk first.
func DecodeIcon ¶ added in v0.2.0
DecodeIcon reads an icon file into an image. It handles the stdlib raster formats (PNG, JPEG, GIF) directly and unwraps a .ico container, decoding either the PNG a modern high-resolution favicon embeds or the classic BMP/DIB bitmap older ones (Apple's among them) still ship.
func Embedded ¶
Embedded inspects the running executable for an appended ZIM archive. If the KAGEPCK1 trailer is present, it returns a ReaderAt bounded to the archive, its size, and ok=true; the file handle stays open for the life of the process so the viewer can serve from it. A normal kage build has no trailer, so the cost to every ordinary invocation is one Open plus a 24-byte ReadAt.
func EncodeICNS ¶ added in v0.2.0
EncodeICNS renders img into a macOS .icns at every standard size. The source is scaled to each size with Catmull-Rom resampling, which keeps a small favicon from turning to mush when it is enlarged for the Dock. It returns an error only if img is empty or a PNG fails to encode.
func Favicon48 ¶ added in v0.2.1
Favicon48 finds the mirror's icon and renders it to a 48x48 PNG, the form the ZIM Illustrator_48x48@1 metadata takes and the icon Kiwix shows for the book. It returns ok=false when the mirror has no usable icon, in which case the archive simply ships without one rather than failing the pack.
func FindIcon ¶ added in v0.2.0
FindIcon looks through a cloned mirror for the site's icon and decodes it. It returns the image, the path it came from (for a friendly log line), and ok=false when nothing usable is found, in which case the caller just builds a bundle with the default icon. Discovery never fails the pack.
func Handler ¶
Handler serves a ZIM archive over HTTP. "/" redirects to the archive's main page; "/a/b.png" maps to the C/a/b.png content entry. Because the saved HTML's links are mirror-relative paths, and those are exactly the C urls, a click in a served page hits the right entry with no rewriting. A miss is a plain 404.
func MimeForExt ¶
MimeForExt returns the MIME type for a path's extension, defaulting to application/octet-stream when the extension is unknown or absent.
func SniffOS ¶ added in v0.1.2
SniffOS reads the first bytes of an executable and returns the GOOS family it was built for: "windows", "darwin", "linux", or "" when the bytes match none of them. It is how pack decides whether a cross-built viewer needs a .exe suffix and which run hint to print, without trusting the base's file name.
Types ¶
type AppOptions ¶ added in v0.2.0
type AppOptions struct {
Out string // path to the .app directory
Base string // base kage binary (must be a macOS build); default os.Executable()
Name string // display name shown in Finder and the Dock
ExecName string // file name of the executable inside Contents/MacOS
Identifier string // CFBundleIdentifier, e.g. com.kage.paulgraham
Version string // CFBundleShortVersionString; default 1.0
Icon image.Image // optional; written as Resources/icon.icns
}
AppOptions controls how a macOS .app bundle is assembled around a packed viewer.
type BinaryOptions ¶
type BinaryOptions struct {
Out string // output path
Base string // base kage binary; default os.Executable()
}
BinaryOptions controls how a self-contained viewer is assembled.
type LinuxAppOptions ¶ added in v0.2.0
type LinuxAppOptions struct {
Out string // path to the .AppDir directory
Base string // base kage binary (must be a Linux build); default os.Executable()
Name string // display name shown in menus
ExecName string // base name for the .desktop and icon files
Comment string // optional one-line description for the launcher
Version string // version string recorded in the .desktop
Icon image.Image // optional; written as the launcher icon
}
LinuxAppOptions controls how a Linux application directory is assembled around a packed viewer.
type PackStats ¶ added in v0.3.0
PackStats reports how a pack reused cached compression. ClustersReused is the number of clusters whose compressed bytes came straight from the cache; ClustersCompressed is the number that were zstd-compressed this run.
type ZIMOptions ¶
type ZIMOptions struct {
Out string // output path (default <mirror-base>.zim)
NoCompress bool // store every cluster raw (code 1)
Title string // overrides M/Title
Description string // M/Description
Language string // M/Language (default "eng")
Date string // M/Date, e.g. "2026-06-14"
Version string // kage version, recorded as M/Scraper
// CachePath, when set, points at a content-addressed cluster cache sidecar.
// Compression of unchanged clusters is reused from it, and the cache is
// rewritten after a successful pack. Empty disables the cache. It has no
// effect with NoCompress, where nothing is compressed.
CachePath string
// Stats, when non-nil, is filled with how many clusters were reused from the
// cache versus compressed fresh. It lets the caller report incremental gains
// without changing the function's return signature.
Stats *PackStats
}
ZIMOptions controls how a mirror is packed into a ZIM archive. Date is passed in from the CLI boundary rather than read from the clock, so the zim and pack packages stay pure and packing the same mirror twice is byte-identical.