polisher 0.9.1 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,379 +3,443 @@
3
3
  # Licensed under the MIT license
4
4
  # Copyright (C) 2013-2014 Red Hat, Inc.
5
5
 
6
- require 'gem2rpm'
7
- require 'versionomy'
8
- require 'active_support/core_ext'
9
-
10
6
  require 'polisher/core'
11
7
  require 'polisher/gem'
12
8
  require 'polisher/rpm/requirement'
9
+ require 'polisher/component'
13
10
 
14
11
  module Polisher
15
- module RPM
16
- class Spec
17
- AUTHOR = "#{ENV['USER']} <#{ENV['USER']}@localhost.localdomain>"
18
-
19
- COMMENT_MATCHER = /^\s*#.*/
20
- GEM_NAME_MATCHER = /^%global\s*gem_name\s(.*)$/
21
- SPEC_NAME_MATCHER = /^Name:\s*rubygem-(.*)$/
22
- SPEC_VERSION_MATCHER = /^Version:\s*(.*)$/
23
- SPEC_RELEASE_MATCHER = /^Release:\s*(.*)$/
24
- SPEC_REQUIRES_MATCHER = /^Requires:\s*(.*)$/
25
- SPEC_BUILD_REQUIRES_MATCHER = /^BuildRequires:\s*(.*)$/
26
- SPEC_GEM_REQ_MATCHER = /^.*\s*rubygem\((.*)\)(\s*(.*))?$/
27
- SPEC_SUBPACKAGE_MATCHER = /^%package\s(.*)$/
28
- SPEC_CHANGELOG_MATCHER = /^%changelog$/
29
- SPEC_FILES_MATCHER = /^%files$/
30
- SPEC_SUBPKG_FILES_MATCHER = /^%files\s*(.*)$/
31
- SPEC_CHECK_MATCHER = /^%check$/
32
-
33
- FILE_MACRO_MATCHERS =
34
- [/^%doc\s/, /^%config\s/, /^%attr\s/,
35
- /^%verify\s/, /^%docdir.*/, /^%dir\s/,
36
- /^%defattr.*/, /^%exclude\s/, /^%{gem_instdir}\/+/]
37
-
38
- FILE_MACRO_REPLACEMENTS =
39
- {"%{_bindir}" => 'bin',
40
- "%{gem_libdir}" => 'lib'}
41
-
42
- attr_accessor :metadata
43
-
44
- # Return the currently configured author
45
- def self.current_author
46
- ENV['POLISHER_AUTHOR'] || AUTHOR
47
- end
48
-
49
- def initialize(metadata={})
50
- @metadata = metadata
51
- end
52
-
53
- # Dispatch all missing methods to lookup calls in rpm spec metadata
54
- def method_missing(method, *args, &block)
55
- # proxy to metadata
56
- if @metadata.has_key?(method)
57
- @metadata[method]
58
-
59
- else
60
- super(method, *args, &block)
12
+ deps = ['gem2rpm', 'versionomy', 'active_support', 'active_support/core_ext']
13
+ Component.verify("RPM::Spec", *deps) do
14
+ module RPM
15
+ class Spec
16
+ # RPM Spec Requirement Prefix
17
+ def self.requirement_prefix
18
+ Requirement.prefix
61
19
  end
