gem2rpm 0.11.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 911d15cecd229ed97a9a901cfdac408ef08796cb
4
- data.tar.gz: 211b7ad4686015ac6eb03729f61a31f85894c581
3
+ metadata.gz: 533b43170c8f68fbc24c8a17071ea0aa8d620cbf
4
+ data.tar.gz: e3b075d6da795f5d9629eeca762a6a1114e77e76
5
5
  SHA512:
6
- metadata.gz: f4cb61a3ab8618afda9f3530bafb8712e76ebc21eb7f00ff97678704584342a3f1af230d4b4d150457db1f33feec7c5756ff0dcc92b7985921e3c3d7f5f2505c
7
- data.tar.gz: bf4a5b88e63300b0f0db6bd0f64685250c182a638a2b6e0e41588bd588f65e5ade8187fe438d7ae05e951d09ad907cb7e3284620488f681341bdad6661c83172
6
+ metadata.gz: 1b886216fa24aee9387abd0beb6518930ad33bb474336f43f36a4b99302af005458b99a7af12de3be79f49fa5773bc59175aacbf9659bc01da9dbf073795064e
7
+ data.tar.gz: ae28972dbc76725945a3edb23e60fa774fd06867b9e0326f2ad167dfba2a2c413b334b0e659a239240b8ec17265df38f69f1b983f1bb4c29340abc821ed3dd22
data/README.md CHANGED
@@ -15,7 +15,7 @@ $ gem install gem2rpm
15
15
  or download gem2rpm from Fedora repositories as RPM package:
16
16
 
17
17
  ```
18
- # yum install rubygem-gem2rpm
18
+ # dnf install rubygem-gem2rpm
19
19
  ```
20
20
 
21
21
  ## Usage
@@ -41,8 +41,7 @@ You can also use the `--fetch` flag to fetch the (latest) gem before generating
41
41
  $ gem2rpm --fetch GEM
42
42
  ```
43
43
 
44
- This will print an rpm spec file based on the information contained in the gem's spec file. In general, it is necessary to edit the generated spec file because the gem is missing some important information that is
45
- customarily provided in rpm's, most notably the license and the changelog.
44
+ This will print an rpm spec file based on the information contained in the gem's spec file. In general, it is necessary to edit the generated spec file because the gem is missing some important information that is customarily provided in rpm's, most notably the license and the changelog.
46
45
 
47
46
 
48
47
  Rather than editing the generated specfile, edit the template from which
@@ -71,11 +70,17 @@ $ gem2rpm --templates
71
70
 
72
71
  ## Templates
73
72
 
74
- The template is a standard ERB file that comes with three main variables:
73
+ The template is a standard ERB file that comes with several variables:
75
74
 
76
75
  - `package` - the `Gem::Package` for the gem
77
76
  - `spec` - the `Gem::Specification` for the gem (the same as `format.spec`)
78
77
  - `config` - the `Gem2Rpm::Configuration` that can redefine default macros or rules used in `spec` template helpers
78
+ - `runtime_dependencies` - the `Gem2Rpm::RpmDependencyList` providing list of package runtime dependencies
79
+ - `development_dependencies` - the `Gem2Rpm::RpmDependencyList` providing list of package development dependencies
80
+ - `tests` - the `Gem2Rpm::TestSuite` providing list of test frameworks allowing their execution
81
+ - `files` - the `Gem2Rpm::RpmFileList` providing unfiltered list of files in package
82
+ - `main_files` - the `Gem2Rpm::RpmFileList` providing list of files suitable for main package
83
+ - `doc_files` - the `Gem2Rpm::RpmFileList` providing list of files suitable for -doc subpackage
79
84
 
80
85
  The following variables still work, but are now deprecated:
81
86
 
@@ -83,7 +88,7 @@ The following variables still work, but are now deprecated:
83
88
 
84
89
  ### Template Configuration
85
90
 
86
- To make the templates lighter and more complete, Gem2Rpm introduced in version 0.11.0 new configurable `spec` helpers such as `spec.main_file_entries` or `spec.doc_file_entries` that can be further configured via local `config` variable as follows:
91
+ To make the templates lighter and more complete, Gem2Rpm introduced in version 0.11.0 new configurable template variables such as `main_files` or `doc_files` that can be further configured via local `config` variable as follows:
87
92
 
88
93
  ```ruby
89
94
  # Change macros for Vagrant packaging
@@ -105,15 +110,11 @@ $ irb -rgem2rpm
105
110
 
106
111
  ## Conventions
107
112
 
108
- A typical source RPM for a gem should consist of three files: the gem file
109
- itself, the template for the spec file and the spec file. To ensure that
110
- the template will be included in the source RPM, it must be listed as one
111
- of the sources in the spec file.
113
+ A typical source RPM for a gem should consist of two files: the gem file
114
+ itself and the spec file.
112
115
 
113
116
  The resulting RPMs should follow the naming convention 'rubygem-$GEM'
114
- where GEM is the name of the packaged gem. The default template also makes
115
- sure that the resulting package provides 'ruby($GEM)', according to general
116
- packaging conventions for scripting languages.
117
+ where GEM is the name of the packaged gem.
117
118
 
118
119
  ## Limitations
119
120
 
data/bin/gem2rpm CHANGED
@@ -4,12 +4,26 @@
4
4
  $LOAD_PATH.push(File.expand_path(File.dirname(__FILE__) + "/../lib"))
5
5
 
6
6
  require 'gem2rpm'
7
- require 'optparse'
8
7
  require 'fileutils'
