commit 0f68bd29fd9c6c2f623463137d5fe1e9137bc7a8
parent 0db23b0b5610f970a61c13955aa1abd178e31a77
Author: phoebos <ben@bvnf.space>
Date: Fri, 26 Apr 2024 14:31:53 +0100
add ldoc documentation
Diffstat:
10 files changed, 193 insertions(+), 63 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +1,2 @@
*.so
+doc/
diff --git a/Makefile b/Makefile
@@ -23,3 +23,9 @@ bliss/b3sum.so: bliss/b3sum.c
clean:
rm -f bliss/b3sum.so
+
+doc:
+ rm -fr doc/
+ ldoc .
+
+.PHONY: all install clean doc
diff --git a/README b/README
@@ -1,38 +0,0 @@
-BLISS
-=====
-
-An implementation of the kiss package manager in Lua.
-
-[ ] alternatives
-[x] build
-[ ] hooks
-[x] checksum
-[x] download
-[ ] install
-[x] list
-[ ] remove
-[x] search
-[ ] update
-[ ] upgrade
-[x] version
-[ ] ext
-
-Why Lua?
---------
-
-Lua ...
- - shares many goals with KISS, such as simplicity and efficiency.
- - offers advantages over shell as a "proper" programming language.
- - can easily be extended by code written in C (etc).
- - is relatively fast.
-
-Dependencies
-------------
-
-Lua 5.4
-lua-posix library (https://github.com/luaposix/luaposix)
-BLAKE3 C library (https://git.sr.ht/~mcf/b3sum) (built with -fPIC)
-
-Rationale: plain Lua lacks UNIX-specific bindings which we need (working with
-files and paths) so either I would write a set of Lua bindings to C, but it's as
-simple to use an existing set such as lua-posix.
diff --git a/README.md b/README.md
@@ -0,0 +1,39 @@
+BLISS
+=====
+
+An implementation of the kiss package manager in Lua.
+
+ * [ ] alternatives
+ * [x] build
+ * [ ] hooks
+ * [x] checksum
+ * [x] download
+ * [ ] install
+ * [x] list
+ * [ ] remove
+ * [x] search
+ * [ ] update
+ * [ ] upgrade
+ * [x] version
+ * [ ] ext
+
+Why Lua?
+--------
+
+Lua ...
+
+ * shares many goals with KISS, such as simplicity and efficiency.
+ * offers advantages over shell as a "proper" programming language.
+ * can easily be extended by code written in C (etc).
+ * is relatively fast.
+
+Dependencies
+------------
+
+ * Lua 5.4
+ * luaposix library <https://github.com/luaposix/luaposix>
+ * BLAKE3 C library <https://git.sr.ht/~mcf/b3sum> (built with -fPIC)
+
+Rationale: plain Lua lacks UNIX-specific bindings which we need (working with
+files and paths) so either I would write a set of Lua bindings to C, but it's as
+simple to use an existing set such as luaposix.
diff --git a/bliss/b3sum.c b/bliss/b3sum.c
@@ -1,5 +1,11 @@
-/* Copyright 2023 phoebos
- * Lua wrapper for the C blake3 library.
+/*** Lua wrapper for the C blake3 library.
+ * @module bliss.b3sum
+ * @copyright 2023 phoebos
+ * @usage
+ * local data = "some text"
+ * local ctx = bliss.b3sum.init()
+ * bliss.b3sum.update(ctx, data)
+ * local hash = bliss.b3sum.finalize(ctx)
*/
#include <blake3.h>
#include <errno.h>
@@ -8,6 +14,11 @@
#include <stdlib.h>
#include <string.h>
+/***
+ * Initialise the hasher context.
+ * @function init
+ * @treturn ctx blake3 hasher context userdata
+ */
int
l_init(lua_State *L) {
blake3_hasher *ctx = lua_newuserdata(L, sizeof(blake3_hasher));
@@ -15,6 +26,12 @@ l_init(lua_State *L) {
return 1;
}
+/***
+ * Add string input to the hasher
+ * @function update
+ * @tparam ctx ctx hasher context
+ * @tparam string s data to hash
+ */
int
l_update(lua_State *L) {
blake3_hasher *ctx = lua_touserdata(L, 1);
@@ -26,6 +43,13 @@ l_update(lua_State *L) {
return 0;
}
+/***
+ * Finalize the hasher
+ * @function finalize
+ * @tparam ctx ctx hasher context
+ * @tparam[opt=32] int n length of output string
+ * @treturn string hex-encoded hash
+ */
int
l_finalize(lua_State *L) {
blake3_hasher *ctx = lua_touserdata(L, 1);
diff --git a/bliss/init.lua b/bliss/init.lua
@@ -1,6 +1,10 @@
+--- module initialisation
+-- @module bliss
local cwd = (...):gsub("%.init$", "")
local M = {}
+--- module version
+M.version = "0.0.0"
-- merge these into the toplevel bliss module
local names = {"utils", "search", "list", "pkg", "download", "checksum", "build", "install"}
diff --git a/bliss/pkg.lua b/bliss/pkg.lua
@@ -1,3 +1,6 @@
+--- Package processing routines
+-- @module bliss.pkg
+
local utils = require "bliss.utils"
local tsort = require "bliss.tsort"
local glob = require "posix.glob"
diff --git a/bliss/utils.lua b/bliss/utils.lua
@@ -1,4 +1,6 @@
--- Copyright 2023 phoebos
+--- Commonly used utilities and initialisation code
+-- @module bliss.utils
+
local libgen = require "posix.libgen"
local pwd = require "posix.pwd"
local sys_stat = require "posix.sys.stat"
@@ -10,6 +12,8 @@ local signal = require "posix.signal"
local colors = {"", "", ""}
local setup, setup_colors, check_execute, get_available, get_pkg_clean, trap_on, trap_off, split, mkdirp, mkcd, rm_rf, log, warn, die, prompt, run_shell, run, run_quiet, capture, shallowcopy, am_not_owner, as_user
+--- Setup the environment.
+-- @treturn env The environment table containing the parsed KISS_* variables, atexit handler, and temporary directory names.
function setup()
colors = setup_colors()
check_execute()
@@ -89,6 +93,10 @@ function check_execute()
if not os.execute() then die("cannot execute shell commands") end
end
+--- Find the path of the first command which exists.
+-- @param ... list of commands to try
+-- @treturn[1] string the path to the first command in the list which exists
+-- @treturn[2] nil if none found
function get_available(...)
local x, res
for i = 1, select("#", ...) do
@@ -99,7 +107,7 @@ function get_available(...)
return nil
end
--- returns a function with cached env so that it can be called without args or globals.
+-- makes a closure with cached env so that it can be called without args or globals.
function get_pkg_clean(env)
return function ()
if env.DEBUG ~= 0 then return end
@@ -111,6 +119,9 @@ function get_pkg_clean(env)
end
end
+--- Turn on the cleanup trap.
+-- @tparam env env
+-- @treturn table env.atexit
function trap_on(env)
signal.signal(signal.SIGINT, function () os.exit(false) end)
-- use a finalizer to get pkg_clean to run on EXIT. A reference to atexit must
@@ -119,11 +130,17 @@ function trap_on(env)
return env.atexit
end
+--- Turn off the cleanup trap.
+-- @tparam env env
function trap_off(env)
signal.signal(signal.SIGINT, signal.SIG_IGN)
setmetatable(env.atexit, {})
end
+--- Split a string.
+-- @tparam string s string to split
+-- @tparam string sep delimiter
+-- @treturn table array of substrings
function split(s, sep)
if not s then return {} end
local c = {}
@@ -133,6 +150,11 @@ function split(s, sep)
return c
end
+--- Make directories recursively.
+-- The equivalent of running `mkdir -p ...`.
+-- @{die}s if an element of the path already exists and is not a directory, or if making a directory fails.
+-- Does not fail for directories which exist.
+-- @param ... list of directory names
function mkdirp(...)
for i = 1, select("#", ...) do
local path = select(i, ...)
@@ -160,16 +182,26 @@ function mkdirp(...)
end
end
+--- Make directories and chdir into the first one.
+-- @param ... list of directories
function mkcd(...)
mkdirp(...)
local first = select(1, ...)
unistd.chdir(first)
end
+--- Recursively remove files and directories.
+-- This simply executes `rm -rf "path"`.
+-- @tparam string path path to remove
function rm_rf(path)
return os.execute("rm -rf \"" .. path .. "\"")
end
+--- Print a formatted log message.
+-- Follows the same convention as kiss.
+-- @tparam string name
+-- @tparam[opt] string msg
+-- @tparam[opt] string category
function log(name, msg, category)
-- This is a direct translation of kiss's log(). Quite hacky.
io.stderr:write(string.format("%s%s %s%s%s %s\n",
@@ -181,15 +213,20 @@ function log(name, msg, category)
msg or ""))
end
+--- Print a warning.
function warn(name, msg)
log(name, msg, "WARNING")
end
+--- Print an error and exit.
function die(name, msg)
log(name, msg, "ERROR")
os.exit(false)
end
+--- Prompt the user to continue or quit.
+-- @tparam env env
+-- @tparam[opt] string msg
function prompt(env, msg)
if msg then log(msg) end
log("Continue? Press Enter to continue or Ctrl+C to abort")
@@ -198,19 +235,31 @@ function prompt(env, msg)
end
end
--- cmd is a string.
+--- Run a command in the system shell.
+-- Also prints the command.
+-- @see run
+-- @see capture
+-- @tparam string cmd
function run_shell(cmd)
io.stderr:write(cmd.."\n")
return os.execute(cmd)
end
--- path is a string, cmd is an array, env is a table
--- Despite the variable name, path doesn't have to be absolute because execp is used.
--- If logfile is provided, the output of cmd is copied to a file of that name.
+--- Run an executable directly.
+-- @tparam string path file to run. Doesn't have to be an absolute path.
+-- @tparam table cmd array of arguments
+-- @tparam[opt] table env table of environment variables for the new process
+-- @tparam[opt] string logfile if provided, the output is copied to this file.
function run(path, cmd, env, logfile)
io.stderr:write(path .. " " .. table.concat(cmd, " ", 1) .. "\n")
return run_quiet(path, cmd, env, logfile)
end
+--- Run without printing the command.
+-- @see run
+-- @tparam string path
+-- @tparam table cmd
+-- @tparam[opt] table env
+-- @tparam[opt] string logfile
function run_quiet(path, cmd, env, logfile)
local f,r,w
if logfile then
@@ -269,8 +318,11 @@ function run_quiet(path, cmd, env, logfile)
end
end
--- If cmd fails, return nil. Otherwise, return an array of lines
--- printed by cmd.
+--- Run a command in the shell and capture its output.
+-- @see run
+-- @tparam string cmd command to run
+-- @treturn[1] table an array of lines printed by cmd
+-- @treturn[2] nil If cmd fails
function capture(cmd)
local p = io.popen(cmd, "r")
local res = {}
@@ -281,13 +333,19 @@ function capture(cmd)
return res
end
+--- Make a shallow copy of a table.
+-- @tparam table t
+-- @treturn table a table with the first-level keys of t copied
function shallowcopy(t)
local u = {}
for k,v in pairs(t) do u[k] = v end
return u
end
--- If process is not the owner of file, return the name of the owner; otherwise nil.
+--- Check if the process is not the owner of a file.
+-- @tparam string file
+-- @treturn[1] string username of file owner
+-- @treturn[2] nil if process owns file
function am_not_owner(file)
local sb = sys_stat.stat(file)
if not sb then die("Failed to stat '"..file.."'") end
@@ -297,6 +355,10 @@ function am_not_owner(file)
return nil
end
+--- Run a command as a different user.
+-- @tparam env env containing the KISS_SU to use
+-- @tparam string user user to become
+-- @tparam table arg array of command arguments
function as_user(env, user, arg)
print("Using '".. env.SU .. "' (to become "..user..")")
@@ -311,6 +373,7 @@ function as_user(env, user, arg)
run_quiet(env.SU, flags)
end
+--- @export
local M = {
setup = setup,
trap_on = trap_on,
diff --git a/config.ld b/config.ld
@@ -0,0 +1,25 @@
+-- vi: ft=lua
+project = "bliss 0.0.0"
+title = "bliss 0.0.0 reference"
+description = "kiss in Lua"
+
+output = "doc"
+sort = true
+readme = "README.md"
+format = "markdown"
+
+file = {
+ "main.lua",
+ "bliss/archive.lua",
+ "bliss/b3sum.c",
+ "bliss/build.lua",
+ "bliss/checksum.lua",
+ "bliss/download.lua",
+ "bliss/init.lua",
+ "bliss/install.lua",
+ "bliss/list.lua",
+ "bliss/pkg.lua",
+ "bliss/search.lua",
+ "bliss/tsort.lua",
+ "bliss/utils.lua",
+}
diff --git a/main.lua b/main.lua
@@ -1,24 +1,27 @@
#!/usr/bin/env lua
+--- Executable interface to the bliss library.
+-- @script bliss
local bliss = require "bliss"
local function version()
- print("0.0.0")
+ print(bliss.version)
end
local function usage()
- bliss.log("bliss [a|b|c|d|i|l|r|s|u|U|v] [pkg]...")
- --bliss.log("alternatives List and swap alternatives")
- bliss.log("build Build packages")
- bliss.log("checksum Generate checksums")
- bliss.log("download Download sources")
- bliss.log("install Install packages")
- bliss.log("list List installed packages")
- --bliss.log("remove Remove packages")
- bliss.log("search Search for packages")
- --bliss.log("update Update the repositories")
- --bliss.log("upgrade Update the system")
- bliss.log("version Package manager version")
-
+ --- @usage
+ local usage = [[bliss [a|b|c|d|i|l|r|s|u|U|v] [pkg]...
+ alternatives List and swap alternatives
+ build Build packages
+ checksum Generate checksums
+ download Download sources
+ install Install packages
+ list List installed packages
+ remove Remove packages
+ search Search for packages
+ update Update the repositories
+ upgrade Update the system
+ version Package manager version]]
+ print(usage)
os.exit(true)
end