62
- end
63
-
64
- # Return boolean indicating if spec has a %check section
65
- def has_check?
66
- @metadata.has_key?(:has_check) && @metadata[:has_check]
67
- end
68
-
69
- # Return all the Requires for the specified gem
70
- def requirements_for_gem(gem_name)
71
- @metadata[:requires].nil? ? [] :
72
- @metadata[:requires].select { |r| r.gem_name == gem_name }
73
- end
74
-
75
- # Return all the BuildRequires for the specified gem
76
- def build_requirements_for_gem(gem_name)
77
- @metadata[:build_requires].nil? ? [] :
78
- @metadata[:build_requires].select { |r| r.gem_name == gem_name }
79
- end
80
-
81
- # Return bool indicating if this spec specifies all the
82
- # requirements in the specified gem dependency
83
- #
84
- # @param [Gem::Dependency] gem_dep dependency which to retreive / compare
85
- # requirements
86
- def has_all_requirements_for?(gem_dep)
87
- reqs = self.requirements_for_gem gem_dep.name
88
- # create a spec requirement dependency for each expanded subrequirement,
89
- # verify we can find a match for that
90
- gem_dep.requirement.to_s.split(',').all? { |greq|
91
- Gem2Rpm::Helpers.expand_requirement([greq.split]).all? { |ereq|
92
- tereq = Requirement.new :name => "rubygem(#{gem_dep.name})",
93
- :condition => ereq.first,
94
- :version => ereq.last.to_s
95
- reqs.any? { |req| req.matches?(tereq)}
96
- }
97
- }
98
- end
99
-
100
- # Return all gem Requires
101
- def gem_requirements
102
- @metadata[:requires].nil? ? [] :
103
- @metadata[:requires].select { |r| r.gem? }
104
- end
105
-
106
- # Return all gem BuildRequires
107
- def gem_build_requirements
108
- @metadata[:build_requires].nil? ? [] :
109
- @metadata[:build_requires].select { |r| r.gem? }
110
- end
111
-
112
- # Return all non gem Requires
113
- def non_gem_requirements
114
- @metadata[:requires].nil? ? [] :
115
- @metadata[:requires].select { |r| !r.gem? }
116
- end
117
-
118
- # Return all non gem BuildRequires
119
- def non_gem_build_requirements
120
- @metadata[:build_requires].nil? ? [] :
121
- @metadata[:build_requires].select { |r| !r.gem? }
122
- end
123
-
124
- # Return all gem requirements _not_ in the specified gem
125
- def extra_gem_requirements(gem)
126
- gem_reqs = gem.deps.collect { |d| requirements_for_gem(d.name) }.flatten
127
- gem_requirements - gem_reqs
128
- end
129
-
130
- # Return all gem build requirements _not_ in the specified gem
131
- def extra_gem_build_requirements(gem)
132
- gem_reqs = gem.deps.collect { |d| requirements_for_gem(d.name) }.flatten
133
- gem_build_requirements - gem_reqs
134
- end
135
-
136
- # Parse the specified rpm spec and return new RPM::Spec instance from metadata
137
- #
138
- # @param [String] string contents of spec to parse
139
- # @return [Polisher::RPM::Spec] spec instantiated from rpmspec metadata
140
- def self.parse(spec)
141
- in_subpackage = false
142
- in_changelog = false
143
- in_files = false
144
- subpkg_name = nil
145
- meta = {:contents => spec}
146
- spec.each_line { |l|
147
- if l =~ COMMENT_MATCHER
148
- ;
149
-
150
- # TODO support optional gem prefix
151
- elsif l =~ GEM_NAME_MATCHER
152
- meta[:gem_name] = $1.strip
153
- meta[:gem_name] = $1.strip
154
-
155
- elsif l =~ SPEC_NAME_MATCHER &&
156
- $1.strip != "%{gem_name}"
157
- meta[:gem_name] = $1.strip
158
-
159
- elsif l =~ SPEC_VERSION_MATCHER
160
- meta[:version] = $1.strip
161
-
162
- elsif l =~ SPEC_RELEASE_MATCHER
163
- meta[:release] = $1.strip
164
-
165
- elsif l =~ SPEC_SUBPACKAGE_MATCHER
166
- subpkg_name = $1.strip
167
- in_subpackage = true
168
-
169
- elsif l =~ SPEC_REQUIRES_MATCHER &&
170
- !in_subpackage
171
- meta[:requires] ||= []
172
- meta[:requires] << RPM::Requirement.parse($1.strip)
173
-
174
- elsif l =~ SPEC_BUILD_REQUIRES_MATCHER &&
175
- !in_subpackage
176
- meta[:build_requires] ||= []
177
- meta[:build_requires] << RPM::Requirement.parse($1.strip)
178
-
179
- elsif l =~ SPEC_CHANGELOG_MATCHER
180
- in_changelog = true
181
-
182
- elsif l =~ SPEC_FILES_MATCHER
183
- subpkg_name = nil
184
- in_files = true
185
-
186
- elsif l =~ SPEC_SUBPKG_FILES_MATCHER
187
- subpkg_name = $1.strip
188
- in_files = true
189
-
190
- elsif l =~ SPEC_CHECK_MATCHER
191
- meta[:has_check] = true
192
-
193
- elsif in_changelog
194
- meta[:changelog] ||= ""
195
- meta[:changelog] << l
196
-
197
- elsif in_files
198
- tgt = subpkg_name.nil? ? meta[:gem_name] : subpkg_name
199
- meta[:files] ||= {}
200
- meta[:files][tgt] ||= []
201
-
202
- sl = l.strip.unrpmize
203
- meta[:files][tgt] << sl unless sl.blank?
20
+
21
+ def requirement_prefix
22
+ self.class.requirement_prefix
23
+ end
24
+
25
+ def self.package_prefix
26
+ requirement_prefix
27
+ end
28
+
29
+ AUTHOR = "#{ENV['USER']} <#{ENV['USER']}@localhost.localdomain>"
30
+
31
+ COMMENT_MATCHER = /^\s*#.*/
32
+ GEM_NAME_MATCHER = /^%global\s*gem_name\s(.*)$/
33
+ SPEC_NAME_MATCHER = /^Name:\s*#{package_prefix}-(.*)$/
34
+ SPEC_VERSION_MATCHER = /^Version:\s*(.*)$/
35
+ SPEC_RELEASE_MATCHER = /^Release:\s*(.*)$/
36
+ SPEC_REQUIRES_MATCHER = /^Requires:\s*(.*)$/
37
+ SPEC_BUILD_REQUIRES_MATCHER = /^BuildRequires:\s*(.*)$/
38
+ SPEC_GEM_REQ_MATCHER = /^.*\s*#{requirement_prefix}\((.*)\)(\s*(.*))?$/
39
+ SPEC_SUBPACKAGE_MATCHER = /^%package\s(.*)$/
40
+ SPEC_CHANGELOG_MATCHER = /^%changelog$/
41
+ SPEC_FILES_MATCHER = /^%files$/
42
+ SPEC_SUBPKG_FILES_MATCHER = /^%files\s*(.*)$/
43
+ SPEC_DOC_FILES_MATCHER = /^%files doc$/
44
+ SPEC_CHECK_MATCHER = /^%check$/
45
+
46
+ FILE_MACRO_MATCHERS =
47
+ [/^%doc\s/, /^%config\s/, /^%attr\s/,
48
+ /^%verify\s/, /^%docdir.*/, /^%dir\s/,
49
+ /^%defattr.*/, /^%exclude\s/, /^%{gem_instdir}\/+/]
50
+
51
+ FILE_MACRO_REPLACEMENTS =
52
+ {"%{_bindir}" => 'bin',
53
+ "%{gem_libdir}" => 'lib'}
54
+
55
+ attr_accessor :metadata
56
+
57
+ # Return the currently configured author
58
+ def self.current_author
59
+ ENV['POLISHER_AUTHOR'] || AUTHOR
60
+ end
61
+
62
+ def initialize(metadata={})
63
+ @metadata = metadata
64
+ end
65
+
66
+ # Dispatch all missing methods to lookup calls in rpm spec metadata
67
+ def method_missing(method, *args, &block)
68
+ # proxy to metadata
69
+ if @metadata.has_key?(method)
70
+ @metadata[method]
71
+
72
+ else
73
+ super(method, *args, &block)
204
74
  end
205
- }
206
-
207
- meta[:changelog_entries] = meta[:changelog] ?
208
- meta[:changelog].split("\n\n") : []
209
- meta[:changelog_entries].collect! { |c| c.strip }.compact!
210
-
211
- self.new meta
212
- end
75
+ end
76
+
77
+ # Return gem corresponding to spec name/version
78
+ def upstream_gem
79
+ @gem ||= Polisher::Gem.from_rubygems gem_name, version
80
+ end
81
+
82
+ # Return boolean indicating if spec has a %check section
83
+ def has_check?
84
+ @metadata.has_key?(:has_check) && @metadata[:has_check]
85
+ end
86
+
87
+ # Return all the Requires for the specified gem
88
+ def requirements_for_gem(gem_name)
89
+ @metadata[:requires].nil? ? [] :
90
+ @metadata[:requires].select { |r| r.gem_name == gem_name }
91
+ end
92
+
93
+ # Return all the BuildRequires for the specified gem
94
+ def build_requirements_for_gem(gem_name)
95
+ @metadata[:build_requires].nil? ? [] :
96
+ @metadata[:build_requires].select { |r| r.gem_name == gem_name }
97
+ end
98
+
99
+ # Return bool indicating if this spec specifies all the
100
+ # requirements in the specified gem dependency
101
+ #
102
+ # @param [Gem::Dependency] gem_dep dependency which to retreive / compare
103
+ # requirements
104
+ def has_all_requirements_for?(gem_dep)
105
+ reqs = self.requirements_for_gem gem_dep.name
106
+ # create a spec requirement dependency for each expanded subrequirement,
107
+ # verify we can find a match for that
108
+ gem_dep.requirement.to_s.split(',').all? { |greq|
109
+ Gem2Rpm::Helpers.expand_requirement([greq.split]).all? { |ereq|
110
+ tereq = Requirement.new :name => "#{requirement_prefix}(#{gem_dep.name})",
111
+ :condition => ereq.first,
112
+ :version => ereq.last.to_s
113
+ reqs.any? { |req| req.matches?(tereq)}
114
+ }
115
+ }
116
+ end
117
+
118
+ # Return list of gem dependencies for which we have no
119
+ # corresponding requirements
120
+ def missing_deps_for(gem)
121
+ # Comparison by name here assuming if it is in existing spec,
122
+ # spec author will have ensured versions are correct for their purposes
123
+ gem.deps.select { |dep| requirements_for_gem(dep.name).empty? }
124
+ end
213
125
 
