technomancy-harker 0.0.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ === 0.5.0 / 2009-03-30
2
+
3
+ * Use gem's config/database.yml for a base.
4
+ * Gemifying existing apps works now.
5
+ * Accept arguments for script/server when starting app.
6
+
1
7
  === 0.0.3 / 2009-03-26
2
8
 
3
9
  * A release!
data/Manifest.txt CHANGED
@@ -7,6 +7,9 @@ lib/harker.rb
7
7
  lib/harker/gemify.rb
8
8
  lib/harker/rails_configuration.rb
9
9
  lib/harker/server.rb
10
+ lib/harker/templates/bin.erb
11
+ lib/harker/templates/hoe.erb
12
+ lib/harker/templates/lib.erb
10
13
  test/sample/Manifest.txt
11
14
  test/sample/README.rdoc
12
15
  test/sample/Rakefile
@@ -31,8 +34,6 @@ test/sample/config/locales/en.yml
31
34
  test/sample/config/routes.rb
32
35
  test/sample/db/migrate/20090326050232_create_harks.rb
33
36
  test/sample/lib/sample_rails.rb
34
- test/sample/log/development.log
35
- test/sample/log/test.log
36
37
  test/sample/public/404.html
37
38
  test/sample/public/422.html
38
39
  test/sample/public/500.html
@@ -61,4 +62,5 @@ test/sample/test/performance/browsing_test.rb
61
62
  test/sample/test/test_helper.rb
62
63
  test/sample/test/unit/hark_test.rb
63
64
  test/sample/test/unit/helpers/harks_helper_test.rb
65
+ test/test_gemify.sh
64
66
  test/test_harker.rb
data/README.rdoc CHANGED
@@ -7,12 +7,31 @@ http://github.com/technomancy/harker
7
7
  Harker means Rails deployments via RubyGems--because a package manager
8
8
  is a terrible thing to waste.
9
9
 
10
+ == Motivation
11
+
12
+ This will mean you can use the same infrastructure you already rely on
13
+ for your dependencies to manage your application itself. It means
14
+ never having to keep a checkout of your app just for deployment. It
15
+ also becomes very easy to see what versions are installed on a given
16
+ box and run multiple instances (of the same or different versions) at
17
+ the same time on different ports.
18
+
19
+ Your app code will live in your gem home, but all the files specific
20
+ to a given instance will live in an instance directory.
21
+
22
+ In short: you've already got a package manager. Why are you handling
23
+ installation of your deployed apps with a one-off tool?
24
+
10
25
  == Setup
11
26
 
12
27
  Your Rails app will need to be modified a bit to become a gem and work
13
- with Harker. Running "harker /path/to/rails/app" will attempt to turn
14
- it into a gem that uses Hoe. It probably won't be perfect, but it's a
15
- start. See the app in test/sample/ for an example of how this works.
28
+ with Harker. But don't worry, these modifications will improve your
29
+ app and make it more awesome. Running "harker /path/to/rails/app" will
30
+ attempt to turn it into a gem that uses Hoe. You may need to perform a
31
+ bit of tweaking in order to get it to build cleanly since every app is
32
+ different--see the one in test/sample/ for an example of how this
33
+ works. In particular, be sure Manifest.txt does not include any files
34
+ that shouldn't go in the gem, such as pid or log files.
16
35
 
17
36
  You don't have to use Hoe if you want to turn your app into a gem
18
37
  manually or using another library, but it helps.
@@ -23,21 +42,24 @@ Once your app is a gem, install it locally with "rake install_gem",
23
42
  and you should be able to use the bin wrapper to generate a new
24
43
  instance:
25
44
 
26
- $ your_app init /var/myapp
45
+ $ your_app init ~/apps/your_app_3000
27
46
 
28
47
  Then edit /var/myapp/database.yml with your database settings. At that
29
48
  point you should be able to bring up your database:
30
49
 
31
- $ RAILS_ENV=production your_app migrate /var/myapp
50
+ $ your_app migrate ~/apps/your_app_3000
32
51
 
33
52
  Test it out by dropping into the console:
