1#!/usr/libexec/flua 2 3--[[ usage: 4generare-ucl.lua [<variablename> <variablevalue>]... <sourceucl> <destucl> 5 6Build a package's UCL configuration by loading the template UCL file 7<sourceucl>, replacing any $VARIABLES in the UCL based on the provided 8variables, then writing the result to <destucl>. 9]]-- 10 11local ucl = require("ucl") 12 13-- Give subpackages a special comment and description suffix to indicate what 14-- they contain, so e.g. "foo-man" has " (manual pages)" appended to its 15-- comment. This avoids having to create a separate ucl files for every 16-- subpackage just to set this. 17-- 18-- Note that this is not a key table because the order of the pattern matches 19-- is important. 20pkg_suffixes = { 21 { 22 "%-dev%-lib32$", "(32-bit development files)", 23 "This package contains development files for compiling ".. 24 "32-bit applications on a 64-bit host." 25 }, 26 { 27 "%-dbg%-lib32$", "(32-bit debugging symbols)", 28 "This package contains 32-bit external debugging symbols ".. 29 "for use with a source-level debugger.", 30 }, 31 { 32 "%-man%-lib32$", "(32-bit manual pages)", 33 "This package contains the online manual pages for 32-bit ".. 34 "components on a 64-bit host.", 35 }, 36 { 37 "%-lib32$", "(32-bit libraries)", 38 "This package contains 32-bit libraries for running 32-bit ".. 39 "applications on a 64-bit host.", 40 }, 41 { 42 "%-lib$", "(libraries)", 43 "This package contains runtime shared libraries.", 44 }, 45 { 46 "%-dev$", "(development files)", 47 "This package contains development files for ".. 48 "compiling applications." 49 }, 50 { 51 "%-man$", "(manual pages)", 52 "This package contains the online manual pages." 53 }, 54 { 55 "%-dbg$", "(debugging symbols)", 56 "This package contains external debugging symbols for use ".. 57 "with a source-level debugger.", 58 }, 59} 60 61-- A list of packages which don't get the automatic suffix handling, 62-- e.g. -man packages with no corresponding base package. 63local no_suffix_pkgs = { 64 ["kernel-man"] = true, 65} 66 67function add_suffixes(obj) 68 local pkgname = obj["name"] 69 70 for _,pattern in pairs(pkg_suffixes) do 71 if pkgname:match(pattern[1]) ~= nil then 72 obj["comment"] = obj["comment"] .. " " .. pattern[2] 73 obj["desc"] = obj["desc"] .. "\n\n" .. pattern[3] 74 return 75 end 76 end 77end 78 79-- Hardcode a list of packages which don't get the automatic pkggenname 80-- dependency because the base package doesn't exist. We should have a better 81-- way to handle this. 82local no_gen_deps = { 83 ["libcompat-dev"] = true, 84 ["libcompat-dev-lib32"] = true, 85 ["libcompat-man"] = true, 86 ["libcompiler_rt-dev"] = true, 87 ["libcompiler_rt-dev-lib32"] = true, 88 ["liby-dev"] = true, 89 ["liby-dev-lib32"] = true, 90 ["kernel-man"] = true, 91} 92 93-- Return true if the package 'pkgname' should have a dependency on the package 94-- pkggenname. 95function add_gen_dep(pkgname, pkggenname) 96 if pkgname == pkggenname then 97 return false 98 end 99 if pkgname == nil or pkggenname == nil then 100 return false 101 end 102 if no_gen_deps[pkgname] ~= nil then 103 return false 104 end 105 if pkgname:match("%-lib$") ~= nil then 106 return false 107 end 108 if pkggenname == "kernel" then 109 return false 110 end 111 112 return true 113end 114 115local pkgname = nil 116local pkggenname = nil 117local pkgprefix = nil 118local pkgversion = nil 119 120-- This parser is the output UCL we want to build. 121local parser = ucl.parser() 122 123-- Set any $VARIABLES from the command line in the parser. This causes ucl to 124-- automatically replace them when we load the source ucl. 125if #arg < 2 or #arg % 2 ~= 0 then 126 io.stderr:write(arg[0] .. ": expected an even number of arguments, got " .. #arg) 127 os.exit(1) 128end 129 130for i = 2, #arg - 2, 2 do 131 local varname = arg[i - 1] 132 local varvalue = arg[i] 133 134 if varname == "PKGNAME" and #varvalue > 0 then 135 pkgname = varvalue 136 elseif varname == "PKGGENNAME" and #varvalue > 0 then 137 pkggenname = varvalue 138 elseif varname == "VERSION" and #varvalue > 0 then 139 pkgversion = varvalue 140 elseif varname == "PKG_NAME_PREFIX" and #varvalue > 0 then 141 pkgprefix = varvalue 142 end 143 144 parser:register_variable(varname, varvalue) 145end 146 147-- Load the source ucl file. 148local res,err = parser:parse_file(arg[#arg - 1]) 149if not res then 150 io.stderr:write(arg[0] .. ": fail to parse("..arg[#arg - 1].."): "..err) 151 os.exit(1) 152end 153 154local obj = parser:get_object() 155 156-- If pkgname is different from pkggenname, add a dependency on pkggenname. 157-- This means that e.g. -dev packages depend on their respective base package. 158if add_gen_dep(pkgname, pkggenname) then 159 if obj["deps"] == nil then 160 obj["deps"] = {} 161 end 162 obj["deps"][pkggenname] = { 163 ["version"] = pkgversion, 164 ["origin"] = "base" 165 } 166end 167 168-- If PKG_NAME_PREFIX is provided, rewrite the names of dependency packages. 169-- We can't do this in UCL since variable substitution doesn't work in array 170-- keys. 171if pkgprefix ~= nil and obj["deps"] ~= nil then 172 newdeps = {} 173 for dep, opts in pairs(obj["deps"]) do 174 local newdep = pkgprefix .. "-" .. dep 175 newdeps[newdep] = opts 176 end 177 obj["deps"] = newdeps 178end 179 180-- Add comment and desc suffix. 181if no_suffix_pkgs[pkgname] == nil then 182 add_suffixes(obj) 183end 184 185-- Write the output file. 186local f,err = io.open(arg[#arg], "w") 187if not f then 188 io.stderr:write(arg[0] .. ": fail to open("..arg[#arg].."): ".. err) 189 os.exit(1) 190end 191 192f:write(ucl.to_format(obj, 'ucl', true)) 193f:close() 194