polisher 0.6.1 → 0.7.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.
@@ -0,0 +1,34 @@
1
+ # Mechanism to cache gems
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013-2014 Red Hat, Inc.
5
+
6
+ require 'fileutils'
7
+
8
+ module Polisher
9
+ class GemCache
10
+ DIR = "#{ENV['HOME']}/.polisher/gems"
11
+
12
+ def self.create!
13
+ FileUtils.mkdir_p(DIR) unless File.directory?(DIR)
14
+ end
15
+
16
+ def self.clear!
17
+ FileUtils.rm_rf(DIR)
18
+ end
19
+
20
+ def self.path_for(name, version)
21
+ "#{DIR}/#{name}-#{version}.gem"
22
+ end
23
+
24
+ def self.get(name, version)
25
+ path = path_for(name, version)
26
+ File.exists?(path) ? File.read(path) : nil
27
+ end
28
+
29
+ def self.set(name, version, gem)
30
+ self.create!
31
+ File.write(path_for(name, version), gem)
32
+ end
33
+ end # class GemCache
34
+ end # module Polisher
@@ -1,7 +1,7 @@
1
1
  # Polisher Gemfile Represenation
2
2
  #
3
3
  # Licensed under the MIT license
4
- # Copyright (C) 2013 Red Hat, Inc.
4
+ # Copyright (C) 2013-2014 Red Hat, Inc.
5
5
 
6
6
  require 'bundler'
7
7
 
@@ -39,13 +39,13 @@ module Polisher
39
39
  attr_accessor :dev_deps
40
40
 
41
41
  # always empty array, for interface compatability
42
- attr_accessor :files
42
+ attr_accessor :file_paths
43
43
 
44
44
  def initialize(args={})
45
45
  @version = nil
46
46
  @deps = args[:deps]
47
47
  @dev_deps = args[:dev_deps]
48
- @files = []
48
+ @file_paths = []
49
49
  end
50
50
 
51
51
  # Parse the specified gemfile & return new Gemfile instance from metadata
@@ -68,5 +68,14 @@ module Polisher
68
68
 
69
69
  self.new metadata
70
70
  end
71
+
72
+ # TODO simply alias for gems in gemfile?
73
+ def vendored
74
+ end
75
+
76
+ # TODO retrieve gems which differ from
77
+ # rubygems.org/other upstream sources
78
+ def patched
79
+ end
71
80
  end # class Gemfile
72
81
  end # module Polisher
@@ -1,7 +1,7 @@
1
1
  # Polisher Gemspec Represenation
2
2
  #
3
3
  # Licensed under the MIT license
4
- # Copyright (C) 2013 Red Hat, Inc.
4
+ # Copyright (C) 2013-2014 Red Hat, Inc.
5
5
 
6
6
  require 'polisher/version_checker'
7
7
 
@@ -1,112 +1,209 @@
1
- # Polisher DistGit Package Representation
1
+ # Polisher Git Entity Representations
2
2
  #
3
3
  # Licensed under the MIT license
4
- # Copyright (C) 2013 Red Hat, Inc.
5
-
6
- # TODO use ruby git api and others
4
+ # Copyright (C) 2013-2014 Red Hat, Inc.
7
5
 
8
6
  require 'tmpdir'
9
7
  require 'awesome_spawn'
10
8
  require 'polisher/rpmspec'
9
+ require 'polisher/git_cache'
11
10
 
12
11
  module Polisher
