packtory 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.
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: []