rpgem 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/rpgem +108 -0
- data/lib/rpgem.rb +177 -0
- data/lib/template.spec.erb +72 -0
- metadata +84 -0
data/bin/rpgem
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','rpgem'))
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = <<-banner.split($/).map { |l| l.strip }.join($/)
|
10
|
+
Usage: rpgem gem_name [OPTIONS]
|
11
|
+
if no action is specified (-f, -s, -b), then all three will
|
12
|
+
be performed in that order.
|
13
|
+
banner
|
14
|
+
|
15
|
+
opts.on('-v VER',
|
16
|
+
'--version VER',
|
17
|
+
"Specify a specific gem version"
|
18
|
+
) do |v|
|
19
|
+
options[:version] = v
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('-V VER',
|
23
|
+
'--version-req VER',
|
24
|
+
"Specify a fuzzy version (i.e. '> 4.0')"
|
25
|
+
) do |v|
|
26
|
+
options[:version_reqs] ||= []
|
27
|
+
options[:version_reqs] << v
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('-R',
|
31
|
+
'--recursive',
|
32
|
+
"Recursively rpgem the dependencies"
|
33
|
+
) do
|
34
|
+
options[:recursive] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('-f',
|
38
|
+
'--fetch',
|
39
|
+
"Fetch the gem"
|
40
|
+
) do
|
41
|
+
options[:action] = :fetch!
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on('-s',
|
45
|
+
'--make-spec',
|
46
|
+
"Make the rpm specfile"
|
47
|
+
) do
|
48
|
+
options[:action] = :make_spec!
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on('-b',
|
52
|
+
'--build',
|
53
|
+
"Build the rpm (this is the default)"
|
54
|
+
) do
|
55
|
+
options[:action] = :build!
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on('-p PREFIX',
|
59
|
+
'--prefix PREFIX',
|
60
|
+
'Specify a prefix to use during the install. Default: /usr'
|
61
|
+
) do |p|
|
62
|
+
options[:prefix] = p.chomp('/')
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on('-d DEPENDS',
|
66
|
+
'--depends DEPENDS',
|
67
|
+
'Specify a non-gem dependency (e.g. mysql-devel, etc.)'
|
68
|
+
) do |d|
|
69
|
+
options[:dependencies] ||= []
|
70
|
+
options[:dependencies] << d
|
71
|
+
end
|
72
|
+
end.parse!
|
73
|
+
|
74
|
+
options.rmerge!({
|
75
|
+
:version => nil,
|
76
|
+
:recursive => false,
|
77
|
+
:version_reqs => [],
|
78
|
+
:action => :build!,
|
79
|
+
:ruby_cmd => "ruby",
|
80
|
+
:prefix => '/usr',
|
81
|
+
:dependencies => []
|
82
|
+
})
|
83
|
+
|
84
|
+
p [options, ARGV]
|
85
|
+
|
86
|
+
FileUtils.mkdir RPGem::TMP unless File.directory? RPGem::TMP
|
87
|
+
|
88
|
+
unless File.directory? RPGem::RPMBUILD_DIR
|
89
|
+
FileUtils.mkdir RPGem::RPMBUILD_DIR
|
90
|
+
FileUtils.in_dir RPGem::RPMBUILD_DIR do
|
91
|
+
FileUtils.mkdir "SOURCES"
|
92
|
+
FileUtils.mkdir "SPECS"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
g = RPGem.new(ARGV[0], options)
|
97
|
+
g.fetch!
|
98
|
+
if options[:recursive]
|
99
|
+
g.recurse!(options[:action])
|
100
|
+
end
|
101
|
+
g.send(options[:action]) unless options[:action] == :fetch!
|
102
|
+
|
103
|
+
|
104
|
+
rescue Exception => e
|
105
|
+
puts e.to_s
|
106
|
+
puts e.backtrace
|
107
|
+
exit! 1
|
108
|
+
end
|
data/lib/rpgem.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/format'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
module FileUtils
|
7
|
+
def self.in_dir(dir)
|
8
|
+
cwd = `pwd`.strip
|
9
|
+
cd dir
|
10
|
+
r = yield
|
11
|
+
cd cwd
|
12
|
+
r
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Hash
|
17
|
+
# like merge!, but doesn't update existing keys.
|
18
|
+
# useful for defaulting options
|
19
|
+
def rmerge!(hsh)
|
20
|
+
hsh.each do |k,v|
|
21
|
+
self[k] = v unless self.has_key? k
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def rmerge(hsh)
|
27
|
+
self.dup.rmerge!(hsh)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class << File
|
32
|
+
def write(fname, str)
|
33
|
+
self.open(fname, "w") do |f|
|
34
|
+
f.write str
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
LIB_DIR = File.expand_path(File.dirname(__FILE__))
|
40
|
+
|
41
|
+
|
42
|
+
class RPGem
|
43
|
+
HOME_DIR = `echo ~`.strip
|
44
|
+
CWD = `pwd`.strip
|
45
|
+
TMP = "/tmp/rpgem"
|
46
|
+
RPMBUILD_DIR = "#{HOME_DIR}/rpmbuild"
|
47
|
+
SOURCES_DIR = "#{RPMBUILD_DIR}/SOURCES"
|
48
|
+
SPECS_DIR = "#{RPMBUILD_DIR}/SPECS"
|
49
|
+
|
50
|
+
def initialize(name, options={})
|
51
|
+
@name = name
|
52
|
+
@options = options.rmerge({
|
53
|
+
:version => nil,
|
54
|
+
:version_reqs => [],
|
55
|
+
:recursive => false,
|
56
|
+
:ruby_cmd => "ruby",
|
57
|
+
:dependencies => []
|
58
|
+
})
|
59
|
+
@options.each do |k,v|
|
60
|
+
instance_variable_set("@#{k}", v)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def sh_version_reqs
|
65
|
+
@version_reqs.map do |r|
|
66
|
+
"--version '#{r}'"
|
67
|
+
end.join ' '
|
68
|
+
end
|
69
|
+
|
70
|
+
attr_reader :name, :version
|
71
|
+
|
72
|
+
def to_s
|
73
|
+
if @version.nil?
|
74
|
+
@name
|
75
|
+
else
|
76
|
+
"#{@name}-#{@version}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def gem_loc
|
81
|
+
"#{SOURCES_DIR}/#{self.to_s}.gem"
|
82
|
+
end
|
83
|
+
|
84
|
+
def spec_loc
|
85
|
+
"#{SPECS_DIR}/rpgem-#{self.to_s}.spec"
|
86
|
+
end
|
87
|
+
|
88
|
+
def format
|
89
|
+
@format ||= Gem::Format.from_file_by_path(gem_loc)
|
90
|
+
end
|
91
|
+
|
92
|
+
def spec
|
93
|
+
@spec ||= format.spec
|
94
|
+
end
|
95
|
+
|
96
|
+
def fetched_version(name_or_dep, requirements=[])
|
97
|
+
if name_or_dep.is_a? Gem::Dependency
|
98
|
+
d = name_or_dep
|
99
|
+
else
|
100
|
+
d = Gem::Dependency.new(name_or_dep, requirements)
|
101
|
+
end
|
102
|
+
|
103
|
+
currents = `ls #{SOURCES_DIR} | grep '^#{d.name}'`.split($/)
|
104
|
+
return nil if currents.empty?
|
105
|
+
|
106
|
+
currents.each do |c|
|
107
|
+
ver = c.match(/-(\d+(\.\d+)+)(\.gem)?$/)[1]
|
108
|
+
return ver if d.match?(d.name, ver)
|
109
|
+
end
|
110
|
+
return nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def fetched?
|
114
|
+
return File.exists?(self.gem_loc)
|
115
|
+
end
|
116
|
+
|
117
|
+
def fetch!
|
118
|
+
v = self.fetched_version(@name, @version_reqs)
|
119
|
+
if (@version.nil? && v) || (!@version.nil? && self.fetched?)
|
120
|
+
@version = v
|
121
|
+
puts "Skipping fetch of #{self.to_s}"
|
122
|
+
else
|
123
|
+
puts "Fetching the gem #{self.to_s}"
|
124
|
+
if @version.nil?
|
125
|
+
system("rm -rf #{TMP}")
|
126
|
+
system("mkdir #{TMP}")
|
127
|
+
FileUtils.in_dir TMP do
|
128
|
+
system("gem fetch #{@name} #{sh_version_reqs}")
|
129
|
+
gem_title = `ls`
|
130
|
+
@version = gem_title.match(/-(\d+(\.\d+)+)\.gem$/)[1]
|
131
|
+
end
|
132
|
+
system("mv #{TMP}/* #{SOURCES_DIR}/")
|
133
|
+
else
|
134
|
+
FileUtils.in_dir SOURCES_DIR do
|
135
|
+
system("gem fetch #{@name} --version #{@version}")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def make_spec!
|
142
|
+
puts "rendering the specfile..."
|
143
|
+
template = File.read("#{LIB_DIR}/template.spec.erb")
|
144
|
+
specfile = ERB.new(template).result(binding)
|
145
|
+
puts "rendered:"
|
146
|
+
puts "==============="
|
147
|
+
puts specfile
|
148
|
+
puts "==============="
|
149
|
+
File.write(spec_loc, specfile)
|
150
|
+
puts "rendered to #{spec_loc}"
|
151
|
+
end
|
152
|
+
|
153
|
+
def build!
|
154
|
+
make_spec!
|
155
|
+
puts "-*- Building RPM -*-"
|
156
|
+
FileUtils.in_dir RPMBUILD_DIR do
|
157
|
+
system("rpmbuild -ba #{spec_loc}")
|
158
|
+
end
|
159
|
+
puts "-*- Done Building RPM -*-"
|
160
|
+
end
|
161
|
+
|
162
|
+
def recurse!(action=:setup!)
|
163
|
+
#TODO: add an option for dev dependencies
|
164
|
+
#TODO: don't choke on circular dependencies
|
165
|
+
deps = self.spec.runtime_dependencies
|
166
|
+
deps.each do |d|
|
167
|
+
g = self.class.new(d.name,
|
168
|
+
:version_reqs => d.requirements_list,
|
169
|
+
:recursive => true,
|
170
|
+
:ruby_cmd => @ruby_cmd
|
171
|
+
)
|
172
|
+
g.fetch!
|
173
|
+
g.recurse!(action)
|
174
|
+
g.send(action) unless action == :fetch!
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<%
|
2
|
+
ruby_ver = begin
|
3
|
+
v = spec.required_ruby_version.to_s
|
4
|
+
v == ">= 0" ? "" : " #{v}"
|
5
|
+
end
|
6
|
+
rubygems_ver = begin
|
7
|
+
v = spec.required_rubygems_version.to_s
|
8
|
+
v == ">= 0" ? "" : " #{v}"
|
9
|
+
end
|
10
|
+
|
11
|
+
%>
|
12
|
+
%define rbname <%= spec.name %>
|
13
|
+
|
14
|
+
Name: rpgem-%{rbname}
|
15
|
+
Version: <%= spec.version.to_s %>
|
16
|
+
Release: 1%{?dist}
|
17
|
+
Summary: <%= spec.summary || spec.description %>
|
18
|
+
|
19
|
+
Group: Development/Languages/Ruby
|
20
|
+
License: <%= spec.license || "#FIXME - this gem has an unspecified license!" %>
|
21
|
+
URL: <%= spec.homepage %>
|
22
|
+
Source0: %{_sourcedir}/%{rbname}-%{version}.gem
|
23
|
+
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
24
|
+
Vendor: <%= spec.author %>
|
25
|
+
|
26
|
+
BuildRequires: ruby<%=ruby_ver%>, rubygems<%=rubygems_ver%>
|
27
|
+
Requires: ruby<%=ruby_ver%>, rubygems<%=rubygems_ver%><%=
|
28
|
+
spec.runtime_dependencies.map do |d|
|
29
|
+
", rpgem-#{d.name} #{d.requirements_list.first.gsub(/~>/,'>=')}"
|
30
|
+
end.join
|
31
|
+
%><%=
|
32
|
+
@dependencies.map {|d| ", #{d}"}.join
|
33
|
+
%>
|
34
|
+
|
35
|
+
Prefix: <%=@prefix%>
|
36
|
+
|
37
|
+
%define gem_prefix %{prefix}/lib/gems/%(%{prefix}/bin/ruby -e "puts VERSION.split('.')[0..1].join('.')")
|
38
|
+
|
39
|
+
%description
|
40
|
+
<%= spec.description %>
|
41
|
+
|
42
|
+
%prep
|
43
|
+
#noop
|
44
|
+
|
45
|
+
%build
|
46
|
+
rm -rf $RPM_BUILD_ROOT
|
47
|
+
mkdir $RPM_BUILD_ROOT
|
48
|
+
%{prefix}/bin/gem install %{SOURCE0} --force --local --no-rdoc --no-ri --install-dir=.
|
49
|
+
|
50
|
+
%install
|
51
|
+
|
52
|
+
echo %{gem_prefix}
|
53
|
+
rm -rf $RPM_BUILD_ROOT%{gem_prefix}
|
54
|
+
mkdir -p $RPM_BUILD_ROOT%{gem_prefix}
|
55
|
+
mv * $RPM_BUILD_ROOT%{gem_prefix}
|
56
|
+
chmod -R 0755 $RPM_BUILD_ROOT%{gem_prefix}
|
57
|
+
|
58
|
+
%clean
|
59
|
+
rm -rf $RPM_BUILD_ROOT
|
60
|
+
|
61
|
+
|
62
|
+
%files
|
63
|
+
%defattr(-,root,root,-)
|
64
|
+
%{gem_prefix}/gems/%{rbname}-%{version}/
|
65
|
+
%{gem_prefix}/specifications/%{rbname}-%{version}.gemspec
|
66
|
+
%{gem_prefix}/cache/%{rbname}-%{version}.gem
|
67
|
+
<% spec.executables.each do |e| %>
|
68
|
+
%{gem_prefix}/bin/<%= e %>
|
69
|
+
<% end %>
|
70
|
+
|
71
|
+
|
72
|
+
%changelog
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rpgem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jay Adkisson
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-05-17 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: erubis
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description: RPGem will create a binary RPM with the compiled extensions, which you can install on a machine painlessly.
|
36
|
+
email: jay@causes.com
|
37
|
+
executables:
|
38
|
+
- rpgem
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- lib/rpgem.rb
|
45
|
+
- lib/template.spec.erb
|
46
|
+
- bin/rpgem
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://github.com/jayferd/rpgem
|
49
|
+
licenses:
|
50
|
+
- MIT
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 3
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
version: "0"
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 23
|
71
|
+
segments:
|
72
|
+
- 1
|
73
|
+
- 3
|
74
|
+
- 6
|
75
|
+
version: 1.3.6
|
76
|
+
requirements:
|
77
|
+
- rpmbuild
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.3.7
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: A gem-to-rpm converter, done right.
|
83
|
+
test_files: []
|
84
|
+
|