13
- class GitPackage
12
+ # Git Repository
13
+ class GitRepo
14
+ # TODO use ruby git api
15
+ GIT_CMD = '/usr/bin/git'
16
+
17
+ attr_accessor :url
18
+
19
+ def initialize(args={})
20
+ @url = args[:url]
21
+ end
22
+
23
+ def path
24
+ GitCache.path_for(@url)
25
+ end
26
+
27
+ def clone
28
+ AwesomeSpawn.run "#{GIT_CMD} clone #{url} #{path}"
29
+ end
30
+
31
+ def cloned?
32
+ File.directory?(path)
33
+ end
34
+
35
+ def in_repo
36
+ Dir.chdir path do
37
+ yield
38
+ end
39
+ end
40
+
41
+ # Note be careful when invoking:
42
+ def reset!
43
+ in_repo { AwesomeSpawn.run "#{GIT_CMD} reset HEAD~ --hard" }
44
+ self
45
+ end
46
+
47
+ def pull
48
+ in_repo { AwesomeSpawn.run "#{GIT_CMD} pull" }
49
+ self
50
+ end
51
+
52
+ def checkout(tgt)
53
+ in_repo { AwesomeSpawn.run "#{GIT_CMD} checkout #{tgt}" }
54
+ self
55
+ end
56
+
57
+ def commit(msg)
58
+ in_repo { AwesomeSpawn.run "#{GIT_CMD} commit -m '#{msg}'" }
59
+ self
60
+ end
61
+ end
62
+
63
+ # DistGit Package Representation
64
+ class GitPackage < GitRepo
14
65
  attr_accessor :name
15
66
  attr_accessor :version
16
67
 
17
68
  # TODO these should be to be configurable
69
+ RPM_PREFIX = 'rubygem-'
18
70
  PKG_CMD = '/usr/bin/fedpkg'
19
- GIT_CMD = '/usr/bin/git'
20
71
  BUILD_CMD = '/usr/bin/koji'
21
72
  BUILD_TGT = 'rawhide'
73
+
22
74
  MD5SUM_CMD = '/usr/bin/md5sum'
23
75
  SED_CMD = '/usr/bin/sed'
24
- RPM_PREFIX = 'rubygem-'
25
76
  DIST_GIT_URL = 'git://pkgs.fedoraproject.org/'
26
77
 
27
78
  def initialize(args={})
28
79
  @name = args[:name]
29
80
  @version = args[:version]
81
+ super(args)
30
82
  end
31
83
 
32
84
  # Return full rpm name of package containing optional prefix
33
85
  def rpm_name
34
- "#{RPM_PREFIX}#{self.name}"
86
+ @rpm_name ||= "#{RPM_PREFIX}#{self.name}"
35
87
  end
36
88
 
37
89
  # Return full srpm file name of package
38
90
  def srpm
39
- "#{rpm_name}-#{self.version}-1.*.src.rpm"
91
+ @srpm ||= "#{rpm_name}-#{self.version}-1.*.src.rpm"
40
92
  end
41
93
 
42
94
  # Return full spec file name
95
+ def spec_file
96
+ @spec_path ||= "#{rpm_name}.spec"
97
+ end
98
+
99
+ # Return handle to instance of Polisher::RPMSpec corresponding to spec
43
100
  def spec
44
- "#{rpm_name}.spec"
101
+ @spec ||= in_repo { Polisher::RPMSpec.parse spec_file }
45
102
  end
46
103
 
47
- # Clone git package
48
- #
49
- # @param [String] name name of package to clone
50
- # @return [Polisher::GitPackage] git package instance representing cloned package
51
- def self.clone(name)
52
- rpm_name = "#{RPM_PREFIX}#{name}"
104
+ # Files representing pkg tracked by git
105
+ def pkg_files
106
+ @pkg_files ||= [spec_file, 'sources', '.gitignore']
107
+ end
108
+
109
+ # Override path to reference pkg name
110
+ # @override
111
+ def path
112
+ GitCache.path_for(rpm_name)
113
+ end
53
114
 
54
- unless File.directory? rpm_name
115
+ # Alias orig clone method to git_clone
116
+ alias :git_clone :clone
117
+
118
+ # Override clone to use PKG_PCMD
119
+ # @override
120
+ def clone
121
+ in_repo do
55
122
  AwesomeSpawn.run "#{PKG_CMD} clone #{rpm_name}"
123
+ Dir.glob(rpm_name, '*').each { |f| File.move f, '.' }
124
+ FileUtils.rm_rf rpm_name
56
125
  end
57
-
58
- # cd into working directory
59
- Dir.chdir rpm_name
60
126
 
