Posted by kev
Sun, 06 Apr 2008 00:13:00 GMT
Just drop this in your Rakefile. This is slightly modified from something I’m using in production.
Disect! Enjoy! Explanation (read: spoilers) after the jump.
begin
require 'rake_remote_task'
APP_NAME = "someapp"
DEPLOY_ROOT = "/usr/local/share/applications/#{APP_NAME}"
ON_DEPLOY_RESTART = ["someappd"]
role :app_server, "myserver.com"
def archive
commit = `git-rev-list --max-count=1 --abbrev=10 --abbrev-commit HEAD`.chomp
file = "#{APP_NAME}-#{commit}.tar.gz"
end
def restart_daemons
ON_DEPLOY_RESTART.each do |app|
run "sudo god restart #{app}"
end
end
namespace :deploy do
task :build do
sh "git archive --format=tar HEAD | gzip > #{archive}"
end
remote_task :push => :build do
rsync archive, "/tmp"
end
desc "Install a release from the latest commit"
remote_task :install => :push do
date_stamp = Time.now.strftime("%Y%m%d")
last_release = run("ls #{DEPLOY_ROOT}/rels | sort -r | head -n 1").chomp
if last_release =~ /#{date_stamp}\-(\d+)/
serial = $1.to_i + 1
else
serial = 0
end
rel = ("%d-%02d" % [date_stamp, serial])
rel_dir = "#{DEPLOY_ROOT}/rels/#{rel}"
run "sudo mkdir -p #{rel_dir}"
run "sudo tar -xzvf /tmp/#{archive} -C #{rel_dir} && rm -rf /tmp/#{archive}"
run "sudo ln -s -f -T #{rel_dir} #{DEPLOY_ROOT}/current"
restart_daemons
end
desc "Rollback to the previous release"
remote_task :rollback do
current_link = run("ls -alF #{DEPLOY_ROOT} | awk '/current -> .*/ { print $NF }'").chomp
current = File.basename(current_link)
releases = run("ls #{DEPLOY_ROOT}/rels | sort -r").split("\n")
previous = releases.find {|rel| current > rel}
raise "No previous release" if previous.nil?
run "sudo ln -s -f -T #{DEPLOY_ROOT}/rels/#{previous} #{DEPLOY_ROOT}/current"
restart_daemons
puts "Moved to #{previous}"
end
desc "Rollforward to the next release"
remote_task :rollforward do
current_link = run("ls -alF #{DEPLOY_ROOT} | awk '/current -> .*/ { print $NF }'").chomp
current = File.basename(current_link)
releases = run("ls #{DEPLOY_ROOT}/rels | sort -r").split("\n")
next_rel = releases.find {|rel| current < rel}
raise "No next release" if next_rel.nil?
run "sudo ln -s -f -T #{DEPLOY_ROOT}/rels/#{next_rel} #{DEPLOY_ROOT}/current"
restart_daemons
puts "Moved to #{next_rel}"
end
end
rescue LoadError => e
puts "NOTE: Install vlad to get Kevin's awesome deployment tasks"
end
Read more...
Posted in Ruby, Hacks | 4 comments
Posted by kev
Sun, 23 Dec 2007 01:24:00 GMT
This fails horribly.
The solution is to make sure you’re only building for your architecture:
Odysseus:ext kev$ sudo -s
bash-3.2# ARCHFLAGS='-arch i386' gem install postgres
Building native extensions. This could take a while...
Successfully installed postgres-0.7.9.2007.12.22
Installing ri documentation for postgres-0.7.9.2007.12.22...
Installing RDoc documentation for postgres-0.7.9.2007.12.22...
Posted in Ruby | 5 comments
Posted by kev
Mon, 10 Dec 2007 09:40:00 GMT
Reposted from my message to rubinius-dev. Congrats to the whole Rubinius team. This was entirely a group effort, and one hell of an achievement.
Here's the first Mongrel handler running on Rubinius:
http://pastie.caboo.se/paste/asset/126441/Picture_4.png
From this code:
$:.unshift "/Users/kev/code/mongrel/mongrel-1.1.1/lib"
puts "Requiring mongrel"
require 'mongrel'
class HelloHandler < Mongrel::HttpHandler
def process(request, response)
response.start(200) do |head, out|
head["Content-Type"] = "text/html"
out.write "Hello World! I'm running on Rubinius!"
end
end
end
server = Mongrel::HttpServer.new("0.0.0.0", 3000)
puts "Started Server"
server.register("/hello", HelloHandler.new)
puts "Registered handler"
t = server.run
t.join
***THE CATCH (as this may be viewed by many people)***
This isn't completely complete. rb_global_variable was #define'd out
to do nothing (so no garbage collection on the global vars), and there
was a slight modification from the trunk to make global aliasing
ignore the fact that the globals just weren't there. Mongrel's
http11.c was also _slightly (very very slightly)_ modified to use the
rb_str_get_char_* methods we've decided to move to from RSTRING()->ptr
and RSTRING()->len, and I haven't gotten around to defining ALLOC_N
yet, so it was changed to a simple malloc. That's it though.
And it seems to run. And I feel like I need to run around the block.
It's in 9976301ba.
WOOOOOOOOOOOOOOOOOOOOO!
Posted in Ruby | 4 comments
Posted by kev
Mon, 10 Dec 2007 06:03:00 GMT
Install the do_postgres gem against postgresql82 on MacPorts:
Make sure that /opt/local/lib/postgresql82/bin/ is in your path. You need pg_config easily accessible. Then run:
sudo gem install do_postgres -- --with-pgsql-include-dir=/opt/local/include/postgresql82/ --with-pgsql-lib=/opt/local/lib/postgresql82/
Autotest with Rspec on Merb with a Leopard install using the supplied Ruby (whew)
This will break because it can’t find the “spec command”. It searches the configured bin directory, which with the supplied ruby is /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin.
ln -s /usr/bin/spec /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/spec
Posted in Ruby | no comments
Posted by kev
Tue, 27 Nov 2007 19:24:00 GMT
Because I hadn’t implemented DFS in Ruby before, and it’s just so damn easy.
Update: Phillip rightly pointed out in the comments that with the yield at the end, it’s actually post-order traversal, not depth first search per se.
class TreeNode
attr_reader :name
def initialize(name)
@name = name
@children = []
end
def add_node(node)
@children << node
end
def each_depth_first
@children.each do |child|
child.each_depth_first do |c|
yield c
end
end
yield self
end
end
root = TreeNode.new("root")
root.add_node( a = TreeNode.new("a"))
a.add_node( b = TreeNode.new("b"))
a.add_node( c = TreeNode.new("c"))
c.add_node( d = TreeNode.new("d"))
root.add_node(e = TreeNode.new("e"))
e.add_node(f = TreeNode.new("f"))
e.add_node(g = TreeNode.new("g"))
root.each_depth_first do |child|
puts child.name
end
Posted in Ruby, Hacks | 3 comments
Posted by kev
Sat, 03 Nov 2007 15:04:00 GMT
They’re all up at once. Wow.
Mine felt good, but it’s long. Rather long. 50 minutes fairly non-stop, ~600 megs long. Find some time before watching.
Episode 036: The Return of Kevin Clark
Kevin Clark takes a break from Powerset to give a full-throttle talk
on using Merb as a JSON-RPC service, god, gem2rpm, and heckle.
Episode 035: ActiveRecord Backup & MimetypeFu
Matt Aimonetti demonstrates his newest plugins: ActiveRecord Backup
and MimetypeFu.
Episode 034: Intro to JRuby
Brian Chapados shows how to install and work with the latest JRuby
release.
Episode 033: Life on Edge
If you’re a Rails junkie, you’ll want to develop on Edge Rails. Matt
Clark explains how to get started and shares some of the challenges
of working on Edge.
Episode 032: Capistrano
Rob Kaufman takes on Capistrano 2. What is it? How does it work?
What’s changed since version 1?
Episode 031: Seaside
Roger Whitney explores Seaside, the web application framework based
on Smalltalk.
Episode 030: Tuneshelf
Dominic Damian talks about his experiences building Tuneshelf, a web
application that allows music fans to keep track of their favorite
music albums.
Episode 029: Big Stinking Piles (of data)
What do you do when third-party data vendors don’t speak REST? Rob
Kaufman discuss real-world techniques for importing and exporting
data. (This talk was also given at RailsConf 2007.)
Episode 028: Simple Sidebar Plugin
Ryan Felton shows how to use Simple Sidebar plugin to DRY up sidebar
content in applications.
Episode 027: Headliner and Styler
Patrick Crowley talks about his newest plugins: Headliner and Styler.
Episode 026: ActsAsSolr
Rob Kaufman shows how easy it is to integrate Solr powered search
into your Rails application using the ActsAsSolr plugin.
Episode 025: Ajax CSS Star Rating with ActsAsRateable
Ryan Felton shows off how to build an Ajax-powered, CSS star rater
using the ActsAsRateable plugin and Komodo Media’s CSS Star Rating
Redux technique.
Episode 024: Using Ruby + Amazon SQS to build backdoors
Brian Chapados talks about using Ruby and Amazon’s Simple Que Service
web service to build backdoors into systems.
Posted in Ruby, sd.rb | 2 comments
Posted by kev
Tue, 30 Oct 2007 01:16:00 GMT
I haven’t yet decided if this is a good idea or not.
I’ll be at RubyConf this weekend. Say hello, if you get the urge.
require "test/unit"
require 'rubygems'
require 'mocha'
require 'stubba'
module ForwardsToEnumerable
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def forward_to_enum(instance_var, *meths)
meths.each do |meth|
class_eval <<-METH
def #{meth}(*args, &block)
#{instance_var.to_s}.each do |i|
i.send(:#{meth}, *args, &block)
end
end
METH
end
end
end
end
class ForwardsToArray
include ForwardsToEnumerable
forward_to_enum :@array, :foo, :bar, :baz
def initialize(array)
@array = array
end
end
class TestForwardsToArray < Test::Unit::TestCase
def test_forward_to_enum
items = [mock(), mock(), mock()]
items.each {|i| i.expects(:foo); i.expects(:bar); i.expects(:baz) }
f = ForwardsToArray.new(items)
f.foo
f.bar
f.baz
end
end
Posted in Ruby, Hacks | no comments
Posted by kev
Fri, 21 Sep 2007 20:21:00 GMT
def <=>(other)
return 0 if self.version == other.version and self.rel == other.rel
versions = self.version.split(/[^[:alnum:]]/).push self.rel
other_versions = other.version.split(/[^[:alnum:]]/).push other.rel
return 1 if versions.size > other_versions.size
return -1 if versions.size < other_versions.size
versions.size.times do |n|
if versions[n] =~ /[^\d]/ && other_versions[n] =~ /[^\d]/
comparison = (versions[n] <=> other_versions[n])
elsif versions[n] !~ /[^\d]/ && other_versions[n] !~ /[^\d]/
comparison = (versions[n].to_i <=> other_versions[n].to_i)
else
comparison = -1
end
return comparison unless comparison.zero?
end
return 0
end
Original version sort was here.
Posted in Ruby, Hacks | no comments
Posted by kev
Fri, 17 Aug 2007 23:44:00 GMT
require 'yaml'
require 'pp'
pp YAML.load(`svn info`)
Posted in Ruby | 5 comments
Posted by kev
Wed, 25 Jul 2007 18:21:00 GMT
I hate the fact that googling syslog ruby didn’t turn up anything useful, and the rdoc doesn’t seem to be there. So, I’m posting the README from the extension in Ruby’s source. This is as much for me as for you. Using PageRank for good is.. well.. good I’d assume.
Read more...
Posted in Ruby, documentation