gem2pkg 0.1.0
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.
- data/Rakefile +8 -0
- data/bin/gem2pkg +4 -0
- data/gem2pkg.gemspec +14 -0
- data/lib/gem2pkg.rb +139 -0
- data/resources/Info.plist.erb +46 -0
- metadata +71 -0
data/Rakefile
ADDED
data/bin/gem2pkg
ADDED
data/gem2pkg.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'gem2pkg'
|
3
|
+
s.version = '0.1.0'
|
4
|
+
s.date = '2011-11-21'
|
5
|
+
s.summary = "OSX packages from Ruby Gems!"
|
6
|
+
s.description = "Creates Mac OSX installer packages for 10.5 and up from ruby gems"
|
7
|
+
s.authors = ["Justin Schumacher"]
|
8
|
+
s.email = 'justin@thethinkingtree.com'
|
9
|
+
s.executables << 'gem2pkg'
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
s.homepage = 'http://rubygems.org/gems/gem2pkg'
|
12
|
+
s.required_rubygems_version = ">= 1.8.11"
|
13
|
+
s.require_paths = ["lib"]
|
14
|
+
end
|
data/lib/gem2pkg.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'YAML'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'rubygems/dependency_installer'
|
6
|
+
require 'erb'
|
7
|
+
require 'tmpdir'
|
8
|
+
|
9
|
+
class Gem2Pkg
|
10
|
+
def build(gemname)
|
11
|
+
if gemname == nil
|
12
|
+
puts "Please specify the name of the gem to package."
|
13
|
+
return -1
|
14
|
+
end
|
15
|
+
|
16
|
+
gembin = `which gem`.strip
|
17
|
+
if gembin != '/usr/bin/gem'
|
18
|
+
puts "This tool is meant to make gem packages for the Mac OSX system installed ruby. If you are using RVM, please switch to the system ruby first by running: 'rvm use system'"
|
19
|
+
return -2
|
20
|
+
end
|
21
|
+
|
22
|
+
gemspec = Gem::Specification.find_by_name(gemname)
|
23
|
+
if gemspec == nil
|
24
|
+
dep = Gem::Dependency.new(gemname)
|
25
|
+
matches = Gem::SpecFetcher.fetcher.fetch dep
|
26
|
+
if matches.length == 0
|
27
|
+
puts "Gem #{gemname} was not found!"
|
28
|
+
return -4
|
29
|
+
end
|
30
|
+
gemspec = matches.first.first
|
31
|
+
|
32
|
+
puts "Gem is not installed locally-- install with:"
|
33
|
+
puts "gem install #{gemname} -v #{gemspec.version}"
|
34
|
+
return -4
|
35
|
+
end
|
36
|
+
|
37
|
+
puts "Making installer for gem #{gemname} (#{gemspec.version})"
|
38
|
+
|
39
|
+
#inst = Gem::DependencyInstaller.new
|
40
|
+
#inst.install gemspec.name, gemspec.version
|
41
|
+
|
42
|
+
puts "Building dependency list from dependency tree..."
|
43
|
+
|
44
|
+
def gather_dependencies(specs)
|
45
|
+
dependency_list = Gem::DependencyList.new
|
46
|
+
dependency_list.add(*specs)
|
47
|
+
|
48
|
+
to_do = specs.dup
|
49
|
+
seen = {}
|
50
|
+
|
51
|
+
until to_do.empty? do
|
52
|
+
spec = to_do.shift
|
53
|
+
next if spec.nil? or seen[spec.name]
|
54
|
+
seen[spec.name] = true
|
55
|
+
|
56
|
+
deps = spec.runtime_dependencies
|
57
|
+
deps.each do |dep|
|
58
|
+
result = dep.to_spec
|
59
|
+
if result == nil
|
60
|
+
puts "Could not find local gem to satisfy dependency #{dep.name} (#{dep.requirement})"
|
61
|
+
end
|
62
|
+
next if seen[result.name]
|
63
|
+
dependency_list.add result
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
dependency_list.dependency_order.reverse
|
68
|
+
end
|
69
|
+
|
70
|
+
puts "We will be bundling up the following gems into our installer:"
|
71
|
+
dependencies = gather_dependencies([gemspec])
|
72
|
+
dependencies.each do |dependency|
|
73
|
+
puts "#{dependency.name} (#{dependency.version}) from '#{dependency.full_gem_path}'"
|
74
|
+
end
|
75
|
+
|
76
|
+
pkg_name = "#{gemspec.name}-#{gemspec.version}"
|
77
|
+
installed_size = nil
|
78
|
+
Dir.mktmpdir(pkg_name) do |payload_staging_dir|
|
79
|
+
dependencies.each do |dependency|
|
80
|
+
`mkdir -p #{payload_staging_dir}#{dependency.full_gem_path}`
|
81
|
+
`cp -r #{dependency.full_gem_path}/ #{payload_staging_dir}#{dependency.full_gem_path}/`
|
82
|
+
`mkdir -p #{payload_staging_dir}#{File.dirname(dependency.loaded_from)}`
|
83
|
+
`cp #{dependency.loaded_from} #{payload_staging_dir}#{dependency.loaded_from}`
|
84
|
+
end
|
85
|
+
|
86
|
+
# write BOM
|
87
|
+
`rm -rf #{pkg_name}.pkg` if File.exists?("#{pkg_name}.pkg")
|
88
|
+
`mkdir -p #{pkg_name}.pkg/Contents/Resources`
|
89
|
+
|
90
|
+
puts "Generating BOM..."
|
91
|
+
`mkbom #{payload_staging_dir} #{pkg_name}.pkg/Contents/Archive.bom`
|
92
|
+
|
93
|
+
puts "Archiving payload..."
|
94
|
+
`pax -wz -x cpio \"#{payload_staging_dir}\" > #{pkg_name}.pkg/Contents/Archive.pax.gz`
|
95
|
+
|
96
|
+
installed_size = (`/usr/bin/du -k -s #{payload_staging_dir}`.split(' ')[0]).to_i * 1024
|
97
|
+
end
|
98
|
+
|
99
|
+
puts "Generating postflight script..."
|
100
|
+
File.open("#{pkg_name}.pkg/Contents/Resources/postflight", "w") do |file|
|
101
|
+
file.puts '#!/bin/sh'
|
102
|
+
dependencies.each do |dependency|
|
103
|
+
# make symbolic links to executables
|
104
|
+
dependency.executables.each do |exe|
|
105
|
+
file.puts "ln -f -s #{dependency.full_gem_path}/#{dependency.bindir}/#{exe} /usr/bin/#{exe}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
puts "Generating package info..."
|
111
|
+
erb_path = File.join(File.dirname(__FILE__), "..", "resources", "Info.plist.erb")
|
112
|
+
|
113
|
+
src = File.read erb_path
|
114
|
+
erb = ERB.new(src)
|
115
|
+
File.open("#{pkg_name}.pkg/Contents/Info.plist", "w") do |file|
|
116
|
+
package_name = pkg_name
|
117
|
+
package_info = gemspec.summary
|
118
|
+
package_identifier = "org.rubygems.gems.#{gemspec.name}"
|
119
|
+
package_version = gemspec.version
|
120
|
+
file.puts erb.result(binding)
|
121
|
+
end
|
122
|
+
|
123
|
+
`echo pmkrpkg1 > "#{pkg_name}.pkg/Contents/PkgInfo"`
|
124
|
+
|
125
|
+
puts "Setting permissions..."
|
126
|
+
`chmod 444 #{pkg_name}.pkg/Contents/Archive.bom`
|
127
|
+
`chmod 444 #{pkg_name}.pkg/Contents/Archive.pax.gz`
|
128
|
+
`chmod 444 #{pkg_name}.pkg/Contents/PkgInfo`
|
129
|
+
`chmod 444 #{pkg_name}.pkg/Contents/Info.plist`
|
130
|
+
`chmod 555 #{pkg_name}.pkg/Contents/Resources/postflight`
|
131
|
+
|
132
|
+
puts "Done. Package has been saved as '#{pkg_name}.pkg'"
|
133
|
+
# flatten package
|
134
|
+
#puts "Flattening package..."
|
135
|
+
#`pkgutil --flatten #{pkg_name}.pkg #{pkg_name}.flat.pkg`
|
136
|
+
|
137
|
+
return 0
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>CFBundleDevelopmentRegion</key>
|
6
|
+
<string>English</string>
|
7
|
+
<key>CFBundleGetInfoString</key>
|
8
|
+
<string><%= package_info %></string>
|
9
|
+
<key>CFBundleIdentifier</key>
|
10
|
+
<string><%= package_identifier %></string>
|
11
|
+
<key>CFBundleName</key>
|
12
|
+
<string><%= package_name %></string>
|
13
|
+
<key>CFBundleShortVersionString</key>
|
14
|
+
<string><%= package_version %></string>
|
15
|
+
<key>IFMajorVersion</key>
|
16
|
+
<integer>1</integer>
|
17
|
+
<key>IFMinorVersion</key>
|
18
|
+
<integer>0</integer>
|
19
|
+
<key>IFPkgCreator</key>
|
20
|
+
<string>gempkr</string>
|
21
|
+
<key>IFPkgFlagAllowBackRev</key>
|
22
|
+
<false/>
|
23
|
+
<key>IFPkgFlagAuthorizationAction</key>
|
24
|
+
<string>NoAuthorization</string>
|
25
|
+
<key>IFPkgFlagDefaultLocation</key>
|
26
|
+
<string>/</string>
|
27
|
+
<key>IFPkgFlagFollowLinks</key>
|
28
|
+
<false/>
|
29
|
+
<key>IFPkgFlagInstalledSize</key>
|
30
|
+
<integer><%= installed_size %></integer>
|
31
|
+
<key>IFPkgFlagIsRequired</key>
|
32
|
+
<false/>
|
33
|
+
<key>IFPkgFlagOverwritePermissions</key>
|
34
|
+
<false/>
|
35
|
+
<key>IFPkgFlagRelocatable</key>
|
36
|
+
<false/>
|
37
|
+
<key>IFPkgFlagRestartAction</key>
|
38
|
+
<string>NoRestart</string>
|
39
|
+
<key>IFPkgFlagRootVolumeOnly</key>
|
40
|
+
<false/>
|
41
|
+
<key>IFPkgFlagUpdateInstalledLanguages</key>
|
42
|
+
<false/>
|
43
|
+
<key>IFPkgFormatVersion</key>
|
44
|
+
<real>0.10000000149011612</real>
|
45
|
+
</dict>
|
46
|
+
</plist>
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gem2pkg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Justin Schumacher
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-11-21 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Creates Mac OSX installer packages for 10.5 and up from ruby gems
|
22
|
+
email: justin@thethinkingtree.com
|
23
|
+
executables:
|
24
|
+
- gem2pkg
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- Rakefile
|
31
|
+
- bin/gem2pkg
|
32
|
+
- gem2pkg.gemspec
|
33
|
+
- lib/gem2pkg.rb
|
34
|
+
- resources/Info.plist.erb
|
35
|
+
homepage: http://rubygems.org/gems/gem2pkg
|
36
|
+
licenses: []
|
37
|
+
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
hash: 3
|
49
|
+
segments:
|
50
|
+
- 0
|
51
|
+
version: "0"
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 33
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 8
|
61
|
+
- 11
|
62
|
+
version: 1.8.11
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 1.8.11
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: OSX packages from Ruby Gems!
|
70
|
+
test_files: []
|
71
|
+
|