Class: Pkgr::Builder
- Inherits:
-
Object
- Object
- Pkgr::Builder
- Defined in:
- lib/pkgr/builder.rb
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#tarball ⇒ Object
readonly
Returns the value of attribute tarball.
Instance Method Summary collapse
- #addons_dir ⇒ Object
-
#build_dir ⇒ Object
Build directory.
-
#buildpack_for_app ⇒ Object
Buildpack detected for the app, if any.
-
#buildpacks ⇒ Object
List of available buildpacks for the current distribution.
-
#call ⇒ Object
Launch the full packaging procedure.
-
#check ⇒ Object
Check configuration, and verifies that the current distribution’s requirements are satisfied.
-
#compile ⇒ Object
Pass the app through the buildpack.
-
#compile_cache_dir ⇒ Object
Directory where the buildpacks can store stuff.
- #config_file ⇒ Object
-
#distribution ⇒ Object
Returns the current distribution we’re packaging for.
-
#extract ⇒ Object
Extract the given tarball to the target directory.
- #fpm_command ⇒ Object
-
#initialize(tarball, config) ⇒ Builder
constructor
Accepts a path to a tarball (gzipped or not), or you can pass ‘-’ to read from stdin.
-
#package(remaining_attempts = 3) ⇒ Object
Launch the FPM command that will generate the package.
- #pipeline ⇒ Object
-
#proc_dir ⇒ Object
Directory where binstubs will be created for the corresponding Procfile commands.
-
#procfile ⇒ Object
Returns the path to the app’s (supposedly present) Procfile.
- #procfile_entries ⇒ Object
-
#release_file ⇒ Object
Path to the release file generated after the buildpack compilation.
- #scaling_dir ⇒ Object
-
#setup ⇒ Object
Setup the build directory structure.
-
#setup_addons ⇒ Object
LEGACY, remove once openproject no longer needs it If addons are declared in .pkgr.yml, add them.
-
#setup_crons ⇒ Object
Write cron files.
- #setup_pipeline ⇒ Object
-
#source_dir ⇒ Object
Path to the directory containing the main app files.
- #store_cache ⇒ Object
-
#teardown ⇒ Object
Make sure to get rid of the build directory.
-
#update_config ⇒ Object
Update existing config with the one from .pkgr.yml file, if any.
- #vendor_dir ⇒ Object
- #verify ⇒ Object
-
#write_env ⇒ Object
Parses the output of buildpack/bin/release executable to find out its default Procfile commands.
-
#write_init ⇒ Object
Write startup scripts.
Constructor Details
#initialize(tarball, config) ⇒ Builder
Accepts a path to a tarball (gzipped or not), or you can pass ‘-’ to read from stdin.
15 16 17 18 19 |
# File 'lib/pkgr/builder.rb', line 15 def initialize(tarball, config) @tarball = tarball @config = config Pkgr.debug "Initializing builder with the following config: #{config.inspect}" end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
12 13 14 |
# File 'lib/pkgr/builder.rb', line 12 def config @config end |
#tarball ⇒ Object (readonly)
Returns the value of attribute tarball.
12 13 14 |
# File 'lib/pkgr/builder.rb', line 12 def tarball @tarball end |
Instance Method Details
#addons_dir ⇒ Object
266 267 268 |
# File 'lib/pkgr/builder.rb', line 266 def addons_dir File.join(vendor_dir, "addons") end |
#build_dir ⇒ Object
Build directory. Will be used by fpm to make the package.
258 259 260 |
# File 'lib/pkgr/builder.rb', line 258 def build_dir @build_dir ||= Dir.mktmpdir end |
#buildpack_for_app ⇒ Object
Buildpack detected for the app, if any.
300 301 302 303 304 305 306 |
# File 'lib/pkgr/builder.rb', line 300 def buildpack_for_app raise "#{source_dir} does not exist" unless File.directory?(source_dir) @buildpack_for_app ||= buildpacks.find do |buildpack| buildpack.setup(config.edge, config.home) buildpack.detect(source_dir) end end |
#buildpacks ⇒ Object
List of available buildpacks for the current distribution.
295 296 297 |
# File 'lib/pkgr/builder.rb', line 295 def buildpacks distribution.buildpacks end |
#call ⇒ Object
Launch the full packaging procedure
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/pkgr/builder.rb', line 22 def call extract update_config check setup if config.installer setup_pipeline else setup_addons end compile write_env write_init setup_crons package store_cache ensure teardown if config.clean end |
#check ⇒ Object
Check configuration, and verifies that the current distribution’s requirements are satisfied
95 96 97 98 |
# File 'lib/pkgr/builder.rb', line 95 def check raise Errors::ConfigurationInvalid, config.errors.join("; ") unless config.valid? distribution.check end |
#compile ⇒ Object
Pass the app through the buildpack
127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/pkgr/builder.rb', line 127 def compile if buildpack_for_app puts "-----> #{buildpack_for_app.} app" FileUtils.mkdir_p(compile_cache_dir) run_hook config.before_hook buildpack_for_app.compile(source_dir, compile_cache_dir) buildpack_for_app.release(source_dir, compile_cache_dir) run_hook config.after_hook else raise Errors::UnknownAppType, "Can't find a buildpack for your app" end end |
#compile_cache_dir ⇒ Object
Directory where the buildpacks can store stuff.
285 286 287 |
# File 'lib/pkgr/builder.rb', line 285 def compile_cache_dir config.compile_cache_dir || File.join(source_dir, ".git/cache") end |
#config_file ⇒ Object
248 249 250 |
# File 'lib/pkgr/builder.rb', line 248 def config_file File.join(source_dir, ".pkgr.yml") end |
#distribution ⇒ Object
Returns the current distribution we’re packaging for.
290 291 292 |
# File 'lib/pkgr/builder.rb', line 290 def distribution @distribution ||= Distributions.current(config) end |
#extract ⇒ Object
Extract the given tarball to the target directory
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/pkgr/builder.rb', line 45 def extract FileUtils.mkdir_p source_dir opts = {} if tarball == "-" # FIXME: not really happy with reading everything in memory opts[:input] = $stdin.read end tarball_extract = Mixlib::ShellOut.new("tar xzf #{tarball} -C #{source_dir}", opts) tarball_extract.logger = Pkgr.logger tarball_extract.run_command tarball_extract.error! end |
#fpm_command ⇒ Object
308 309 310 |
# File 'lib/pkgr/builder.rb', line 308 def fpm_command distribution.fpm_command(build_dir) end |
#package(remaining_attempts = 3) ⇒ Object
Launch the FPM command that will generate the package.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/pkgr/builder.rb', line 190 def package(remaining_attempts = 3) app_package = Mixlib::ShellOut.new(fpm_command) app_package.logger = Pkgr.logger app_package.run_command app_package.error! begin verify rescue Mixlib::ShellOut::ShellCommandFailed => e if remaining_attempts > 0 package(remaining_attempts - 1) else raise end end end |
#pipeline ⇒ Object
84 85 86 87 88 89 90 91 92 |
# File 'lib/pkgr/builder.rb', line 84 def pipeline @pipeline ||= begin components = [] unless config.wizards.empty? || config.installer == false components << Installer.new(config.installer, distribution).setup end components end end |
#proc_dir ⇒ Object
Directory where binstubs will be created for the corresponding Procfile commands.
271 272 273 |
# File 'lib/pkgr/builder.rb', line 271 def proc_dir File.join(vendor_dir, "processes") end |
#procfile ⇒ Object
Returns the path to the app’s (supposedly present) Procfile.
280 281 282 |
# File 'lib/pkgr/builder.rb', line 280 def procfile File.join(source_dir, "Procfile") end |
#procfile_entries ⇒ Object
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/pkgr/builder.rb', line 223 def procfile_entries @procfile_entries ||= begin default_process_types = YAML.load_file(release_file)["default_process_types"] default_process_types = {} unless default_process_types entries = if File.exist?(procfile) File.read(procfile).gsub("\r\n","\n").split("\n").map do |line| if line =~ /^([A-Za-z0-9_]+):\s*(.+)$/ [$1, $2] end end.compact else [] end default_process_types.merge(Hash[entries]).map{|name, command| Process.new(name, command)} end end |
#release_file ⇒ Object
Path to the release file generated after the buildpack compilation.
244 245 246 |
# File 'lib/pkgr/builder.rb', line 244 def release_file File.join(source_dir, ".release") end |
#scaling_dir ⇒ Object
275 276 277 |
# File 'lib/pkgr/builder.rb', line 275 def scaling_dir File.join(vendor_dir, "scaling") end |
#setup ⇒ Object
Setup the build directory structure
101 102 103 104 105 106 107 |
# File 'lib/pkgr/builder.rb', line 101 def setup Dir.chdir(build_dir) do distribution.templates.each do |template| template.install(config.sesame) end end end |
#setup_addons ⇒ Object
LEGACY, remove once openproject no longer needs it If addons are declared in .pkgr.yml, add them
117 118 119 120 121 122 123 124 |
# File 'lib/pkgr/builder.rb', line 117 def setup_addons config.addons.each do |addon| puts "-----> [addon] #{addon.name} (#{addon.url} @ #{addon.branch})" addon.install!(source_dir) dependency = distribution.add_addon(addon) config.dependencies.push(dependency) if dependency end end |
#setup_crons ⇒ Object
Write cron files
176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/pkgr/builder.rb', line 176 def setup_crons crons_dir = File.join("/", distribution.crons_dir) config.crons.map! do |cron_path| Cron.new(File.(cron_path, config.home), File.join(crons_dir, File.basename(cron_path))) end config.crons.each do |cron| puts "-----> [cron] #{cron.source} => #{cron.destination}" end end |
#setup_pipeline ⇒ Object
109 110 111 112 113 |
# File 'lib/pkgr/builder.rb', line 109 def setup_pipeline pipeline.each do |component| @config = component.call(config) end end |
#source_dir ⇒ Object
Path to the directory containing the main app files.
253 254 255 |
# File 'lib/pkgr/builder.rb', line 253 def source_dir File.join(build_dir, config.home) end |
#store_cache ⇒ Object
211 212 213 214 215 216 |
# File 'lib/pkgr/builder.rb', line 211 def store_cache return true unless config.store_cache generate_cache_tarball = Mixlib::ShellOut.new %{tar czf cache.tar.gz -C #{compile_cache_dir} .} generate_cache_tarball.logger = Pkgr.logger generate_cache_tarball.run_command end |
#teardown ⇒ Object
Make sure to get rid of the build directory
219 220 221 |
# File 'lib/pkgr/builder.rb', line 219 def teardown FileUtils.rm_rf(build_dir) end |
#update_config ⇒ Object
Update existing config with the one from .pkgr.yml file, if any
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/pkgr/builder.rb', line 61 def update_config if File.exist?(config_file) Pkgr.debug "Loading #{distribution.slug} from #{config_file}." @config = Config.load_file(config_file, distribution.slug).merge(config) Pkgr.debug "Found .pkgr.yml file. Updated config is now: #{config.inspect}" # update distribution config distribution.config = @config # FIXME: make Config the authoritative source of the runner config (distribution only tells the default runner) if @config.runner type, *version = @config.runner.split("-") distribution.runner = Distributions::Runner.new(type, version.join("-")) end end config.distribution = distribution # required to build proper Addon objects config.addons_dir = addons_dir # useful for templates that need to read files config.source_dir = source_dir config.build_dir = build_dir end |
#vendor_dir ⇒ Object
262 263 264 |
# File 'lib/pkgr/builder.rb', line 262 def vendor_dir File.join(source_dir, "vendor", "pkgr") end |
#verify ⇒ Object
206 207 208 209 |
# File 'lib/pkgr/builder.rb', line 206 def verify return true unless config.verify distribution.verify(Dir.pwd) end |
#write_env ⇒ Object
Parses the output of buildpack/bin/release executable to find out its default Procfile commands. Then merges those with the ones from the app’s Procfile (if any). Finally, generates a binstub in vendor/pkgr/processes/ so that these commands can be called using the app’s executable.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/pkgr/builder.rb', line 145 def write_env FileUtils.mkdir_p proc_dir procfile_entries.each do |process| process_file = File.join(proc_dir, process.name) File.open(process_file, "w+") do |f| f.puts "#!/bin/sh" f << "exec " f << process.command f << " $@" end FileUtils.chmod 0755, process_file end end |
#write_init ⇒ Object
Write startup scripts.
163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/pkgr/builder.rb', line 163 def write_init FileUtils.mkdir_p scaling_dir Dir.chdir(scaling_dir) do distribution.initializers_for(config.name, procfile_entries).each do |(process, file)| process_config = config.dup process_config.process_name = process.name process_config.process_command = process.command file.install(process_config.sesame) end end end |