34
53
 
35
- $ RAILS_ENV=production your_app console /var/myapp
54
+ $ your_app console ~/apps/your_app_3000
36
55
 
37
56
  Then you can start and stop your application server via Rack:
38
57
 
39
- $ RAILS_ENV=production your_app start /var/myapp
40
- $ RAILS_ENV=production your_app stop /var/myapp
58
+ $ your_app start ~/apps/your_app_3000 --daemon
59
+ $ your_app stop ~/apps/your_app_3000
60
+
61
+ To configure the web server, create a config.ru file in your instance
62
+ directory, and Rails will pick that up with Rack.
41
63
 
42
64
  If you omit the second argument, it defaults to the current directory.
43
65
 
@@ -45,8 +67,6 @@ For deployment, simply publish your gem to a gem server (public or
45
67
  private), install it on the target server, and launch it via the bin
46
68
  wrappers.
47
69
 
48
- TODO: automate /etc/init.d scripts?
49
-
50
70
  == Requirements
51
71
 
52
72
  * rails (at least 2.3.2)
@@ -58,6 +78,12 @@ TODO: automate /etc/init.d scripts?
58
78
 
59
79
  * sudo gem install technomancy-harker --source=http://gems.github.com --source=http://gems.rubyforge.org
60
80
 
81
+ == Todo
82
+
83
+ * rake tasks for remotely installing gem
84
+ * make it easy to "rake release" to a private gem repo
85
+ * test, test, test. try it out with more rails apps!
86
+
61
87
  == License
62
88
 
63
89
  Copyright (c) 2009 Phil Hagelberg.
data/bin/harker CHANGED
@@ -6,11 +6,11 @@ begin
6
6
  gem 'hoe'
7
7
  rescue LoadError
8
8
  abort 'Hoe not found. You can continue without hoe if you gemify
9
- your app yourself; see Harker documentation for details.' # TODO: document!
9
+ your app yourself; see Harker documentation for details.'
10
10
  end
11
11
 
12
12
  if ARGV.include?('-h') or ARGV.include?('--help') or ARGV.size > 1
13
- puts "Usage: #{File.dirname($0)} [RAILS_ROOT]"
13
+ puts "Usage: #{File.basename($0)} [RAILS_ROOT]"
14
14
  puts
15
15
  puts "Attempts to turn your Rails app into a gem for deployment with harker."
16
16
  exit
data/lib/harker.rb CHANGED
@@ -1,9 +1,14 @@
1
1
  require 'fileutils'
2
2
 
3
3
  # Harker lets you deploy Rails apps via RubyGems.
4
+ #
5
+ # These commands get invoked by the bin wrapper of the rails app gem
6
+ # rather than by Harker itself.
7
+ #
4
8
  module Harker
5
- VERSION = '0.0.3'
6
- ACTIONS = %w(start stop restart init migrate console foreground)
9
+ VERSION = '0.5.0'
10
+ ACTIONS = %w(start stop restart init migrate console)
11
+ GEM_ROOT = Gem.loaded_specs[File.basename($0)].full_gem_path rescue '.'
7
12
 
8
13
  module_function
9
14
 
@@ -12,31 +17,35 @@ module Harker
12
17
  action = args.shift
13
18
 
14
19
  unless ACTIONS.include?(action)
15
- abort "Usage: #{@name} INSTANCE_DIR (#{ACTIONS.join('|')})"
20
+ abort "Usage: #{name} INSTANCE_DIR (#{ACTIONS.join('|')}).
21
+ The start command takes the same arguments as script/server."
16
22
  end
17
23
 
18
- @root = File.expand_path(args.shift || Dir.pwd)
24
+ # We need to get rid of the first arg if it's the optional
25
+ # instance directory so script/server doesn't get confused.
26
+ @root = if File.directory? args.first.to_s or action == 'init'
27
+ File.expand_path args.shift
28
+ else
29
+ Dir.pwd
30
+ end
31
+
19
32
  @name = name
20
33
 
