Skip to content
This repository has been archived by the owner on Oct 26, 2018. It is now read-only.

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
ddollar committed Sep 4, 2012
0 parents commit 5a35ae3
Show file tree
Hide file tree
Showing 30 changed files with 2,125 additions and 0 deletions.
7 changes: 7 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright (c) 2012 David Dollar

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# heroku-push

Push to Heroku without using Git.

## Installation

$ heroku plugins:install https://github.com/ddollar/heroku-push

## Usage

Usage: heroku push [SOURCE]

deploy code to heroku

if SOURCE is a local directory, the contents of the directory will be built
if SOURCE is a git URL, the contents of the repo will be built
if SOURCE is a tarball URL, the contents of the tarball will be built

SOURCE will default to "."

-b, --buildpack URL # use a custom buildpack
18 changes: 18 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
desc "Revendor"
task :revendor do
FileUtils.rm_rf File.join(root, "vendor")

vendor "anvil", "https://github.com/ddollar/anvil-cli.git"
vendor "progress", "https://github.com/toy/progress.git"
end

def root
File.dirname(__FILE__)
end

def vendor(name, git)
system "git clone #{git} vendor/#{name}"
Dir[File.join(root, "vendor", name, "**", ".git")].each do |dir|
FileUtils.rm_rf dir
end
end
6 changes: 6 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Dir[File.join(File.expand_path("../vendor", __FILE__), "*")].each do |vendor|
$:.unshift File.join(vendor, "lib")
end

require "push/heroku/client"
require "push/heroku/command/push"
22 changes: 22 additions & 0 deletions lib/push/heroku/client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Heroku::Client

# valid options:
#
# slug_url: url to a slug
#
def release(app_name, description, options={})
release_options = { :description => description }.merge(options)
json_decode(releases_api["/apps/#{app_name}/release"].post(release_options))
end

private

def releases_host
ENV["RELEASES_HOST"] || "https://releases-production.herokuapp.com"
end

def releases_api
RestClient::Resource.new(releases_host, Heroku::Auth.user, Heroku::Auth.password)
end

end
73 changes: 73 additions & 0 deletions lib/push/heroku/command/push.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require "anvil/engine"
require "cgi"
require "digest/sha2"
require "heroku/command/base"
require "net/https"
require "pathname"
require "progress"
require "tmpdir"
require "uri"

# deploy code
#
class Heroku::Command::Push < Heroku::Command::Base

# push [SOURCE]
#
# deploy code to heroku
#
# if SOURCE is a local directory, the contents of the directory will be built
# if SOURCE is a git URL, the contents of the repo will be built
# if SOURCE is a tarball URL, the contents of the tarball will be built
#
# SOURCE will default to "."
#
# -b, --buildpack URL # use a custom buildpack
#
def index
source = shift_argument || "."
validate_arguments!
release_to = app # validate that we have an app

user = api.post_login("", Heroku::Auth.password).body["email"]

slug_url = Anvil::Engine.build source, :buildpack => options[:buildpack]

action("Releasing to #{app}") do
begin
release = heroku.release(app, "Pushed by #{user}", :slug_url => slug_url)
status release["release"]
rescue RestClient::Forbidden => ex
error ex.http_body
end
end
rescue Anvil::Builder::BuildError => ex
puts "ERROR: Build failed, #{ex.message}"
exit 1
end

private

def is_url?(string)
URI.parse(string).scheme rescue nil
end

def prepare_buildpack(buildpack)
if buildpack == ""
buildpack
elsif is_url?(buildpack)
buildpack
elsif buildpack =~ /\A\w+\/\w+\Z/
"http://buildkits-dev.s3.amazonaws.com/buildpacks/#{buildpack}.tgz"
elsif File.exists?(buildpack) && File.directory?(buildpack)
print "Uploading buildpack... "
manifest = Anvil::Manifest.new(buildpack)
manifest.upload
manifest.save
puts "done"
else
error "unrecognized buildpack specification: #{buildpack}"
end
end