8
+ require 'tmpdir'
9
9
  require 'open-uri'
10
10
  require 'uri'
11
11
 
12
- options = Gem2Rpm::Configuration.instance.options
12
+ options = begin
13
+ Gem2Rpm::Configuration.instance.options
14
+ rescue Gem2Rpm::Configuration::InvalidOption => e
15
+ Gem2Rpm.show_message(e)
16
+ exit(1)
17
+ end
18
+ if options[:templates]
19
+ Gem2Rpm.show_templates
20
+ exit(0)
21
+ end
22
+ if options[:version]
23
+ Gem2Rpm.show_version
24
+ exit(0)
25
+ end
26
+
13
27
  rest = options[:args]
14
28
 
15
29
  template = begin
@@ -25,50 +39,76 @@ if options[:print_template_file]
25
39
  end
26
40
 
27
41
  if rest.size != 1
28
- $stderr.puts "Missing GEMFILE\n\n"
29
- $stderr.puts opts
42
+ Gem2Rpm.show_message('Missing GEMFILE')
30
43
  exit(1)
31
44
  end
32
45
  gemfile = rest[0]
46
+ out_dir = options[:directory]
47
+ unless File.directory?(out_dir)
48
+ Gem2Rpm.show_message("No such directory #{out_dir}")
49
+ exit(1)
50
+ end
33
51
 
34
52
  if options[:fetch]
35
53
  gem_uri = ''
36
- open("https://rubygems.org/api/v1/gems/#{gemfile}.json") do |f|
37
- gem_uri = f.read.match(/"gem_uri":\s*"(.*?)",/m)[1]
38
- gemfile = URI.parse(gem_uri).path.split('/').last
39
- open(gemfile, 'w') do |gf|
40
- gf.write(open(gem_uri).read)
54
+ begin
55
+ open("https://rubygems.org/api/v1/gems/#{gemfile}.json") do |f|
56
+ gem_uri = f.read.match(/"gem_uri":\s*"(.*?)",/m)[1]
57
+ gemfile = URI.parse(gem_uri).path.split('/').last
58
+ gemfile = File.join(out_dir, gemfile)
59
+ open(gemfile, 'w') do |gf|
60
+ gf.write(open(gem_uri).read)
61
+ end
41
62
  end
63
+ rescue OpenURI::HTTPError => e
64
+ Gem2Rpm.show_message("Gem fetch failed with error: #{e.message}")
65
+ exit(1)
42
66
  end
43
67
  end
44
68
 
45
- srpmdir = nil
46
- specfile = nil
47
- if options[:srpm]
48
- gemname = Gem2Rpm::Package.new(gemfile).spec.name
49
- srpmdir = `/bin/mktemp -t -d gem2rpm-#{gemname}.XXXXXX`.chomp
50
- specfile = File.join(srpmdir, "rubygem-#{gemname}.spec")
51
- options[:output_file] ||= specfile
69
+ unless File.exist?(gemfile)
70
+ Gem2Rpm.show_message("Invalid GEMFILE #{gemfile}")
71
+ exit(1)
52
72
  end
53
73
 
54
- # Produce a specfile
55
- if options[:output_file].nil?
56
- Gem2Rpm.convert(gemfile, template, $stdout, options[:nongem], options[:local], options[:doc_subpackage]) unless options[:deps]
57
- else
58
- begin
59
- out = open(options[:output_file], "w")
60
- Gem2Rpm.convert(gemfile, template, out, options[:nongem], options[:local], options[:doc_subpackage])
61
- ensure
62
- out.close
74
+ if options[:deps]
75
+ Gem2Rpm.print_dependencies(gemfile)
76
+ exit 0
77
+ end
78
+
79
+ output_spec = StringIO.new
80
+ Gem2Rpm.convert(gemfile, template, output_spec, options[:nongem], options[:local], options[:doc_subpackage])
81
+
82
+ # Save or print a specfile.
83
+ if options[:output_file]
84
+ File.open(options[:output_file], "w") do |f|
85
+ f.puts(output_spec.string)
63
86
  end
87
+ else
88
+ puts output_spec.string unless options[:srpm]
64
89
  end
65
90
 
66
- # Create a source RPM
91
+ # Create a SRPM.
67
92
  if options[:srpm]
68
- FileUtils.copy(options[:output_file], specfile) unless File.exist?(specfile)
69
- FileUtils.copy(gemfile, srpmdir)
93
+ gemname = Gem2Rpm::Package.new(gemfile).spec.name
94
+ Dir.mktmpdir "gem2rpm-#{gemname}-" do |srpmdir|
95
+ specfile = File.join(srpmdir, "rubygem-#{gemname}.spec")
70
96
 
71
- system("rpmbuild -bs --nodeps --define '_sourcedir #{srpmdir}' --define '_srcrpmdir #{Dir.pwd}' #{specfile}")
72
- end
97
+ File.open(specfile, "w") do |f|
98
+ f.puts(output_spec.string)
99
+ end
100
+
101
+ FileUtils.copy(gemfile, srpmdir)
102
+
103
+ command =
104
+ "rpmbuild -bs --nodeps " +
105
+ "--define '_sourcedir #{srpmdir}' " +
106
+ "--define '_srcrpmdir #{out_dir}' " +
107
+ specfile
73
108
 
74
- Gem2Rpm.print_dependencies(gemfile) if options[:deps]
109
+ unless system(command)
110
+ Gem2Rpm.show_message("Command failed: #{command}")
111
+ exit(1)
112
+ end
113
+ end
114
+ end
data/lib/gem2rpm.rb CHANGED
@@ -1,17 +1,20 @@
1
1
  require 'erb'
