gem2rpm 0.11.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,29 @@
1
+ require 'optparse'
1
2
  require 'singleton'
2
3
 
3
4
  module Gem2Rpm
4
5
  class Configuration
5
6
  include Singleton
6
7
 
8
+ class InvalidOption < Exception; end
9
+
10
+ CURRENT_DIR = Dir.pwd
11
+
12
+ DEFAULT_OPTIONS = {
13
+ :print_template_file => nil,
14
+ :template_file => nil,
15
+ :templates => false,
16
+ :version => false,
17
+ :output_file => nil,
18
+ :local => false,
19
+ :srpm => false,
20
+ :deps => false,
21
+ :nongem => false,
22
+ :doc_subpackage => true,
23
+ :fetch => false,
24
+ :directory => CURRENT_DIR,
25
+ }.freeze
26
+
7
27
  # The defaults should mostly work
8
28
  DEFAULT_MACROS = {
9
29
  :instdir => '%{gem_instdir}',
@@ -11,23 +31,64 @@ module Gem2Rpm
11
31
  :doc => '%doc',
12
32
  :license => '%license',
13
33
  :ignore => '%exclude'
14
- }
34
+ }.freeze
15
35
 
16
36
  DEFAULT_RULES = {
17
- :doc => [/\/?CHANGELOG.*/i, /\/?CONTRIBUTING.*/i, /\/?CONTRIBUTORS.*/i,
18
- /\/?AUTHORS.*/i,/\/?README.*/i, /\/?History.*/i, /\/?Release.*/i,
19
- /\/?doc(\/.*)?/, 'NEWS'],
20
- :license => [/\/?MIT/, /\/?GPLv[0-9]+/, /\/?.*LICEN(C|S)E/, /\/?COPYING/],
21
- :ignore => ['.gemtest', '.gitignore', '.travis.yml', '.yardopts', '.rvmrc',
22
- '.rubocop.yml', /^\..*rc$/i],
37
+ :doc => [
38
+ /\/?CHANGELOG.*/i,
39
+ /\/?CONTRIBUTING.*/i,
40
+ /\/?CONTRIBUTORS.*/i,
41
+ /\/?AUTHORS.*/i,
42
+ /\/?README.*/i,
43
+ /\/?History.*/i,
44
+ /\/?Release.*/i,
45
+ /\/?doc(\/.*)?/,
46
+ 'NEWS',
47
+ ],
48
+ :license => [
49
+ /\/?MIT/,
50
+ /\/?GPLv[0-9]+/,
51
+ /\/?.*LICEN(C|S)E/i,
52
+ /\/?COPYING/,
53
+ ],
54
+ :ignore => [
55
+ '.gemtest',
56
+ '.gitignore',
57
+ '.travis.yml',
58
+ '.hound.yml',
59
+ '.yardopts',
60
+ '.rspec',
61
+ '.rvmrc',
62
+ '.rubocop.yml',
63
+ '.rubocop_todo.yml',
64
+ /^\..*rc$/i,
65
+ ],
66
+ :test => [
67
+ '.rspec',
68
+ 'cucumber.yml',
69
+ /^features.*/,
70
+ /^r?spec.*/,
71
+ /^tests?/,
72
+ ],
23
73
  # Other files including test files that are not required for
24
74
  # runtime and therefore currently included in -doc
25
- :misc => [/.*.gemspec/, /Gemfile.*/, 'Rakefile', 'rakefile.rb', 'Vagrantfile',
26
- /^spec.*/, /^rspec.*/, /^test(s|)/, /^examples.*/]
27
- }
75
+ :misc => [
76
+ /Gemfile.*/,
77
+ 'Rakefile',
78
+ 'rakefile.rb',
79
+ 'Vagrantfile',
80
+ /^examples.*/,
81
+ /\/?.*\.gemspec$/,
82
+ ]
83
+ }.freeze
84
+
85
+ def initialize
86
+ @options = nil
87
+ @parser = nil
88
+ end
28
89
 