61
- if File.exists? 'dead.package'
62
- raise Exception, "Dead package detected"
127
+ self
128
+ end
129
+
130
+ def dead?
131
+ in_repo { File.exists?('dead.package') }
132
+ end
133
+
134
+ # Clone / init GitPkg
135
+ def fetch
136
+ clone unless cloned?
137
+ raise Exception, "Dead package detected" if dead?
138
+ checkout 'master'
139
+ reset!
140
+ pull
141
+
142
+ self
143
+ end
144
+
145
+ # Update the local spec to the specified gem version
146
+ #
147
+ # FIXME this should be removed and calls replaced with self.spec.update_to(gem)
148
+ def update_spec_to(gem)
149
+ in_repo do
150
+ replace_version = "s/Version.*/Version: #{gem.version}/"
151
+ replace_release = "s/Release:.*/Release: 1%{?dist}/"
152
+ [replace_version, replace_release].each do |replace|
153
+ AwesomeSpawn.run "#{SED_CMD} -i '#{replace}' #{spec_file}"
154
+ end
63
155
  end
64
-
65
- # checkout the latest rawhide
66
- # TODO allow other branches to be specified
67
- AwesomeSpawn.run "#{GIT_CMD} checkout master"
68
- AwesomeSpawn.run "#{GIT_CMD} reset HEAD~ --hard"
69
- AwesomeSpawn.run "#{GIT_CMD} pull"
156
+ end
70
157
 
71
- self.new :name => name
158
+ # Generate new sources file
159
+ def gen_sources_for(gem)
160
+ in_repo do
161
+ AwesomeSpawn.run "#{MD5SUM_CMD} #{gem.name}-#{gem.version}.gem > sources"
162
+ end
163
+ end
164
+
165
+ # Update git ignore to ignore gem
166
+ def ignore(gem)
167
+ File.open(".gitignore", "w") { |f| f.write "#{gem.name}-#{gem.version}.gem" }
72
168
  end
73
169
 
74
- # Update the locally cloned package to the specified gem version
170
+ # Update the local pkg to specified gem
75
171
  #
76
172
  # @param [Polisher::Gem] gem instance of gem containing metadata to update to
77
173
  def update_to(gem)
78
- # TODO use Polisher::RPMSpec to update spec
79
- AwesomeSpawn.run "#{SED_CMD} -i 's/Version.*/Version: #{gem.version}/' #{spec}"
80
- AwesomeSpawn.run "#{SED_CMD} -i 's/Release:.*/Release: 1%{?dist}/' #{spec}"
81
- AwesomeSpawn.run "#{MD5SUM_CMD} #{gem.name}-#{gem.version}.gem > sources"
82
- File.open(".gitignore", "w") { |f| f.write "#{gem.name}-#{gem.version}.gem" }
174
+ update_spec_to gem
175
+ gen_sources_for gem
176
+ ignore gem
177
+ self
83
178
  end
84
179
 
85
- # Build the locally cloned package using the configured build command
86
- def build
87
- # build srpm
88
- AwesomeSpawn.run "#{PKG_CMD} srpm"
89
-
90
- # attempt to build packages
91
- AwesomeSpawn.run "#{BUILD_CMD} build --scratch #{BUILD_TGT} #{srpm}"
92
- # TODO if build fails, spit out error, exit
180
+ # Override commit, generate a default msg, always add pkg files
181
+ # @override
182
+ def commit(msg=nil)
183
+ in_repo { AwesomeSpawn.run "#{GIT_CMD} add #{pkg_files.join(' ')}" }
184
+ super(msg.nil? ? "updated to #{version}" : msg)
185
+ self
93
186
  end
94
187
 
95
- # Return boolean indicating if package spec has a %check section
96
- #
97
- # @return [Boolean] true/false depending on whether or not spec has %check
98
- def has_check?
99
- File.open(spec, "r") do |spec|
100
- spec.lines.any? { |line| line.include?("%check") }
101
- end
188
+ # Build the srpm
189
+ def build_srpm
190
+ in_repo { AwesomeSpawn.run "#{PKG_CMD} srpm" }
191
+ self
102
192
  end
103
193
 
