diff --git a/Gemfile b/Gemfile index c80ee369..44d9cf77 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,14 @@ source "http://rubygems.org" gemspec + +group :development do + gem 'parka' + gem 'rake' + gem 'ronn' + gem 'fakefs', '~> 0.2.1' + gem 'rcov', '~> 0.9.8' + gem 'rr', '~> 1.0.2' + gem 'rspec', '~> 2.6.0' + gem "rubyzip" +end diff --git a/Gemfile.lock b/Gemfile.lock index 0ceba4d6..f184e794 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,6 +36,7 @@ GEM rspec-expectations (2.6.0) diff-lcs (~> 1.1.2) rspec-mocks (2.6.0) + rubyzip (0.9.4) term-ansicolor (1.0.6) thor (0.14.6) @@ -51,3 +52,4 @@ DEPENDENCIES ronn rr (~> 1.0.2) rspec (~> 2.6.0) + rubyzip diff --git a/Rakefile b/Rakefile index eeba521a..c1096054 100644 --- a/Rakefile +++ b/Rakefile @@ -54,3 +54,115 @@ task :pages => "man:commit" do git checkout master } end + +## dist + +require "erb" +require "fileutils" +require "tmpdir" + +def assemble(source, target, perms=0644) + FileUtils.mkdir_p(File.dirname(target)) + File.open(target, "w") do |f| + f.puts ERB.new(File.read(source)).result(binding) + end + File.chmod(perms, target) +end + +def assemble_distribution(target_dir=Dir.pwd) + distribution_files.each do |source| + target = source.gsub(/^#{project_root}/, target_dir) + FileUtils.mkdir_p(File.dirname(target)) + FileUtils.cp(source, target) + end +end + +GEM_BLACKLIST = %w( bundler foreman ) + +def assemble_gems(target_dir=Dir.pwd) + lines = %x{ bundle show }.strip.split("\n") + raise "error running bundler" unless $?.success? + + %x{ env BUNDLE_WITHOUT="development:test" bundle show }.split("\n").each do |line| + if line =~ /^ \* (.*?) \((.*?)\)/ + next if GEM_BLACKLIST.include?($1) + puts "vendoring: #{$1}-#{$2}" + gem_dir = %x{ bundle show #{$1} }.strip + FileUtils.mkdir_p "#{target_dir}/vendor/gems" + %x{ cp -R "#{gem_dir}" "#{target_dir}/vendor/gems" } + end + end.compact +end + +def beta? + Foreman::VERSION.to_s =~ /pre/ +end + +def clean(file) + rm file if File.exists?(file) +end + +def distribution_files + require "foreman/distribution" + Foreman::Distribution.files +end + +def mkchdir(dir) + FileUtils.mkdir_p(dir) + Dir.chdir(dir) do |dir| + yield(File.expand_path(dir)) + end +end + +def pkg(filename) + File.expand_path("../pkg/#{filename}", __FILE__) +end + +def project_root + File.dirname(__FILE__) +end + +def resource(name) + File.expand_path("../dist/resources/#{name}", __FILE__) +end + +def s3_connect + return if @s3_connected + + require "aws/s3" + + unless ENV["HEROKU_RELEASE_ACCESS"] && ENV["HEROKU_RELEASE_SECRET"] + puts "please set HEROKU_RELEASE_ACCESS and HEROKU_RELEASE_SECRET in your environment" + exit 1 + end + + AWS::S3::Base.establish_connection!( + :access_key_id => ENV["HEROKU_RELEASE_ACCESS"], + :secret_access_key => ENV["HEROKU_RELEASE_SECRET"] + ) + + @s3_connected = true +end + +def store(package_file, filename, bucket="assets.heroku.com") + s3_connect + puts "storing: #{filename}" + AWS::S3::S3Object.store(filename, File.open(package_file), bucket, :access => :public_read) +end + +def tempdir + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + yield(dir) + end + end +end + +def version + require "foreman/version" + Foreman::VERSION +end + +Dir[File.expand_path("../dist/**/*.rake", __FILE__)].each do |rake| + import rake +end diff --git a/dist/gem.rake b/dist/gem.rake new file mode 100644 index 00000000..1b22ae1d --- /dev/null +++ b/dist/gem.rake @@ -0,0 +1,14 @@ +file pkg("foreman-#{version}.gem") => distribution_files do |t| + sh "gem build foreman.gemspec" + sh "mv foreman-#{version}.gem #{t.name}" +end + +task "gem:build" => pkg("foreman-#{version}.gem") + +task "gem:clean" do + clean pkg("foreman-#{version}.gem") +end + +task "gem:release" => "gem:build" do |t| + sh "parka push -f #{pkg("foreman-#{version}.gem")}" +end diff --git a/dist/pkg.rake b/dist/pkg.rake new file mode 100644 index 00000000..d06a1347 --- /dev/null +++ b/dist/pkg.rake @@ -0,0 +1,52 @@ +require "erb" + +file pkg("foreman-#{version}.pkg") => distribution_files do |t| + tempdir do |dir| + mkchdir("foreman") do + assemble_distribution + assemble_gems + assemble resource("pkg/foreman"), "bin/foreman", 0755 + end + + kbytes = %x{ du -ks foreman | cut -f 1 } + num_files = %x{ find foreman | wc -l } + + mkdir_p "pkg" + mkdir_p "pkg/Resources" + mkdir_p "pkg/foreman-#{version}.pkg" + + dist = File.read(resource("pkg/Distribution.erb")) + dist = ERB.new(dist).result(binding) + File.open("pkg/Distribution", "w") { |f| f.puts dist } + + dist = File.read(resource("pkg/PackageInfo.erb")) + dist = ERB.new(dist).result(binding) + File.open("pkg/foreman-#{version}.pkg/PackageInfo", "w") { |f| f.puts dist } + + mkdir_p "pkg/foreman-#{version}.pkg/Scripts" + cp resource("pkg/postinstall"), "pkg/foreman-#{version}.pkg/Scripts/postinstall" + chmod 0755, "pkg/foreman-#{version}.pkg/Scripts/postinstall" + + sh %{ mkbom -s foreman pkg/foreman-#{version}.pkg/Bom } + + Dir.chdir("foreman") do + sh %{ pax -wz -x cpio . > ../pkg/foreman-#{version}.pkg/Payload } + end + + sh %{ pkgutil --flatten pkg foreman-#{version}.pkg } + + cp_r "foreman-#{version}.pkg", t.name + end +end + +task "pkg:build" => pkg("foreman-#{version}.pkg") + +task "pkg:clean" do + clean pkg("foreman-#{version}.pkg") +end + +task "pkg:release" => "pkg:build" do |t| + store pkg("foreman-#{version}.pkg"), "foreman/foreman-#{version}.pkg" + store pkg("foreman-#{version}.pkg"), "foreman/foreman-beta.pkg" if beta? + store pkg("foreman-#{version}.pkg"), "foreman/foreman.pkg" unless beta? +end diff --git a/dist/resources/tgz/foreman b/dist/resources/tgz/foreman new file mode 100644 index 00000000..6475debe --- /dev/null +++ b/dist/resources/tgz/foreman @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby + +require "pathname" +bin_file = Pathname.new(__FILE__).realpath + +gem_dir = File.expand_path("../vendor/gems", bin_file) + Dir["#{gem_dir}/**/lib"].each do |libdir| + $:.unshift libdir +end + +$:.unshift File.expand_path("../lib", bin_file) + +require "foreman/cli" + +Foreman::CLI.start diff --git a/dist/tgz.rake b/dist/tgz.rake new file mode 100644 index 00000000..1f6c8617 --- /dev/null +++ b/dist/tgz.rake @@ -0,0 +1,24 @@ +file pkg("foreman-#{version}.tgz") => distribution_files do |t| + tempdir do |dir| + mkchdir("foreman") do + assemble_distribution + assemble_gems + rm_rf "bin" + assemble resource("tgz/foreman"), "foreman", 0755 + end + + sh "tar czvf #{t.name} foreman" + end +end + +task "tgz:build" => pkg("foreman-#{version}.tgz") + +task "tgz:clean" do + clean pkg("foreman-#{version}.tgz") +end + +task "tgz:release" => "tgz:build" do |t| + store pkg("foreman-#{version}.tgz"), "foreman/foreman-#{version}.tgz" + store pkg("foreman-#{version}.tgz"), "foreman/foreman-beta.tgz" if beta? + store pkg("foreman-#{version}.tgz"), "foreman/foreman.tgz" unless beta? +end diff --git a/foreman.gemspec b/foreman.gemspec index b6222866..aee7e83c 100644 --- a/foreman.gemspec +++ b/foreman.gemspec @@ -18,12 +18,4 @@ Gem::Specification.new do |gem| gem.add_dependency 'term-ansicolor', '~> 1.0.5' gem.add_dependency 'thor', '>= 0.13.6' - - gem.add_development_dependency 'parka' - gem.add_development_dependency 'rake' - gem.add_development_dependency 'ronn' - gem.add_development_dependency 'fakefs', '~> 0.2.1' - gem.add_development_dependency 'rcov', '~> 0.9.8' - gem.add_development_dependency 'rr', '~> 1.0.2' - gem.add_development_dependency 'rspec', '~> 2.6.0' end diff --git a/lib/foreman/distribution.rb b/lib/foreman/distribution.rb new file mode 100644 index 00000000..2d5650e7 --- /dev/null +++ b/lib/foreman/distribution.rb @@ -0,0 +1,9 @@ +module Foreman + module Distribution + def self.files + Dir[File.expand_path("../../../{bin,data,lib}/**/*", __FILE__)].select do |file| + File.file?(file) + end + end + end +end