pkgr 0.3.4 → 1.0.1.pre

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.
Files changed (43) hide show
  1. data/README.md +68 -463
  2. data/bin/pkgr +4 -52
  3. data/lib/pkgr.rb +13 -29
  4. data/lib/pkgr/app.rb +19 -4
  5. data/lib/pkgr/builder.rb +207 -0
  6. data/lib/pkgr/buildpack.rb +80 -0
  7. data/lib/pkgr/cli.rb +34 -158
  8. data/lib/pkgr/config.rb +65 -0
  9. data/lib/pkgr/data/distributions/debian/build_dependencies.yml +14 -0
  10. data/lib/pkgr/data/{debian → distributions/debian}/cron.d +0 -0
  11. data/lib/pkgr/data/distributions/debian/default.erb +12 -0
  12. data/lib/pkgr/data/distributions/debian/dependencies.yml +17 -0
  13. data/lib/pkgr/data/distributions/debian/hooks/postinstall.sh +27 -0
  14. data/lib/pkgr/data/distributions/debian/hooks/preinstall.sh +9 -0
  15. data/lib/pkgr/data/{debian → distributions/debian}/logrotate.erb +0 -0
  16. data/lib/pkgr/data/distributions/debian/runner.erb +122 -0
  17. data/lib/pkgr/data/distributions/debian/upstart/master.conf.erb +7 -0
  18. data/lib/pkgr/data/distributions/debian/upstart/process.conf.erb +7 -0
  19. data/lib/pkgr/data/distributions/debian/upstart/process_master.conf.erb +2 -0
  20. data/lib/pkgr/dispatcher.rb +51 -0
  21. data/lib/pkgr/distributions.rb +18 -0
  22. data/lib/pkgr/distributions/debian.rb +157 -0
  23. data/lib/pkgr/git.rb +24 -0
  24. data/lib/pkgr/process.rb +18 -0
  25. data/lib/pkgr/templates/dir_template.rb +14 -0
  26. data/lib/pkgr/templates/file_template.rb +38 -0
  27. data/lib/pkgr/version.rb +1 -1
  28. metadata +93 -26
  29. data/lib/pkgr/data/debian/changelog +0 -0
  30. data/lib/pkgr/data/debian/compat.erb +0 -1
  31. data/lib/pkgr/data/debian/control.erb +0 -12
  32. data/lib/pkgr/data/debian/copyright.erb +0 -17
  33. data/lib/pkgr/data/debian/default.erb +0 -11
  34. data/lib/pkgr/data/debian/dirs.erb +0 -2
  35. data/lib/pkgr/data/debian/docs.erb +0 -0
  36. data/lib/pkgr/data/debian/init.d.erb +0 -155
  37. data/lib/pkgr/data/debian/install.erb +0 -16
  38. data/lib/pkgr/data/debian/links.erb +0 -5
  39. data/lib/pkgr/data/debian/postinst.erb +0 -59
  40. data/lib/pkgr/data/debian/prerm.erb +0 -57
  41. data/lib/pkgr/data/debian/rules.erb +0 -7
  42. data/lib/pkgr/pkgr.rake +0 -50
  43. data/lib/pkgr/railtie.rb +0 -7
data/bin/pkgr CHANGED
@@ -1,56 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'optparse'
4
- require 'pkgr/cli'
3
+ require "pkgr/cli"
5
4
 
6
- OPTIONS = {:dir => "./", :ref => "master", :reuse => false}
5
+ STDERR.sync = true
6
+ STDOUT.sync = true
7
7
 