214
- # Update RPM::Spec metadata to new gem
215
- #
216
- # @param [Polisher::Gem] new_source new gem to update rpmspec to
217
- def update_to(new_source)
218
- update_deps_from(new_source)
219
- update_files_from(new_source)
220
- update_metadata_from(new_source)
221
- end
126
+ # Return list of gem dev dependencies for which we have
127
+ # no corresponding requirements
128
+ def missing_dev_deps_for(gem)
129
+ # Same note as in #missing_deps_for above
130
+ gem.dev_deps.select { |dep| build_requirements_for_gem(dep.name).empty? }
131
+ end
222
132
 
223
- private
224
-
225
- # Update spec dependencies from new source
226
- def update_deps_from(new_source)
227
- @metadata[:requires] =
228
- non_gem_requirements +
229
- extra_gem_requirements(new_source) +
230
- new_source.deps.collect { |r|
231
- RPM::Requirement.from_gem_dep(r)
232
- }.flatten
133
+ # Return list of dependencies of upstream gem which
134
+ # have not been included
135
+ def excluded_deps
136
+ missing_deps_for(upstream_gem)
137
+ end
233
138
 
234
- @metadata[:build_requires] =
235
- non_gem_build_requirements +
236
- extra_gem_build_requirements(new_source) +
237
- new_source.dev_deps.collect { |r|
238
- RPM::Requirement.from_gem_dep(r, true)
239
- }.flatten
240
- end
139
+ # Return boolean indicating if the specified gem is on excluded list
140
+ def excludes_dep?(gem_name)
141
+ excluded_deps.any? { |d| d.name == gem_name }
142
+ end
241
143
 
