Packages and identity
A package is a folder with a package.kdl manifest and a fixed
layout of code and files. It is the unit you run, share and depend on, and
its name says who owns it.
Layout
my-package/
+-- package.kdl the manifest: name, version, kind, needs
+-- init.lua an app's script, or what a library returns
+-- lib/ modules: .lua files, at any depth
| +-- util.lua require("util")
| +-- sub/
| +-- leaf.lua require("sub.leaf")
+-- assets/ every other file, at any depth
| +-- player.png
+-- tests/ the package's tests, never shipped
DatumHue loads only these parts:
package.kdl, which every package has;init.lua, the app's script, or whatrequireof a library returns;lib/, the modules your code loads withrequire(Modules and dependencies);assets/, everything else: images, sounds, data, fonts. Your code reads them through its own package, as indatumhue..package: dir(): read("assets/ player. png"): image()
Anything else at the top, such as a README.md, an editor's settings or
the tests/ folder, stays out of the package when it is packed or run.
deps/ is kept for the dependencies DatumHue fetches into it; you never
write it yourself. A .dhignore file at the top leaves out more, with
the same patterns as a .gitignore.
The manifest
package.kdl says what the package is.
Manifest reference lists every key; these four
say which package it is and what kind:
nameis the package's identity, written@scope/name. The scope is the person or team that owns it._reads as-, so@alice/ball_pitand@alice/ball-pitare one package.titleis the name people see. Leave it out and DatumHue makes one fromname:@alice/ball-pitreads Ball Pit.versionorders the package's releases, as a SemVer version such as1.4.0.kindsays what the package is:
| Kind | Holds | Used by |
|---|---|---|
app | a script in init.lua that people run | people, launchers, other apps |
library | modules in lib/ | packages that require them |
asset_pack | files and no code: themes, books, data, fonts, media | packages that read them |
Publishing checks the scope against your sign-in, so only you, or your team, can publish under it.
Some keys apply only to apps. service #true makes an app a service
app, with no window (How your app runs).
sealed #true keeps its files from other apps: one that loads it sees
its manifest, but not its code. capabilities lists the permissions the
app needs (Permissions and capabilities).
Archives
A package also travels as one file, a .dhpkg archive: a zip of the
package's files under their paths in the package.
datumhue pkg pack makes one, and datumhue pkg unpack turns it back
into a folder. datumhue run takes either.
Packing and unpacking change nothing in an unsealed package: the archive
and its folder have the same content hash, the one datumhue pkg hash
prints.
Package handles
A Package handle is a loaded package: your app's own,
datumhue.package, or another one your app loads with
Dir:load_package or File:load_package. Its Package.name and
Package.title are properties, and Package:version, Package:kind and
Package:dir are methods. Package:dir reads the package's files, and is
nil for a sealed package loaded from outside; your app always reads its
own.
local own = datumhue.package
print(own.title, own:version())
local addon = datumhue.args.files.addon:load_package()
print(addon.name, addon:version(), addon:kind())
local dir = addon:dir()
if dir then
print(dir:read("init.lua"):text())
end
Two handles are equal only when they are the same handle: loading one package twice gives two handles that are not equal. Compare their names and versions instead.
See also
Reference used on this page: datumhue.package Package.title Package:version datumhue.args File:load_package Package.name Package:kind Package:dir Dir:read Bytes:text Dir:load_package