8
- option_parser = OptionParser.new do |opts|
9
- opts.banner = <<BANNER
10
- * Description
11
- pkgr #{Pkgr::VERSION} - Package Rails apps effortlessly.
12
- * Usage
13
- pkgr --uri GIT_REPOSITORY --config database.yml:http://path/to/database.yml --config ...
14
- BANNER
15
-
16
- opts.separator ""
17
- opts.separator "* Common options"
18
- opts.on("--uri=", "Sets the Git repository URI (FILE, HTTP, SSH, GIT, etc.) [required]") do |v|
19
- OPTIONS[:uri] = v
20
- end
21
- opts.on("-c=", "--config=", "Download a configuration file into the config/ folder of the app (HTTP or FILE URIs)") do |v|
22
- OPTIONS[:config_files] ||= []
23
- OPTIONS[:config_files] << v
24
- end
25
- opts.on("-b=", "--bump=", "Sets the app version [required]") do |v|
26
- OPTIONS[:version] = v
27
- end
28
- opts.on("-n=", "--name=", "Sets the app name [optional]") do |v|
29
- OPTIONS[:name] = v
30
- end
31
- opts.on("--ref=", "Sets the git reference to checkout [default=#{OPTIONS[:ref]}]") do |v|
32
- OPTIONS[:ref] = v
33
- end
34
- opts.on("--host=", "Sets the build machine hostname. If none, the process will stop just before building the package.") do |v|
35
- OPTIONS[:host] = v
36
- end
37
-
38
- opts.separator ""
39
- opts.separator "* Other"
40
- opts.on_tail("-h", "--help", "Show this message") do
41
- puts opts
42
- exit
43
- end
44
- opts.on_tail("--version", "Show version") do
45
- puts Pkgr::VERSION
46
- exit
47
- end
48
- end.parse!
49
-
50
- begin
51
- cli = Pkgr::CLI.new(OPTIONS)
52
- cli.run
53
- rescue Pkgr::CLI::Error, StandardError => e
54
- puts e.message
55
- puts e.backtrace if $DEBUG
56
- end
8
+ Pkgr::CLI.start
data/lib/pkgr.rb CHANGED
@@ -1,35 +1,19 @@
1
- require 'pkgr/app'
2
- require 'pkgr/railtie' if defined?(Rails)
1
+ require 'pkgr/version'
2
+ require 'pkgr/cli'
3
+ require 'pkgr/dispatcher'
4
+ require 'mixlib/log'
3
5
 
4
6
  module Pkgr
5
- DEBIAN_DIR = "debian"
7
+ extend Mixlib::Log
6
8
 
7
- def self.setup(root)
8
- setup_config(root)
9
+ module Errors
10
+ class Base < StandardError; end
11
+ class UnknownAppType < Base; end
12
+ class ConfigurationInvalid < Base; end
9
13
  end
10
14
 
11
- protected
12
-
13
- def self.setup_config(root)
14
- puts "Setting up configuration file..."
15
- target = File.join(root, "config", "pkgr.yml")
16
- FileUtils.mkdir_p(File.dirname(target))
17
- if File.exist?(target)
18
- puts "'#{target}' already exists. Skipped."
19
- else
20
- FileUtils.cp(File.expand_path("../pkgr/data/pkgr.yml", __FILE__), target, :verbose => true)
21
- puts "Edit '#{target}' and fill in the required information, then enter 'rake pkgr:generate' to generate the debian files."
22
- end
23
- end
24
-
25
-
26
- def self.mkdir(target)
27
- if File.directory?(target)
28
- puts "#{target} directory already exists. Skipped."
29
- elsif File.file?(target)
30
- raise "#{target} already exists and is a file. Aborting."
31
- else
32
- FileUtils.mkdir_p target, :verbose => true
33
- end
15
+ def data_dir
16
+ File.expand_path("../pkgr/data", __FILE__)
34
17
  end
35
- end
18
+ module_function :data_dir
19
+ end
data/lib/pkgr/app.rb CHANGED
@@ -22,6 +22,7 @@ module Pkgr
22
22
  @config = YAML::load_file(path)
23
23
  raise ArgumentError, "The given configuration file at '#{path}' is not a well-formed YAML file. Please fix it or remove it and run 'rake pkgr:setup'" unless @config.kind_of?(Hash)
24
24
  @config['_path'] = path
25
+ normalize_name!
25
26
  end