2
2
  require 'socket'
3
- require 'gem2rpm/package'
4
3
  require 'gem2rpm/distro'
5
- require 'gem2rpm/format'
6
- require 'gem2rpm/spec_fetcher'
7
- require 'gem2rpm/specification'
4
+ require 'gem2rpm/gem/format'
5
+ require 'gem2rpm/gem/package'
6
+ require 'gem2rpm/gem/spec_fetcher'
7
+ require 'gem2rpm/gem/specification'
8
+ require 'gem2rpm/rpm_dependency_list'
9
+ require 'gem2rpm/rpm_file_list'
8
10
  require 'gem2rpm/template_helpers'
9
11
  require 'gem2rpm/template'
12
+ require 'gem2rpm/test_suite'
10
13
 
11
14
  module Gem2Rpm
12
15
  extend Gem2Rpm::TemplateHelpers
13
16
 
14
- Gem2Rpm::VERSION = "0.11.3"
17
+ Gem2Rpm::VERSION = "1.0.0".freeze
15
18
 
16
19
  class Exception < RuntimeError; end
17
20
  class DownloadUrlError < Exception; end
@@ -23,6 +26,24 @@ module Gem2Rpm
23
26
  'r'
24
27
  end
25
28
 
29
+ def self.show_message(message, obj = nil, out = $stderr)
30
+ out.puts("#{message}\n\n")
31
+ out.puts obj if obj
32
+ end
33
+
34
+ def self.show_templates(out = $stdout)
35
+ out.puts "Available templates in #{Gem2Rpm::Template.default_location}:\n\n"
36
+ template_list = Gem2Rpm::Template.list.map do |t|
37
+ t = t.gsub(/(.*)\.spec.erb/, '\\1')
38
+ t.gsub(/^/, t == Distro.nature ? '* ' : ' ')
39
+ end.join("\n")
40
+ out.puts template_list
41
+ end
42
+
43
+ def self.show_version(out = $stdout)
44
+ out.puts Gem2Rpm::VERSION
45
+ end
46
+
26
47
  def self.find_download_url(name, version)
27
48
  dep = Gem::Dependency.new(name, "=#{version}")
28
49
  fetcher = Gem2Rpm::SpecFetcher.new(Gem::SpecFetcher.fetcher)
@@ -47,7 +68,18 @@ module Gem2Rpm
47
68
  # Deprecate, kept just for backward compatibility.
48
69
  format = Gem2Rpm::Format.new(package)
49
70
  spec = Gem2Rpm::Specification.new(package.spec)
50
- config = Gem2Rpm::Configuration.instance.reset
71
+
72
+ config = Configuration.instance.reset
73
+
74
+ runtime_dependencies = Gem2Rpm::RpmDependencyList.new(spec.runtime_dependencies)
75
+ development_dependencies = Gem2Rpm::RpmDependencyList.new(spec.development_dependencies)
76
+
77
+ tests = TestSuite.new(spec)
78
+
79
+ files = RpmFileList.new(spec.files)
80
+ main_files = files.top_level_entries.main_entries
81
+ doc_files = files.top_level_entries.doc_entries
82
+
51
83
  download_path = ""
52
84
  unless local
53
85
  begin
@@ -66,11 +98,8 @@ module Gem2Rpm
66
98
 
67
99
  # Print gem dependencies to the specified output ($stdout by default).
68
100
  def self.print_dependencies(gemfile, out = $stdout)
69
- Gem2Rpm::Package.new(gemfile).spec.dependencies.each do |dep|
70
- Gem2Rpm::Dependency.new(dep).requirement.each do |r|
71
- out.puts "rubygem(#{dep.name}) #{r}"
72
- end
73
- end
101
+ dl = RpmDependencyList.new(Gem2Rpm::Package.new(gemfile).spec.dependencies)
102
+ out.puts dl.virtualize.to_rpm
74
103
  end
75
104
 
76
105
  # Returns the email address of the packager (i.e., the person running
@@ -1,12 +1,19 @@
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
+
7
12
  DEFAULT_OPTIONS = {
8
13
  :print_template_file => nil,
9
14
  :template_file => nil,
15
+ :templates => false,
16
+ :version => false,
10
17
  :output_file => nil,
11
18
  :local => false,
12
19
  :srpm => false,
@@ -14,7 +21,8 @@ module Gem2Rpm
14
21
  :nongem => false,
15
22
  :doc_subpackage => true,
16
23
  :fetch => false,
17
- }
24
+ :directory => CURRENT_DIR,
25
+ }.freeze
18
26
 
19
27
  # The defaults should mostly work
20
28
  DEFAULT_MACROS = {
@@ -23,7 +31,7 @@ module Gem2Rpm
23
31
  :doc => '%doc',
24
32
  :license => '%license',
25
33
  :ignore => '%exclude'
26
- }
34
+ }.freeze
27
35
 