29
- # Set the configuration back to default
30
- def to_default
90
+ # Set the configuration back to default values
91
+ def reset
31
92
  @_macros = nil
32
93
  @_rules = nil
33
94
  self
@@ -51,5 +112,104 @@ module Gem2Rpm
51
112
  rules[category] ||= ''
52
113
  end
53
114
 
115
+ # Get options.
116
+ def options
117
+ handle_options unless @options
118
+ @options
119
+ end
120
+
121
+ private
122
+
123
+ # Handles list of given options. Use ARGV by default.
124
+ def handle_options(args = ARGV)
125
+ @options = Marshal.load Marshal.dump DEFAULT_OPTIONS # deep copy
126
+ parser.parse!(args)
127
+ @options[:args] = args
128
+ # TODO: Refactor, this is probably not the best palce.
129
+ rescue OptionParser::InvalidOption => e
130
+ message = "#{e}\n\n#{parser}\n"
131
+ fail(InvalidOption, message)
132
+ end
133
+
134
+ # Creates an option parser.
135
+ def create_option_parser
136
+ @parser = OptionParser.new
137
+ setup_parser_options
138
+ end
139
+
140
+ # Get parser instance.
141
+ def parser
142
+ create_option_parser unless @parser
143
+ @parser
144
+ end
145
+
146
+ def setup_parser_options
147
+ parser.banner = "Usage: #{$PROGRAM_NAME} [OPTIONS] GEM"
148
+
149
+ parser.separator(' Convert Ruby gems to source RPMs and specfiles.')
150
+ parser.separator(' Uses a template to generate the RPM specfile')
151
+ parser.separator(' from the gem specification.')
152
+
153
+ parser.separator('')
154
+
155
+ parser.separator(' Options:')
156
+
157
+ parser.on('-T', '--current-template', 'Print the current template') do
158
+ options[:print_template_file] = true
159
+ end
160
+
161
+ parser.on('-t', '--template TEMPLATE', 'Use TEMPLATE for the specfile') do |val|
162
+ options[:template_file] = val
163
+ end
164
+
165
+ parser.on('--templates', 'List all available templates') do
166
+ options[:templates] = true
167
+ end
168
+
169
+ parser.on('-v', '--version', 'Print gem2rpm\'s version and exit') do
170
+ options[:version] = true
171
+ end
172
+
173
+ parser.on('-o', '--output FILE', 'Send the specfile to FILE') do |val|
174
+ options[:output_file] = val
175
+ end
176
+
177
+ parser.on('-s', '--srpm', 'Create a source RPM') do
178
+ options[:srpm] = true
179
+ end
180
+
181
+ parser.on('-l', '--local', "Do not retrieve Gem information over
182
+ #{' ' * 22} the network. Use on disconnected machines") do
183
+ options[:local] = true
184
+ end
185
+
186
+ parser.on('-d', '--dependencies', 'Print the dependencies of the gem') do
187
+ options[:deps] = true
188
+ end
189
+
190
+ parser.on('-n', '--nongem', 'Generate a subpackage for non-gem use') do
191
+ options[:nongem] = true
192
+ end
193
+
194
+ parser.on('--no-doc', 'Disable document subpackage') do
195
+ options[:doc_subpackage] = false
196
+ end
197
+
198
+ parser.on('--fetch', 'Fetch the gem from rubygems.org') do
199
+ options[:fetch] = true
200
+ end
201
+
202
+ parser.on('-C', '--directory DIR', 'Change to directory DIR') do |val|
203
+ options[:directory] = val
204
+ end
205
+
206
+ parser.separator('')
207
+
208
+ parser.separator(' Arguments:')
209
+ parser.separator(' GEM The path to the locally stored gem package file or the name')
210
+ parser.separator(' of the gem when using --fetch.')
211
+
212
+ parser.separator('')
213
+ end
54
214
  end
55
215
  end
@@ -5,7 +5,7 @@ module Gem2Rpm
5
5
  OPENSUSE = :opensuse
6
6
  DEFAULT = :default
7
7
 
8
- ROLLING_RELEASES = ['rawhide', 'factory', 'tumbleweed']
8
+ ROLLING_RELEASES = %w[rawhide factory tumbleweed].freeze
9
9
 
10
10
  OsRelease = Struct.new :os, :version
11
11
 
@@ -25,14 +25,12 @@ module Gem2Rpm
25
25
  end
26
26
 
27
27
  # Try os-release first.
28
- if os_release_files = grouped_release_files['os-release']
29
- content = File.open(os_release_files.first, Gem2Rpm::OPEN_MODE) do |f|
30
- f.read
31
- end
28
+ if (os_release_files = grouped_release_files['os-release'])
29
+ content = File.open(os_release_files.first, Gem2Rpm::OPEN_MODE, &:read)
32
30
 
33
31
  begin
34
- os_release.os = content[/^ID=(.*)$/, 1].to_sym
35
- os_release.version = content[/^VERSION_ID=(.*)$/, 1]
32
+ os_release.os = content[/^ID=['"]?(.*?)['"]?$/, 1].to_sym
33
+ os_release.version = content[/^VERSION_ID=['"]?(.*?)['"]?$/, 1]
36
34
  rescue
37
35
  end
38
36
  end
@@ -40,7 +38,7 @@ module Gem2Rpm
40
38
  # If os-release failed (it is empty or has not enough information),
41
39
  # try some other release files.
42
40
  if os_release.os == DEFAULT
43
- if fedora_release_files = grouped_release_files['fedora']
41
+ if (fedora_release_files = grouped_release_files['fedora'])
44
42
  os_release.os = FEDORA
45
43
  versions = []
46
44
 
@@ -67,13 +65,13 @@ module Gem2Rpm
67
65
  end
68
66
 
69
67
  def self.nature
70
- template_by_os_version(os_release.os, os_release.version) || DEFAULT
68
+ template_by_os_version(os_release.os, os_release.version) || DEFAULT.to_s
71
69
  end
72
70
 
73
71
  # Provides list of release files found on the system.
74
72
  def self.release_files
75
73
  @release_files ||=
76
- Dir.glob('/etc/{os-release,*{_version,-release}}*').uniq.select {|e| File.file? e}
74
+ Dir.glob('/etc/{os-release,*{_version,-release}}*').uniq.select { |e| File.file? e }
77
75
  end
78
76
 
79
77
  # Allows to override release files list.
@@ -84,13 +82,13 @@ module Gem2Rpm
84
82
 
85
83
  # Tries to find best suitable template for specified os and version.
86
84
  def self.template_by_os_version(os, version)
87
- os_templates = Template.list.grep /#{os}.*\.spec\.erb/
85
+ os_templates = Template.list.grep(/#{os}.*\.spec\.erb/)
88
86
 
89
87
  os_templates.each do |file|
90
88
  # We want only distro RubyGems templates to get the right versions
91
89
  next unless file =~ /^#{os}((-([0-9]+\.{0,1}[0-9]+){0,}){0,}(-(#{ROLLING_RELEASES.join('|')})){0,1}).spec.erb/
92
90
 
93
- if match = Regexp.last_match
91
+ if (match = Regexp.last_match)
94
92
  return file.gsub('.spec.erb', '') if in_range?(version, match[1].to_s.split('-').drop(1)) || match[1].empty?
95
93
  end
96
94
  end
@@ -105,7 +103,7 @@ module Gem2Rpm
105
103
  return true if range.first.to_s == version.to_s
106
104
  else # range: [xx, yy]
107
105
  if range[0].to_s <= version.to_s
108
- return true if ROLLING_RELEASES.include? range[1] or version.to_s <= range[1].to_s
106
+ return true if ROLLING_RELEASES.include?(range[1]) || (version.to_s <= range[1].to_s)
109
107
  end
110
108
  end
111
109
 
@@ -11,7 +11,7 @@ module Gem2Rpm
11
11
  version_requirements # For RubyGems < 1.3.6
12
12
  end
13
13
 
14
- Helpers::requirement_versions_to_rpm r
14
+ Helpers.requirement_versions_to_rpm r
15
15
  end
16
16
 
17
17
  # Dependency type. Needs to be explicitly reimplemented.
File without changes
File without changes
@@ -6,7 +6,7 @@ module Gem2Rpm
6
6
  # Find and fetch specs that match +dependency+.
7
7
  #
8
8
  # If +matching_platform+ is false, gems for all platforms are returned.
9
- def spec_for_dependency(dependency, matching_platform=true)
9
+ def spec_for_dependency(dependency, matching_platform = true)
10
10
  super
11
11
  rescue
12
12
  errors = []
@@ -1,28 +1,36 @@
1
1
  require 'delegate'
2
2
  require 'gem2rpm/configuration'
3
- require 'gem2rpm/dependency'
3
+ require 'gem2rpm/gem/dependency'
4
4
  require 'gem2rpm/helpers'
5
5
 
6
6
  module Gem2Rpm
7
7
  class Specification < SimpleDelegator
8
+ BLANK_RE = /\A[[:space:]]*\z/
8
9
 
9
10
  # A long description of gem wrapped to 78 characters.
10
11
  def description
11
12
  d = super.to_s.chomp
12
13
  d = summary.to_s.chomp if d.empty?
13
14
  d.gsub!(/([^.!?])\Z/, "\\1.")
14
- Helpers::word_wrap(d, 78) + "\n"
15
+ Helpers.word_wrap(d, 78) + "\n"
16
+ end
17
+
18
+ # The URL of this gem's home page
19
+ def homepage
20
+ h = super
21
+ h = nil if h && BLANK_RE =~ h
22
+ h
15
23
  end
16
24
 
17
25
  # A list of Gem::Dependency objects this gem depends on (includes every
18
26
  # runtime or development dependency).
19
27
  def dependencies
20
- super.map {|d| Gem2Rpm::Dependency.new d}
28
+ super.map { |d| Gem2Rpm::Dependency.new d }
21
29
  end
22
30
 
23
31
  # List of dependencies that are used for development.
24
32
  def development_dependencies
25
- super.map {|d| Gem2Rpm::Dependency.new d}
33
+ super.map { |d| Gem2Rpm::Dependency.new d }
26
34
  end
27
35
 
28
36
  # The license(s) for the library. Each license must be a short name,
@@ -36,7 +44,7 @@ module Gem2Rpm
36
44
 
37
45
  # List of dependencies that will automatically be activated at runtime.
38
46
  def runtime_dependencies
39
- super.map {|d| Gem2Rpm::Dependency.new d}
47
+ super.map { |d| Gem2Rpm::Dependency.new d }
40
48
  end
41
49
 
42
50
  # The version of Ruby required by the gem. Returns array with
@@ -53,7 +61,7 @@ module Gem2Rpm
53
61
  # array with empty string. However, this should happen only in rare cases.
54
62
  def required_rubygems_version
55
63
  @required_rubygems_version ||= begin
56
- Helpers::requirement_versions_to_rpm(super)
64
+ Helpers.requirement_versions_to_rpm(super)
57
65
  rescue
58
66
  ['']
59
67
  end
@@ -24,7 +24,7 @@ module Gem2Rpm
24
24
  # '<' pair.
25
25
  def self.expand_pessimistic_requirement(requirement)
26
26
  next_version = Gem::Version.create(requirement.last).bump
27
- return ['=>', requirement.last], ['<', next_version]
27
+ return ['>=', requirement.last], ['<', next_version]
28
28
  end
29
29
 
30
30
  # Expands the not equal version operator '!=' into equivalent '<' and
@@ -36,55 +36,11 @@ module Gem2Rpm
36
36
  # Converts Gem::Requirement into array of requirements strings compatible
37
37
  # with RPM .spec file.
38
38
  def self.requirement_versions_to_rpm(requirement)
39
- self.expand_requirement(requirement.requirements).map do |op, version|
39
+ expand_requirement(requirement.requirements).map do |op, version|
40
40
  version == Gem::Version.new(0) ? "" : "#{op} #{version}"
41
41
  end
42
42
  end
43
43
 
44
- def self.file_entries_to_rpm(entries)
45
- rpm_file_list = entries.map{ |e| self.file_entry_to_rpm(e) }
46
- rpm_file_list.join("\n")
47
- end
48
-
49
- def self.doc_file?(file)
50
- check_str_on_conditions(file, Gem2Rpm::Configuration.instance.rule_for(:doc))
51
- end
52
-
53
- def self.license_file?(file)
54
- check_str_on_conditions(file, Gem2Rpm::Configuration.instance.rule_for(:license))
55
- end
56
-
57
- def self.ignore_file?(file)
58
- check_str_on_conditions(file, Gem2Rpm::Configuration.instance.rule_for(:ignore))
59
- end
60
-
61
- def self.misc_file?(file)
62
- check_str_on_conditions(file, Gem2Rpm::Configuration.instance.rule_for(:misc))
63
- end
64
-
65
- def self.file_entry_to_rpm(entry)
66
- config = Gem2Rpm::Configuration.instance
67
- case true
68
- when doc_file?(entry)
69
- "#{config.macro_for(:doc)} #{config.macro_for(:instdir)}/#{entry}".strip
70
- when license_file?(entry)
71
- "#{config.macro_for(:license)} #{config.macro_for(:instdir)}/#{entry}".strip
72
- when ignore_file?(entry)
73
- "#{config.macro_for(:ignore)} #{config.macro_for(:instdir)}/#{entry}".strip
74
- # /lib should have its own macro
75
- when entry == 'lib'
76
- "#{config.macro_for(:libdir)}"
77
- else
78
- "#{config.macro_for(:instdir)}/#{entry}"
79
- end
80
- end
81
-
82
- # Returns a list of top level directories and files
83
- # out of an array of file_list
84
- def self.top_level_from_file_list(file_list)
85
- file_list.map{ |f| f.gsub!(/([^\/]*).*/,"\\1") }.uniq
86
- end
87
-
88
44
  # Compares string to the given regexp conditions
89
45
  def self.check_str_on_conditions(str, conditions)
90
46
  conditions.any? do |condition|
@@ -0,0 +1,49 @@
1
+ module Gem2Rpm
2
+ class RpmDependency < Gem2Rpm::Dependency
3
+ def initialize(dependency)
4
+ if dependency.respond_to? :__getobj__
5
+ super dependency.__getobj__
6
+ else
7
+ super
8
+ end
9
+ end
10
+
11
+ # Convert to rubygem() virtual provide dependency.
12
+ def virtualize
13
+ dep = __getobj__.dup
14
+ dep.name = "rubygem(#{dep.name})"
15
+
16
+ self.class.new dep
17
+ end
18
+
19
+ # Output dependency with RPM requires tag.
20
+ def with_requires
21
+ dep = __getobj__.dup
22
+ dep.name = case dep.type
23
+ when :development
24
+ "BuildRequires: #{dep.name}"
25
+ else
26
+ "Requires: #{dep.name}"
27
+ end
28
+
29
+ self.class.new dep
30
+ end
31
+
32
+ # Comment out the dependency.
33
+ def comment_out
34
+ dep = __getobj__.dup
35
+ dep.name = "# #{dep.name}"
36
+
37
+ self.class.new dep
38
+ end
39
+
40
+ # Returns string with entry suitable for RPM .spec file.
41
+ def to_rpm
42
+ rpm_dependencies = requirement.map do |version|
43
+ version = nil if version && version.to_s.empty?
44
+ [name, version].compact.join(' ')
45
+ end
46
+ rpm_dependencies.join("\n")
47
+ end
48
+ end
49
+ end