104
- # Command the local package to the local git repo
105
- def commit
106
- # git add spec, git commit w/ message
107
- AwesomeSpawn.run "#{GIT_CMD} add #{spec} sources .gitignore"
108
- #`git add #{gem_name}-#{version}.gem`
109
- AwesomeSpawn.run "#{GIT_CMD} commit -m 'updated to #{self.version}'"
194
+ # Run a scratch build
195
+ def scratch_build
196
+ # TODO if build fails, raise error, else return output
197
+ cmd = "#{BUILD_CMD} build --scratch #{BUILD_TGT} #{srpm}"
198
+ in_repo { AwesomeSpawn.run(cmd) }
199
+ self
200
+ end
201
+
202
+ # Build the pkg
203
+ def build
204
+ build_srpm
205
+ scratch_build
206
+ self
110
207
  end
111
208
 
112
209
  # Retrieve list of the version of the specified package in git
@@ -115,23 +212,24 @@ module Polisher
115
212
  # @param [Callable] bl optional block to invoke with version retrieved
116
213
  # @return [String] version retrieved, or nil if none found
117
214
  def self.version_for(name, &bl)
118
- rpm_name = "#{RPM_PREFIX}#{name}"
119
215
  version = nil
120
-
121
- Dir.mktmpdir do |dir|
122
- Dir.chdir(dir) do |path|
123
- version = nil
124
- AwesomeSpawn.run "#{GIT_CMD} clone #{DIST_GIT_URL}#{rpm_name}.git ."
125
- begin
126
- spec = Polisher::RPMSpec.parse(File.read("#{rpm_name}.spec"))
127
- version = spec.version
128
- rescue => e
129
- end
130
- end
216
+ gitpkg = self.new :name => name
217
+ gitpkg.url = "#{DIST_GIT_URL}#{gitpkg.rpm_name}.git"
218
+ gitpkg.git_clone
219
+ begin
220
+ version = gitpkg.spec.version
221
+ rescue => e
131
222
  end
132
223
 
133
224
  bl.call(:git, name, [version]) unless(bl.nil?)
134
225
  version
135
226
  end
136
227
  end # class GitPackage
228
+
229
+ # Upstream Git project representation
230
+ class GitProject < GitRepo
231
+ # TODO scan project for vendored components
232
+ def vendored
233
+ end
234
+ end
137
235
  end # module Polisher
@@ -0,0 +1,25 @@
1
+ # Mechanism to cache git repos
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013-2014 Red Hat, Inc.
5
+
6
+ require 'fileutils'
7
+
8
+ module Polisher
9
+ class GitCache
10
+ DIR = "#{ENV['HOME']}/.polisher/git"
11
+
12
+ def self.create!
13
+ FileUtils.mkdir_p(DIR) unless File.directory?(DIR)
14
+ end
15
+
16
+ def self.clear!
17
+ FileUtils.rm_rf(DIR)
18
+ end
19
+
20
+ def self.path_for(id)
21
+ self.create!
22
+ "#{DIR}/#{id.gsub(/[:\/]/, '')}"
23
+ end
24
+ end # class GemCache
25
+ end # module Polisher
@@ -1,7 +1,7 @@
1
1
  # Polisher Koji Operations
2
2
  #
3
3
  # Licensed under the MIT license
4
- # Copyright (C) 2013 Red Hat, Inc.
4
+ # Copyright (C) 2013-2014 Red Hat, Inc.
5
5
 
6
6
  require 'xmlrpc/client'
7
7
  XMLRPC::Config::ENABLE_NIL_PARSER = true
@@ -1,7 +1,7 @@
1
1
  # Polisher RHN Operations
2
2
  #
3
3
  # Licensed under the MIT license
4
- # Copyright (C) 2013 Red Hat, Inc.
4
+ # Copyright (C) 2013-2014 Red Hat, Inc.
5
5
 
6
6
  require 'pkgwat'
7
7
 
@@ -1,15 +1,163 @@
1
1
  # Polisher RPM Spec Represenation
2
2
  #
3
3
  # Licensed under the MIT license
4
- # Copyright (C) 2013 Red Hat, Inc.
4
+ # Copyright (C) 2013-2014 Red Hat, Inc.
5
5
 
6
6
  require 'gem2rpm'
7
+ require 'versionomy'
7
8
  require 'active_support/core_ext'
8
9
 
9
10
  require 'polisher/core'
11
+ require 'polisher/gem'
10
12
 
11
13
  module Polisher
12
14
  class RPMSpec
