166f36c36SLexi Winter#!/usr/libexec/flua 2*c8f9a9abSLexi Winter-- 3*c8f9a9abSLexi Winter-- Copyright (c) 2024-2025 Baptiste Daroussin <bapt@FreeBSD.org> 4*c8f9a9abSLexi Winter-- Copyright (c) 2025 Lexi Winter <ivy@FreeBSD.org> 5*c8f9a9abSLexi Winter-- 6*c8f9a9abSLexi Winter-- SPDX-License-Identifier: BSD-2-Clause 7*c8f9a9abSLexi Winter-- 866f36c36SLexi Winter 966f36c36SLexi Winter--[[ usage: 109e6cea12SJose Luis Durangenerate-set-ucl.lua <template> [<variablename> <variablevalue>] 1166f36c36SLexi Winter 1266f36c36SLexi WinterGenerate the UCL for a set metapackage. The variables provided will be 1366f36c36SLexi Wintersubstituted as UCL variables. 1466f36c36SLexi Winter]]-- 1566f36c36SLexi Winter 1666f36c36SLexi Winterlocal ucl = require("ucl") 1766f36c36SLexi Winter 1866f36c36SLexi Winter-- This parser is the output UCL we want to build. 1966f36c36SLexi Winterlocal parser = ucl.parser() 2066f36c36SLexi Winter 2166f36c36SLexi Winterif #arg < 1 then 2266f36c36SLexi Winter io.stderr:write(arg[0] .. ": missing template filename\n") 2366f36c36SLexi Winter os.exit(1) 2466f36c36SLexi Winterend 2566f36c36SLexi Winter 2666f36c36SLexi Winterlocal template = table.remove(arg, 1) 2766f36c36SLexi Winter 2866f36c36SLexi Winter-- Set any $VARIABLES from the command line in the parser. This causes ucl to 2966f36c36SLexi Winter-- automatically replace them when we load the source ucl. 3066f36c36SLexi Winterif #arg % 2 ~= 0 then 3166f36c36SLexi Winter io.stderr:write(arg[0] .. ": expected an even number of arguments, " 3266f36c36SLexi Winter .. "got " .. #arg .. "\n") 3366f36c36SLexi Winter os.exit(1) 3466f36c36SLexi Winterend 3566f36c36SLexi Winter 3666f36c36SLexi Winterlocal pkgprefix = nil 3766f36c36SLexi Winterlocal pkgversion = nil 3866f36c36SLexi Winterlocal pkgdeps = "" 3966f36c36SLexi Winter 4066f36c36SLexi Winterfor i = 2, #arg, 2 do 4166f36c36SLexi Winter local varname = arg[i - 1] 4266f36c36SLexi Winter local varvalue = arg[i] 4366f36c36SLexi Winter 4466f36c36SLexi Winter if varname == "PKG_NAME_PREFIX" and #varvalue > 0 then 4566f36c36SLexi Winter pkgprefix = varvalue 4666f36c36SLexi Winter elseif varname == "VERSION" and #varvalue > 0 then 4766f36c36SLexi Winter pkgversion = varvalue 4866f36c36SLexi Winter elseif varname == "SET_DEPENDS" and #varvalue > 0 then 4966f36c36SLexi Winter pkgdeps = varvalue 5066f36c36SLexi Winter end 5166f36c36SLexi Winter 5266f36c36SLexi Winter parser:register_variable(varname, varvalue) 5366f36c36SLexi Winterend 5466f36c36SLexi Winter 5566f36c36SLexi Winter-- Load the source template. 5666f36c36SLexi Winterlocal res,err = parser:parse_file(template) 5766f36c36SLexi Winterif not res then 5866f36c36SLexi Winter io.stderr:write(arg[0] .. ": fail to parse(" .. template .. "): " 5966f36c36SLexi Winter .. err .. "\n") 6066f36c36SLexi Winter os.exit(1) 6166f36c36SLexi Winterend 6266f36c36SLexi Winter 6366f36c36SLexi Winterlocal obj = parser:get_object() 6466f36c36SLexi Winter 6566f36c36SLexi Winter-- Dependency handling. 6666f36c36SLexi Winterobj["deps"] = obj["deps"] or {} 6766f36c36SLexi Winter 6866f36c36SLexi Winter-- If PKG_NAME_PREFIX is provided, rewrite the names of dependency packages. 6966f36c36SLexi Winter-- We can't do this in UCL since variable substitution doesn't work in array 7066f36c36SLexi Winter-- keys. Note that this only applies to dependencies from the set UCL files, 7166f36c36SLexi Winter-- because SET_DEPENDS already have the correct prefix. 7266f36c36SLexi Winterif pkgprefix ~= nil then 7366f36c36SLexi Winter newdeps = {} 7466f36c36SLexi Winter for dep, opts in pairs(obj["deps"]) do 7566f36c36SLexi Winter local newdep = pkgprefix .. "-" .. dep 7666f36c36SLexi Winter newdeps[newdep] = opts 7766f36c36SLexi Winter end 7866f36c36SLexi Winter obj["deps"] = newdeps 7966f36c36SLexi Winterend 8066f36c36SLexi Winter 8166f36c36SLexi Winter-- Add dependencies from SET_DEPENDS. 8266f36c36SLexi Winterfor dep in string.gmatch(pkgdeps, "[^%s]+") do 8366f36c36SLexi Winter obj["deps"][dep] = { 84a507a702SLexi Winter ["origin"] = "base/"..dep 8566f36c36SLexi Winter } 8666f36c36SLexi Winterend 8766f36c36SLexi Winter 88a507a702SLexi Winter-- Add a version and origin key to all dependencies, otherwise pkg 89a507a702SLexi Winter-- doesn't like it. 9066f36c36SLexi Winterfor dep, opts in pairs(obj["deps"]) do 91a507a702SLexi Winter obj["deps"][dep]["origin"] = obj["deps"][dep]["origin"] or "base/"..dep 92a507a702SLexi Winter obj["deps"][dep]["version"] = obj["deps"][dep]["version"] or pkgversion 9366f36c36SLexi Winterend 9466f36c36SLexi Winter 9566f36c36SLexi Winter-- If there are no dependencies, remove the deps key, otherwise pkg raises an 9666f36c36SLexi Winter-- error trying to read the manifest. 9766f36c36SLexi Winterif next(obj["deps"]) == nil then 9866f36c36SLexi Winter obj["deps"] = nil 9966f36c36SLexi Winterend 10066f36c36SLexi Winter 10166f36c36SLexi Winter-- Write the output. 10266f36c36SLexi Winterio.stdout:write(ucl.to_format(obj, 'ucl', true)) 103