Permalink
Browse files

init

  • Loading branch information...
ddollar committed May 25, 2012
0 parents commit 899a4749c07565ce77fa701bc2e6dd98a7cf7e37
Showing 502 changed files with 68,165 additions and 0 deletions.
@@ -0,0 +1 @@
+.env
@@ -0,0 +1 @@
+web: bin/web
@@ -0,0 +1,25 @@
+# anvil
+
+Alternate Heroku push/deploy workflow.
+
+## Installation
+
+ $ heroku plugins:install https://github.com/ddollar/heroku-anvil
+
+## Usage
+
+#### Push your app
+
+ $ heroku push
+ Generating application manifest... done
+ Computing diff for upload... done
+ Uploading new files... done
+ Compiling...
+ Launching build slave
+ Buildpack: Buildkit+Node.js
+ -----> Compiling for Node.js
+ -----> Resolving engine versions
+ Using Node.js version: 0.6.12
+ Using npm version: 1.1.4
+ -----> Fetching Node.js binaries
+ ...
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+id=$1
+buildpack=$2
+
+# create a temporary compile directory
+compile_dir=$(mktemp -t compile_XXXXX)
+rm -rf $compile_dir
+mkdir -p $compile_dir
+
+# create a cache dir
+cache_dir=$(mktemp -t cache_XXXXX)
+rm -rf $cache_dir
+mkdir -p $cache_dir
+
+# fetching app
+cd $compile_dir
+curl -s $ANVIL_HOST/manifest/$id.tgz -o app.tgz
+tar xzf app.tgz
+rm app.tgz
+
+# fetch buildpack
+rm -rf .buildpack
+mkdir -p .buildpack
+cd .buildpack
+curl -s $buildpack -o- | tar xzf -
+cd ..
+
+# get buildpack name
+buildpack_name=$(.buildpack/bin/detect "$compile_dir")
+
+# abort if detect failes
+if [ $? -eq 0 ]; then
+ echo "Buildpack: ${buildpack_name}"
+else
+ echo "compile failed"
+ exit 1
+fi
+
+# compile
+cd $compile_dir
+.buildpack/bin/compile $compile_dir $cache_dir
10 bin/web
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+ROOT=$(dirname $(dirname $0))
+PATH="node_modules/.bin:$PATH"
+
+if [ "${NODE_ENV}" == "production" ]; then
+ exec coffee web.coffee
+else
+ exec nodemon -w . web.coffee
+fi
@@ -0,0 +1,92 @@
+async = require("async")
+fs = require("fs")
+knox = require("knox")
+mkdirp = require("mkdirp")
+path = require("path")
+spawn = require("child_process").spawn
+spawner = require("spawner").init()
+temp = require("temp")
+uuid = require("node-uuid")
+
+class Manifest
+
+ constructor: (@manifest) ->
+ @knox = knox.createClient
+ key: process.env.AWS_ACCESS,
+ secret: process.env.AWS_SECRET,
+ bucket: process.env.AWS_BUCKET
+
+ build: (cb) ->
+ id = uuid.v1()
+ buffer = new Buffer(JSON.stringify(@manifest), "binary")
+
+ buildpack = "https://buildkit.herokuapp.com/buildkit/example.tgz"
+
+ put = @knox.put "/manifest/#{id}", { "Content-Length":buffer.length, "Content-Type":"text/plain" }
+ put.on "response", (res) -> cb(spawner.spawn("bin/compile \"#{id}\" \"#{buildpack}\""))
+ put.end(buffer)
+
+ create_hash: (hash, stream, cb) ->
+ @knox.putStream stream, "/hash/#{hash}", (err, knox_res) ->
+ cb null
+
+ generate_tarball: (cb) ->
+ temp.mkdir "compile", (err, path) =>
+ async.parallel @datastore_fetchers(path), (err, results) ->
+ cb spawn("tar", ["czf", "-", "."], cwd:path)
+
+ missing_hashes: (cb) ->
+ async.parallel @datastore_testers(), (err, results) ->
+ missing = []
+ for hash, exists of results
+ missing.push(hash) unless exists
+ cb missing
+
+ test_datastore_presence: (hash, cb) ->
+ @knox.headFile "/hash/#{hash}", (err, res) ->
+ cb(res.statusCode != 404)
+
+ datastore_fetchers: (dir) ->
+ fetchers = {}
+ for name, file_manifest of @manifest
+ do (name, file_manifest) =>
+ fetchers[file_manifest.hash] = (async_cb) =>
+ filename = "#{dir}/#{name}"
+ mkdirp path.dirname(filename), =>
+ fs.open filename, "w", (err, fd) =>
+ @knox.getFile "/hash/#{file_manifest["hash"]}", (err, get) =>
+ console.log "writing:#{filename}"
+ get.setEncoding "binary"
+ get.on "data", (chunk) -> fs.write fd, chunk
+ get.on "end", ->
+ fs.fchmod fd, file_manifest.mode
+ fs.close fd
+ async_cb null, true
+
+ datastore_testers: ->
+ @hashes(@manifest).reduce (ax, hash) =>
+ ax[hash] = (async_cb) =>
+ @test_datastore_presence hash, (exists) ->
+ async_cb(null, exists)
+ ax
+ ,{}
+
+ hashes: (manifest) ->
+ object.hash for name, object of manifest
+
+module.exports.init = (manifest) ->
+ new Manifest(manifest)
+
+module.exports.init_with_id = (id, cb) ->
+ manifest = ""
+
+ subknox = knox.createClient
+ key: process.env.AWS_ACCESS,
+ secret: process.env.AWS_SECRET,
+ bucket: process.env.AWS_BUCKET
+
+ subknox.getFile "/manifest/#{id}", (err, get) =>
+ get.setEncoding "binary"
+ get.on "data", (chunk) -> manifest += chunk
+ get.on "end", (success) ->
+ cb(new Manifest(JSON.parse(manifest)))
@@ -0,0 +1,10 @@
+events = require("events")
+
+module.exports.inject = (object) ->
+ object.emitter = events.EventEmitter()
+
+ object.on = (key, handler) ->
+ object.emitter.on key, handler
+
+ object.emit = ->
+ object.emitter.emit arguments
@@ -0,0 +1,61 @@
+events = require("events")
+https = require("https")
+net = require("net")
+qs = require("querystring")
+restler = require("restler")
+spawn = require("child_process").spawn
+tls = require("tls")
+
+class Spawner
+
+ constructor: (env) ->
+ @env = env or process.env.SPAWN_ENV or "local"
+
+ spawn: (command, options, cb) ->
+ spawner = this["spawn_#{@env}"]
+ spawner command, options, cb
+
+ spawn_local: (command, options, cb) ->
+ args = command.match(/("[^"]*"|[^"]+)(\s+|$)/g)
+ command = args.shift().replace(/\s+$/g, "")
+ args = args.map (arg) -> arg.match(/"?([^"]*)"?/)[1]
+ proc = spawn command, args, env:process.env
+ emitter = new events.EventEmitter()
+
+ proc.stdout.on "data", (data) -> emitter.emit("data", data)
+ proc.stderr.on "data", (data) -> emitter.emit("data", data)
+ proc.on "exit", (code) -> emitter.emit("end", code)
+ emitter
+
+ spawn_heroku: (command, cb) ->
+ api_key = process.env.HEROKU_API_KEY
+ app = process.env.HEROKU_APP
+ emitter = new events.EventEmitter()
+
+ request = restler.post "https://api.heroku.com/apps/#{app}/ps",
+ headers:
+ "Authorization": new Buffer(":" + api_key).toString("base64")
+ "Accept": "application/json"
+ "User-Agent": "heroku-gem/2.5"
+ data:
+ attach: true
+ command: command
+
+ request.on "success", (data) ->
+ url = require("url").parse(data.rendezvous_url)
+ rendezvous = tls.connect url.port, url.hostname, ->
+ if rendezvous.authorized
+ console.log "valid socket"
+ rendezvous.write url.pathname.substring(1) + "\n"
+ else
+ console.log "invalid socket"
+ rendezvous.on "data", (data) -> console.log "data", data; emitter.emit("data", data) unless data.toString() is "rendezvous\r\n"
+ rendezvous.on "end", -> emitter.emit "end"
+
+ request.on "error", (error) ->
+ emitter.emit "error", error
+
+ emitter
+
+module.exports.init = (env) ->
+ new Spawner(env)

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit 899a474

Please sign in to comment.