15
+ class Requirement
16
+ # Bool indiciating if req is a BR
17
+ attr_accessor :br
18
+
19
+ # Name of requirement
20
+ attr_accessor :name
21
+
22
+ # Condition, eg >=, =, etc
23
+ attr_accessor :condition
24
+
25
+ # Version number
26
+ attr_accessor :version
27
+
28
+ # Requirement string
29
+ def str
30
+ sp = self.specifier
31
+ sp.nil? ? "#{@name}" : "#{@name} #{sp}"
32
+ end
33
+
34
+ # Specified string
35
+ def specifier
36
+ @version.nil? ? nil : "#{@condition} #{@version}"
37
+ end
38
+
39
+ def self.parse(str, opts={})
40
+ stra = str.split
41
+ br = str.include?('BuildRequires')
42
+ name = condition = version = nil
43
+
44
+ if str.include?('Requires')
45
+ name = stra[1]
46
+ condition = stra[2]
47
+ version = stra[3]
48
+
49
+ else
50
+ name = stra[0]
51
+ condition = stra[1]
52
+ version = stra[2]
53
+
54
+ end
55
+
56
+ req = self.new({:name => name,
57
+ :condition => condition,
58
+ :version => version,
59
+ :br => br}.merge(opts))
60
+ req
61
+ end
62
+
63
+ def initialize(args={})
64
+ @br = args[:br] || false
65
+ @name = args[:name]
66
+ @condition = args[:condition]
67
+ @version = args[:version]
68
+
69
+ @name.strip! unless @name.nil?
70
+ @condition.strip! unless @condition.nil?
71
+ @version.strip! unless @version.nil?
72
+ end
73
+
74
+ def ==(other)
75
+ @br == other.br &&
76
+ @name == other.name &&
77
+ @condition == other.condition &&
78
+ @version == other.version
79
+ end
80
+
81
+ # Greatest Common Denominator,
82
+ # Max version in list that is less than the local version
83
+ def gcd(versions)
84
+ lversion = Versionomy.parse(self.version)
85
+ versions.collect { |v| Versionomy.parse(v) }.
86
+ sort { |a,b| a <=> b }.reverse.
87
+ find { |v| v < lversion }.to_s
88
+ end
89
+
90
+ # Minimum gem version which satisfies this dependency
91
+ def min_satisfying_version
92
+ return "0.0" if self.version.nil? ||
93
+ self.condition == '<' ||
94
+ self.condition == '<='
95
+ return self.version if self.condition == '=' ||
96
+ self.condition == '>='
97
+ Versionomy.parse(self.version).bump(:tiny).to_s # self.condition == '>'
98
+ end
99
+
100
+ # Max gem version which satisfies this dependency
101
+ #
102
+ # Can't automatically deduce in '<' case, so if that is the conditional
103
+ # we require a version list, and will return the gcd from it
104
+ def max_satisfying_version(versions=nil)
105
+ return Float::INFINITY if self.version.nil? ||
106
+ self.condition == '>' ||
107
+ self.condition == '>='
108
+ return self.version if self.condition == '=' ||
109
+ self.condition == '<='
110
+
111
+ raise ArgumentError if versions.nil?
112
+ self.gcd(versions)
113
+ end
114
+
115
+ # Minimum gem version for which this dependency fails
116
+ def min_failing_version
117
+ raise ArgumentError if self.version.nil?
118
+ return "0.0" if self.condition == '>' ||
119
+ self.condition == '>='
120
+ return self.version if self.condition == '<'
121
+ Versionomy.parse(self.version).bump(:tiny).to_s # self.condition == '<=' and '='
122
+ end
123
+
124
+ # Max gem version for which this dependency fails
125
+ #
126
+ # Can't automatically deduce in '>=', and '=' cases, so if that is the
127
+ # conditional we require a version list, and will return the gcd from it
128
+ def max_failing_version(versions=nil)
129
+ raise ArgumentError if self.version.nil? ||
130
+ self.condition == '<=' ||
131
+ self.condition == '<'
132
+ return self.version if self.condition == '>'
133
+
134
+ raise ArgumentError if versions.nil?
135
+ self.gcd(versions)
136
+ end
137
+
138
+ def matches?(dep)
139
+ return self == dep if dep.is_a?(self.class)
140
+ raise ArgumentError unless dep.is_a?(::Gem::Dependency)
141
+
142
+ return false if !self.gem? || self.gem_name != dep.name
143
+ return true if self.version.nil?
144
+
145
+ Gem2Rpm::Helpers.expand_requirement([dep.requirement.to_s.split]).
146
+ any?{ |req|
147
+ req.first == self.condition && req.last.to_s == self.version
148
+ }
149
+ end
150
+
151
+ def gem?
152
+ !!(self.str =~ SPEC_GEM_REQ_MATCHER)
153
+ end
154
+
155
+ def gem_name
156
+ # XXX need to explicitly run regex here to get $1
157
+ !!(self.str =~ SPEC_GEM_REQ_MATCHER) ? $1 : nil
158
+ end
159
+ end
160
+
13
161
  AUTHOR = "#{ENV['USER']} <#{ENV['USER']}@localhost.localdomain>"
