tsukuru 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. data/README.md +11 -0
  2. data/Rakefile +15 -0
  3. data/VERSION +1 -0
  4. data/bin/tsukuru +154 -0
  5. metadata +65 -0
@@ -0,0 +1,11 @@
1
+ Tsukuru will fetch your latest bundle and prepare it for running locally. It keeps an archive of downloaded bundles. You can also use restore from a local bundle (archived or manually downloaded).
2
+
3
+ Usage: reanimate
4
+ -a, --app NAME Application name
5
+ -c, --capture Capture a new bundle instead of using the latest one
6
+ -p, --password Yuur Heroku password
7
+ -h, --help Display this message
8
+ -l, --local FILE Use a local bundle instead of downloading
9
+ -t, --target PATH Path to where the application should be restored
10
+ -r, --reindex Start search deamon and reindex (sunspot + solr only)
11
+ -u, --username Your Heroku username
@@ -0,0 +1,15 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "tsukuru"
5
+ gemspec.summary = "Run Heroku bundles locally"
6
+ gemspec.description = "Tsukuru will fetch your latest bundle and prepare it for running locally. It keeps an archive of downloaded bundles."
7
+ gemspec.email = "tel@jklm.no"
8
+ gemspec.homepage = "http://github.com/toreriklinnerud/tsukuru"
9
+ gemspec.authors = ["Tor Erik Linnerud"]
10
+
11
+ end
12
+ Jeweler::GemcutterTasks.new
13
+ rescue LoadError
14
+ puts "Jeweler not available. Install it with: gem install jeweler"
15
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'heroku'
4
+ require 'restclient'
5
+ require 'ruby-unix-now'
6
+ require 'optparse'
7
+ require 'pathname'
8
+ require 'fileutils'
9
+
10
+ options = Struct.new(:capture, :local, :reindex, :app, :target, :current, :username, :password).new
11
+
12
+ parser = OptionParser.new do|opts|
13
+ opts.banner = <<-TEXT
14
+ Tsukuru will fetch your latest Heroku bundle and prepare it for running locally
15
+
16
+ Usage: tsukuru
17
+ TEXT
18
+
19
+ opts.on( '-a', '--app NAME', 'Application name' ) do |app|
20
+ options.app = app
21
+ end
22
+
23
+ opts.on( '-c', '--capture', 'Capture a new bundle instead of using the latest one' ) do
24
+ options.capture = true
25
+ end
26
+
27
+ opts.on( '-p', '--password', 'Yuur Heroku password' ) do |password|
28
+ options.password = password
29
+ end
30
+
31
+ opts.on('-h', '--help', 'Display this message') do
32
+ puts opts
33
+ exit
34
+ end
35
+
36
+ opts.on( '-l', '--local FILE', 'Use a local bundle instead of downloading' ) do |file|
37
+ options.local = file
38
+ end
39
+
40
+ opts.on('-t', '--target PATH', 'Path to where the application should be restored') do |path|
41
+ options.target = Pathname.new(path)
42
+ end
43
+
44
+ opts.on( '-r', '--reindex', 'Start search deamon and reindex (sunspot + solr only)' ) do
45
+ options.reindex = true
46
+ end
47
+
48
+ opts.on( '-u', '--username', 'Your Heroku username' ) do |password|
49
+ options.password = password
50
+ end
51
+
52
+ end.parse!
53
+
54
+ def error(msg)
55
+ puts(msg)
56
+ exit(-1)
57
+ end
58
+
59
+ error('Specify the app name') unless options.app
60
+
61
+ options.target ||= Pathname('/apps') + options.app
62
+ options.current = options.target + 'current'
63
+ @options = options
64
+
65
+ if !options.local
66
+ error('You must provide your heroku username') unless options.username
67
+ error('You must provide your heroku password') unless options.password
68
+
69
+ heroku = Heroku::Client.new(*CREDENTIALS)
70
+ if options.capture
71
+ heroku.bundle_capture(options.app)
72
+ puts 'Starting capture'
73
+
74
+ sleep 10 until((bundle = heroku.bundles(options.app).last)[:state] == 'complete')
75
+ puts 'Capture complete'
76
+ else
77
+ bundle = heroku.bundles(options.app).last
78
+ end
79
+ end
80
+
81
+ bundle_file = options.local || "/tmp/#{bundle[:name]}.tar.gz"
82
+
83
+ if options.local
84
+ puts "Using local bundle #{options.local}"
85
+ else
86
+ error('Bundle is not complete, please check') unless bundle[:state] == 'complete'
87
+ url = heroku.bundle_url(options.app, bundle[:name])
88
+ puts "Downloading #{bundle[:name]}"
89
+ url = heroku.bundle_url(options.app, bundle[:name])
90
+ File.open(bundle_file, "wb") { |f| f.write RestClient.get(url) }
91
+ puts 'Download complete'
92
+ end
93
+
94
+ if options.local
95
+ error('The local file does not exist.') unless File.exist?(options.local)
96
+ error('The local files not end in tar.gz or tar.bz2') unless options.local =~ /(tar\.gz|tar.bz2)$/
97
+ end
98
+
99
+ def in_path(*commands)
100
+ run :cd, @options.path, '&&', commands
101
+ end
102
+
103
+ def in_app(*commands)
104
+ run :cd, @options.current, '&&', commands
105
+ end
106
+
107
+ sunspot_pid_file = options.current + "tmp/pids/sunspot-solr-production.pid"
108
+ Process.kill('KILL', File.read(sunspot_pid_file).to_i) if File.exist?(sunspot_pid_file) rescue Errno::ESRCH
109
+
110
+ tempdir = Pathname('/tmp') + 'reanimate' + rand(10**10).to_s
111
+ FileUtils.mkdir_p(tempdir)
112
+
113
+ compression_type = (bundle_file =~ /.gz$/) ? :z : :j
114
+ run :tar, :x, compression_type, :C => tempdir, :f => bundle_file
115
+
116
+ extracted_folder = Dir.glob("#{tempdir}/*").first
117
+ error("Extraction of #{tempdir} failed") unless extracted_folder
118
+
119
+ FileUtils.mkdir_p(options.target)
120
+ FileUtils.rm_rf(options.current)
121
+ FileUtils.mv(extracted_folder, options.current)
122
+
123
+ db_file = options.current + 'db/pgdump.sql'
124
+
125
+ run :dropdb, options.app if `psql --list`.include?(options.app)
126
+ run :createdb, options.app
127
+ run :sed, "-i '' -E 's/Owner: [a-z]+/Owner: #{options.app}/g'", db_file
128
+ run :sed, "-i '' -E 's/OWNER TO [a-z]+/OWNER TO #{options.app}/g'", db_file
129
+ run :psql, :q, :f => db_file, :d => options.app
130
+
131
+ database_config = options.current + 'config/database.yml'
132
+ if File.exist?(database_config)
133
+ in_app "sed -i '' -E 's/database: alpha_dev/database: #{options.app}/g'", database_config
134
+ end
135
+ in_app 'bundle install'
136
+
137
+
138
+ if options.reindex
139
+ in_app 'mkdir -p solr/pids/production'
140
+ in_app 'RAILS_ENV=production rake sunspot:solr:start'
141
+ sleep 15
142
+ in_app 'RAILS_ENV=production bundle exec rake sunspot:solr:reindex'
143
+ end
144
+
145
+ in_app 'mkdir -p tmp'
146
+ in_app 'touch', 'tmp/restart'
147
+
148
+ if !options.local
149
+ archive = options.target + 'archive'
150
+ FileUtils.mkdir_p(archive)
151
+ run 'tar', '-cjf', "#{archive}.tar.bz2", extracted_folder
152
+ end
153
+
154
+ FileUtils.rm_rf(tempdir)
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tsukuru
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Tor Erik Linnerud
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-28 00:00:00 +01:00
18
+ default_executable: tsukuru
19
+ dependencies: []
20
+
21
+ description: Tsukuru will fetch your latest bundle and prepare it for running locally. It keeps an archive of downloaded bundles.
22
+ email: tel@jklm.no
23
+ executables:
24
+ - tsukuru
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.md
29
+ files:
30
+ - README.md
31
+ - Rakefile
32
+ - VERSION
33
+ - bin/tsukuru
34
+ has_rdoc: true
35
+ homepage: http://github.com/toreriklinnerud/tsukuru
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --charset=UTF-8
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.3.6
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Run Heroku bundles locally
64
+ test_files: []
65
+