21
- load_app unless action == 'init'
22
- self.send(action)
23
- end
34
+ unless action == 'init'
35
+ # 2.3.2 doesn't support tmp_dir config option; needs a monkeypatch.
36
+ require 'harker/rails_configuration'
37
+ require @name
38
+ end
24
39
 
25
- # Start the application server in the foreground.
26
- def foreground
27
- start(false)
40
+ self.send(action)
28
41
  end
29
42
 
30
- # Start and daemonize the application server
31
- def start(daemonize = true)
32
- # can has internal consistency plz, Rails?
33
- Rails::Rack::LogTailer::EnvironmentLog.replace(Rails.configuration.log_path)
43
+ # Start and optionally daemonize the application server
44
+ def start
34
45
  # http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2350
35
46
  # Submitted a patch to Rails, but this lets it work with 2.3.2
47
+ Rails::Rack::LogTailer::EnvironmentLog.replace(Rails.configuration.log_path)
36
48
 
37
- ARGV.replace ["--config=#{@root}/config.ru"]
38
- ARGV.push('--daemon') if daemonize
39
-
40
49
  abort "Can't start; pidfile exists at #{pidfile}." if File.exist? pidfile
41
50
  require 'harker/server'
42
51
  end
@@ -48,6 +57,7 @@ module Harker
48
57
 
49
58
  def restart
50
59
  stop
60
+ rescue SystemExit
51
61
  start
52
62
  end
53
63
 
@@ -56,28 +66,34 @@ module Harker
56
66
  FileUtils.mkdir_p(@root)
57
67
  FileUtils.mkdir_p(@root + '/log')
58
68
  FileUtils.mkdir_p(@root + '/tmp')
69
+ FileUtils.mkdir_p(@root + '/db') # In case we use sqlite.
70
+
71
+ base_db_file = File.join(GEM_ROOT, 'config', 'database.yml')
59
72
 
60
- # TODO: use the in-gem copy of database.yml as a base for this
61
73
  File.open("#{@root}/database.yml", 'w') do |fp|
62
- # TODO: be smart about environments; bleh
63
- fp.puts({ 'production' => { 'adapter' => 'sqlite3',
64
- 'database' => @root + '/db.sqlite3',
65
- 'pool' => 5, 'timeout' => 5000 }}.to_yaml)
74
+ # Need to make sure any sqlite3 DB paths are absolute.
75
+ db_config = YAML.load_file(base_db_file)
76
+ db_config.each do |env, hash|
77
+ if hash['adapter'] =~ /sqlite3?/
78
+ hash['database'] = File.join(@root, hash['database'])
79
+ end
80
+ end
81
+
82
+ fp.puts(db_config.to_yaml)
66
83
  end
67
84
 
68
- # TODO: write a default config.ru?
69
-
70
85
  puts "Initialized #{@name} instance in #{@root}..."
71
86
  puts
72
87
  puts "Configure your database by editing #{@root}/database.yml."
73
88
  puts "Optionally configure your web server via rack in #{@root}/config.ru."
74
89
  puts
75
90
  puts "Migrate your DB with: #{@name} migrate"
76
- puts "Then launch with: #{@name} start"
91
+ puts "Then launch with: #{@name} start --daemon"
77
92
  end
78
93
 
79
94
  def migrate
