tsukuru 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+