26
27
 
27
28
  def write_config
@@ -215,8 +216,8 @@ module Pkgr
215
216
  #{debian_steps.join(" &&\n")}'
216
217
  }
217
218
  sh cmd
218
- # Fetch the .deb, and put it in the `pkg` directory
219
- sh "scp #{host}:/tmp/#{name}_#{version}*.deb pkg/"
219
+ # Fetch all package files, and put it in the `pkg` directory
220
+ sh "scp #{host}:/tmp/#{name}_#{version}* pkg/"
220
221
  end
221
222
  end
222
223
 
@@ -252,7 +253,7 @@ module Pkgr
252
253
 
253
254
  private
254
255
  def bundler_version
255
- @config.fetch('bundler_version') { '1.1.3' }
256
+ @config.fetch('bundler_version') { '1.3.5' }
256
257
  end
257
258
 
258
259
  def debian_file(filename)
@@ -260,5 +261,19 @@ module Pkgr
260
261
  raise "The debian/changelog file does not exist. Please generate it first." unless File.exist?(file)
261
262
  file
262
263
  end
264
+
265
+ def normalize_name!
266
+ # debian packages can not contain capitalized letters nor underscores
267
+ if (raw_name = @config.fetch('name', '')) =~ /[A-Z_-]/
268
+ normalized_name = raw_name.
269
+ gsub(/[A-Z]/) { |m| "_#{m.downcase}" }. # underscore each word
270
+ gsub(/[_-]+/, '-'). # normalize underscores/dashes
271
+ sub(/^-/, '') # strip leading dash
272
+ puts "Normalized application name to %s (original: %s)." % [
273
+ normalized_name.inspect, raw_name.inspect
274
+ ] unless normalized_name == raw_name
275
+ @config['name'] = normalized_name
276
+ end
277
+ end
263
278
  end
