packtory 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 27cb2492004a82f696dfd78d5aaab669a9fa9fec7391d84a2fbe5ed049bce612
4
+ data.tar.gz: fa5db1bab4451e2364cdd98062157355499f33208538cd5807e3ef39bf481fc4
5
+ SHA512:
6
+ metadata.gz: ec25d2bd6b0c37613e070890493270f79335bb795b13659253bbc0cacb0344db49fc8a10f1e4067cfcb070c0c6dfc11ed0cdcc67ed4bc15453dd4464bd1752e2
7
+ data.tar.gz: 8b68c017d373c376a648d7668b516aa4ac307e3f4cfd19731f69bcd99a2b30bb28f1c9f44b2bc36b2de3e3bc225c452156db9c457449b0258edba056f6f02d9f
data/README.md ADDED
@@ -0,0 +1,9 @@
1
+ ## Overview
2
+
3
+ This is packtory, an integrated, easy to use packaging tool for your
4
+ Ruby gem, Node module, and Python module.
5
+
6
+ ## State
7
+
8
+ Still a work in progress. Stay tuned for when ready for human
9
+ consumption.
data/bin/packtory ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../../lib', __FILE__)
4
+ require 'packtory'
5
+
6
+ Packtory::Command.run(ARGV)
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env bash
2
+
3
+ PACKAGE_PATH="<%= pg_PACKAGE_PATH %>"
4
+
5
+ # this is a special trap, in case the fpm templating did not its job
6
+ if [[ $PACKAGE_PATH == \<* ]]; then
7
+ PACKAGE_PATH=""
8
+ fi
9
+
10
+ this_dir=$(cd $(dirname $0); pwd)
11
+
12
+ if [ -n "$PACKAGE_PATH" ]; then
13
+ eval "export PACKAGE_PATH=$PACKAGE_PATH"
14
+ else
15
+ echo "ERROR: PACKAGE_PATH is not set. Aborting."
16
+ exit 1
17
+ fi
18
+
19
+ if [ -f $this_dir/gem_build_extensions ]; then
20
+ gem_build_extensions_path=$this_dir/gem_build_extensions
21
+ else
22
+ gem_build_extensions_path=$PACKAGE_PATH/packtory_tools/gem_build_extensions
23
+ fi
24
+
25
+ echo "After install script for: $PACKAGE_PATH"
26
+
27
+ extensions_path=$PACKAGE_PATH/extensions
28
+ if [ -d $extensions_path ]; then
29
+ for gemspec in $extensions_path/*.gemspec; do
30
+ echo "== Processing $(basename $gemspec) =="
31
+ $gem_build_extensions_path $PACKAGE_PATH/bundle $gemspec
32
+ done
33
+ fi
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'rubygems/installer'
5
+ require 'fileutils'
6
+
7
+ bundle_path = ARGV[0]
8
+ if bundle_path.nil? || bundle_path.empty?
9
+ abort 'ERROR: Please specify a bundle path'
10
+ else
11
+ bundle_path = File.expand_path(bundle_path)
12
+ end
13
+
14
+ gemspec_path = ARGV[1]
15
+ if gemspec_path.nil? || gemspec_path.empty?
16
+ abort 'ERROR: Please specify a gemspec path'
17
+ else
18
+ gemspec_path = File.expand_path(gemspec_path)
19
+ end
20
+
21
+ puts 'Bundle path : %s' % bundle_path
22
+ puts 'Gemspec path : %s' % gemspec_path
23
+
24
+ spec = eval(File.read(gemspec_path)).tap do |spec|
25
+ spec.loaded_from = gemspec_path
26
+ end
27
+
28
+ gem_path = File.join(bundle_path, spec.name)
29
+ puts 'Gem path : %s' % gem_path
30
+ spec.full_gem_path = gem_path
31
+
32
+ unless spec.extensions.empty?
33
+ builder = Gem::Ext::Builder.new(spec)
34
+ builder.build_extensions
35
+ else
36
+ warn 'WARN: No extensions found, nothing to do'
37
+ end
data/lib/packtory.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler'
2
+
3
+ module Packtory
4
+ autoload :VERSION, File.expand_path('../packtory/version', __FILE__)
5
+ autoload :Command, File.expand_path('../packtory/command', __FILE__)
6
+
7
+ autoload :PatchBundlerNoMetadataDeps, File.expand_path('../packtory/patch_bundler_no_metadata_deps', __FILE__)
8
+ autoload :DebPackage, File.expand_path('../packtory/deb_package', __FILE__)
9
+ autoload :RpmPackage, File.expand_path('../packtory/rpm_package', __FILE__)
10
+ autoload :FpmExec, File.expand_path('../packtory/fpm_exec', __FILE__)
11
+ autoload :Packer, File.expand_path('../packtory/packer', __FILE__)
12
+
13
+ # TODO: Evaluate and refactor
14
+ autoload :RakeTask, File.expand_path('../packtory/rake_task', __FILE__)
15
+
16
+ def self.gem_build_extensions_path
17
+ File.expand_path('../../bin/support/gem_build_extensions', __FILE__)
18
+ end
19
+ end
@@ -0,0 +1,164 @@
1
+ module Packtory
2
+ class Command
3
+ def self.run(argv)
4
+ self.new.run(argv)
5
+ end
6
+
7
+ def detect_envs(argv)
8
+ if ENV['FPM_EXEC_PATH']
9
+ @fpm_exec_path = File.expand_path(ENV['FPM_EXEC_PATH'])
10
+ else
11
+ @fpm_exec_path = `which fpm`.strip
12
+ end
13
+
14
+ if @fpm_exec_path.nil? || @fpm_exec_path.empty?
15
+ puts 'ERROR: `fpm` executable is not in path. Perhaps, install fpm first?'
16
+ exit 1
17
+ end
18
+
19
+ if argv[0].nil? || argv[0].empty?
20
+ puts 'ERROR: Build path not specified, aborting.'
21
+ exit 1
22
+ end
23
+
24
+ @build_path = File.expand_path(argv[0])
25
+ unless File.exists?(@build_path)
26
+ puts 'ERROR: Build path %s do not exist, aborting.' % @build_path
27
+ exit 1
28
+ end
29
+
30
+ say 'Using fpm path : %s' % @fpm_exec_path
31
+ say 'Using fpm : %s' % `#{@fpm_exec_path} -v`.strip
32
+
33
+ say 'Using build path : %s' % @build_path
34
+
35
+ Packer.config[:fpm_exec_path] = @fpm_exec_path
36
+ Packer.config[:path] = @build_path
37
+
38
+ self
39
+ end
40
+
41
+ def detect_specfile(argv)
42
+ if ENV['GEM_SPECFILE']
43
+ @gemspec_file = ENV['GEM_SPECFILE']
44
+ unless @gemspec_file =~ /^\/(.+)$/
45
+ @gemspec_file = File.join(@build_path, @gemspec_file)
46
+ end
47
+
48
+ unless File.exists?(@gemspec_file)
49
+ puts 'ERROR: Specified gemspec file %s not found, aborting.' % @gemspec_file
50
+ exit 1
51
+ end
52
+ else
53
+ paths = Dir.glob(File.join(@build_path, '/*.gemspec'))
54
+ if paths.empty?
55
+ puts 'ERROR: No gemspec file found, aborting.'
56
+ exit 1
57
+ elsif paths.count > 1
58
+ puts 'ERROR: Multiple gemspec file found, aborting.'
59
+ exit 1
60
+ end
61
+
62
+ @gemspec_file = paths[0]
63
+ end
64
+
65
+ say 'Using spec file : %s' % @gemspec_file
66
+ Packer.config[:gemspec] = @gemspec_file
67
+
68
+ self
69
+ end
70
+
71
+ def detect_gemfile(argv)
72
+ @bundle_gemfile = nil
73
+
74
+ if ENV['BUNDLE_GEMFILE'] && !ENV['BUNDLE_GEMFILE'].empty?
75
+ @bundle_gemfile = ENV['BUNDLE_GEMFILE']
76
+
77
+ unless @bundle_gemfile =~ /^\/(.+)$/
78
+ @bundle_gemfile = File.join(@build_path, @bundle_gemfile)
79
+ end
80
+
81
+ unless File.exists?(@bundle_gemfile)
82
+ puts 'ERROR: Specified bundle gemfile %s not found, aborting.' % @bundle_gemfile
83
+ exit 1
84
+ end
85
+
86
+ puts 'Using Gemfile : %s' % @bundle_gemfile
87
+ Packer.config[:gemfile] = @bundle_gemfile
88
+ end
89
+
90
+ self
91
+ end
92
+
93
+ def detect_deps(argv)
94
+ @deps = { }
95
+
96
+ if ENV['PACKAGE_RUBY_VERSION'] && !ENV['PACKAGE_RUBY_VERSION'].empty?
97
+ @ruby_version = ENV['PACKAGE_RUBY_VERSION']
98
+ puts 'Using ruby deps : %s' % @ruby_version
99
+ else
100
+ @ruby_version = nil
101
+ puts 'Using ruby deps : latest'
102
+ end
103
+
104
+ Packer.config[:dependencies]['ruby'] = @ruby_version
105
+ @deps['ruby'] = @ruby_version
106
+
107
+ if ENV['PACKAGE_DEPENDENCIES']
108
+ deps = ENV['PACKAGE_DEPENDENCIES'].split(',')
109
+ deps.each do |d|
110
+ if d =~ /^([^\<\>\=]+)(.+)?$/
111
+ pname = $~[1]
112
+ pver = $~[2]
113
+
114
+ Packer.config[:dependencies][pname] = pver
115
+ @deps[pname] = pver
116
+ end
117
+ end
118
+ end
119
+
120
+ self
121
+ end
122
+
123
+ def detect_package_output(argv)
124
+ packages = [ ]
125
+
126
+ if ENV['PACKAGE_OUTPUT'] == 'rpm'
127
+ packages << :rpm
128
+ elsif ENV['PACKAGE_OUTPUT'] == 'deb'
129
+ packages << :deb
130
+ else
131
+ # Debian is the default output
132
+ packages << :deb
133
+ end
134
+
135
+ puts 'Package output : %s' % packages.join(', ')
136
+ Packer.config[:packages] = packages
137
+
138
+ self
139
+ end
140
+
141
+ def run(argv)
142
+ detect_envs(argv)
143
+
144
+ $:.unshift(@build_path)
145
+ Dir.chdir(@build_path)
146
+
147
+ detect_specfile(argv)
148
+ detect_gemfile(argv)
149
+ detect_deps(argv)
150
+ detect_package_output(argv)
151
+
152
+ puts '=================='
153
+
154
+ Packer.setup
155
+ unless ENV['TEST_NOBUILD']
156
+ Packer.build_package
157
+ end
158
+ end
159
+
160
+ def say(msg)
161
+ puts msg
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,20 @@
1
+ require 'bundler'
2
+
3
+ module Packtory
4
+ class DebPackage
5
+ INSTALL_PREFIX = '/usr/lib/ruby/vendor_ruby/'
6
+
7
+ def self.build_package(opts = { })
8
+ packager = Packer.new(opts)
9
+ fpm_exec = FpmExec.new(packager, INSTALL_PREFIX)
10
+
11
+ sfiles_map = packager.prepare_files(INSTALL_PREFIX)
12
+ package_filename = '%s_%s_%s.deb' % [ packager.package_name, packager.version, packager.architecture ]
13
+ pkg_file_path = fpm_exec.build(sfiles_map, package_filename, type: :deb)
14
+
15
+ Bundler.ui.info 'Created package: %s (%s bytes)' % [ pkg_file_path, File.size(pkg_file_path) ]
16
+
17
+ [ packager, pkg_file_path ]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,92 @@
1
+ require 'bundler'
2
+
3
+ module Packtory
4
+ class FpmExec
5
+ def self.fpm_exec_path
6
+ if !Packer.config[:fpm_exec_path].nil? && !Packer.config[:fpm_exec_path].empty?
7
+ Packer.config[:fpm_exec_path]
8
+ else
9
+ fep = `which fpm`.strip
10
+ fep = 'fpm' if fep.empty?
11
+ fep
12
+ end
13
+ end
14
+
15
+ def initialize(packager, prefix_path)
16
+ @packager = packager
17
+ @prefix_path = prefix_path
18
+ end
19
+
20
+ def build(sfiles_map, package_file, opts = { })
21
+ pkg_file = File.join(@packager.pkg_path, package_file)
22
+ FileUtils.mkpath(File.dirname(pkg_file))
23
+
24
+ cmd = build_cmd(sfiles_map, pkg_file, opts)
25
+
26
+ Bundler.ui.info 'CMD: %s' % cmd
27
+ Bundler.clean_system('%s >/dev/null 2>&1' % cmd)
28
+
29
+ pkg_file
30
+ end
31
+
32
+ def build_cmd(sfiles_map, pkg_file, opts = { })
33
+ cmd = '%s --log warn -f -s dir' % self.class.fpm_exec_path
34
+
35
+ case opts[:type]
36
+ when :rpm
37
+ cmd << ' -t rpm --rpm-os linux'
38
+ when :deb
39
+ cmd << ' -t deb'
40
+ else
41
+ raise 'Unsupported type: %s' % opts[:type]
42
+ end
43
+
44
+ cmd << ' -a %s -m "%s" -n %s -v %s --description "%s" --url "%s" --license "%s" --vendor "%s"' %
45
+ [ @packager.architecture,
46
+ @packager.maintainer,
47
+ @packager.package_name,
48
+ @packager.version,
49
+ @packager.description,
50
+ @packager.homepage,
51
+ @packager.license,
52
+ @packager.author ]
53
+
54
+ cmd << ' -p %s --after-install %s --template-scripts %s %s %s' %
55
+ [ pkg_file,
56
+ after_install_script,
57
+ package_dependencies,
58
+ template_values,
59
+ source_files_map(sfiles_map) ]
60
+
61
+ cmd
62
+ end
63
+
64
+ def source_files_map(files)
65
+ files.inject([ ]) do |a, (k,v)|
66
+ a << '%s=%s' % [ k, v ]; a
67
+ end.join(' ')
68
+ end
69
+
70
+ def template_values
71
+ values = { 'pg_PACKAGE_PATH' => File.join(@prefix_path, @packager.package_name) }
72
+
73
+ values.collect do |k, v|
74
+ '--template-value %s="%s"' % [ k, v ]
75
+ end.join(' ')
76
+ end
77
+
78
+ def package_dependencies
79
+ @packager.opts[:dependencies].collect do |k, v|
80
+ if v.nil?
81
+ '-d %s' % k
82
+ else
83
+ '-d "%s%s"' % [ k, v ]
84
+ end
85
+ end.join(' ')
86
+ end
87
+
88
+ def after_install_script
89
+ File.expand_path('../../../bin/support/after_install_script', __FILE__)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,559 @@
1
+ require 'fileutils'
2
+ require 'bundler'
3
+
4
+ module Packtory
5
+ class Packer
6
+ BUNDLE_TARGET_PATH = 'bundle'
7
+ BUNDLE_EXTENSIONS_PATH = 'extensions'
8
+ BUNDLE_PACKTORY_TOOLS_PATH = 'packtory_tools'
9
+ BUNDLE_BUNDLER_SETUP_FILE = 'bundler/setup.rb'
10
+
11
+ PACKTORY_PACKFILE = 'Packfile'
12
+
13
+ DEFAULT_CONFIG = {
14
+ :path => nil,
15
+ :gemspec => nil,
16
+ :gemfile => nil,
17
+ :binstub => nil,
18
+ :packages => nil,
19
+ :architecture => 'all',
20
+
21
+ # maybe specified, if wanting to override as set in gemspec file
22
+ :package_name => nil,
23
+ :working_path => nil,
24
+
25
+ :dependencies => { },
26
+ :bundle_working_path => nil,
27
+
28
+ :fpm_exec_path => nil,
29
+ :bundler_silent => false,
30
+ :bundler_local => false
31
+ }
32
+
33
+ DEFAULT_PACKAGES = [ :deb, :rpm ]
34
+ DEFAULT_LOCAL_BIN_PATH = '/usr/local/bin'
35
+
36
+ PACKAGE_METHOD_MAP = {
37
+ :deb => :build_deb,
38
+ :rpm => :build_rpm
39
+ }
40
+
41
+ def self.load_patch
42
+ PatchBundlerNoMetadataDeps.patch!
43
+ end
44
+
45
+ def self.setup
46
+ load_patch
47
+ load_packfile
48
+ setup_defaults
49
+ end
50
+
51
+ def self.setup_defaults
52
+ if ENV.include?('PACKTORY_PACKAGES') && !ENV['PACKTORY_PACKAGES'].empty?
53
+ config[:packages] = ENV['PACKTORY_PACKAGES'].split(',').collect { |p| p.to_sym }
54
+ elsif config[:packages].nil?
55
+ config[:packages] = DEFAULT_PACKAGES
56
+ end
57
+
58
+ if ENV.include?('PACKTORY_BUNDLE_WORKING_PATH')
59
+ config[:bundle_working_path] = File.expand_path(ENV['PACKTORY_BUNDLE_WORKING_PATH'])
60
+ end
61
+
62
+ unless config[:dependencies].include?('ruby')
63
+ config[:dependencies]['ruby'] = nil
64
+ end
65
+ end
66
+
67
+ def self.load_packfile
68
+ packfile_path = nil
69
+
70
+ if ENV.include?('PACKTORY_PACKFILE')
71
+ packfile_path = File.expand_path(ENV['PACKTORY_PACKFILE'])
72
+ else
73
+ packfile_path = search_up(PACKTORY_PACKFILE)
74
+ end
75
+
76
+ unless packfile_path.nil?
77
+ load packfile_path
78
+ end
79
+
80
+ packfile_path
81
+ end
82
+
83
+ def self.search_up(*names)
84
+ previous = nil
85
+ current = File.expand_path(config[:path] || Dir.pwd).untaint
86
+ found_path = nil
87
+
88
+ until !File.directory?(current) || current == previous || !found_path.nil?
89
+ names.each do |name|
90
+ path = File.join(current, name)
91
+ if File.exists?(path)
92
+ found_path = path
93
+ break
94
+ end
95
+ end
96
+
97
+ if found_path.nil?
98
+ previous = current
99
+ current = File.expand_path("..", current)
100
+ end
101
+ end
102
+
103
+ found_path
104
+ end
105
+
106
+ def self.configure
107
+ yield config
108
+ end
109
+
110
+ def self.config
111
+ if defined?(@@global_config)
112
+ @@global_config
113
+ else
114
+ @@global_config = DEFAULT_CONFIG.merge({ })
115
+ end
116
+ end
117
+
118
+ def self.build_package(opts = { })
119
+ packages = config[:packages]
120
+ packages.each do |pack|
121
+ build_method = PACKAGE_METHOD_MAP[pack]
122
+ unless build_method.nil?
123
+ send(build_method, opts)
124
+ end
125
+ end
126
+ end
127
+
128
+ def self.build_deb(opts = { })
129
+ DebPackage.build_package(opts)
130
+ end
131
+
132
+ def self.build_rpm(opts = { })
133
+ RpmPackage.build_package(opts)
134
+ end
135
+
136
+ def self.silence_warnings
137
+ original_verbosity = $VERBOSE
138
+ $VERBOSE = nil
139
+ ret = yield
140
+ $VERBOSE = original_verbosity
141
+ ret
142
+ end
143
+
144
+ attr_reader :opts
145
+ attr_reader :gemfile
146
+ attr_reader :gemspec_file
147
+
148
+ def initialize(opts = { })
149
+ @opts = self.class.config.merge(opts)
150
+
151
+ unless @opts[:gemfile].nil?
152
+ @gemfile = Pathname.new(@opts[:gemfile])
153
+ else
154
+ @gemfile = nil
155
+ end
156
+
157
+ if @opts[:gemspec].nil?
158
+ @gemspec_file = find_default_gemspec_file
159
+ else
160
+ @gemspec_file = @opts[:gemspec]
161
+ end
162
+
163
+ if @gemfile.nil?
164
+ @gemfile = autogenerate_clean_gemfile
165
+ end
166
+
167
+ self
168
+ end
169
+
170
+ def find_default_gemspec_file
171
+ files = [ ]
172
+ try_paths = [ ]
173
+
174
+ unless @gemfile.nil?
175
+ try_paths << @gemfile.untaint.expand_path.parent.to_s
176
+ end
177
+
178
+ try_paths << root_path
179
+
180
+ try_paths.detect do |tpath|
181
+ files.concat(Dir.glob(File.join(tpath, '{,*}.gemspec')))
182
+ files.count > 0
183
+ end
184
+
185
+ unless files.empty?
186
+ File.expand_path(files.first)
187
+ else
188
+ nil
189
+ end
190
+ end
191
+
192
+ def bundler_definition
193
+ if defined?(@bundle_def)
194
+ @bundle_def
195
+ else
196
+ ENV['BUNDLE_GEMFILE'] = @gemfile.to_s
197
+
198
+ install_opts = { }
199
+ install_opts[:with] = [ :default ]
200
+ install_opts[:without] = [ :development, :test, :documentation ]
201
+ install_opts[:path] = bundle_working_path
202
+ install_opts[:retry] = 3
203
+ install_opts[:jobs] = 3
204
+
205
+ # in case, we are called multiple times
206
+ Bundler.reset!
207
+
208
+ if @opts[:bundler_silent]
209
+ Bundler.ui = Bundler::UI::Silent.new
210
+ else
211
+ Bundler.ui = Bundler::UI::Shell.new
212
+ Bundler.ui.info 'Bundling with: %s' % @gemfile.to_s
213
+ end
214
+
215
+ if @opts[:bundler_local]
216
+ install_opts[:local] = true
217
+ end
218
+
219
+ self.class.silence_warnings do
220
+ Bundler.settings.temporary(install_opts) do
221
+ @bundle_def = ::Bundler.definition
222
+ @bundle_def.validate_runtime!
223
+ end
224
+
225
+ Bundler.settings.temporary({ :no_install => true }.merge(install_opts)) do
226
+ Bundler::Installer.install(Bundler.root, @bundle_def, install_opts)
227
+ end
228
+ end
229
+
230
+ rubygems_dir = Bundler.rubygems.gem_dir
231
+ FileUtils.mkpath(File.join(rubygems_dir, 'specifications'))
232
+
233
+ @bundle_def.specs.each do |spec|
234
+ next unless spec.source.is_a?(Bundler::Source::Rubygems)
235
+
236
+ cached_gem = spec.source.send(:cached_gem, spec)
237
+ installer = Gem::Installer.at(cached_gem, :path => rubygems_dir)
238
+ installer.extract_files
239
+ installer.write_spec
240
+ end
241
+
242
+ @bundle_def
243
+ end
244
+ end
245
+
246
+ def gemspec
247
+ if defined?(@spec)
248
+ @spec
249
+ elsif !@gemspec_file.nil?
250
+ @spec = Gem::Specification.load(@gemspec_file)
251
+ else
252
+ @spec = nil
253
+ end
254
+ end
255
+
256
+ def autogenerate_clean_gemfile
257
+ FileUtils.mkpath(working_path)
258
+
259
+ gemfile_path = File.join(working_path, 'Gemfile')
260
+ File.open(gemfile_path, 'w') do |f|
261
+ gemfile_content = <<GEMFILE
262
+ source "http://rubygems.org"
263
+ gemspec :path => '%s', :name => '%s'
264
+ GEMFILE
265
+
266
+ gemfile_content = gemfile_content % [ File.dirname(@gemspec_file),
267
+ File.basename(@gemspec_file, '.gemspec') ]
268
+ f.write(gemfile_content)
269
+ end
270
+
271
+ Pathname.new(gemfile_path)
272
+ end
273
+
274
+ def root_path
275
+ if @opts[:path].nil?
276
+ File.expand_path('./')
277
+ else
278
+ @opts[:path]
279
+ end
280
+ end
281
+
282
+ def pkg_path
283
+ File.join(root_path, 'pkg')
284
+ end
285
+
286
+ def working_path
287
+ if @opts[:working_path].nil?
288
+ File.join(root_path, 'tmp/packtory_wp')
289
+ else
290
+ @opts[:working_path]
291
+ end
292
+ end
293
+
294
+ def bundle_working_path
295
+ @opts[:bundle_working_path] || File.join(working_path, 'bundle')
296
+ end
297
+
298
+ def package_working_path
299
+ File.join(working_path, 'package')
300
+ end
301
+
302
+ def package_name
303
+ if @opts[:package_name].nil?
304
+ gemspec.name
305
+ else
306
+ @opts[:package_name]
307
+ end
308
+ end
309
+
310
+ def version
311
+ gemspec.version
312
+ end
313
+
314
+ def description
315
+ gemspec.description.strip
316
+ end
317
+
318
+ def homepage
319
+ gemspec.homepage
320
+ end
321
+
322
+ def author
323
+ gemspec.authors.join(', ')
324
+ end
325
+
326
+ def license
327
+ gemspec.license
328
+ end
329
+
330
+ def maintainer
331
+ case gemspec.email
332
+ when Array
333
+ gemspec.email.first
334
+ when String
335
+ gemspec.email
336
+ else
337
+ nil
338
+ end
339
+ end
340
+
341
+ def architecture
342
+ @opts[:architecture]
343
+ end
344
+
345
+ def bundle_gems
346
+ bgems = { }
347
+ specs = bundler_definition.specs_for([ :default ])
348
+
349
+ specs.each do |spec|
350
+ if spec.name != 'bundler' && (gemspec.nil? || spec.name != gemspec.name)
351
+ orig_spec = spec
352
+ if spec.is_a?(Bundler::EndpointSpecification)
353
+ rs = spec.instance_variable_get(:@remote_specification)
354
+ if rs
355
+ spec = rs
356
+ elsif spec._local_specification
357
+ spec = spec._local_specification
358
+ end
359
+ end
360
+
361
+ bhash = { }
362
+
363
+ bhash[:orig_spec] = orig_spec
364
+ bhash[:spec] = spec
365
+ bhash[:gem_path] = spec.full_gem_path
366
+
367
+ bhash[:files] = Dir.glob(File.join(spec.full_gem_path, '**/*')).inject([ ]) { |a, f|
368
+ unless File.directory?(f)
369
+ a << f.gsub('%s/' % spec.full_gem_path, '')
370
+ end
371
+
372
+ a
373
+ }.uniq
374
+
375
+ bhash[:require_paths] = spec.full_require_paths.collect { |path|
376
+ path.include?(bhash[:gem_path]) ?
377
+ path.gsub(bhash[:gem_path], '') : nil
378
+ }.compact
379
+
380
+ bgems[spec.name] = bhash
381
+ end
382
+ end
383
+
384
+ bgems
385
+ end
386
+
387
+ def add_ruby_build_dependencies!
388
+ unless @opts[:dependencies].include?('ruby-dev')
389
+ @opts[:dependencies]['ruby-dev'] = @opts[:dependencies]['ruby']
390
+ end
391
+
392
+ unless @opts[:dependencies].include?('ruby-build')
393
+ @opts[:dependencies]['ruby-build'] = @opts[:dependencies]['ruby']
394
+ end
395
+
396
+ @opts[:dependencies]
397
+ end
398
+
399
+ def gather_files_for_package
400
+ files = { }
401
+
402
+ unless gemspec.nil?
403
+ (gemspec.files - gemspec.test_files).each do |fname|
404
+ next if File.directory?(fname)
405
+ fname = fname.gsub('%s/' % gemspec.full_gem_path, '')
406
+ files[fname] = fname
407
+ end
408
+ end
409
+
410
+ include_packtory_tools = false
411
+
412
+ bgems = bundle_gems
413
+ bgems.each do |gem_name, bhash|
414
+ bhash[:files].each do |file|
415
+ src_full_path = File.join(bhash[:gem_path], file)
416
+ files[src_full_path] = File.join(BUNDLE_TARGET_PATH, gem_name, file)
417
+ end
418
+
419
+ unless bhash[:spec].extensions.empty?
420
+ add_ruby_build_dependencies!
421
+ include_packtory_tools = true
422
+
423
+ files[bhash[:orig_spec].loaded_from] = File.join(BUNDLE_EXTENSIONS_PATH, '%s.gemspec' % gem_name)
424
+ end
425
+ end
426
+
427
+ if include_packtory_tools
428
+ files = gather_packtory_tools_for_package(files)
429
+ end
430
+
431
+ files
432
+ end
433
+
434
+ def gather_packtory_tools_for_package(files)
435
+ gem_build_extensions_path = Packtory.gem_build_extensions_path
436
+ target_tools_path = File.join(BUNDLE_PACKTORY_TOOLS_PATH)
437
+
438
+ files[gem_build_extensions_path] = File.join(target_tools_path, File.basename(gem_build_extensions_path))
439
+
440
+ files
441
+ end
442
+
443
+ def create_bundle_setup_rb
444
+ bundle_setup_file = File.join(BUNDLE_TARGET_PATH, BUNDLE_BUNDLER_SETUP_FILE)
445
+ bundle_setup_path = File.join(package_working_path, package_name, bundle_setup_file)
446
+
447
+ FileUtils.mkpath(File.dirname(bundle_setup_path))
448
+
449
+ bgems = bundle_gems
450
+ File.open(bundle_setup_path, 'w') do |f|
451
+ f.puts '# Adding require paths to load path (empty if no gems is needed)'
452
+ f.puts ''
453
+
454
+ bgems.each do |gem_name, bhash|
455
+ spec = bhash[:spec]
456
+ f.puts '# == Gem: %s, version: %s' % [ spec.name, spec.version ]
457
+
458
+ src_paths = bhash[:require_paths]
459
+ if src_paths.count > 0
460
+ rpaths = src_paths.dup
461
+ else
462
+ rpaths = [ '/lib' ]
463
+ end
464
+
465
+ rpaths.each do |rpath|
466
+ load_path_line = "$:.unshift File.expand_path('../../%s%s', __FILE__)" % [ gem_name, rpath ]
467
+ f.puts(load_path_line)
468
+ end
469
+ end
470
+ end
471
+
472
+ [ bundle_setup_file, bundle_setup_path ]
473
+ end
474
+
475
+ def gather_files
476
+ prefix_path = File.join(package_working_path, package_name)
477
+
478
+ if File.exists?(prefix_path)
479
+ FileUtils.rm_r(prefix_path)
480
+ end
481
+
482
+ FileUtils.mkpath(prefix_path)
483
+
484
+ files = gather_files_for_package
485
+ files.each do |fsrc, ftarget|
486
+ if fsrc =~ /^\//
487
+ fsrc_path = fsrc
488
+ else
489
+ fsrc_path = File.join(root_path, fsrc)
490
+ end
491
+
492
+ ftarget_path = File.join(prefix_path, ftarget)
493
+
494
+ FileUtils.mkpath(File.dirname(ftarget_path))
495
+ FileUtils.cp_r(fsrc_path, ftarget_path)
496
+ end
497
+
498
+ fsrc, ftarget = create_bundle_setup_rb
499
+ files[fsrc] = ftarget
500
+
501
+ files
502
+ end
503
+
504
+ def create_binstub(binstub_fname, prefix_path)
505
+ binstub_code = <<CODE
506
+ #!/usr/bin/env ruby
507
+
508
+ require "%s"
509
+ load "%s"
510
+ CODE
511
+
512
+ src_bin_path = File.join(package_working_path, 'bin', binstub_fname)
513
+ FileUtils.mkpath(File.dirname(src_bin_path))
514
+
515
+ bundler_setup_path = File.join(prefix_path, package_name, BUNDLE_TARGET_PATH, BUNDLE_BUNDLER_SETUP_FILE)
516
+
517
+ bindir_name = gemspec.nil? ? 'bin' : gemspec.bindir
518
+ actual_bin_path = File.join(prefix_path, package_name, bindir_name, binstub_fname)
519
+
520
+ File.open(src_bin_path, 'w') { |f| f.write(binstub_code % [ bundler_setup_path, actual_bin_path ]) }
521
+ FileUtils.chmod(0755, src_bin_path)
522
+
523
+ src_bin_path
524
+ end
525
+
526
+ def build_source_files(prefix_path)
527
+ files = { }
528
+
529
+ source_path = File.join(package_working_path, package_name, '/')
530
+ target_path = File.join(prefix_path, package_name)
531
+ files[source_path] = target_path
532
+
533
+ files
534
+ end
535
+
536
+ def prepare_files(prefix_path)
537
+ gather_files
538
+
539
+ files = build_source_files(prefix_path)
540
+
541
+ if @opts[:binstub].nil?
542
+ unless gemspec.nil? || gemspec.executables.nil? || gemspec.executables.empty?
543
+ @opts[:binstub] = { }
544
+
545
+ gemspec.executables.each do |exec_fname|
546
+ @opts[:binstub][exec_fname] = File.join(DEFAULT_LOCAL_BIN_PATH, exec_fname)
547
+ end
548
+ end
549
+ end
550
+
551
+ @opts[:binstub].each do |binstub_fname, binstub_file|
552
+ src_binstub_file = create_binstub(binstub_fname, prefix_path)
553
+ files[src_binstub_file] = binstub_file
554
+ end unless @opts[:binstub].nil?
555
+
556
+ files
557
+ end
558
+ end
559
+ end
@@ -0,0 +1,20 @@
1
+ require 'bundler/resolver/spec_group'
2
+ require 'bundler/installer'
3
+
4
+ module Packtory
5
+ module PatchBundlerNoMetadataDeps
6
+ def self.patch!
7
+ Bundler::Resolver::SpecGroup.class_eval do
8
+ alias :metadata_dependencies_without_patch :metadata_dependencies
9
+
10
+ def metadata_dependencies(spec, platform); return []; end
11
+ end
12
+
13
+ Bundler::Installer.class_eval do
14
+ alias :ensure_specs_are_compatible_without_path! :ensure_specs_are_compatible!
15
+
16
+ def ensure_specs_are_compatible!; end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,107 @@
1
+ module Packtory
2
+ class RakeTask < ::Rake::TaskLib
3
+ def self.install_tasks
4
+ new.define_tasks
5
+ end
6
+
7
+ def initialize(which = [ ])
8
+ @which = which
9
+
10
+ Packer.setup
11
+ detect_environment
12
+ end
13
+
14
+ def detect_environment
15
+ if defined?(::RSpec)
16
+ unless @which.include?(:spec_with_package)
17
+ @which << :spec_with_package
18
+ end
19
+ end
20
+
21
+ packages = Packer.config[:packages]
22
+ packages.each do |pack|
23
+ unless @which.include?(PACKAGE_METHOD_MAP)
24
+ @which << PACKAGE_METHOD_MAP[pack]
25
+ end
26
+ end
27
+
28
+ unless packages.empty?
29
+ @which << :build_package
30
+ end
31
+
32
+ @which
33
+ end
34
+
35
+ def define_tasks
36
+ @which.each do |task_name|
37
+ case task_name
38
+ when :build_package
39
+ desc 'Create all the packages'
40
+ task :build_package do
41
+ build_package
42
+ end
43
+ when :build_deb
44
+ desc 'Create a debian package'
45
+ task :build_deb do
46
+ build_deb
47
+ end
48
+ when :build_rpm
49
+ desc 'Create an RPM package'
50
+ task :build_rpm do
51
+ build_rpm
52
+ end
53
+ when :spec_with_package
54
+ desc 'Run RSpec code examples with package files'
55
+ task :spec_with_package do
56
+ spec_with_package
57
+ end
58
+ when :bundle_standalone
59
+ desc 'Execute bundle --standalone to download and install local copies of gems'
60
+ task :bundle_standalone do
61
+ bundle_standalone
62
+ end
63
+ else
64
+ # do nothing
65
+ end
66
+ end
67
+
68
+ self
69
+ end
70
+
71
+ def build_package
72
+ packages = Packer.config[:packages]
73
+ packages.each do |pack|
74
+ build_method = PACKAGE_METHOD_MAP[pack]
75
+ unless build_method.nil?
76
+ send(build_method)
77
+ end
78
+ end
79
+ end
80
+
81
+ def build_deb
82
+ puts 'Building DEB package file...'
83
+ packager, pkg_path = Packer.build_deb
84
+ puts 'Done creating DEB: %s' % pkg_path
85
+ end
86
+
87
+ def build_rpm
88
+ puts 'Building RPM package file...'
89
+ packager, pkg_path = Packer.build_rpm
90
+ puts 'Done creating RPM: %s' % pkg_path
91
+ end
92
+
93
+ def spec_with_package
94
+ prefix_path = Packer.config[:deb_prefix]
95
+
96
+ packager = Packer.new
97
+ sfiles_map = packager.prepare_files(prefix_path)
98
+
99
+ ENV['PACKTORY_WORKING_PATH'] = packager.working_path
100
+ Rake::Task['spec'].execute
101
+ end
102
+
103
+ def bundle_standalone
104
+ RakeTools.bundle_standalone
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,20 @@
1
+ require 'bundler'
2
+
3
+ module Packtory
4
+ class RpmPackage
5
+ INSTALL_PREFIX = '/usr/share/ruby/vendor_ruby/'
6
+
7
+ def self.build_package(opts = { })
8
+ packager = Packer.new(opts)
9
+ fpm_exec = FpmExec.new(packager, INSTALL_PREFIX)
10
+
11
+ sfiles_map = packager.prepare_files(INSTALL_PREFIX)
12
+ package_filename = '%s_%s_%s.rpm' % [ packager.package_name, packager.version, packager.architecture ]
13
+ pkg_file_path = fpm_exec.build(sfiles_map, package_filename, type: :rpm)
14
+
15
+ Bundler.ui.info 'Created package: %s (%s bytes)' % [ pkg_file_path, File.size(pkg_file_path) ]
16
+
17
+ [ packager, pkg_file_path ]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Packtory
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: packtory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark John Buenconsejo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: 'A packtory
28
+
29
+ '
30
+ email: hello@gemfury.com
31
+ executables:
32
+ - packtory
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - README.md
37
+ - bin/packtory
38
+ - bin/support/after_install_script
39
+ - bin/support/gem_build_extensions
40
+ - lib/packtory.rb
41
+ - lib/packtory/command.rb
42
+ - lib/packtory/deb_package.rb
43
+ - lib/packtory/fpm_exec.rb
44
+ - lib/packtory/packer.rb
45
+ - lib/packtory/patch_bundler_no_metadata_deps.rb
46
+ - lib/packtory/rake_task.rb
47
+ - lib/packtory/rpm_package.rb
48
+ - lib/packtory/version.rb
49
+ homepage: https://gemfury.com
50
+ licenses:
51
+ - MIT
52
+ metadata: {}
53
+ post_install_message: |
54
+ ************************************************************************
55
+
56
+ Heyyy, thank you for using packtory. Have fun!
57
+
58
+ ************************************************************************
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.7.7
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: A packtory
78
+ test_files: []