diff options
-rwxr-xr-x | buildrepo.lua | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/buildrepo.lua b/buildrepo.lua new file mode 100755 index 0000000..3cee760 --- /dev/null +++ b/buildrepo.lua @@ -0,0 +1,193 @@ +#!/usr/bin/lua5.2 + +local abuild = require("aports.abuild") +local apkrepo = require("aports.apkrepo") +local lfs = require("lfs") + +local function warn(formatstr, ...) + io.stderr:write(("WARNING: %s\n"):format(formatstr:format(...))) +end + +local function err(formatstr, ...) + io.stderr:write(("ERROR: %s\n"):format(formatstr:format(...))) +end + +local function fatal(exitcode, formatstr, ...) + err(formatstr, ...) + os.exit(exitcode) +end + +local function parse_opts(opthelp, raw_args) + local valid_opts = {} + local opts = {} + local args = {} + local moreopts = true + for optc, separator in opthelp:gmatch("%s+%-(%a)(%s+)") do + valid_opts[optc] = { hasarg = (separator == " ") } + end + + local i = 1 + while i <= #raw_args do + local a = raw_args[i] + i = i + 1 + if a == "--" then + moreopts = false + elseif moreopts and a:sub(1,1) == "-" then + for j = 2, #a do + local opt = a:sub(j,j) + if not valid_opts[opt] then + return nil, opt, "invalid option" + end + if valid_opts[opt].hasarg then + opts[opt] = raw_args[i] + i = i + 1 + else + opts[opt] = true + end + if not opts[opt] then + return nil, opt, "optarg required" + end + end + else + args[#args + 1] = a + end + end + return opts, args +end + +local function build_aport(aport, repodest, logdir) + if not lfs.chdir(aport.dir) then + return nil + end + local log + if logdir ~= nil then + local dir = ("%s/%s"):format(logdir, aport.pkgname) + assert(lfs.mkdir(dir), dir) + local logfile = ("%s/%s-%s-r%s.log"):format(dir, aport.pkgname, aport.pkgver, aport.pkgrel) + log = io.open(logfile, "w") + else + log = io.stdout + end + local pipe = io.popen(("REPODEST='%s' abuild -r -m 2>&1"):format(aport.dir, repodest)) + for line in pipe:lines() do + log:write(("%s\n"):format(line)) + end + if log ~= io.stdout then + log:close() + end + return pipe:close() +end + +local function build_repo(aportsdir, repodest, logdir, repo, keep_going) + return true +end + +local function post_purge(repodest, repo) + local keep = {} + local lfs = require('lfs') + + +end + +----------------------------------------------------------------- +local opthelp = [[ + -a DIR Set the aports base dir to DIR instead of $HOME/aports + -d DIR Set destination repository base to DIR instead of $HOME/packages + -h Show this help and exit + -l DIR Create build logs in DIR/REPO/pkgname/ instead of stdout + -k Keep going, even if packages fails + -n Dry run. Don't acutally build or delete, just print + -p Purge obsolete packages from REPODIR after build + -r REPO Dependencies are found in REPO +]] + +local function usage(exitcode) + io.stdout:write(("options:\n%s\n"):format(opthelp)) + os.exit(exitcode) +end + +opts, args, errmsg = parse_opts(opthelp, arg) +if opts == nil then + io.stderr:write(("%s: -%s\n"):format(errmsg, args)) + usage(1) +end + +if opts.h then + usage(0) +end + +if #args == 0 then + usage(1) +end + +homedir = os.getenv("HOME") +aportsdir = opts.a or ("%s/aports"):format(homedir) +repodest = opts.d or abuild.repodest or ("%s/packages"):format(homedir) +logdirbase = opts.l + +if opts.n then + build_aport = function() return true end +end + +for _,repo in pairs(args) do + local db = require('aports.db').new(aportsdir, repo) + local pkgs = {} + local unsorted = {} + local logdir = nil + + -- find out what needs to be built + for aport in db:each_need_build() do + table.insert(pkgs, aport.pkgname) + if unsorted[aport.pkgname] then + warn("more than one aport provides %s", aport.pkgname) + end + unsorted[aport.pkgname] = true + end + + if logdirbase ~= nil then + logdir = ("%s/%s"):format(logdirbase, repo) + assert(lfs.mkdir(logdir), logdir) + end + + -- build packages + count = 1 + for aport in db:each_in_build_order(pkgs) do + io.write(("%d/%d %s\n"):format(count, #pkgs, aport.pkgname)) + if build_aport(aport, repodest, logdir) then + count = count + 1 + else + err("failed to build %s", aport.pkgname) + if not opts.k then + os.exit(1) + end + end + end + + -- purge old packages + if opts.p then + local keep = {} + for aport,name in db:each() do + keep[aport:get_apk_file_name(name)] = true + end + local apkrepodir = ("%s/%s/%s"):format(repodest, repo, abuild.arch) + for file in lfs.dir(apkrepodir) do + if file:match("%.apk$") and not keep[file] then + if not logdirbase or opts.n then + print("delete:", file) + end + if not opts.n then + os.remove(("%s/%s"):format(apkrepodir, file)) + end + end + + end + end + + -- generate new apkindex + if not opts.n then + apkrepo.update_index(("%s/%s"):format(repodest, repo), + abuild.arch, db:git_describe()) + end +end + + |