end
1 change: 1 addition & 0 deletions vendor/anvil/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pkg
3 changes: 3 additions & 0 deletions vendor/anvil/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source :rubygems

gemspec
22 changes: 22 additions & 0 deletions vendor/anvil/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
PATH
remote: .
specs:
anvil-cli (0.3.1)
progress (~> 2.4.0)
rest-client (~> 1.6.7)
thor (~> 0.15.2)

GEM
remote: http://rubygems.org/
specs:
mime-types (1.19)
progress (2.4.0)
rest-client (1.6.7)
mime-types (>= 1.16)
thor (0.15.4)

PLATFORMS
ruby

DEPENDENCIES
anvil-cli!
21 changes: 21 additions & 0 deletions vendor/anvil/anvil-cli.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
$:.unshift File.expand_path("../lib", __FILE__)
require "anvil/version"

Gem::Specification.new do |gem|
gem.name = "anvil-cli"
gem.version = Anvil::VERSION

gem.author = "David Dollar"
gem.email = "david@dollar.io"
gem.homepage = "http://github.com/ddollar/anvil-cli"
gem.summary = "Alternate Heroku build workflow"

gem.description = gem.summary

gem.executables = "anvil"
gem.files = Dir["**/*"].select { |d| d =~ %r{^(README|bin/|data/|ext/|lib/|spec/|test/)} }

gem.add_dependency "progress", "~> 2.4.0"
gem.add_dependency "rest-client", "~> 1.6.7"
gem.add_dependency "thor", "~> 0.15.2"
end
7 changes: 7 additions & 0 deletions vendor/anvil/bin/anvil
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env ruby

$:.unshift File.expand_path("../../lib", __FILE__)

require "anvil/cli"

Anvil::CLI.start
2 changes: 2 additions & 0 deletions vendor/anvil/lib/anvil.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module Anvil
end
69 changes: 69 additions & 0 deletions vendor/anvil/lib/anvil/builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require "anvil"
require "anvil/helpers"
require "net/http"
require "net/https"
require "rest_client"

class Anvil::Builder

include Anvil::Helpers

class BuildError < StandardError; end

attr_reader :source

def initialize(source)
@source = source
end

def build(options={})
uri = URI.parse("#{anvil_host}/build")
http = Net::HTTP.new(uri.host, uri.port)

if uri.scheme == "https"
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end

req = Net::HTTP::Post.new uri.request_uri

req.set_form_data({
"buildpack" => options[:buildpack],
"cache" => options[:cache],
"env" => json_encode(options[:env] || {}),
"source" => source
})

slug_url = nil

http.request(req) do |res|
slug_url = res["x-slug-url"]

begin
res.read_body do |chunk|
yield chunk
end
rescue EOFError
puts
raise BuildError, "terminated unexpectedly"
end

manifest_id = [res["x-manifest-id"]].flatten.first
code = Integer(String.new(anvil["/exit/#{manifest_id}"].get.to_s))
raise BuildError, "exited #{code}" unless code.zero?
end

slug_url
end

private

def anvil
@anvil ||= RestClient::Resource.new(anvil_host)
end

def anvil_host
ENV["ANVIL_HOST"] || "https://api.anvilworks.org"
end

end
31 changes: 31 additions & 0 deletions vendor/anvil/lib/anvil/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require "anvil"
require "anvil/builder"
require "anvil/engine"
require "anvil/manifest"
require "anvil/version"
require "progress"
require "thor"
require "uri"

class Anvil::CLI < Thor

map ["-v", "--version"] => :version

desc "build [SOURCE]", "Build an application"

method_option :buildpack, :type => :string, :aliases => "-b", :desc => "Use a specific buildpack"
method_option :pipeline, :type => :boolean, :aliases => "-p", :desc => "Pipe compile output to stderr and put the slug url on stdout"

def build(source=nil)
Anvil::Engine.build(source, options)
rescue Anvil::Builder::BuildError => ex
error "Build Error: #{ex.message}"
end

desc "version", "Display Anvil version"

def version
Anvil::Engine.version
end

end
Loading

0 comments on commit 5a35ae3

Please sign in to comment.