xref: /freebsd/release/scripts/pkgbase-stage.lua (revision 7e79bc8ce70693a892c443c42af5ec16a95ba466)
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