gem2rpm 0.11.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/AUTHORS +1 -0
- data/README.md +21 -14
- data/bin/gem2rpm +72 -98
- data/lib/gem2rpm.rb +58 -18
- data/lib/gem2rpm/configuration.rb +172 -12
- data/lib/gem2rpm/distro.rb +11 -13
- data/lib/gem2rpm/{dependency.rb → gem/dependency.rb} +1 -1
- data/lib/gem2rpm/{format.rb → gem/format.rb} +0 -0
- data/lib/gem2rpm/{package.rb → gem/package.rb} +0 -0
- data/lib/gem2rpm/{spec_fetcher.rb → gem/spec_fetcher.rb} +1 -1
- data/lib/gem2rpm/{specification.rb → gem/specification.rb} +14 -6
- data/lib/gem2rpm/helpers.rb +2 -46
- data/lib/gem2rpm/rpm_dependency.rb +49 -0
- data/lib/gem2rpm/rpm_dependency_list.rb +60 -0
- data/lib/gem2rpm/rpm_file.rb +51 -0
- data/lib/gem2rpm/rpm_file_list.rb +55 -0
- data/lib/gem2rpm/template.rb +9 -8
- data/lib/gem2rpm/template_helpers.rb +8 -7
- data/lib/gem2rpm/test_suite.rb +46 -0
- data/templates/{fedora-21-rawhide-vagrant-plugin.spec.erb → fedora-21-25-vagrant-plugin.spec.erb} +0 -3
- data/templates/{fedora-21-rawhide.spec.erb → fedora-21-25.spec.erb} +0 -0
- data/templates/fedora-26-vagrant-plugin.spec.erb +112 -0
- data/templates/fedora-26.spec.erb +119 -0
- data/templates/fedora-27-rawhide-vagrant-plugin.spec.erb +108 -0
- data/templates/fedora-27-rawhide.spec.erb +115 -0
- metadata +24 -38
- checksums.yaml.gz.sig +0 -3
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -2
@@ -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 => [
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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 => [
|
26
|
-
|
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
|
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
|
data/lib/gem2rpm/distro.rb
CHANGED
@@ -5,7 +5,7 @@ module Gem2Rpm
|
|
5
5
|
OPENSUSE = :opensuse
|
6
6
|
DEFAULT = :default
|
7
7
|
|
8
|
-
ROLLING_RELEASES = [
|
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)
|
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=(
|
35
|
-
os_release.version = content[/^VERSION_ID=(
|
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
|
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?
|
106
|
+
return true if ROLLING_RELEASES.include?(range[1]) || (version.to_s <= range[1].to_s)
|
109
107
|
end
|
110
108
|
end
|
111
109
|
|
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
|
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
|
64
|
+
Helpers.requirement_versions_to_rpm(super)
|
57
65
|
rescue
|
58
66
|
['']
|
59
67
|
end
|
data/lib/gem2rpm/helpers.rb
CHANGED
@@ -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 ['
|
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
|
-
|
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
|