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 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
+