Package Examples
A set of `.pkg.lua` examples for creating Zoi packages.
This document provides a set of examples for creating .pkg.lua files. These files are the core of Zoi's packaging system, defining everything from metadata to installation methods using the power of Lua scripting.
Simple Pre-compiled Binary
This example shows how to package a simple pre-compiled binary that is downloaded from a URL (like a GitHub release). It's for a hypothetical tool called my-cli.
-- my-cli.pkg.lua
metadata({
name = "my-cli",
repo = "community",
version = "1.2.3",
description = "A cool command-line tool.",
website = "https://example.com/my-cli",
license = "MIT",
bins = { "my-cli" },
types = { "pre-compiled" },
})
function prepare()
local version = PKG.version
local os = SYSTEM.OS
local arch = SYSTEM.ARCH
local ext = "tar.gz"
if os == "windows" then
ext = "zip"
end
-- Construct the download URL, e.g. from GitHub releases
local url = "https://example.com/my-cli/releases/download/v" .. version .. "/my-cli-" .. os .. "-" .. arch .. "." .. ext
-- Download and extract the archive into a directory named "extracted_cli" inside the temporary build directory
UTILS.EXTRACT(url, "extracted_cli")
end
function package()
local bin_name = "my-cli"
if SYSTEM.OS == "windows" then
bin_name = "my-cli.exe"
end
-- Copy the binary from the extracted directory to the package store.
-- ${pkgstore} is a special variable that points to the final installation directory for the package.
zcp("extracted_cli/" .. bin_name, "${pkgstore}/bin/" .. bin_name)
endBundling a Local Asset
This example shows how to use the ${pkgluadir} variable to bundle a file that is located in the same directory as your .pkg.lua file.
Assume you have the following file structure:
my-package/
├── my-package.pkg.lua
└── icon.png-- my-package.pkg.lua
metadata({
name = "my-package-with-asset",
repo = "community",
version = "1.0.0",
description = "A package that bundles a local asset.",
license = "MIT",
types = { "source" },
})
function package()
-- Copy the icon.png from the same directory as the pkg.lua file
-- into the package's shared data directory.
zcp("${pkgluadir}/icon.png", "${pkgstore}/share/icons/my-package.png")
endSimple Source Build
This example shows how to build a package from source. It clones a git repository and runs make to build the binary.
-- my-git-tool.pkg.lua
metadata({
name = "my-git-tool",
repo = "community",
version = "1.0.0",
description = "A simple tool built from a git repository.",
website = "https://example.com/my-git-tool",
license = "GPL-3.0-or-later",
bins = { "my-git-tool" },
types = { "source" },
})
-- Define build-time dependencies. Zoi will ensure these are available.
dependencies({
build = {
required = { "native:gcc", "native:make", "native:git" }
}
})
function prepare()
-- Clone the git repository into a "source" directory inside the temporary build directory
cmd("git clone https://example.com/my-git-tool.git source")
end
function package()
-- Run build commands inside the cloned repository
cmd("cd source && make")
-- Copy the final binary to the package store
zcp("source/my-git-tool", "${pkgstore}/bin/my-git-tool")
endAdvanced Example
This example, based on the real hello package from the zillowe repository, demonstrates more advanced features like platform mapping, checksum and signature verification, and handling both pre-compiled and source builds in one file.
local repo_owner = "Zillowe"
local repo_name = "Hello"
local version = ZOI.VERSION or "3.0.0"
local git_url = "https://github.com/" .. repo_owner .. "/" .. repo_name .. ".git"
local release_base_url = "https://github.com/" .. repo_owner .. "/" .. repo_name .. "/releases/download/v" .. version
local platform_map = {
macos = "darwin",
}
local function get_mapped_platform()
local current_platform = SYSTEM.OS .. "-" .. SYSTEM.ARCH
return platform_map[current_platform] or platform_map[SYSTEM.OS] or current_platform
end
local function get_mapped_os()
return get_mapped_platform():match("([^-]+)")
end
metadata({
name = "hello",
repo = "zillowe",
version = version,
description = "Hello World",
website = "https://github.com/Zillowe/Hello",
git = git_url,
man = "https://raw.githubusercontent.com/Zillowe/Hello/refs/heads/main/app/man.md",
maintainer = {
name = "Zillowe Foundation",
website = "https://zillowe.qzz.io",
email = "[email protected]",
},
author = {
name = "Zillowe Foundation",
website = "https://zillowe.qzz.io",
email = "[email protected]",
},
license = "Apache-2.0",
bins = { "hello" },
conflicts = { "hello" },
types = { "source", "pre-compiled" },
})
dependencies({
build = {
types = {
source = {
required = { "native:zig" },
}
}
},
})
function prepare()
print("Adding PGP key for verification...")
addPgpKey("https://zillowe.pages.dev/keys/zillowe-main.asc", "zillowe-main")
if BUILD_TYPE == "pre-compiled" then
local ext
if SYSTEM.OS == "windows" then
ext = "zip"
else
ext = "tar.xz"
end
local file_name = "hello-" .. get_mapped_os() .. "-" .. SYSTEM.ARCH .. "." .. ext
local url = release_base_url .. "/" .. file_name
UTILS.EXTRACT(url, "precompiled")
elseif BUILD_TYPE == "source" then
cmd("git clone " .. PKG.git .. " " .. BUILD_DIR .. "/source")
cmd("cd " .. BUILD_DIR .. "/source && zig build-exe main.zig -O ReleaseSmall --name hello")
end
end
function package()
local bin_name = "hello"
if SYSTEM.OS == "windows" then
bin_name = "hello.exe"
end
if BUILD_TYPE == "pre-compiled" then
local bin_path = UTILS.FIND.file("precompiled", bin_name)
if bin_path then
zcp(bin_path, "${pkgstore}/bin/" .. bin_name)
else
error("Could not find '" .. bin_name .. "' in pre-compiled archive.")
end
elseif BUILD_TYPE == "source" then
zcp("source/" .. bin_name, "${pkgstore}/bin/" .. bin_name)
end
end
function verify()
if BUILD_TYPE == "pre-compiled" then
local checksum_url = release_base_url .. "/checksums-512.txt"
local checksum_content = UTILS.FETCH.url(checksum_url)
local ext
if SYSTEM.OS == "windows" then
ext = "zip"
else
ext = "tar.xz"
end
local file_name = "hello-" .. get_mapped_os() .. "-" .. SYSTEM.ARCH .. "." .. ext
local file_path = BUILD_DIR .. "/" .. file_name
local expected_checksum = UTILS.PARSE.checksumFile(checksum_content, file_name)
if not expected_checksum or not verifyHash(file_path, "sha512-" .. expected_checksum) then
print("Checksum verification failed!")
return false
end
print("Checksum verified successfully.")
print("Verifying signature...")
local sig_url = release_base_url .. "/" .. file_name .. ".sig"
local sig_path = BUILD_DIR .. "/" .. file_name .. ".sig"
print("Downloading signature from " .. sig_url)
UTILS.FILE(sig_url, sig_path)
if not verifySignature(file_path, sig_path, "zillowe-main") then
print("Signature verification failed!")
return false
end
print("Signature verified successfully.")
return true
end
return true
end
function uninstall() endLast updated on