264
- end
279
+ end
@@ -0,0 +1,207 @@
1
+ require 'tempfile'
2
+ require 'fileutils'
3
+ require 'pkgr/config'
4
+ require 'pkgr/distributions'
5
+ require 'pkgr/process'
6
+
7
+ module Pkgr
8
+ class Builder
9
+ attr_reader :tarball, :config
10
+
11
+ # Accepts a path to a tarball (gzipped or not), or you can pass '-' to read from stdin.
12
+ def initialize(tarball, config)
13
+ @tarball = tarball
14
+ @config = config
15
+ Pkgr.debug "Initializing builder with the following config: #{config.inspect}"
16
+ end
17
+
18
+ # Launch the full packaging procedure
19
+ def call
20
+ check
21
+ setup
22
+ extract
23
+ compile
24
+ write_env
25
+ write_init
26
+ package
27
+ end
28
+
29
+ # Check configuration, and verifies that the current distribution's requirements are satisfied
30
+ def check
31
+ raise Errors::ConfigurationInvalid, config.errors.join("; ") unless config.valid?
32
+ distribution.check(config)
33
+ end
34
+
35
+ # Setup the build directory structure
36
+ def setup
37
+ Dir.chdir(build_dir) do
38
+ distribution.templates(config.name).each do |template|
39
+ template.install(config.sesame)
40
+ end
41
+ end
42
+ end
43
+
44
+ # Extract the given tarball to the target directory
45
+ def extract
46
+ raise "#{source_dir} does not exist" unless File.directory?(source_dir)
47
+
48
+ opts = {}
49
+ if tarball == "-"
50
+ # FIXME: not really happy with reading everything in memory
51
+ opts[:input] = $stdin.read
52
+ end
53
+
54
+ tarball_extract = Mixlib::ShellOut.new("tar xzf #{tarball} -C #{source_dir}", opts)
55
+ tarball_extract.run_command
56
+ tarball_extract.error!
57
+ end
58
+
59
+ # Pass the app through the buildpack
60
+ def compile
61
+ if buildpack_for_app
62
+ puts "-----> #{buildpack_for_app.banner} app"
63
+
64
+ FileUtils.mkdir_p(compile_cache_dir)
65
+
66
+ run_hook config.before_precompile
67
+ buildpack_for_app.compile(source_dir, compile_cache_dir)
68
+ buildpack_for_app.release(source_dir, compile_cache_dir)
69
+ else
70
+ raise Errors::UnknownAppType, "Can't find a buildpack for your app"
71
+ end
72
+ end
73
+
74
+ # Parses the output of buildpack/bin/release executable to find out its default Procfile commands.
75
+ # Then merges those with the ones from the app's Procfile (if any).
76
+ # Finally, generates a binstub in vendor/pkgr/processes/ so that these commands can be called using the app's executable.
77
+ def write_env
78
+ FileUtils.mkdir_p proc_dir
79
+
80
+ procfile_entries.each do |process|
81
+ process_file = File.join(proc_dir, process.name)
82
+
83
+ File.open(process_file, "w+") do |f|
84
+ f << process.command
85
+ f << " $@"
86
+ end
87
+
88
+ FileUtils.chmod 0755, process_file
89
+ end
90
+ end
91
+
92
+ # Write startup scripts.
93
+ def write_init
94
+ FileUtils.mkdir_p scaling_dir
95
+ Dir.chdir(scaling_dir) do
96
+ distribution.initializers_for(config.name, procfile_entries).each do |(process, file)|
97
+ process_config = config.dup
98
+ process_config.process_name = process.name
99
+ process_config.process_command = process.command
100
+ file.install(process_config.sesame)
101
+ end
102
+ end
103
+ end
104
+
105
+ # Launch the FPM command that will generate the package.
106
+ def package
107
+ Pkgr.info "Running command: #{fpm_command}"
108
+ app_package = Mixlib::ShellOut.new(fpm_command)
109
+ app_package.run_command
110
+ app_package.error!
111
+ end
112
+
113
+ # Make sure to get rid of the build directory
114
+ def teardown
115
+ FileUtils.rm_rf(build_dir)
116
+ end
117
+
118
+ def procfile_entries
119
+ @procfile_entries ||= begin
120
+ default_process_types = YAML.load_file(release_file)["default_process_types"]
121
+
122
+ entries = if File.exist?(procfile)
123
+ File.read(procfile).gsub("\r\n","\n").split("\n").map do |line|
124
+ if line =~ /^([A-Za-z0-9_]+):\s*(.+)$/
125
+ [$1, $2]
126
+ end
127
+ end.compact
128
+ else
129
+ []
130
+ end
131
+
132
+ default_process_types.merge(Hash[entries]).map{|name, command| Process.new(name, command)}
133
+ end
134
+ end
135
+
136
+ # Path to the release file generated after the buildpack compilation.
137
+ def release_file
138
+ File.join(source_dir, ".release")
139
+ end
140
+
141
+ # Path to the directory containing the main app files.
142
+ def source_dir
143
+ File.join(build_dir, "opt/#{config.name}")
144
+ end
145
+
146
+ # Build directory. Will be used by fpm to make the package.
147
+ def build_dir
148
+ @build_dir ||= Dir.mktmpdir
149
+ end
150
+
151
+ def vendor_dir
152
+ File.join(source_dir, "vendor", "pkgr")
153
+ end
154
+
155
+ # Directory where binstubs will be created for the corresponding Procfile commands.
156
+ def proc_dir
157
+ File.join(vendor_dir, "processes")
158
+ end
159
+
160
+ def scaling_dir
161
+ File.join(vendor_dir, "scaling")
162
+ end
163
+
164
+ # Returns the path to the app's (supposedly present) Procfile.
165
+ def procfile
166
+ File.join(source_dir, "Procfile")
167
+ end
168
+
169
+ # Directory where the buildpacks can store stuff.
170
+ def compile_cache_dir
171
+ config.compile_cache_dir || File.join(source_dir, ".git/cache")
172
+ end
173
+
174
+ # Returns the current distribution we're packaging for.
175
+ def distribution
176
+ @distribution ||= Distributions.current
177
+ end
178
+
179
+ # List of available buildpacks for the current distribution.
180
+ def buildpacks
181
+ distribution.buildpacks
182
+ end
183
+
184
+ # Buildpack detected for the app, if any.
185
+ def buildpack_for_app
186
+ raise "#{source_dir} does not exist" unless File.directory?(source_dir)
187
+ @buildpack_for_app ||= buildpacks.find do |buildpack|
188
+ buildpack.setup
189
+ buildpack.detect(source_dir)
190
+ end
191
+ end
192
+
193
+ def fpm_command
194
+ distribution.fpm_command(build_dir, config)
195
+ end
196
+
197
+ protected
198
+ def run_hook(file)
199
+ return true if file.nil?
200
+ Dir.chdir(source_dir) do
201
+ app_package = Mixlib::ShellOut.new("bash '#{file}'")
202
+ app_package.run_command
203
+ app_package.error!
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,80 @@
1
+ require 'fileutils'
2
+
3
+ module Pkgr
4
+ class Buildpack
5
+ class << self
6
+ attr_writer :buildpack_cache_dir
7
+
8
+ def buildpack_cache_dir
9
+ @buildpack_cache_dir ||= File.expand_path("~/.pkgr/buildpacks").tap do |dir|
10
+ FileUtils.mkdir_p(dir)
11
+ end
12
+ end
13
+ end
14
+
15
+ attr_reader :url, :banner
16
+
17
+ def initialize(url)
18
+ @url = url
19
+ end
20
+
21
+ def buildpack_cache_dir
22
+ self.class.buildpack_cache_dir
23
+ end
24
+
25
+ def detect(path)
26
+ buildpack_detect = Mixlib::ShellOut.new("#{dir}/bin/detect \"#{path}\"")
27
+ buildpack_detect.run_command
28
+ @banner = buildpack_detect.stdout.chomp
29
+ buildpack_detect.exitstatus == 0
30
+ end
31
+
32
+ def compile(path, compile_cache_dir)
33
+ Dir.chdir(path) do
34
+ IO.popen(%{ env -i PATH="$PATH" #{dir}/bin/compile "#{path}" "#{compile_cache_dir}" }) do |io|
35
+ until io.eof?
36
+ data = io.gets
37
+ print data
38
+ end
39
+ end
40
+ raise "compile failed" unless $?.exitstatus.zero?
41
+ end
42
+
43
+ true
44
+ end
45
+
46
+ def release(path, compile_cache_dir)
47
+ buildpack_release = Mixlib::ShellOut.new("#{dir}/bin/release \"#{path}\" \"#{compile_cache_dir}\" > #{path}/.release")
48
+ buildpack_release.run_command
49
+ buildpack_release.exitstatus == 0
50
+ end
51
+
52
+ def dir
53
+ File.join(buildpack_cache_dir, File.basename(url, ".git"))
54
+ end
55
+
56
+ def exists?
57
+ File.directory?(dir)
58
+ end
59
+
60
+ def setup
61
+ exists? ? refresh : install
62
+ end
63
+
64
+ def refresh
65
+ Dir.chdir(dir) do
66
+ buildpack_refresh = Mixlib::ShellOut.new("git fetch origin && git reset --hard origin/master")
67
+ buildpack_refresh.run_command
68
+ buildpack_refresh.error!
69
+ end
70
+ end
71
+
72
+ def install
73
+ Dir.chdir(buildpack_cache_dir) do
74
+ buildpack_install = Mixlib::ShellOut.new("git clone \"#{url}\"")
75
+ buildpack_install.run_command
76
+ buildpack_install.error!
77
+ end
78
+ end
79
+ end
80
+ end
data/lib/pkgr/cli.rb CHANGED
@@ -1,164 +1,40 @@
1
- require 'open-uri'
2
- require 'fileutils'
1
+ require "thor"
3
2
  require 'pkgr'
4
- require 'uri'
5
3
 
6
4
  module Pkgr
7
- class CLI
8
- include Rake::DSL
9
-
10
- class Error < StandardError; end
11
-
12
- attr_reader :errors
13
- attr_reader :uri
14
- attr_reader :dir
15
- attr_reader :config_files
16
- attr_reader :version
17
- attr_reader :name
18
- attr_reader :app
19
- attr_reader :host
20
- attr_reader :ref
21
-
22
- def initialize(opts = {})
23
- @errors = []
24
- @uri, @config_files, @version, @name, @host, @ref = opts.values_at(
25
- :uri, :config_files, :version, :name, :host, :ref
26
- )
27
- @app = nil
28
- end
29
-
30
- def run
31
- raise Error, "Can't run pkgr: #{errors.join(", ")}" unless valid?
32
- clone_repository
33
- Dir.chdir(dir) do
34
- checkout
35
- copy_remote_config_files
36
- copy_example_config_files
37
- setup
38
- bundle
39
- configure_app
40
- generate
41
- bump
42
- build
43
- end
44
- end
45
-
46
- def valid?
47
- @errors.clear
48
- @errors.push("You must pass a repository URI through --uri") if uri.nil?
49
- @errors.push("You must pass a version number through --bump") if version.nil?
50
- @errors.empty?
51
- end
52
-
53
- def build
54
- if host.nil?
55
- puts "Can't build the package. You must pass the --host option for this."
56
- else
57
- @app.build_debian_package(host)
58
- end
59
- end
60
-
61
- def bump
62
- @app.bump!(:custom, version)
63
- end
64
-
65
- def bundle
66
- sh "bundle install"
67
- sh "git add -f Gemfile.lock"
68
- sh "if git status --porcelain | grep Gemfile.lock; then git commit -m '[pkgr] Update Gemfile.lock.'; fi"
69
- end
70
-
71
- def checkout
72
- sh "if git branch | grep '#{pkgr_branch}'; then git checkout #{pkgr_branch}; else git checkout -b #{pkgr_branch} #{ref}; fi"
73
- end
74
-
75
- def clone_repository
76
- parsed_uri = URI.parse(uri)
77
- case parsed_uri.scheme
78
- when nil, "file"
79
- @dir = parsed_uri.path
80
- else
81
- @dir = File.basename(uri, ".git")
82
- sh "git clone #{uri}"
83
- end
84
- @dir = File.expand_path @dir
85
- end
86
-
87
- def configure_app
88
- @app = Pkgr::App.new(dir, "config/pkgr.yml")
89
- @app.config['git_ref'] = pkgr_branch
90
- @app.config['config_files'].push(*Dir["config/*.yml"].map{|f| File.basename(f)}).uniq!
91
- if name.nil?
92
- @app.config['name'] = File.basename(dir) if @app.name.nil?
93
- else
94
- @app.config['name'] = name
95
- end
96
- raise Error, "The app is not correctly configured: #{@app.errors.join(", ")}" unless @app.valid?
97
- @app.write_config
98
- end
99
-
100
- # Download the given config files
101
- def copy_remote_config_files
102
- (config_files || []).each do |file|
103
- filename, file_uri = file.split("::")
104
- if file_uri.nil?
105
- file_uri = filename
106
- filename = File.basename(file_uri)
107
- end
108
-
109
- file_uri = File.expand_path(file_uri) if URI.parse(file_uri).scheme.nil?
110
- target = "config/#{filename}"
111
- puts "Copying #{file_uri} into #{target}..."
112
- File.open(target, "w+") { |f| f << open(file_uri).read }
113
- end
114
- end
115
-
116
- def copy_example_config_files
117
- [".example", ".dist"].each do |pattern|
118
- Dir["config/*.yml#{pattern}"].each do |file|
119
- target = File.basename(file, pattern)
120
- unless File.exist?("config/#{target}")
121
- FileUtils.cp(file, "config/#{target}")
122
- end
123
- end
124
- end
125
- end
126
-
127
- def generate
128
- @app.generate_required_files
129
- sh "git add debian/"
130
- sh "if git status --porcelain | grep debian/; then git commit -m '[pkgr] Add debian files.'; fi"
131
- sh "git add bin/"
132
- sh "if git status --porcelain | grep bin/; then git commit -m '[pkgr] Add executable file.'; fi"
133
- end
134
-
135
- def pkgr_branch
136
- "pkgr-#{ref}"
137
- end
138
-
139
- def setup
140
- Pkgr.setup(dir)
141
-
142
- gemfile = File.read("Gemfile")
143
- unless gemfile =~ /^gem 'pkgr'/
144
- File.open("Gemfile", "a") do |f|
145
- f.puts
146
- f.puts "gem 'pkgr'"
147
- end
148
- end
149
-
150
- unless gemfile =~ /^gem 'thin'/
151
- File.open("Gemfile", "a") do |f|
152
- f.puts
153
- f.puts "gem 'thin'"
154
- end
155
- end
156
-
157
- sh "git add Gemfile"
158
- sh" if git status --porcelain | grep Gemfile; then git commit -m '[pkgr] Update Gemfile.'; fi"
159
- sh "git add -f config/*.yml"
160
- sh" if git status --porcelain | grep config/*.yml; then git commit -m '[pkgr] Update configuration files.'; fi"
5
+ class CLI < Thor
6
+ class_option :verbose, :type => :boolean, :default => false, :desc => "Run verbosely"
7
+ class_option :debug, :type => :boolean, :default => false, :desc => "Run very verbosely"
8
+ class_option :name, :type => :string, :desc => "Application name (if directory given, it will default to the directory name)"
9
+
10
+ desc "package TARBALL", "Package the given tarball or directory"
11
+
12
+ method_option :target, :type => :string, :default => "deb", :desc => "Target package to build (only 'deb' supported for now)"
13
+ method_option :changelog, :type => :string, :desc => "Changelog"
14
+ method_option :architecture, :type => :string, :default => "x86_64", :desc => "Target architecture for the package"
15
+ method_option :homepage, :type => :string, :desc => "Project homepage"
16
+ method_option :description, :type => :string, :desc => "Project description"
17
+ method_option :version, :type => :string, :desc => "Package version (if git directory given, it will use the latest git tag available)"
18
+ method_option :iteration, :type => :string, :default => Time.now.strftime("%Y%m%d%H%M%S"), :desc => "Package iteration (you should keep the default here)"
19
+ method_option :user, :type => :string, :desc => "User to run the app under (defaults to your app name)"
20
+ method_option :group, :type => :string, :desc => "Group to run the app under (defaults to your app name)"
21
+ method_option :compile_cache_dir, :type => :string, :desc => "Where to store the files cached between packaging runs"
22
+ method_option :dependencies, :type => :array, :default => [], :desc => "Specific system dependencies that you want to install with the package"
23
+ method_option :build_dependencies, :type => :array, :default => [], :desc => "Specific system dependencies that must be present before building"
24
+ method_option :before_precompile, :type => :string, :desc => "Provide a script to run just before the buildpack compilation"
25
+ method_option :host, :type => :string, :desc => "Remote host to build on (default: local machine)"
26
+ method_option :auto, :type => :boolean, :default => false, :desc => "Automatically attempt to install missing dependencies"
27
+
28
+ def package(tarball)
29
+ Pkgr.level = Logger::INFO if options[:verbose]
30
+ Pkgr.level = Logger::DEBUG if options[:debug]
31
+
32
+ packager = Dispatcher.new(tarball, options)
33
+ packager.call
34
+ rescue Pkgr::Errors::Base => e
35
+ Pkgr.error "#{e.class.name} : #{e.message}"
36
+ puts "* ERROR: #{e.message}"
37
+ exit 1
161
38
  end
162
39
  end
163
-
164
40
  end