rpgem 0.1.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.
Files changed (4) hide show
  1. data/bin/rpgem +108 -0
  2. data/lib/rpgem.rb +177 -0
  3. data/lib/template.spec.erb +72 -0
  4. 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
+