14
162
 
15
163
  COMMENT_MATCHER = /^\s*#.*/
@@ -24,18 +172,24 @@ module Polisher
24
172
  SPEC_CHANGELOG_MATCHER = /^%changelog$/
25
173
  SPEC_FILES_MATCHER = /^%files$/
26
174
  SPEC_SUBPKG_FILES_MATCHER = /^%files\s*(.*)$/
175
+ SPEC_CHECK_MATCHER = /^%check$/
27
176
 
28
177
  FILE_MACRO_MATCHERS =
29
178
  [/^%doc\s/, /^%config\s/, /^%attr\s/,
30
179
  /^%verify\s/, /^%docdir.*/, /^%dir\s/,
31
- /^%defattr.*/, /^%exclude\s/, /^%{gem_instdir}/]
180
+ /^%defattr.*/, /^%exclude\s/, /^%{gem_instdir}\/+/]
32
181
 
33
182
  FILE_MACRO_REPLACEMENTS =
34
- {"%{_bindir}" => '/bin',
35
- "%{gem_libdir}" => '/lib'}
183
+ {"%{_bindir}" => 'bin',
184
+ "%{gem_libdir}" => 'lib'}
36
185
 
37
186
  attr_accessor :metadata
38
187
 
188
+ # Return the currently configured author
189
+ def self.current_author
190
+ ENV['POLISHER_AUTHOR'] || AUTHOR
191
+ end
192
+
39
193
  def initialize(metadata={})
40
194
  @metadata = metadata
41
195
  end
@@ -51,6 +205,32 @@ module Polisher
51
205
  end
52
206
  end
53
207
 
208
+ def has_check?
209
+ @metadata.has_key?(:has_check) && @metadata[:has_check]
210
+ end
211
+
212
+ # Return all the requirements for the specified gem
213
+ def requirements_for_gem(gem_name)
214
+ @metadata[:requires].nil? ? [] :
215
+ @metadata[:requires].select { |r| r.gem_name == gem_name }
216
+ end
217
+
218
+ # Return bool indicating if this spec specifies all the
219
+ # requirements in the specified gem dependency
220
+ def has_all_requirements_for?(gem_dep)
221
+ reqs = self.requirements_for_gem gem_dep.name
222
+ # create a spec requirement dependency for each expanded subrequirement,
223
+ # verify we can find a match for that
224
+ gem_dep.requirement.to_s.split(',').all? { |greq|
225
+ Gem2Rpm::Helpers.expand_requirement([greq.split]).all? { |ereq|
226
+ tereq = Requirement.new :name => "rubygem(#{gem_dep.name})",
227
+ :condition => ereq.first,
228
+ :version => ereq.last.to_s
229
+ reqs.any? { |req| req.matches?(tereq)}
230
+ }
231
+ }
232
+ end
233
+
54
234
  # Parse the specified rpm spec and return new RPMSpec instance from metadata
55
235
  #
56
236
  # @param [String] string contents of spec to parse
@@ -87,12 +267,12 @@ module Polisher
87
267
  elsif l =~ SPEC_REQUIRES_MATCHER &&
88
268
  !in_subpackage
89
269
  meta[:requires] ||= []