242
- # Internal helper to update spec files from new source
243
- def update_files_from(new_source)
244
- to_add = new_source.file_paths
245
- @metadata[:files] ||= {}
246
- @metadata[:files].each { |pkg,spec_files|
247
- (new_source.file_paths & to_add).each { |gem_file|
248
- # skip files already included in spec or in dir in spec
249
- has_file = spec_files.any? { |sf|
250
- gem_file.gsub(sf,'') != gem_file
251
- }
144
+ # Return list of dev dependencies of upstream gem which
145
+ # have not been included
146
+ def excluded_dev_deps
147
+ missing_dev_deps_for(upstream_gem)
148
+ end
252
149
 
253
- to_add.delete(gem_file)
254
- to_add << gem_file.rpmize if !has_file &&
255
- !Gem.ignorable_file?(gem_file)
150
+ # Return boolean indicating if the specified gem is on
151
+ # excluded dev dep list
152
+ def excludes_dev_dep?(gem_name)
153
+ excluded_dev_deps.any? { |d| d.name == gem_name }
154
+ end
155
+
156
+ # Return all gem Requires
157
+ def gem_requirements
158
+ @metadata[:requires].nil? ? [] :
159
+ @metadata[:requires].select { |r| r.gem? }
160
+ end
161
+
162
+ # Return all gem BuildRequires
163
+ def gem_build_requirements
164
+ @metadata[:build_requires].nil? ? [] :
165
+ @metadata[:build_requires].select { |r| r.gem? }
166
+ end
167
+
168
+ # Return all non gem Requires
169
+ def non_gem_requirements
170
+ @metadata[:requires].nil? ? [] :
171
+ @metadata[:requires].select { |r| !r.gem? }
172
+ end
173
+
174
+ # Return all non gem BuildRequires
175
+ def non_gem_build_requirements
176
+ @metadata[:build_requires].nil? ? [] :
177
+ @metadata[:build_requires].select { |r| !r.gem? }
178
+ end
179
+
180
+ # Return all gem requirements _not_ in the specified gem
181
+ def extra_gem_requirements(gem)
182
+ gem_reqs = gem.deps.collect { |d| requirements_for_gem(d.name) }.flatten
183
+ gem_requirements - gem_reqs
184
+ end
185
+
186
+ # Return all gem build requirements _not_ in the specified gem
187
+ def extra_gem_build_requirements(gem)
188
+ gem_reqs = gem.deps.collect { |d| requirements_for_gem(d.name) }.flatten
189
+ gem_build_requirements - gem_reqs
190
+ end
191
+
192
+ # Parse the specified rpm spec and return new RPM::Spec instance from metadata
193
+ #
194
+ # @param [String] string contents of spec to parse
195
+ # @return [Polisher::RPM::Spec] spec instantiated from rpmspec metadata
196
+ def self.parse(spec)
197
+ in_subpackage = false
198
+ in_changelog = false
199
+ in_files = false
200
+ subpkg_name = nil
201
+ meta = {:contents => spec}
202
+ spec.each_line { |l|
203
+ if l =~ COMMENT_MATCHER
204
+ ;
205
+
206
+ # TODO support optional gem prefix
207
+ elsif l =~ GEM_NAME_MATCHER
208
+ meta[:gem_name] = $1.strip
209
+ meta[:gem_name] = $1.strip
210
+
211
+ elsif l =~ SPEC_NAME_MATCHER &&
212
+ $1.strip != "%{gem_name}"
213
+ meta[:gem_name] = $1.strip
214
+
215
+ elsif l =~ SPEC_VERSION_MATCHER
216
+ meta[:version] = $1.strip
217
+
218
+ elsif l =~ SPEC_RELEASE_MATCHER
219
+ meta[:release] = $1.strip
220
+
221
+ elsif l =~ SPEC_SUBPACKAGE_MATCHER
222
+ subpkg_name = $1.strip
223
+ in_subpackage = true
224
+
225
+ elsif l =~ SPEC_REQUIRES_MATCHER &&
226
+ !in_subpackage
227
+ meta[:requires] ||= []
228
+ meta[:requires] << RPM::Requirement.parse($1.strip)
229
+
230
+ elsif l =~ SPEC_BUILD_REQUIRES_MATCHER &&
231
+ !in_subpackage
232
+ meta[:build_requires] ||= []
233
+ meta[:build_requires] << RPM::Requirement.parse($1.strip)
234
+
235
+ elsif l =~ SPEC_CHANGELOG_MATCHER
236
+ in_changelog = true
237
+
238
+ elsif l =~ SPEC_FILES_MATCHER
239
+ subpkg_name = nil
240
+ in_files = true
241
+
242
+ elsif l =~ SPEC_SUBPKG_FILES_MATCHER
243
+ subpkg_name = $1.strip
244
+ in_files = true
245
+
246
+ elsif l =~ SPEC_CHECK_MATCHER
247
+ meta[:has_check] = true
248
+
249
+ elsif in_changelog
250
+ meta[:changelog] ||= ""
251
+ meta[:changelog] << l
252
+
253
+ elsif in_files
254
+ tgt = subpkg_name.nil? ? meta[:gem_name] : subpkg_name
255
+ meta[:files] ||= {}
256
+ meta[:files][tgt] ||= []
257
+
258
+ sl = l.strip.unrpmize
259
+ meta[:files][tgt] << sl unless sl.blank?
260
+ end
256
261
  }
257
- }
258
-
259
- @metadata[:new_files] = to_add
260
- end
261
-
262
- # Internal helper to update spec metadata from new source
263
- def update_metadata_from(new_source)
264
- # update to new version
265
- @metadata[:version] = new_source.version
266
- @metadata[:release] = "1%{?dist}"
267
-
268
- # add changelog entry
269
- changelog_entry = <<EOS
262
+
263
+ meta[:changelog_entries] = meta[:changelog] ?
264
+ meta[:changelog].split("\n\n") : []
265
+ meta[:changelog_entries].collect! { |c| c.strip }.compact!
266
+
267
+ self.new meta
268
+ end
269
+
270
+ # Update RPM::Spec metadata to new gem
271
+ #
272
+ # @param [Polisher::Gem] new_source new gem to update rpmspec to
273
+ def update_to(new_source)
274
+ update_deps_from(new_source)
275
+ update_files_from(new_source)
276
+ update_metadata_from(new_source)
277
+ end
278
+
279
+ private
280
+
281
+ # Update spec dependencies from new source
282
+ def update_deps_from(new_source)
283
+ @metadata[:requires] =
284
+ non_gem_requirements +
285
+ extra_gem_requirements(new_source) +
286
+ new_source.deps.select { |r| !excludes_dep?(r.name) }
287
+ .collect { |r| RPM::Requirement.from_gem_dep(r) }.flatten
288
+
289
+ @metadata[:build_requires] =
290
+ non_gem_build_requirements +
291
+ extra_gem_build_requirements(new_source) +
292
+ new_source.dev_deps.select { |r| !excludes_dev_dep?(r.name) }
293
+ .collect { |r| RPM::Requirement.from_gem_dep(r, true) }.flatten
294
+ end
295
+
296
+ # Internal helper to update spec files from new source
297
+ def update_files_from(new_source)
298
+ to_add = new_source.file_paths
299
+ @metadata[:files] ||= {}
300
+ @metadata[:files].each { |pkg,spec_files|
301
+ (new_source.file_paths & to_add).each { |gem_file|
302
+ # skip files already included in spec or in dir in spec
303
+ has_file = spec_files.any? { |sf|
304
+ gem_file.gsub(sf,'') != gem_file
305
+ }
306
+
307
+ to_add.delete(gem_file)
308
+ to_add << gem_file.rpmize if !has_file &&
309
+ !Gem.ignorable_file?(gem_file)
310
+ }
311
+ }
312
+
313
+ @metadata[:new_files] = to_add.select { |f| !Gem.doc_file?(f) }
314
+ @metadata[:new_docs] = to_add - @metadata[:new_files]
315
+ end
316
+
317
+ # Internal helper to update spec metadata from new source
318
+ def update_metadata_from(new_source)
319
+ # update to new version
320
+ @metadata[:version] = new_source.version
321
+ @metadata[:release] = "1%{?dist}"
322
+
323
+ # add changelog entry
324
+ changelog_entry = <<EOS
270
325
  * #{Time.now.strftime("%a %b %d %Y")} #{RPM::Spec.current_author} - #{@metadata[:version]}-1
271
326
  - Update to version #{new_source.version}
272
327
  EOS
273
- @metadata[:changelog_entries] ||= []
274
- @metadata[:changelog_entries].unshift changelog_entry.rstrip
275
- end
276
-
277
- public
278
-
279
- # Return properly formatted rpmspec as string
280
- #
281
- # @return [String] string representation of rpm spec
282
- def to_string
283
- contents = @metadata[:contents]
284
-
285
- # replace version / release
286
- contents.gsub!(SPEC_VERSION_MATCHER, "Version: #{@metadata[:version]}")
287
- contents.gsub!(SPEC_RELEASE_MATCHER, "Release: #{@metadata[:release]}")
288
-
289
- # add changelog entry
290
- cp = contents.index SPEC_CHANGELOG_MATCHER
291
- cpn = contents.index "\n", cp
292
- contents = contents[0...cpn+1] +
293
- @metadata[:changelog_entries].join("\n\n")
294
-
295
- # update requires/build requires
296
- rp = contents.index SPEC_REQUIRES_MATCHER
297
- brp = contents.index SPEC_BUILD_REQUIRES_MATCHER
298
- tp = rp < brp ? rp : brp
299
-
300
- pp = contents.index SPEC_SUBPACKAGE_MATCHER
301
- pp = -1 if pp.nil?
302
-
303
- lrp = contents.rindex SPEC_REQUIRES_MATCHER, pp
304
- lbrp = contents.rindex SPEC_BUILD_REQUIRES_MATCHER, pp
305
- ltp = lrp > lbrp ? lrp : lbrp
306
-
307
- ltpn = contents.index "\n", ltp
308
-
309
- contents.slice!(tp...ltpn)
310
- contents.insert tp,
311
- (@metadata[:requires].collect { |r| "Requires: #{r.str}" } +
312
- @metadata[:build_requires].collect { |r| "BuildRequires: #{r.str}" }).join("\n")
313
-
314
- # add new files
315
- fp = contents.index SPEC_FILES_MATCHER
316
- lfp = contents.index SPEC_SUBPKG_FILES_MATCHER, fp + 1
317
- lfp = contents.index SPEC_CHANGELOG_MATCHER if lfp.nil?
318
-
319
- contents.insert lfp - 1, @metadata[:new_files].join("\n") + "\n"
320
-
321
- # return new contents
322
- contents
323
- end
324
-
325
- # Compare this spec to a sepecified upstream gem source
326
- # and return result.
327
- #
328
- # upstream_source should be an instance of Polisher::Gem,
329
- # Polisher::Gemfile, or other class defining a 'deps'
330
- # accessor that returns an array of Gem::Requirement dependencies
331
- #
332
- # Result will be a hash containing the shared dependencies as
333
- # well as those that differ and their respective differences
334
- def compare(upstream_source)
335
- same = {}
336
- diff = {}
337
- upstream_source.deps.each do |d|
338
- spec_reqs = self.requirements_for_gem(d.name)
339
- spec_reqs_specifier = spec_reqs.empty? ? nil :
340
- spec_reqs.collect { |req| req.specifier }
341
-
342
- if spec_reqs.nil?
343
- diff[d.name] = {:spec => nil,
344
- :upstream => d.requirement.to_s}
345
-
346
- elsif !spec_reqs.any? { |req| req.matches?(d) } ||
347
- !self.has_all_requirements_for?(d)
348
- diff[d.name] = {:spec => spec_reqs_specifier,
349
- :upstream => d.requirement.to_s}
350
-
351
- elsif !diff.has_key?(d.name)
352
- same[d.name] = {:spec => spec_reqs_specifier,
353
- :upstream => d.requirement.to_s }
354
- end
328
+ @metadata[:changelog_entries] ||= []
329
+ @metadata[:changelog_entries].unshift changelog_entry.rstrip
355
330
  end
331
+
332
+ public
333
+
334
+ # Return properly formatted rpmspec as string
335
+ #
336
+ # @return [String] string representation of rpm spec
337
+ def to_string
338
+ contents = @metadata[:contents]
339
+
340
+ # replace version / release
341
+ contents.gsub!(SPEC_VERSION_MATCHER, "Version: #{@metadata[:version]}")
342
+ contents.gsub!(SPEC_RELEASE_MATCHER, "Release: #{@metadata[:release]}")
343
+
344
+ # add changelog entry
345
+ cp = contents.index SPEC_CHANGELOG_MATCHER
346
+ cpn = contents.index "\n", cp
347
+ contents = contents[0...cpn+1] +
348
+ @metadata[:changelog_entries].join("\n\n")
349
+
350
+ # update requires/build requires
351
+ rp = contents.index SPEC_REQUIRES_MATCHER
352
+ brp = contents.index SPEC_BUILD_REQUIRES_MATCHER
353
+ tp = rp < brp ? rp : brp
354
+
355
+ pp = contents.index SPEC_SUBPACKAGE_MATCHER
356
+ pp = -1 if pp.nil?
357
+
358
+ lrp = contents.rindex SPEC_REQUIRES_MATCHER, pp
359
+ lbrp = contents.rindex SPEC_BUILD_REQUIRES_MATCHER, pp
360
+ ltp = lrp > lbrp ? lrp : lbrp
361
+
362
+ ltpn = contents.index "\n", ltp
363
+
364
+ contents.slice!(tp...ltpn)
365
+ contents.insert tp,
366
+ (@metadata[:requires].collect { |r| "Requires: #{r.str}" } +
367
+ @metadata[:build_requires].collect { |r| "BuildRequires: #{r.str}" }).join("\n")
368
+
369
+ # add new files
370
+ fp = contents.index SPEC_FILES_MATCHER
371
+ lfp = contents.index SPEC_SUBPKG_FILES_MATCHER, fp + 1
372
+ lfp = contents.index SPEC_CHANGELOG_MATCHER if lfp.nil?
373
+
374
+ contents.insert lfp - 1, @metadata[:new_files].join("\n") + "\n"
375
+
376
+ # add new doc files
377
+ fp = contents.index SPEC_DOC_FILES_MATCHER
378
+ fp = contents.index SPEC_FILES_MATCHER if fp.nil?
379
+ lfp = contents.index SPEC_SUBPKG_FILES_MATCHER, fp + 1
380
+ lfp = contents.index SPEC_CHANGELOG_MATCHER if lfp.nil?
356
381
 
357
- @metadata[:requires].each do |req|
358
- next unless req.gem?
359
-
360
- upstream_dep = upstream_source.deps.find { |d| d.name == req.gem_name }
361
-
362
- if upstream_dep.nil?
363
- diff[req.gem_name] = {:spec => req.specifier,
364
- :upstream => nil}
365
-
366
- elsif !req.matches?(upstream_dep)
367
- diff[req.gem_name] = {:spec => req.specifier,
368
- :upstream => upstream_dep.requirement.to_s }
369
-
370
- elsif !diff.has_key?(req.gem_name)
371
- same[req.gem_name] = {:spec => req.specifier,
372
- :upstream => upstream_dep.requirement.to_s }
382
+ contents.insert lfp - 1, @metadata[:new_docs].join("\n") + "\n"
383
+
384
+ # return new contents
385
+ contents
386
+ end
387
+
388
+ # Compare this spec to a sepecified upstream gem source
389
+ # and return result.
390
+ #
391
+ # upstream_source should be an instance of Polisher::Gem,
392
+ # Polisher::Gemfile, or other class defining a 'deps'
393
+ # accessor that returns an array of Gem::Requirement dependencies
394
+ #
395
+ # Result will be a hash containing the shared dependencies as
396
+ # well as those that differ and their respective differences
397
+ def compare(upstream_source)
398
+ same = {}
399
+ diff = {}
400
+ upstream_source.deps.each do |d|
401
+ spec_reqs = self.requirements_for_gem(d.name)
402
+ spec_reqs_specifier = spec_reqs.empty? ? nil :
403
+ spec_reqs.collect { |req| req.specifier }
404
+
405
+ if spec_reqs.nil?
406
+ diff[d.name] = {:spec => nil,
407
+ :upstream => d.requirement.to_s}
408
+
409
+ elsif !spec_reqs.any? { |req| req.matches?(d) } ||
410
+ !self.has_all_requirements_for?(d)
411
+ diff[d.name] = {:spec => spec_reqs_specifier,
412
+ :upstream => d.requirement.to_s}
413
+
414
+ elsif !diff.has_key?(d.name)
415
+ same[d.name] = {:spec => spec_reqs_specifier,
416
+ :upstream => d.requirement.to_s }
417
+ end
373
418
  end
374
- end unless @metadata[:requires].nil?
375
-
376
- {:same => same, :diff => diff}
377
- end
378
-
379
- end # class Spec
380
- end # module RPM
419
+
420
+ @metadata[:requires].each do |req|
421
+ next unless req.gem?
422
+
423
+ upstream_dep = upstream_source.deps.find { |d| d.name == req.gem_name }
424
+
425
+ if upstream_dep.nil?
426
+ diff[req.gem_name] = {:spec => req.specifier,
427
+ :upstream => nil}
428
+
429
+ elsif !req.matches?(upstream_dep)
430
+ diff[req.gem_name] = {:spec => req.specifier,
431
+ :upstream => upstream_dep.requirement.to_s }
432
+
433
+ elsif !diff.has_key?(req.gem_name)
434
+ same[req.gem_name] = {:spec => req.specifier,
435
+ :upstream => upstream_dep.requirement.to_s }
436
+ end
437
+ end unless @metadata[:requires].nil?
438
+
439
+ {:same => same, :diff => diff}
440
+ end
441
+
442
+ end # class Spec
443
+ end # module RPM
444
+ end # Component.verify("RPM::Spec")
381
445
  end # module Polisher