aboutsummaryrefslogtreecommitdiff
path: root/release/packages/generate-ucl.lua
blob: 5637bbd3ad995fcb58fb5d99afd610d0363a0162 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/libexec/flua

--[[ usage:
generare-ucl.lua [<variablename> <variablevalue>]... <sourceucl> <destucl>

Build a package's UCL configuration by loading the template UCL file
<sourceucl>, replacing any $VARIABLES in the UCL based on the provided
variables, then writing the result to <destucl>.
]]--

local ucl = require("ucl")

-- Give subpackages a special comment and description suffix to indicate what
-- they contain, so e.g. "foo-man" has " (manual pages)" appended to its
-- comment.  This avoids having to create a separate ucl files for every
-- subpackage just to set this.
--
-- Note that this is not a key table because the order of the pattern matches
-- is important.
pkg_suffixes = {
	{
		"%-dev%-lib32$", "(32-bit development files)",
		"This package contains development files for compiling "..
		"32-bit applications on a 64-bit host."
	},
	{
		"%-dbg%-lib32$", "(32-bit debugging symbols)",
		"This package contains 32-bit external debugging symbols "..
		"for use with a source-level debugger.",
	},
	{
		"%-man%-lib32$", "(32-bit manual pages)",
		"This package contains the online manual pages for 32-bit "..
		"components on a 64-bit host.",
	},
	{
		"%-lib32$", "(32-bit libraries)",
		"This package contains 32-bit libraries for running 32-bit "..
		"applications on a 64-bit host.",
	},
	{
		"%-lib$", "(libraries)",
		"This package contains runtime shared libraries.",
	},
	{
		"%-dev$", "(development files)",
		"This package contains development files for "..
		"compiling applications."
	},
	{
		"%-man$", "(manual pages)",
		"This package contains the online manual pages."
	},
	{
		"%-dbg$", "(debugging symbols)",
		"This package contains external debugging symbols for use "..
		"with a source-level debugger.",
	},
}

-- A list of packages which don't get the automatic suffix handling,
-- e.g. -man packages with no corresponding base package.
local no_suffix_pkgs = {
	["kernel-man"] = true,
}

function add_suffixes(obj)
	local pkgname = obj["name"]

	for _,pattern in pairs(pkg_suffixes) do
		if pkgname:match(pattern[1]) ~= nil then
			obj["comment"] = obj["comment"] .. " " .. pattern[2]
			obj["desc"] = obj["desc"] .. "\n\n" .. pattern[3]
			return
		end
	end
end

-- Hardcode a list of packages which don't get the automatic pkggenname
-- dependency because the base package doesn't exist.  We should have a better
-- way to handle this.
local no_gen_deps = {
	["libcompat-dev"] = true,
	["libcompat-dev-lib32"] = true,
	["libcompat-man"] = true,
	["libcompiler_rt-dev"] = true,
	["libcompiler_rt-dev-lib32"] = true,
	["liby-dev"] = true,
	["liby-dev-lib32"] = true,
	["kernel-man"] = true,
}

-- Return true if the package 'pkgname' should have a dependency on the package
-- pkggenname.
function add_gen_dep(pkgname, pkggenname)
	if pkgname == pkggenname then
		return false
	end
	if pkgname == nil or pkggenname == nil then
		return false
	end
	if no_gen_deps[pkgname] ~= nil then
		return false
	end
	if pkgname:match("%-lib$") ~= nil then
		return false
	end
	if pkggenname == "kernel" then
		return false
	end

	return true
end

local pkgname = nil
local pkggenname = nil
local pkgprefix = nil
local pkgversion = nil

-- This parser is the output UCL we want to build.
local parser = ucl.parser()

-- Set any $VARIABLES from the command line in the parser.  This causes ucl to
-- automatically replace them when we load the source ucl.
if #arg < 2 or #arg % 2 ~= 0 then
	io.stderr:write(arg[0] .. ": expected an even number of arguments, got " .. #arg)
	os.exit(1)
end

for i = 2, #arg - 2, 2 do
	local varname = arg[i - 1]
	local varvalue = arg[i]

	if varname == "PKGNAME" and #varvalue > 0 then
		pkgname = varvalue
	elseif varname == "PKGGENNAME" and #varvalue > 0 then
		pkggenname = varvalue
	elseif varname == "VERSION" and #varvalue > 0 then
		pkgversion = varvalue
	elseif varname == "PKG_NAME_PREFIX" and #varvalue > 0 then
		pkgprefix = varvalue
	end

	parser:register_variable(varname, varvalue)
end

-- Load the source ucl file.
local res,err = parser:parse_file(arg[#arg - 1])
if not res then
	io.stderr:write(arg[0] .. ": fail to parse("..arg[#arg - 1].."): "..err)
	os.exit(1)
end

local obj = parser:get_object()

-- If pkgname is different from pkggenname, add a dependency on pkggenname.
-- This means that e.g. -dev packages depend on their respective base package.
if add_gen_dep(pkgname, pkggenname) then
	if obj["deps"] == nil then
		obj["deps"] = {}
	end
	obj["deps"][pkggenname] = {
		["version"] = pkgversion,
		["origin"] = "base"
	}
end

-- If PKG_NAME_PREFIX is provided, rewrite the names of dependency packages.
-- We can't do this in UCL since variable substitution doesn't work in array
-- keys.
if pkgprefix ~= nil and obj["deps"] ~= nil then
	newdeps = {}
	for dep, opts in pairs(obj["deps"]) do
		local newdep = pkgprefix .. "-" .. dep
		newdeps[newdep] = opts
	end
	obj["deps"] = newdeps
end

-- Add comment and desc suffix.
if no_suffix_pkgs[pkgname] == nil then
	add_suffixes(obj)
end

-- Write the output file.
local f,err = io.open(arg[#arg], "w")
if not f then
	io.stderr:write(arg[0] .. ": fail to open("..arg[#arg].."): ".. err)
	os.exit(1)
end

f:write(ucl.to_format(obj, 'ucl', true))
f:close()