90
- meta[:requires] << $1.strip
270
+ meta[:requires] << RPMSpec::Requirement.parse($1.strip)
91
271
 
92
272
  elsif l =~ SPEC_BUILD_REQUIRES_MATCHER &&
93
273
  !in_subpackage
94
274
  meta[:build_requires] ||= []
95
- meta[:build_requires] << $1.strip
275
+ meta[:build_requires] << RPMSpec::Requirement.parse($1.strip)
96
276
 
97
277
  elsif l =~ SPEC_CHANGELOG_MATCHER
98
278
  in_changelog = true
@@ -104,6 +284,9 @@ module Polisher
104
284
  elsif l =~ SPEC_SUBPKG_FILES_MATCHER
105
285
  subpkg_name = $1.strip
106
286
  in_files = true
287
+
288
+ elsif l =~ SPEC_CHECK_MATCHER
289
+ meta[:has_check] = true
107
290
 
108
291
  elsif in_changelog
109
292
  meta[:changelog] ||= ""
@@ -128,6 +311,9 @@ module Polisher
128
311
 
129
312
  # Update RPMSpec metadata to new gem
130
313
  #
314
+ # TODO add option to enable/disable certain aspects
315
+ # from being updates
316
+ #
131
317
  # @param [Polisher::Gem] new_source new gem to update rpmspec to
132
318
  def update_to(new_source)
133
319
  update_deps_from(new_source)
@@ -145,9 +331,9 @@ module Polisher
145
331
 
146
332
  @metadata[:requires] ||= []