28
36
  DEFAULT_RULES = {
29
37
  :doc => [
@@ -40,7 +48,7 @@ module Gem2Rpm
40
48
  :license => [
41
49
  /\/?MIT/,
42
50
  /\/?GPLv[0-9]+/,
43
- /\/?.*LICEN(C|S)E/,
51
+ /\/?.*LICEN(C|S)E/i,
44
52
  /\/?COPYING/,
45
53
  ],
46
54
  :ignore => [
@@ -48,24 +56,29 @@ module Gem2Rpm
48
56
  '.gitignore',
49
57
  '.travis.yml',
50
58
  '.yardopts',
59
+ '.rspec',
51
60
  '.rvmrc',
52
61
  '.rubocop.yml',
53
62
  /^\..*rc$/i,
63
+ /\/?.*\.gemspec$/,
64
+ ],
65
+ :test => [
66
+ '.rspec',
67
+ 'cucumber.yml',
68
+ /^features.*/,
69
+ /^r?spec.*/,
70
+ /^tests?/,
54
71
  ],
55
72
  # Other files including test files that are not required for
56
73
  # runtime and therefore currently included in -doc
57
74
  :misc => [
58
- /.*.gemspec/,
59
75
  /Gemfile.*/,
60
76
  'Rakefile',
61
77
  'rakefile.rb',
62
78
  'Vagrantfile',
63
- /^spec.*/,
64
- /^rspec.*/,
65
- /^test(s|)/,
66
79
  /^examples.*/,
67
80
  ]
68
- }
81
+ }.freeze
69
82
 
70
83
  def initialize
71
84
  @options = nil
@@ -112,9 +125,8 @@ module Gem2Rpm
112
125
  @options[:args] = args
113
126
  # TODO: Refactor, this is probably not the best palce.
114
127
  rescue OptionParser::InvalidOption => e
115
- $stderr.puts "#{e}\n\n"
116
- $stderr.puts parser
117
- exit(1)
128
+ message = "#{e}\n\n#{parser}\n"
129
+ fail(InvalidOption, message)
118
130
  end
119
131
 
120
132
  # Creates an option parser.
@@ -148,19 +160,12 @@ module Gem2Rpm
148
160
  options[:template_file] = val
149
161
  end
150
162
 
151
- # TODO: This does not belong here.
152
163
  parser.on('--templates', 'List all available templates') do
153
- puts 'Available templates in #{Gem2Rpm::Template.default_location}:\n\n'
154
- puts Gem2Rpm::Template.list.map do |t|
155
- t.gsub(/(.*)\.spec.erb/, '\\1')
156
- end.join("\n")
157
- exit 0
164
+ options[:templates] = true
158
165
  end
159
166
 
160
- # TODO: This does not belong here.
161
167
  parser.on('-v', '--version', 'Print gem2rpm\'s version and exit') do
162
- puts Gem2Rpm::VERSION
163
- exit 0
168
+ options[:version] = true
164
169
  end
165
170
 
166
171
  parser.on('-o', '--output FILE', 'Send the specfile to FILE') do |val|
@@ -192,6 +197,10 @@ module Gem2Rpm
192
197
  options[:fetch] = true
193
198
  end
194
199
 
200
+ parser.on('-C', '--directory DIR', 'Change to directory DIR') do |val|
201
+ options[:directory] = val
202
+ end
203
+
195
204
  parser.separator('')
196
205
 
197
206
  parser.separator(' Arguments:')
@@ -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
 
@@ -29,8 +29,8 @@ module Gem2Rpm
29
29
  content = File.open(os_release_files.first, Gem2Rpm::OPEN_MODE, &:read)
30
30
 
31
31
  begin
