1#!/usr/libexec/flua 2 3-- SPDX-License-Identifier: BSD-2-Clause 4-- 5-- Copyright(c) 2025 The FreeBSD Foundation. 6-- 7-- This software was developed by Isaac Freund <ifreund@freebsdfoundation.org> 8-- under sponsorship from the FreeBSD Foundation. 9 10-- Run a command using the OS shell and capture the stdout 11-- Strips exactly one trailing newline if present, does not strip any other whitespace. 12-- Asserts that the command exits cleanly 13local function capture(command) 14 local p = io.popen(command) 15 local output = p:read("*a") 16 assert(p:close()) 17 -- Strip exactly one trailing newline from the output, if there is one 18 return output:match("(.-)\n$") or output 19end 20 21-- Returns a list of packages to be included in the given media 22local function select_packages(pkg, media, all_libcompats) 23 local components = {} 24 local rquery = capture(pkg .. "rquery -U -r FreeBSD-base %n") 25 for package in rquery:gmatch("[^\n]+") do 26 local set = package:match("^FreeBSD%-set%-(.*)$") 27 if set then 28 components[set] = package 29 -- Kernels other than FreeBSD-kernel-generic are ignored 30 -- Note that on powerpc64 and powerpc64le the names are 31 -- slightly different. 32 elseif package:match("^FreeBSD%-kernel%-generic.*-dbg") then 33 components["kernel-dbg"] = package 34 elseif package:match("^FreeBSD%-kernel%-generic.*") then 35 components["kernel"] = package 36 end 37 end 38 assert(components["kernel"]) 39 assert(components["base"]) 40 41 local selected = {} 42 if media == "disc" then 43 table.insert(selected, components["base"]) 44 table.insert(selected, components["kernel"]) 45 table.insert(selected, components["kernel-dbg"]) 46 table.insert(selected, components["src"]) 47 table.insert(selected, components["tests"]) 48 for compat in all_libcompats:gmatch("%S+") do 49 table.insert(selected, components["lib" .. compat]) 50 end 51 else 52 assert(media == "dvd") 53 table.insert(selected, components["base"]) 54 table.insert(selected, components["base-dbg"]) 55 table.insert(selected, components["kernel"]) 56 table.insert(selected, components["kernel-dbg"]) 57 table.insert(selected, components["src"]) 58 table.insert(selected, components["tests"]) 59 for compat in all_libcompats:gmatch("%S+") do 60 table.insert(selected, components["lib" .. compat]) 61 table.insert(selected, components["lib" .. compat .. "-dbg"]) 62 end 63 end 64 65 return selected 66end 67 68local function main() 69 -- Determines package subset selected 70 local media = assert(arg[1]) 71 assert(media == "disc" or media == "dvd") 72 -- Local repository to fetch from 73 local source = assert(arg[2]) 74 -- Directory to create new repository 75 local target = assert(arg[3]) 76 -- =hitespace separated list of all libcompat names (e.g. "32") 77 local all_libcompats = assert(arg[4]) 78 -- ABI of repository 79 local ABI = assert(arg[5]) 80 81 assert(os.execute("mkdir -p pkgbase-repo-conf")) 82 local f <close> = assert(io.open("pkgbase-repo-conf/FreeBSD-base.conf", "w")) 83 assert(f:write(string.format([[ 84 FreeBSD-base: { 85 url: "file://%s", 86 enabled: yes 87 } 88 ]], source))) 89 assert(f:close()) 90 91 local pkg = "pkg -o ASSUME_ALWAYS_YES=yes -o IGNORE_OSVERSION=yes " .. 92 "-o ABI=" .. ABI .. " " .. 93 "-o INSTALL_AS_USER=1 -o PKG_DBDIR=./pkgdb -R ./pkgbase-repo-conf " 94 95 assert(os.execute(pkg .. "update")) 96 97 local packages = select_packages(pkg, media, all_libcompats) 98 99 assert(os.execute(pkg .. "fetch -d -o " .. target .. " " .. table.concat(packages, " "))) 100 assert(os.execute(pkg .. "repo " .. target)) 101end 102 103main() 104