147
333
  @metadata[:requires].each { |r|
148
- if r !~ SPEC_GEM_REQ_MATCHER
334
+ if !r.gem?
149
335
  non_gem_requires << r
150
- elsif !new_source.deps.any? { |d| d.name == $1 }
336
+ elsif !new_source.deps.any? { |d| d.name == r.gem_name }
151
337
  extra_gem_requires << r
152
338
  #else
153
339
  # spec_version = $2
@@ -156,9 +342,9 @@ module Polisher
156
342
 
157
343
  @metadata[:build_requires] ||= []
158
344
  @metadata[:build_requires].each { |r|
159
- if r !~ SPEC_GEM_REQ_MATCHER
345
+ if !r.gem?
160
346
  non_gem_brequires << r
161
- elsif !new_source.deps.any? { |d| d.name == $1 }
347
+ elsif !new_source.deps.any? { |d| d.name == r.gem_name }
162
348
  extra_gem_brequires << r
163
349
  #else
164
350
  # spec_version = $2
@@ -171,10 +357,13 @@ module Polisher
171
357
  non_gem_requires + extra_gem_requires +
172
358
  new_source.deps.collect { |r|
173
359
  r.requirement.to_s.split(',').collect { |req|
174
- expanded = Gem2Rpm::Helpers.expand_requirement [req.split]
175
- expanded.collect { |e|
176
- "rubygem(#{r.name}) #{e.first} #{e.last}"
177
- }
360
+ expanded = Gem2Rpm::Helpers.expand_requirement [req.split]
361
+ expanded.collect { |e|
362
+ RPMSpec::Requirement.new :name => "rubygem(#{r.name})",
363
+ :condition => e.first.to_s,
364
+ :version => e.last.to_s,
365
+ :br => false
366
+ }
178
367
  }
179
368
  }.flatten
180
369
 
@@ -182,23 +371,30 @@ module Polisher
182
371
  non_gem_brequires + extra_gem_brequires +
183
372
  new_source.dev_deps.collect { |r|
184
373
  r.requirement.to_s.split(',').collect { |req|
185
- "rubygem(#{r.name}) #{req}"
374
+ expanded = Gem2Rpm::Helpers.expand_requirement [req.split]
375
+ expanded.collect { |e|
376
+ RPMSpec::Requirement.new :name => "rubygem(#{r.name})",
377
+ :condition => e.first.to_s,
378
+ :version => e.last.to_s,
379
+ :br => true
380
+ }
186
381
  }
187
382
  }.flatten
188
383
  end
189
384
 
190
385
  def update_files_from(new_source)
191
- to_add = new_source.files
386
+ to_add = new_source.file_paths
192
387
  @metadata[:files] ||= {}
193
388
  @metadata[:files].each { |pkg,spec_files|
194
- (new_source.files & to_add).each { |gem_file|
389
+ (new_source.file_paths & to_add).each { |gem_file|
195
390
  # skip files already included in spec or in dir in spec
196
391
  has_file = spec_files.any? { |sf|
197
392
  gem_file.gsub(sf,'') != gem_file
198
393
  }
199
394
 
200
395
  to_add.delete(gem_file)
201
- to_add << gem_file.rpmize if !has_file
396
+ to_add << gem_file.rpmize if !has_file &&
397
+ !Gem.ignorable_file?(gem_file)
202
398
  }
203
399
  }
204
400
 
@@ -208,14 +404,11 @@ module Polisher
208
404
  def update_metadata_from(new_source)
209
405
  # update to new version
210
406
  @metadata[:version] = new_source.version
211
-
212
- # better release updating ?
213
- release = "1%{?dist}"
214
- @metadata[:release] = release
407
+ @metadata[:release] = "1%{?dist}"
215
408
 
216
409
  # add changelog entry
217
410
  changelog_entry = <<EOS
218
- * #{Time.now.strftime("%a %b %d %Y")} #{AUTHOR} - #{$version}-#{release}
411
+ * #{Time.now.strftime("%a %b %d %Y")} #{RPMSpec.current_author} - #{@metadata[:version]}-1
219
412
  - Update to version #{new_source.version}
220
413
  EOS
221
414
  @metadata[:changelog_entries] ||= []
@@ -256,8 +449,8 @@ EOS
256
449
 
257
450
  contents.slice!(tp...ltpn)
258
451
  contents.insert tp,
259
- (@metadata[:requires].collect { |r| "Requires: #{r}" } +
260
- @metadata[:build_requires].collect { |r| "BuildRequires: #{r}" }).join("\n")
452
+ (@metadata[:requires].collect { |r| "Requires: #{r.str}" } +
453
+ @metadata[:build_requires].collect { |r| "BuildRequires: #{r.str}" }).join("\n")
261
454
 
262
455
  # add new files
263
456
  fp = contents.index SPEC_FILES_MATCHER
@@ -270,5 +463,50 @@ EOS
270
463
  contents
271
464
  end
272
465
 
466
+ def compare(upstream_source)
467
+ same = {}
468
+ diff = {}
469
+ upstream_source.deps.each do |d|
470
+ spec_reqs = self.requirements_for_gem(d.name)
471
+ spec_reqs_specifier = spec_reqs.empty? ? nil :
472
+ spec_reqs.collect { |req| req.specifier }
473
+
474
+ if spec_reqs.nil?
475
+ diff[d.name] = {:spec => nil,
476
+ :upstream => d.requirement.to_s}
477
+
478
+ elsif !spec_reqs.any? { |req| req.matches?(d) } ||
479
+ !self.has_all_requirements_for?(d)
480
+ diff[d.name] = {:spec => spec_reqs_specifier,
481
+ :upstream => d.requirement.to_s}
482
+
483
+ elsif !diff.has_key?(d.name)
484
+ same[d.name] = {:spec => spec_reqs_specifier,
485
+ :upstream => d.requirement.to_s }
486
+ end
487
+ end
488
+
489
+ @metadata[:requires].each do |req|
490
+ next unless req.gem?
491
+
492
+ upstream_dep = upstream_source.deps.find { |d| d.name == req.gem_name }
493
+
494
+ if upstream_dep.nil?
495
+ diff[req.gem_name] = {:spec => req.specifier,
496
+ :upstream => nil}
497
+
498
+ elsif !req.matches?(upstream_dep)
499
+ diff[req.gem_name] = {:spec => req.specifier,
500
+ :upstream => upstream_dep.requirement.to_s }
501
+
502
+ elsif !diff.has_key?(req.gem_name)
503
+ same[req.gem_name] = {:spec => req.specifier,
504
+ :upstream => upstream_dep.requirement.to_s }
505
+ end
506
+ end unless @metadata[:requires].nil?
507
+
508
+ {:same => same, :diff => diff}
509
+ end
510
+
273
511
  end # class RPMSpec
274
512
  end # module Polisher