gem2pkg 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
data/bin/gem2pkg ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'gem2pkg'
4
+ exit(Gem2Pkg.new.build(ARGV[0]))
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
+