Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: v98
Fetching contributors…

Cannot retrieve contributors at this time

282 lines (234 sloc) 7.881 kb
require "fileutils"
require "tmpdir"
require 'hatchet/tasks'
S3_BUCKET_NAME = "heroku-buildpack-ruby"
VENDOR_URL = "https://s3.amazonaws.com/#{S3_BUCKET_NAME}"
def s3_tools_dir
File.expand_path("../support/s3", __FILE__)
end
def s3_upload(tmpdir, name)
sh("#{s3_tools_dir}/s3 put #{S3_BUCKET_NAME} #{name}.tgz #{tmpdir}/#{name}.tgz")
end
def vendor_plugin(git_url, branch = nil)
name = File.basename(git_url, File.extname(git_url))
Dir.mktmpdir("#{name}-") do |tmpdir|
FileUtils.rm_rf("#{tmpdir}/*")
Dir.chdir(tmpdir) do
sh "git clone #{git_url} ."
sh "git checkout origin/#{branch}" if branch
FileUtils.rm_rf("#{name}/.git")
sh("tar czvf #{tmpdir}/#{name}.tgz *")
s3_upload(tmpdir, name)
end
end
end
def in_gem_env(gem_home, &block)
old_gem_home = ENV['GEM_HOME']
old_gem_path = ENV['GEM_PATH']
ENV['GEM_HOME'] = ENV['GEM_PATH'] = gem_home.to_s
yield
ENV['GEM_HOME'] = old_gem_home
ENV['GEM_PATH'] = old_gem_path
end
def install_gem(gem, version)
name = "#{gem}-#{version}"
Dir.mktmpdir("#{gem}-#{version}") do |tmpdir|
Dir.chdir(tmpdir) do |dir|
FileUtils.rm_rf("#{tmpdir}/*")
in_gem_env(tmpdir) do
sh("unset RUBYOPT; gem install #{gem} --version #{version} --no-ri --no-rdoc --env-shebang")
sh("rm #{gem}-#{version}.gem")
sh("rm -rf cache/#{gem}-#{version}.gem")
sh("tar czvf #{tmpdir}/#{name}.tgz *")
s3_upload(tmpdir, name)
end
end
end
end
desc "update plugins"
task "plugins:update" do
vendor_plugin "http://github.com/heroku/rails_log_stdout.git", "legacy"
vendor_plugin "http://github.com/pedro/rails3_serve_static_assets.git"
vendor_plugin "http://github.com/hone/rails31_enable_runtime_asset_compilation.git"
end
desc "install vendored gem"
task "gem:install", :gem, :version do |t, args|
gem = args[:gem]
version = args[:version]
install_gem(gem, version)
end
desc "generate ruby versions manifest"
task "ruby:manifest" do
require 'rexml/document'
require 'yaml'
document = REXML::Document.new(`curl https://#{S3_BUCKET_NAME}.s3.amazonaws.com`)
rubies = document.elements.to_a("//Contents/Key").map {|node| node.text }.select {|text| text.match(/^(ruby|rbx|jruby)-\\\\d+\\\\.\\\\d+\\\\.\\\\d+(-p\\\\d+)?/) }
Dir.mktmpdir("ruby_versions-") do |tmpdir|
name = 'ruby_versions.yml'
File.open(name, 'w') {|file| file.puts(rubies.to_yaml) }
sh("#{s3_tools_dir}/s3 put #{S3_BUCKET_NAME} #{name} #{name}")
end
end
namespace :buildpack do
require 'netrc'
require 'excon'
require 'json'
require 'time'
require 'cgi'
require 'git'
require 'fileutils'
require 'digest/md5'
require 'securerandom'
def connection
@connection ||= begin
user, password = Netrc.read["api.heroku.com"]
Excon.new("https://#{CGI.escape(user)}:#{password}@buildkits.herokuapp.com")
end
end
def latest_release
@latest_release ||= begin
buildpack_name = "heroku/ruby"
response = connection.get(path: "buildpacks/#{buildpack_name}/revisions")
releases = JSON.parse(response.body)
# {
# "tar_link": "https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/ruby-v84.tgz",
# "created_at": "2013-11-06T18:55:04Z",
# "published_by": "richard@heroku.com",
# "id": 84
# }
releases.map! do |a|
a["created_at"] = Time.parse(a["created_at"])
a
end.sort! { |a,b| b["created_at"] <=> a["created_at"] }
releases.first
end
end
def new_version
@new_version ||= "v#{latest_release["id"] + 1}"
end
desc "increment buildpack version"
task :increment do
version_file = './lib/language_pack/version'
require './lib/language_pack'
require version_file
if LanguagePack::Base::BUILDPACK_VERSION != new_version
git = Git.open(".")
stashes = nil
if git.status.changed.any?
stashes = Git::Stashes.new(git)
stashes.save("WIP")
end
File.open("#{version_file}.rb", 'w') do |file|
file.puts <<-FILE
require "language_pack/base"
# This file is automatically generated by rake
module LanguagePack
class LanguagePack::Base
BUILDPACK_VERSION = "#{new_version}"
end
end
FILE
end
git.add "#{version_file}.rb"
git.commit "bump to #{new_version}"
stashes.pop if stashes
puts "Bumped to #{new_version}"
else
puts "Already on #{new_version}"
end
end
def changelog_entry?
File.read("./CHANGELOG.md").split("\n").any? {|line| line.match(/^## #{new_version}/) }
end
desc "check if there's a changelog for the new version"
task :changelog do
if changelog_entry?
puts "Changelog for #{new_version} exists"
else
puts "Please add a changelog entry for #{new_version}"
end
end
desc "stage a tarball of the buildpack"
task :stage do
Dir.mktmpdir("heroku-buildpack-ruby") do |tmpdir|
Git.clone(File.expand_path("."), 'heroku-buildpack-ruby', path: tmpdir)
Dir.chdir(tmpdir) do |dir|
streamer = lambda do |chunk, remaining_bytes, total_bytes|
File.open("ruby.tgz", "w") {|file| file.print(chunk) }
end
Excon.get(latest_release["tar_link"], :response_block => streamer)
Dir.chdir("heroku-buildpack-ruby") do |dir|
sh "tar xzf ../ruby.tgz .env"
sh "tar czf ../buildpack.tgz * .env"
end
@digest = Digest::MD5.hexdigest(File.read("buildpack.tgz"))
end
filename = "buildpacks/#{@digest}.tgz"
puts "Writing to #{filename}"
FileUtils.mkdir_p("buildpacks/")
FileUtils.cp("#{tmpdir}/buildpack.tgz", filename)
FileUtils.cp("#{tmpdir}/buildpack.tgz", "buildpacks/buildpack.tgz")
end
end
def multipart_form_data(buildpack_file_path)
body = ''
boundary = SecureRandom.hex(4)
data = File.open(buildpack_file_path)
data.binmode if data.respond_to?(:binmode)
data.pos = 0 if data.respond_to?(:pos=)
body << "--#{boundary}" << Excon::CR_NL
body << %{Content-Disposition: form-data; name="buildpack"; filename="#{File.basename(buildpack_file_path)}"} << Excon::CR_NL
body << 'Content-Type: application/x-gtar' << Excon::CR_NL
body << Excon::CR_NL
body << File.read(buildpack_file_path)
body << Excon::CR_NL
body << "--#{boundary}--" << Excon::CR_NL
{
:headers => { 'Content-Type' => %{multipart/form-data; boundary="#{boundary}"} },
:body => body
}
end
desc "publish buildpack"
task :publish do
buildpack_name = "heroku/ruby"
puts "Publishing #{buildpack_name} buildpack"
resp = connection.post(multipart_form_data("buildpacks/buildpack.tgz").merge(path: "/buildpacks/#{buildpack_name}"))
puts resp.status
puts resp.body
end
desc "tag a release"
task :tag do
git = Git.open(".")
remote = git.remotes.detect {|remote| remote.url.match(%r{heroku/heroku-buildpack-ruby.git$}) }
puts "Pushing master"
git.push(remote, 'master', false)
tagged_version =
if @new_version.nil?
"v#{latest_release["id"]}"
else
new_version
end
git.add_tag(tagged_version)
puts "Created tag #{tagged_version}"
puts "Pushing tag to remote #{remote}"
git.push(remote, nil, true)
end
desc "release a new version of the buildpack"
task :release do
Rake::Task["buildpack:increment"].invoke
raise "Please add a changelog entry for #{new_version}" unless changelog_entry?
Rake::Task["buildpack:stage"].invoke
Rake::Task["buildpack:publish"].invoke
Rake::Task["buildpack:tag"].invoke
end
end
begin
require 'rspec/core/rake_task'
desc "Run specs"
RSpec::Core::RakeTask.new(:spec) do |t|
t.rspec_opts = %w(-fs --color)
#t.ruby_opts = %w(-w)
end
task :default => :spec
rescue LoadError => e
end
Jump to Line
Something went wrong with that request. Please try again.