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 "%-dev$", "(development files)", 43 "This package contains development files for ".. 44 "compiling applications." 45 }, 46 { 47 "%-man$", "(manual pages)", 48 "This package contains the online manual pages." 49 }, 50 { 51 "%-dbg$", "(debugging symbols)", 52 "This package contains external debugging symbols for use ".. 53 "with a source-level debugger.", 54 }, 55} 56 57-- A list of packages which don't get the automatic suffix handling, 58-- e.g. -man packages with no corresponding base package. 59local no_suffix_pkgs = { 60 ["kernel-man"] = true, 61} 62 63function add_suffixes(obj) 64 local pkgname = obj["name"] 65 66 for _,pattern in pairs(pkg_suffixes) do 67 if pkgname:match(pattern[1]) ~= nil then 68 obj["comment"] = obj["comment"] .. " " .. pattern[2] 69 obj["desc"] = obj["desc"] .. "\n\n" .. pattern[3] 70 return 71 end 72 end 73end 74 75-- Hardcode a list of packages which don't get the automatic pkggenname 76-- dependency because the base package doesn't exist. We should have a better 77-- way to handle this. 78local no_gen_deps = { 79 ["libcompat-dev"] = true, 80 ["libcompat-dev-lib32"] = true, 81 ["libcompat-man"] = true, 82 ["libcompiler_rt-dev"] = true, 83 ["libcompiler_rt-dev-lib32"] = true, 84 ["liby-dev"] = true, 85 ["liby-dev-lib32"] = true, 86 ["kernel-man"] = true, 87} 88 89-- Return true if the package 'pkgname' should have a dependency on the package 90-- pkggenname. 91function add_gen_dep(pkgname, pkggenname) 92 if pkgname == pkggenname then 93 return false 94 end 95 if pkgname == nil or pkggenname == nil then 96 return false 97 end 98 if no_gen_deps[pkgname] ~= nil then 99 return false 100 end 101 if pkggenname == "kernel" then 102 return false 103 end 104 105 return true 106end 107 108local pkgname = nil 109local pkggenname = nil 110local pkgprefix = nil 111local pkgversion = nil 112 113-- This parser is the output UCL we want to build. 114local parser = ucl.parser() 115 116-- Set any $VARIABLES from the command line in the parser. This causes ucl to 117-- automatically replace them when we load the source ucl. 118if #arg < 2 or #arg % 2 ~= 0 then 119 io.stderr:write(arg[0] .. ": expected an even number of arguments, got " .. #arg) 120 os.exit(1) 121end 122 123for i = 2, #arg - 2, 2 do 124 local varname = arg[i - 1] 125 local varvalue = arg[i] 126 127 if varname == "PKGNAME" and #varvalue > 0 then 128 pkgname = varvalue 129 elseif varname == "PKGGENNAME" and #varvalue > 0 then 130 pkggenname = varvalue 131 elseif varname == "VERSION" and #varvalue > 0 then 132 pkgversion = varvalue 133 elseif varname == "PKG_NAME_PREFIX" and #varvalue > 0 then 134 pkgprefix = varvalue 135 end 136 137 parser:register_variable(varname, varvalue) 138end 139 140-- Load the source ucl file. 141local res,err = parser:parse_file(arg[#arg - 1]) 142if not res then 143 io.stderr:write(arg[0] .. ": fail to parse("..arg[#arg - 1].."): "..err) 144 os.exit(1) 145end 146 147local obj = parser:get_object() 148 149-- If pkgname is different from pkggenname, add a dependency on pkggenname. 150-- This means that e.g. -dev packages depend on their respective base package. 151if add_gen_dep(pkgname, pkggenname) then 152 if obj["deps"] == nil then 153 obj["deps"] = {} 154 end 155 obj["deps"][pkggenname] = { 156 ["version"] = pkgversion, 157 ["origin"] = "base" 158 } 159end 160 161-- If PKG_NAME_PREFIX is provided, rewrite the names of dependency packages. 162-- We can't do this in UCL since variable substitution doesn't work in array 163-- keys. 164if pkgprefix ~= nil and obj["deps"] ~= nil then 165 newdeps = {} 166 for dep, opts in pairs(obj["deps"]) do 167 local newdep = pkgprefix .. "-" .. dep 168 newdeps[newdep] = opts 169 end 170 obj["deps"] = newdeps 171end 172 173-- Add comment and desc suffix. 174if no_suffix_pkgs[pkgname] == nil then 175 add_suffixes(obj) 176end 177 178-- Write the output file. 179local f,err = io.open(arg[#arg], "w") 180if not f then 181 io.stderr:write(arg[0] .. ": fail to open("..arg[#arg].."): ".. err) 182 os.exit(1) 183end 184 185f:write(ucl.to_format(obj, 'ucl', true)) 186f:close() 187