1 # This file can be distributed under the same terms as ruby itself.
2 # Author: Marek Gilbert <gil (at) fooplanet (dot) com>
4 # RpmSpecWriter has formatting primitives that simplify generating RPM spec
11 # Write out the contents of +line+ and a newline, just like
17 # Write out an RPM header. If the header is a multi-valued header then
18 # the value is joined with ", ". If the value is nil, nothing is written.
19 def header(name, value)
21 if value.kind_of?(Array)
22 return if value.length == 0
24 value = value.join(', ')
26 puts("#{name}: #{value}")
29 # Declare a section and yield.
30 def section(name, rest = nil)
42 # A simple abstraction for a %name section in an rpm file. Every section
43 # has a %-sign, a name, possibly some text following the %name (e.g.
44 # %files -f %{name}.files), and a block of lines that follow.
46 # The name of the section
49 # The rest of the line following the section declaration, if any.
52 # The block of lines that follow the section declaration after a newline.
55 def initialize(name, rest = nil)
61 # Add a line or lines to +text+.
63 @text << "\n" if @text.length > 0
68 # A generic interface to an RPM specification, consisiting of headers,
69 # sections, and a little bit of glue to connect to RpmSpecWriter.
74 # RPM header names aren't suitable method names because Ruby wants at
75 # least the initial character of the method to be lower case. Generate
76 # good ruby names from the RPM names by converting from CamelCase to
78 def self.sym_name(name)
85 sym.sub!(/^[A-Z]/) { |x| x.downcase }
86 sym.gsub!(/[A-Z]/) { |x| '_' + x.downcase }
92 # Declares an RPM header. +default_value+ can be lambda in which case a
93 # new value is taken from the result of calling the lambda with no
95 def self.rpm_header(name, default_value = nil)
99 @@headers.push([name, get.intern, set.intern, default_value])
100 attr_accessor(get.intern)
103 # Declares an RPM header whose value consists of a list of things.
104 def self.rpm_list_header(name)
105 default_value = lambda do
108 rpm_header(name, default_value)
111 # Declares an RPM section.
112 def self.rpm_section(name)
115 @@sections.push([name, get.intern, set.intern])
116 attr_accessor(get.intern)
119 attr_accessor :spec_filename
122 rpm_header('Version')
123 rpm_header('Release')
124 rpm_header('Summary')
125 rpm_header('License')
129 #rpm_header('AutoReqProv')
130 rpm_list_header('Conflicts')
131 rpm_list_header('Provides')
132 rpm_list_header('Requires')
133 rpm_list_header('Obsoletes')
135 rpm_list_header('Prereq')
137 rpm_header('BuildArch')
138 rpm_header('BuildRoot')
139 rpm_list_header('BuildConflicts')
140 rpm_list_header('BuildRequires')
142 # The +sources+ array generates the Source0, Source1, etc headers.
145 # The +patches+ array generates the Patch0, Patch1, etc headers.
148 rpm_section('description')
151 rpm_section('install')
154 rpm_section('changelog')
156 # Create a new RpmSpec that is intended to be written to the file
158 def initialize(filename)
159 @spec_filename = filename
161 @@headers.each do |name, get, set, default_value|
162 if default_value.kind_of?(Proc)
163 default_value = default_value.call()
165 self.send(set, default_value)
171 @@sections.each do |name, get, set|
172 self.send(set, RpmSection.new(name))
176 # Write the RpmSpec out to the +io+ which is already open for write.
178 @@headers.each do |name, get, set, |
179 io.header(name, self.send(get))
182 @sources.each_with_index do |src, i|
183 io.header('Source' + i.to_s, src)
186 @patches.each_with_index do |src, i|
187 io.header('Source' + i.to_s, src)
190 @@sections.each do |name, get, set|
192 io.section(sec.name, sec.rest) do