80
- ActiveRecord::Migrator.migrate(RAILS_ROOT + '/db/migrate',
95
+ puts "Migrating the #{RAILS_ENV} environment of #{@name}..."
96
+ ActiveRecord::Migrator.migrate(File.join(Rails.root, 'db', 'migrate'),
81
97
  ENV["VERSION"] && ENV["VERSION"].to_i)
82
98
  end
83
99
 
@@ -89,16 +105,9 @@ module Harker
89
105
  def configure(config)
90
106
  config.database_configuration_file = File.join(@root, 'database.yml')
91
107
  config.log_path = File.join(@root, 'log', "#{RAILS_ENV}.log")
92
-
93
- # 2.3.2 doesn't support tmp_dir config option.
94
- require 'harker/rails_configuration' unless config.respond_to?(:tmp_dir=)
95
108
  config.tmp_dir = File.join(@root, '/tmp')
96
109
  end
97
110
 
98
- def load_app
99
- require @name
100
- end
101
-
102
111
  def pidfile
103
112
  File.join(@root, 'tmp', 'pids', 'server.pid')
104
113
  end
data/lib/harker/gemify.rb CHANGED
@@ -1,40 +1,44 @@
1
1
  require 'harker'
2
+ require 'fileutils'
3
+ require 'erb'
2
4
 
3
5
  module Harker
6
+ # Turn an existing Rails app into a gem.
4
7
  def self.gemify(rails_root)
5
- project_name = File.basename(rails_root)
8
+ @project_name = File.basename(rails_root)
6
9
 
7
- if File.exist?(rails_root + "/bin/#{project_name}", 'w') or
8
- File.exist?(rails_root + "/lib/#{project_name}.rb", 'w')
10
+ if File.exist?(rails_root + "/bin/#{@project_name}") or
11
+ File.exist?(rails_root + "/lib/#{@project_name}.rb")
9
12
  abort "Can't write gem files without overwriting existing ones.
10
13
  Try manually gemifying."
11
14
  end
12
15
 
13
- # TODO: can we specify the version better?
14
- hoe = "Hoe.new('#{project_name}', '1.0.0') do |p|
15
- p.extra_deps << ['rails', '~> 2.3.2']
16
- p.extra_deps << ['harker', '~> #{Harker::VERSION}']
17
- p.developer('Your Name', 'you@example.com') # FIXME!
18
- end"
19
-
20
- bin = "#!/usr/bin/env ruby
21
- require 'rubygems'
22
- require 'harker'
16
+ File.open(File.join(rails_root, '/Rakefile'), 'a') do |fp|
17
+ fp.puts template('hoe')
18
+ puts "Added hoe block to Rakefile."
19
+ end
23
20
 
24
- Harker.launch(File.basename($0), ARGV)"
21
+ FileUtils.mkdir_p(File.join(rails_root, '/bin'))
22
+ File.open(File.join(rails_root, "/bin/#{@project_name}"), 'w') do |fp|
23
+ fp.puts template('bin')
24
+ puts "Wrote bin launcher."
25
+ end
25
26
 
26
- lib = "# Allow rubygems to load this app
27
- require File.dirname(__FILE__) + '/../config/environment'"
27
+ File.open(File.join(rails_root, "/lib/#{@project_name}.rb"), 'w') do |fp|
28
+ fp.puts template('lib')
29
+ puts "Wrote lib file."
30
+ end
28
31
 
29
- File.open(rails_root + '/Rakefile', 'a') { |fp| fp.puts hoe }
30
- puts "Added hoe block to Rakefile."
31
- File.open(rails_root + "/bin/#{project_name}", 'w') { fp.puts bin }
32
- puts "Wrote bin launcher."
33
- File.open(rails_root + "/lib/#{project_name}.rb", 'w') { fp.puts lib }
34
- puts "Wrote lib file."
35
- system "cd #{rails_root}; rake check_manifest | patch"
36
- puts "Wrote manifest."
32
+ # Submitted a patch to hoe to make it ignore log files by default,
33
+ # but folks should still give it a once-over manually anyway.
34
+ system "cd #{rails_root}; touch Manifest.txt; rake check_manifest | patch"
35
+ puts "Wrote Manifest.txt."
36
+ puts "Ensure the manifest doesn't contain files you don't want in the gem."
37
+ puts "Then try running rake install_gem."
38
+ end
37
39
 
38
- puts "Done! Try running rake install_gem."
40
+ def self.template(name)
41
+ template_path = File.join File.dirname(__FILE__), 'templates', "#{name}.erb"
42
+ ERB.new(File.read(template_path)).result(binding)
39
43
  end
40
44
  end
@@ -1,4 +1,13 @@
1
- # TODO: not sure if my Rails patches cover tmp/sessions or tmp/sockets
1
+ # This monkeypatches Rails to allow tmp_dir to be configured.
2
+
3
+ # It's been submitted upstream:
4
+ # http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2379
5
+
6
+ # We can remove the Configuration monkeypatch once the above patch is
7
+ # accepted if we don't care about supporting older versions.
8
+
9
+ gem 'rails'
10
+ require 'initializer'
2
11
 
3
12
  class Rails::Configuration
4
13
  attr_accessor :tmp_dir
@@ -17,7 +26,7 @@ class Rails::Configuration
17
26
  end
18
27
 
19
28
  class Rails::Initializer
20
- def self.run(command = :process, configuration = Configuration.new)
29
+ def self.run(command = :process, configuration = Rails::Configuration.new)
21
30
  yield configuration if block_given?
22
31
  Harker.configure(configuration)
23
32
  initializer = new configuration
data/lib/harker/server.rb CHANGED
@@ -1,4 +1,11 @@
1
1
  # A patched copy of what Rails' script/server runs.
2
+
3
+ # These changes were submitted upstream to Rails:
4
+ # http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2379
5
+
6
+ # We can remove this file once that patch is accepted if we don't care
7
+ # about supporting older versions.
8
+
2
9
  # Only two changes were made, noted below by comments beginning with "Harker"
3
10
 
4
11
  require 'active_support'
@@ -7,7 +14,6 @@ require 'action_controller'
7
14
  require 'fileutils'
8
15
  require 'optparse'
9
16
 
10
- # TODO: Push Thin adapter upstream so we don't need worry about requiring it
11
17
  begin
12
18
  require_library_or_gem 'thin'
13
19
  rescue Exception
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'harker'
4
+
5
+ Harker.launch(File.basename($0), ARGV)
@@ -0,0 +1,9 @@
1
+ require 'hoe'
2
+ Hoe.new('<%= @project_name %>', '1.0.0') do |p|
3
+ p.summary = 'A Rails application.' # FIXME!
4
+ p.developer('Your Name', 'you@example.com') # FIXME!
5
+ p.extra_deps << ['rails', '~> 2.3.2']
6
+ p.extra_deps << ['harker', '~> <%= Harker::VERSION %>']
7
+ end
8
+
9
+ # TODO: remove hoe's test tasks once new hoe is released.
@@ -0,0 +1,2 @@
1
+ # Allow rubygems to load this app
2
+ require File.dirname(__FILE__) + '/../config/environment'
data/test/sample/Rakefile CHANGED
@@ -6,8 +6,6 @@ require 'rake/testtask'
6
6
  require 'rake/rdoctask'
7
7
  require 'tasks/rails'
8
8
 
9
- # TODO: Hoe and Rails' test tasks stomp on each other
10
- # TODO: specify version sanely
11
9
  Hoe.new('sample_rails', '1.0.0') do |p|
12
10
  p.readme_file = 'README.rdoc'
13
11
  p.extra_deps << ["rails", "~> 2.3.2"]
@@ -779,7 +779,7 @@ Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
779
779
  onComplete: Prototype.emptyFunction,
780
780
  onSuccess: function(transport) {
781
781
  var js = transport.responseText.strip();
782
- if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
782
+ if (!/^\[.*\]$/.test(js))
783
783
  throw('Server returned an invalid collection representation.');
784
784
  this._collection = eval(js);
785
785
  this.checkForExternalText();
@@ -0,0 +1,18 @@
1
+ #!/bin/sh
2
+
3
+ # The gemification step is tricky to test. =\
4
+
5
+ sudo gem uninstall -x dummy
6
+ rm -rf /tmp/dummy-instance
7
+ rm -rf /tmp/dummy
8
+
9
+ cd /tmp
10
+ rails dummy
11
+ cd /tmp/dummy
12
+ script/generate scaffold Dummy name:string favourite_dumb_thing:string
13
+ harker
14
+ rake install_gem
15
+ dummy init /tmp/dummy-instance
16
+ cd /tmp/dummy-instance
17
+ dummy migrate
18
+ dummy start
data/test/test_harker.rb CHANGED
@@ -1,19 +1,13 @@
1
1
  require "rubygems"
2
2
  require "minitest/unit"
3
3
  require 'fileutils'
4
+ require 'timeout'
4
5
  require 'open-uri'
5
6
 
6
7
  $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../lib/")
8
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/sample/lib/")
7
9
  require 'harker'
8
10
 
9
- begin
10
- ENV['RAILS_ENV'] = 'production'
11
- gem 'sample_rails'
12
- rescue LoadError
13
- abort "You need the sample_rails gem installed:
14
- $ cd #{File.dirname(__FILE__) + '/sample'} && rake install_gem"
15
- end
16
-
17
11
  class TestHarker < MiniTest::Unit::TestCase
18
12
  ROOT = "/tmp/harker-test-#{Process.pid}"
19
13
  URL = 'http://localhost:3000/harks'
@@ -26,6 +20,7 @@ class TestHarker < MiniTest::Unit::TestCase
26
20
 
27
21
  def setup
28
22
  unless File.exist?(ROOT)
23
+ Harker::GEM_ROOT.replace(File.dirname(__FILE__) + '/sample/')
29
24
  harker_action('init')
30
25
  harker_action('migrate')
31
26
  end
@@ -54,7 +49,7 @@ class TestHarker < MiniTest::Unit::TestCase
54
49
  def test_stop
55
50
  start_server_process
56
51
  assert File.exists?(ROOT + '/tmp/pids/server.pid'), "No pid found."
57
- Harker.launch('sample_rails', ['stop', ROOT])
52
+ Harker.launch('sample_rails', ['stop', ROOT]); sleep 0.1
58
53
  assert_raises(Errno::ECONNREFUSED) { open(URL).read }
59
54
  end
60
55
 
@@ -75,8 +70,11 @@ class TestHarker < MiniTest::Unit::TestCase
75
70
  end
76
71
 
77
72
  def start_server_process
78
- `cd #{File.dirname(__FILE__)}/.. ; ruby -I:lib test/sample/bin/sample_rails #{ROOT} start`
79
- loop { break if File.exist?(ROOT + '/tmp/pids/server.pid'); sleep 0.1 }
73
+ `cd #{File.dirname(__FILE__)}/.. ; ruby -I:lib:test/sample/lib test/sample/bin/sample_rails start #{ROOT}`
74
+ Timeout.timeout(5) do
75
+ loop { break if File.exist?(ROOT + '/tmp/pids/server.pid'); sleep 0.1 }
76
+ end
77
+ sleep 0.1 # Waiting for pid to exist isn't enough; it looks like.
80
78
  end
81
79
  end
82
80
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: technomancy-harker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Phil Hagelberg
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-26 00:00:00 -07:00
12
+ date: 2009-03-30 00:00:00 -07:00
13
13
  default_executable: harker
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -72,6 +72,9 @@ files:
72
72
  - lib/harker/gemify.rb
73
73
  - lib/harker/rails_configuration.rb
74
74
  - lib/harker/server.rb
75
+ - lib/harker/templates/bin.erb
76
+ - lib/harker/templates/hoe.erb
77
+ - lib/harker/templates/lib.erb
75
78
  - test/sample/Manifest.txt
76
79
  - test/sample/README.rdoc
77
80
  - test/sample/Rakefile
@@ -96,8 +99,6 @@ files:
96
99
  - test/sample/config/routes.rb
97
100
  - test/sample/db/migrate/20090326050232_create_harks.rb
98
101
  - test/sample/lib/sample_rails.rb
99
- - test/sample/log/development.log
100
- - test/sample/log/test.log
101
102
  - test/sample/public/404.html
102
103
  - test/sample/public/422.html
103
104
  - test/sample/public/500.html
@@ -126,6 +127,7 @@ files:
126
127
  - test/sample/test/test_helper.rb
127
128
  - test/sample/test/unit/hark_test.rb
128
129
  - test/sample/test/unit/helpers/harks_helper_test.rb
130
+ - test/test_gemify.sh
129
131
  - test/test_harker.rb
130
132
  has_rdoc: true
131
133
  homepage: http://github.com/technomancy/harker