32
- os_release.os = content[/^ID=(.*)$/, 1].to_sym
33
- os_release.version = content[/^VERSION_ID=(.*)$/, 1]
32
+ os_release.os = content[/^ID=['"]?(.*?)['"]?$/, 1].to_sym
33
+ os_release.version = content[/^VERSION_ID=['"]?(.*?)['"]?$/, 1]
34
34
  rescue
35
35
  end
36
36
  end
@@ -65,7 +65,7 @@ module Gem2Rpm
65
65
  end
66
66
 
67
67
  def self.nature
68
- 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
69
69
  end
70
70
 
71
71
  # Provides list of release files found on the system.
File without changes
File without changes
File without changes
@@ -1,10 +1,12 @@
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/
9
+
8
10
  # A long description of gem wrapped to 78 characters.
9
11
  def description
10
12
  d = super.to_s.chomp
@@ -13,6 +15,13 @@ module Gem2Rpm
13
15
  Helpers.word_wrap(d, 78) + "\n"
14
16
  end
15
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
23
+ end
24
+
16
25
  # A list of Gem::Dependency objects this gem depends on (includes every
17
26
  # runtime or development dependency).
18
27
  def dependencies
@@ -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
@@ -41,50 +41,6 @@ module Gem2Rpm
41
41
  end
42
42
  end
43
43
 
44
- def self.file_entries_to_rpm(entries)
45
- rpm_file_list = entries.map { |e| 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
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
@@ -0,0 +1,60 @@
1
+ require 'gem2rpm/rpm_dependency'
2
+
3
+ module Gem2Rpm
4
+ class RpmDependencyList
5
+ include Enumerable
6
+
7
+ def initialize(dependencies)
8
+ @items = dependencies.map { |r| RpmDependency.new(r) }
9
+ end
10
+
11
+ # Calls the given block once for each element in self, passing that
12
+ # element as a parameter. Returns the array itself.
13
+ # If no block is given, an Enumerator is returned.
14
+ def each
15
+ # Return Enumerator when called withoug block.
16
+ return to_enum(__callee__) unless block_given?
17
+
18
+ @items.each { |item| yield item }
19
+ end
20
+
21
+ # Returns a new array containing the items in self for which the given
22
+ # block is not true. The ordering of non-rejected elements is maintained.
23
+ # If no block is given, an Enumerator is returned instead.
24
+ def reject
25
+ # Return Enumerator when called withoug block.
26
+ return to_enum(__callee__) unless block_given?
27
+
28
+ self.class.new(@items.reject { |item| yield item })
29
+ end
30
+
31
+ # Convert to rubygem() virtual provide dependencies.
32
+ def virtualize
33
+ dep_list = self.map(&:virtualize)
34
+
35
+ self.class.new dep_list
36
+ end
37
+
38
+ # Output dependencies with RPM requires tag.
39
+ def with_requires
40
+ dep_list = self.map(&:with_requires)
41
+
42
+ self.class.new dep_list
43
+ end
44
+
45
+ # Comment out the dependency.
46
+ def comment_out
47
+ dep_list = self.map(&:comment_out)
48
+
49
+ self.class.new dep_list
50
+ end
51
+
52
+ # Returns string with all dependencies from the list converted into entries
53
+ # suitable for RPM .spec file. Thise entries should include all necessary
54
+ # macros depending on file categorization.
55
+ def to_rpm
56
+ s = entries.map(&:to_rpm).join("\n")
57
+ s += "\n" unless s.empty?
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,51 @@
1
+ require 'pathname'
2
+ require 'gem2rpm/helpers'
3
+
4
+ module Gem2Rpm
5
+ class RpmFile < String
6
+ # Returns string with entry suitable for RPM .spec file. This typically
7
+ # includes all necessary macros depending on file categorization.
8
+ def to_rpm
9
+ config = Gem2Rpm::Configuration.instance
10
+
11
+ case
12
+ when license?
13
+ "#{config.macro_for(:license)} #{config.macro_for(:instdir)}/#{self}".strip
14
+ when doc?
15
+ "#{config.macro_for(:doc)} #{config.macro_for(:instdir)}/#{self}".strip
16
+ when ignore?
17
+ "#{config.macro_for(:ignore)} #{config.macro_for(:instdir)}/#{self}".strip
18
+ # /lib should have its own macro
19
+ when self == 'lib'
20
+ "#{config.macro_for(:libdir)}"
21
+ else
22
+ "#{config.macro_for(:instdir)}/#{self}"
23
+ end
24
+ end
25
+
26
+ # Returs true for documentation files.
27
+ def doc?
28
+ Helpers.check_str_on_conditions(self, Gem2Rpm::Configuration.instance.rule_for(:doc))
29
+ end
30
+
31
+ # Returns true for license files.
32
+ def license?
33
+ Helpers.check_str_on_conditions(self, Gem2Rpm::Configuration.instance.rule_for(:license))
34
+ end
35
+
36
+ # Returns true for files which should be ommited from the package.
37
+ def ignore?
38
+ Helpers.check_str_on_conditions(self, Gem2Rpm::Configuration.instance.rule_for(:ignore))
39
+ end
40
+
41
+ # Returns true for files which are part of package test suite.
42
+ def test?
43
+ Helpers.check_str_on_conditions(self, Gem2Rpm::Configuration.instance.rule_for(:test))
44
+ end
45
+
46
+ # Returns true for other known miscellaneous files.
47
+ def misc?
48
+ Helpers.check_str_on_conditions(self, Gem2Rpm::Configuration.instance.rule_for(:misc))
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,55 @@
1
+ require 'gem2rpm/rpm_file'
2
+
3
+ module Gem2Rpm
4
+ class RpmFileList
5
+ include Enumerable
6
+
7
+ # Returns a new file list created from the array of files (e.g.
8
+ # Gem2Rpm::Specification.files).
9
+ def initialize(files)
10
+ @items = files.map { |f| RpmFile.new(f) }
11
+ end
12
+
13
+ # Calls the given block once for each element in self, passing that
14
+ # element as a parameter. Returns the array itself.
15
+ # If no block is given, an Enumerator is returned.
16
+ def each
17
+ # Return Enumerator when called withoug block.
18
+ return to_enum(__callee__) unless block_given?
19
+
20
+ @items.each { |item| yield item }
21
+ end
22
+
23
+ # Returns a new array containing the items in self for which the given
24
+ # block is not true. The ordering of non-rejected elements is maintained.
25
+ # If no block is given, an Enumerator is returned instead.
26
+ def reject
27
+ # Return Enumerator when called withoug block.
28
+ return to_enum(__callee__) unless block_given?
29
+
30
+ self.class.new(@items.reject { |item| yield item })
31
+ end
32
+
33
+ # Returns a list of top level directories and files, omit all subdirectories.
34
+ def top_level_entries
35
+ self.class.new(entries.map { |f| f.gsub!(/([^\/]*).*/, '\1') }.uniq)
36
+ end
37
+
38
+ # Returns new list of files suitable for main.
39
+ def main_entries
40
+ self.class.new(entries.delete_if { |f| (f.doc? && !f.license?) || f.misc? || f.test? })
41
+ end
42
+
43
+ # Returns new list of files suitable for -doc subpackage.
44
+ def doc_entries
45
+ self.class.new(entries.delete_if { |f| !((f.doc? && !f.license?) || f.misc? || f.test?) })
46
+ end
47
+
48
+ # Returns string with all files from the list converted into entries
49
+ # suitable for RPM .spec file. Thise entries should include all necessary
50
+ # macros depending on file categorization.
51
+ def to_rpm
52
+ entries.map(&:to_rpm).join("\n")
53
+ end
54
+ end
55
+ end
@@ -1,23 +1,24 @@
1
+ require 'gem2rpm/rpm_file_list'
2
+ require 'gem2rpm/rpm_dependency'
3
+
1
4
  module Gem2Rpm
2
5
  module TemplateHelpers
3
6
  # File list block for the main package
4
7
  def main_file_entries(spec)
5
- entries = Helpers.top_level_from_file_list(spec.files)
6
- entries.delete_if { |f| Helpers.doc_file?(f) || Helpers.misc_file?(f) }
7
- Helpers.file_entries_to_rpm(entries)
8
+ entries = RpmFileList.new(spec.files).top_level_entries.main_entries
9
+ entries.to_rpm
8
10
  end
9
11
 
10
12
  # File list block for the doc sub-package
11
13
  def doc_file_entries(spec)
12
- entries = Helpers.top_level_from_file_list(spec.files)
13
- entries.delete_if { |f| !(Helpers.doc_file?(f) || Helpers.misc_file?(f)) }
14
- Helpers.file_entries_to_rpm(entries)
14
+ entries = RpmFileList.new(spec.files).top_level_entries.doc_entries
15
+ entries.to_rpm
15
16
  end
16
17
 
17
18
  # Provides well formatted requirement with version.
18
19
  def requirement(name, version = nil)
19
20
  version = nil if version && version.to_s.empty?
20
- [name, version].compact.join(' ')
21
+ RpmDependency.new(Gem::Dependency.new(name, version)).to_rpm
21
22
  end
22
23
  end
23
24
  end
@@ -0,0 +1,46 @@
1
+ require 'gem2rpm/rpm_file_list'
2
+
3
+ module Gem2Rpm
4
+ class TestSuite
5
+ include Enumerable
6
+
7
+ TestFramework = Struct.new :name, :command
8
+
9
+ TEST_FRAMEWORKS = [
10
+ TestFramework.new('cucumber', %|cucumber|),
11
+ TestFramework.new('minitest', %|ruby -e 'Dir.glob "./test/**/*_test.rb", &method(:require)'|),
12
+ TestFramework.new('rspec', %|rspec spec|),
13
+ TestFramework.new('shindo', %|shindont|),
14
+ TestFramework.new('test-unit', %|ruby -e 'Dir.glob "./test/**/*_test.rb", &method(:require)'|),
15
+ TestFramework.new('bacon', %|bacon -a|),
16
+ ].freeze
17
+
18
+ # Returns new test suite list detected from Gem::Specification.
19
+ def initialize(spec)
20
+ @items = detect_test_frameworks(spec)
21
+ end
22
+
23
+ # Calls the given block once for each element in self, passing that
24
+ # element as a parameter. Returns the array itself.
25
+ # If no block is given, an Enumerator is returned.
26
+ def each
27
+ # Return Enumerator when called withoug block.
28
+ return to_enum(__callee__) unless block_given?
29
+
30
+ @items.each { |item| yield item }
31
+ end
32
+
33
+ private
34
+
35
+ def detect_test_frameworks(spec)
36
+ from_development_dependencies(spec)
37
+ # TODO: Try to guess the test framework from spec.files. This could
38
+ # improve the test execution command a bit, but might not be reliable.
39
+ end
40
+
41
+ def from_development_dependencies(spec)
42
+ deps = spec.development_dependencies.map(&:name)
43
+ TEST_FRAMEWORKS.select { |tf| deps.include?(tf.name) }.map(&:dup)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,112 @@
1
+ # Generated from <%= spec.file_name %> by gem2rpm -*- rpm-spec -*-
2
+ %global vagrant_plugin_name <%= spec.name %>
3
+
4
+ Name: %{vagrant_plugin_name}
5
+ Version: <%= spec.version %>
6
+ Release: 1%{?dist}
7
+ Summary: <%= spec.summary.gsub(/\.$/, "") %>
8
+ License: <%= spec.licenses.join(" and ") %>
9
+ <% if spec.homepage -%>
10
+ URL: <%= spec.homepage %>
11
+ <% end -%>
12
+ Source0: <%= download_path %>%{vagrant_plugin_name}-%{version}.gem
13
+ Requires: vagrant
14
+ BuildRequires: vagrant
15
+ <% if spec.extensions.empty? -%>
16
+ BuildArch: noarch
17
+ <% end -%>
18
+ Provides: vagrant(%{vagrant_plugin_name}) = %{version}
19
+
20
+ %description
21
+ <%= spec.description %>
22
+
23
+ <% if doc_subpackage -%>
24
+ %package doc
25
+ Summary: Documentation for %{name}
26
+ Requires: %{name} = %{version}-%{release}
27
+ BuildArch: noarch
28
+
29
+ %description doc
30
+ Documentation for %{name}.
31
+ <% end # if doc_subpackage -%>
32
+
33
+ %prep
34
+ gem unpack %{SOURCE0}
35
+
36
+ %setup -q -D -T -n %{vagrant_plugin_name}-%{version}
37
+
38
+ gem spec %{SOURCE0} -l --ruby > %{vagrant_plugin_name}.gemspec
39
+
40
+ %build
41
+ # Create the gem as gem install only works on a gem file
42
+ gem build %{vagrant_plugin_name}.gemspec
43
+
44
+ # %%vagrant_plugin_install compiles any C extensions and installs the gem into ./%%gem_dir
45
+ # by default, so that we can move it into the buildroot in %%install
46
+ %vagrant_plugin_install
47
+
48
+ %install
49
+ mkdir -p %{buildroot}%{vagrant_plugin_dir}
50
+ cp -a .%{vagrant_plugin_dir}/* \
51
+ %{buildroot}%{vagrant_plugin_dir}/
52
+
53
+ <% unless spec.extensions.empty? -%>
54
+ mkdir -p %{buildroot}%{vagrant_plugin_extdir_mri}
55
+ cp -a .%{vagrant_plugin_extdir_mri}/{gem.build_complete,*.so} %{buildroot}%{vagrant_plugin_extdir_mri}/
56
+
57
+ <% for ext in spec.extensions -%>
58
+ # Prevent dangling symlink in -debuginfo (rhbz#878863).
59
+ rm -rf %{buildroot}%{vagrant_plugin_instdir}/<%= ext.split(File::SEPARATOR).first %>/
60
+ <% end -%>
61
+ <% end -%>
62
+
63
+ <% unless spec.executables.empty? -%>
64
+ mkdir -p %{buildroot}%{_bindir}
65
+ cp -pa .%{_bindir}/* \
66
+ %{buildroot}%{_bindir}/
67
+
68
+ find %{buildroot}%{vagrant_plugin_instdir}/<%= spec.bindir %> -type f | xargs chmod a+x
69
+ <% end -%>
70
+
71
+ %check
72
+ pushd .%{gem_instdir}
73
+ <% if tests.entries.empty? -%>
74
+ # Run the test suite.
75
+ <% end -%>
76
+ <% for t in tests -%>
77
+ # <%= t.command %>
78
+ <% end -%>
79
+ popd
80
+
81
+ <%
82
+ # Change macros for Vagrant packaging
83
+ config.macros[:instdir] = '%{vagrant_plugin_instdir}'
84
+ config.macros[:libdir] = '%{vagrant_plugin_libdir}'
85
+ -%>
86
+ %files
87
+ %dir %{vagrant_plugin_instdir}
88
+ <% for f in spec.executables -%>
89
+ %{_bindir}/<%= f %>
90
+ <% end -%>
91
+ <% unless spec.extensions.empty? -%>
92
+ %{vagrant_plugin_extdir_mri}
93
+ <% end -%>
94
+ <%= main_files.reject do |item|
95
+ spec.extensions.detect { |extension| item =~ /^#{extension.split(File::SEPARATOR).first}$/}
96
+ end.to_rpm %>
97
+ <% unless doc_subpackage -%>
98
+ %doc %{vagrant_plugin_docdir}
99
+ <%= doc_files.to_rpm %>
100
+ <% end -%>
101
+ %exclude %{vagrant_plugin_cache}
102
+ %{vagrant_plugin_spec}
103
+
104
+ <% if doc_subpackage -%>
105
+ %files doc
106
+ %doc %{vagrant_plugin_docdir}
107
+ <%= files.top_level_entries.doc_entries.to_rpm %>
108
+ <% end # if doc_subpackage -%>
109
+
110
+ %changelog
111
+ * <%= Time.now.strftime("%a %b %d %Y") %> <%= packager %> - <%= spec.version %>-1
112
+ - Initial package
@@ -0,0 +1,119 @@
1
+ # Generated from <%= spec.file_name %> by gem2rpm -*- rpm-spec -*-
2
+ %global gem_name <%= spec.name %>
3
+
4
+ Name: rubygem-%{gem_name}
5
+ Version: <%= spec.version %>
6
+ Release: 1%{?dist}
7
+ Summary: <%= spec.summary.gsub(/\.$/, "") %>
8
+ License: <%= spec.licenses.join(" and ") %>
9
+ <% if spec.homepage -%>
10
+ URL: <%= spec.homepage %>
11
+ <% end -%>
12
+ Source0: <%= download_path %>%{gem_name}-%{version}.gem
13
+ BuildRequires: ruby(release)
14
+ <% for req in spec.required_rubygems_version -%>
15
+ BuildRequires: <%= requirement 'rubygems-devel', req %>
16
+ <% end -%>
17
+ <% for req in spec.required_ruby_version -%>
18
+ BuildRequires: <%= requirement "ruby#{'-devel' unless spec.extensions.empty?}", req %>
19
+ <% end -%>
20
+ <% unless spec.extensions.empty? -%>
21
+ # Compiler is required for build of gem binary extension.
22
+ # https://fedoraproject.org/wiki/Packaging:C_and_C++#BuildRequires_and_Requires
23
+ BuildRequires: gcc
24
+ <% end -%>
25
+ <%= development_dependencies.reject do |d|
26
+ ["rdoc", "rake", "bundler"].include? d.name
27
+ end.virtualize.with_requires.comment_out.to_rpm -%>
28
+ <% if spec.extensions.empty? -%>
29
+ BuildArch: noarch
30
+ <% end -%>
31
+
32
+ %description
33
+ <%= spec.description %>
34
+
35
+ <% if doc_subpackage -%>
36
+ %package doc
37
+ Summary: Documentation for %{name}
38
+ Requires: %{name} = %{version}-%{release}
39
+ BuildArch: noarch
40
+
41
+ %description doc
42
+ Documentation for %{name}.
43
+ <% end # if doc_subpackage -%>
44
+
45
+ %prep
46
+ gem unpack %{SOURCE0}
47
+
48
+ %setup -q -D -T -n %{gem_name}-%{version}
49
+
50
+ gem spec %{SOURCE0} -l --ruby > %{gem_name}.gemspec
51
+
52
+ %build
53
+ # Create the gem as gem install only works on a gem file
54
+ gem build %{gem_name}.gemspec
55
+
56
+ # %%gem_install compiles any C extensions and installs the gem into ./%%gem_dir
57
+ # by default, so that we can move it into the buildroot in %%install
58
+ %gem_install
59
+
60
+ %install
61
+ mkdir -p %{buildroot}%{gem_dir}
62
+ cp -a .%{gem_dir}/* \
63
+ %{buildroot}%{gem_dir}/
64
+
65
+ <% unless spec.extensions.empty? -%>
66
+ mkdir -p %{buildroot}%{gem_extdir_mri}
67
+ cp -a .%{gem_extdir_mri}/{gem.build_complete,*.so} %{buildroot}%{gem_extdir_mri}/
68
+
69
+ <% for ext in spec.extensions -%>
70
+ # Prevent dangling symlink in -debuginfo (rhbz#878863).
71
+ rm -rf %{buildroot}%{gem_instdir}/<%= ext.split(File::SEPARATOR).first %>/
72
+ <% end -%>
73
+ <% end -%>
74
+
75
+ <% unless spec.executables.empty? -%>
76
+ mkdir -p %{buildroot}%{_bindir}
77
+ cp -pa .%{_bindir}/* \
78
+ %{buildroot}%{_bindir}/
79
+
80
+ find %{buildroot}%{gem_instdir}/<%= spec.bindir %> -type f | xargs chmod a+x
81
+ <% end -%>
82
+
83
+ %check
84
+ pushd .%{gem_instdir}
85
+ <% if tests.entries.empty? -%>
86
+ # Run the test suite.
87
+ <% end -%>
88
+ <% for t in tests -%>
89
+ # <%= t.command %>
90
+ <% end -%>
91
+ popd
92
+
93
+ %files
94
+ %dir %{gem_instdir}
95
+ <% for f in spec.executables -%>
96
+ %{_bindir}/<%= f %>
97
+ <% end -%>
98
+ <% unless spec.extensions.empty? -%>
99
+ %{gem_extdir_mri}
100
+ <% end -%>
101
+ <%= main_files.reject do |item|
102
+ spec.extensions.detect { |extension| item =~ /^#{extension.split(File::SEPARATOR).first}$/}
103
+ end.to_rpm %>
104
+ <% unless doc_subpackage -%>
105
+ %doc %{gem_docdir}
106
+ <%= doc_files.to_rpm %>
107
+ <% end -%>
108
+ %exclude %{gem_cache}
109
+ %{gem_spec}
110
+
111
+ <% if doc_subpackage -%>
112
+ %files doc
113
+ %doc %{gem_docdir}
114
+ <%= doc_files.to_rpm %>
115
+ <% end # if doc_subpackage -%>
116
+
117
+ %changelog
118
+ * <%= Time.now.strftime("%a %b %d %Y") %> <%= packager %> - <%= spec.version %>-1
119
+ - Initial package
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem2rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Lutterkort
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-04-26 00:00:00.000000000 Z
12
+ date: 2017-03-30 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: |2
15
15
  Generate source rpms and rpm spec files from a Ruby Gem.
@@ -29,26 +29,33 @@ files:
29
29
  - bin/gem2rpm
30
30
  - lib/gem2rpm.rb
31
31
  - lib/gem2rpm/configuration.rb
32
- - lib/gem2rpm/dependency.rb
33
32
  - lib/gem2rpm/distro.rb
34
- - lib/gem2rpm/format.rb
33
+ - lib/gem2rpm/gem/dependency.rb
34
+ - lib/gem2rpm/gem/format.rb
35
+ - lib/gem2rpm/gem/package.rb
36
+ - lib/gem2rpm/gem/spec_fetcher.rb
37
+ - lib/gem2rpm/gem/specification.rb
35
38
  - lib/gem2rpm/helpers.rb
36
- - lib/gem2rpm/package.rb
37
- - lib/gem2rpm/spec_fetcher.rb
38
- - lib/gem2rpm/specification.rb
39
+ - lib/gem2rpm/rpm_dependency.rb
40
+ - lib/gem2rpm/rpm_dependency_list.rb
41
+ - lib/gem2rpm/rpm_file.rb
42
+ - lib/gem2rpm/rpm_file_list.rb
39
43
  - lib/gem2rpm/template.rb
40
44
  - lib/gem2rpm/template_helpers.rb
45
+ - lib/gem2rpm/test_suite.rb
41
46
  - templates/default.spec.erb
42
47
  - templates/fedora-17-18.spec.erb
43
48
  - templates/fedora-19-20.spec.erb
44
- - templates/fedora-21-rawhide-vagrant-plugin.spec.erb
45
- - templates/fedora-21-rawhide.spec.erb
49
+ - templates/fedora-21-25-vagrant-plugin.spec.erb
50
+ - templates/fedora-21-25.spec.erb
51
+ - templates/fedora-26-rawhide-vagrant-plugin.spec.erb
52
+ - templates/fedora-26-rawhide.spec.erb
46
53
  - templates/fedora.spec.erb
47
54
  - templates/opensuse.spec.erb
48
55
  - templates/pld.spec.erb
49
56
  homepage: https://github.com/fedora-ruby/gem2rpm
50
57
  licenses:
51
- - GPLv2+
58
+ - GPL-2.0+
52
59
  metadata: {}
53
60
  post_install_message:
54
61
  rdoc_options: []
@@ -66,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
73
  version: '0'
67
74
  requirements: []
68
75
  rubyforge_project:
69
- rubygems_version: 2.5.1
76
+ rubygems_version: 2.6.10
70
77
  signing_key:
71
78
  specification_version: 4
72
79
  summary: Generate rpm specfiles from gems