Zig 0.17.0

Modules and migrations

On this page:

  • spider.module: Declares a module: pub const spider_module = spider.module(.{ .name, .version, .spider, ... }), checked at compile time. Mounted with server.mountModules(.{ ... }).
  • spider.Manifest: What a module declares about itself (M.spider_module.manifest).
  • spider.ModuleEnv: The environment variables a module declares in its manifest (.env).
  • spider.Migration: One database migration, a module's or the app's own: .{ .name = "0001_init", .sql = @embedFile(...) }.
  • spider.Check: Given to a module's check(c) before the server starts: c.fail(...), c.env(...).
  • spider.ModuleReport: The modules' checks (server.check): report.ok(), report.write(w).
  • spider.ModuleProblem: One problem in a ModuleReport: the module and the message.

spider.module

zig
pub fn module(comptime spec: anytype) type

Declares a module. Put it in the module's root file as pub const spider_module = spider.module(.{ ... });: it checks the manifest at compile time (name, version, the Spider range against spider.version, requires, migrations, env) and fails the build with a message naming the module when something is wrong.

zig
pub const spider_module = spider.module(.{
    .name = "notify",
    .version = "0.2.0",
    .spider = ">=0.11.0 <0.13.0",
    .migrations = &.{.{ .name = "0001_init", .sql = @embedFile("sql/0001_init.sql") }},
    .env = .{ .optional = .{"VAPID_PUBLIC_KEY"} },
});

pub fn check(c: *spider.Check) !void {
    if (c.env("VAPID_PUBLIC_KEY") != null and c.env("VAPID_PRIVATE_KEY") == null)
        c.fail("VAPID_PRIVATE_KEY is empty while VAPID_PUBLIC_KEY is set", .{});
}

module.manifest

zig
pub const manifest: Manifest = m

The checked manifest.

spider.Manifest

zig
pub const Manifest = struct

What a module declares about itself. Built by spider.module; read from M.spider_module.manifest.

Fields

  • name: []const u8: [a-z][a-z0-9_]*, at most 64 bytes, unique in the app.
  • version: []const u8: The module's own version (semver).
  • spider: []const u8: The Spider versions it supports, as a range: ">=0.11.0 <0.13.0".
  • requires: []const []const u8 = &.{}: The modules it needs, by name; they start before it.
  • migrations: []const Migration = &.{}: Its database migrations, in the order they run.
  • env: Env = .{}: The environment variables it reads.

spider.ModuleEnv

zig
pub const Env = struct

The environment variables a module reads: required ones must be set (and not empty) for the module to start; optional ones are listed for the reader and the surface lock.

Fields

  • required: []const []const u8 = &.{}: Must be set and not empty, or listen() refuses to start.
  • optional: []const []const u8 = &.{}: Read when present.

spider.Migration

zig
pub const Migration = struct

One forward migration: a name and the SQL it runs. A module lists its own in its manifest; an app's come from its migrations folder (spider.addMigrations in build.zig, then server.migrations(...)).

The name is four or more digits, _, then lowercase letters, digits and _ (0001_init); names sort in the order they run. The SQL may hold several statements; it runs in one transaction that Spider opens, so it must not contain BEGIN, COMMIT or ROLLBACK. When the file has a -- migrate:up line, only what follows it runs, up to -- migrate:down.

zig
.migrations = .{
    .{ .name = "0001_init", .sql = @embedFile("sql/0001_init.sql") },
},

Fields

  • name: []const u8: 0001_init: ordering digits, _, a lowercase description.
  • sql: []const u8: The statements, PostgreSQL. Runs inside a transaction.

spider.Check

zig
pub const Check = struct

Given to a module's check(c), which runs before any module boots and must not change anything. fail records a problem (the check goes on, so the report lists every one); a check that returns an error counts as one more.

Fields

  • arena: std.mem.Allocator: Lives until the report is written.
  • io: Io: An Io for the check (a database query, a file).
  • module: []const u8: The module being checked.

Check.fail

zig
pub fn fail(self: *Check, comptime fmt: []const u8, args: anytype) void

Records a problem: c.fail("FCM_PRIVATE_KEY is empty", .{}).

Check.env

zig
pub fn env(_: *Check, name: []const u8) ?[]const u8

The value of an environment variable (as spider.env.get), or null.

spider.ModuleReport

zig
pub const Report = struct

The result of the checks every module runs before listen().

Fields

  • arena: std.mem.Allocator
  • problems: std.ArrayList(Problem) = .empty: Every problem found, in the order the modules start.
  • warnings: std.ArrayList(Problem) = .empty: What deserves attention without keeping the server from starting: the database holds migrations this binary does not know (a newer version migrated it; this one is a rollback).
  • checked: usize = 0: How many modules were checked.

ModuleReport.ok

zig
pub fn ok(self: *const Report) bool

True when no module reported a problem (warnings do not count).

ModuleReport.write

zig
pub fn write(self: *const Report, w: *Io.Writer) Io.Writer.Error!void

Writes the report: one line per problem, under a summary line, then one line per warning.

spider.ModuleProblem

zig
pub const Problem = struct

One thing a module needs and does not have.

Fields

  • module: []const u8: The module's name.
  • message: []const u8: What is wrong, and what to do.