cappy-taffy 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in cappy-taffy.gemspec
4
+ gemspec
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "cappy-taffy/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "cappy-taffy"
7
+ s.version = Cappy::Taffy::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Eric Boehs"]
10
+ s.email = ["ericboehs@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Capistrano task to pull production database to local using taps}
13
+ s.description = %q{Cappy Taffy is based on cap taffy which uses the heroku gem to generate the database and taps urls; this gem however does not depend on the heroku gem.}
14
+
15
+ s.rubyforge_project = "cappy-taffy"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,5 @@
1
+ module Cappy
2
+ module Taffy
3
+ # Your code goes here...
4
+ end
5
+ end
@@ -0,0 +1,125 @@
1
+ require 'rubygems'
2
+ begin
3
+ gem 'taps', '>= 0.2.8'
4
+ rescue LoadError
5
+ error "Install the Taps gem to use db commands."
6
+ end
7
+
8
+ require File.join(File.dirname(__FILE__), 'parse')
9
+ require 'digest/sha1'
10
+
11
+ module CappyTaffy::Db
12
+ extend self
13
+
14
+ # Detects the local database url for +env+.
15
+ def local_database_url(env)
16
+ # return "" unless File.exists?(Dir.pwd + '/config/database.yml')
17
+ # db_config = YAML.load(File.read(Dir.pwd + '/config/database.yml'))
18
+
19
+ CappyTaffy::Parse.database_url(env)
20
+ end
21
+
22
+ # The default server port the Taps server is started on.
23
+ def default_server_port
24
+ 5000
25
+ end
26
+
27
+ # Gets the taps host from the config
28
+ def taps_host
29
+ return YAML.load(File.read(Dir.pwd + '/config/database.yml'))['production']['taps_host']
30
+ end
31
+
32
+ # Generates the remote url used by Taps push/pull.
33
+ def remote_taps_url(options={})
34
+ host = options[:taps_host] || taps_host
35
+ port = options[:port] || default_server_port
36
+
37
+ url = CappyTaffy::Parse.uri_hash_to_url(
38
+ 'username' => options[:login],
39
+ 'password' => options[:password],
40
+ 'host' => host,
41
+ 'port' => port,
42
+ 'scheme' => 'http',
43
+ 'path' => ''
44
+ )
45
+
46
+ return url.sub(/\/$/, '')
47
+ end
48
+
49
+ # Generates a temporary password to be used for the Taps server command.
50
+ def tmp_pass(user)
51
+ pass = YAML.load(File.read(Dir.pwd + '/config/database.yml'))['production']['taps_pass']
52
+ pass = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{user}--") unless pass
53
+
54
+ return pass
55
+ end
56
+
57
+ def run(instance, options = {})
58
+ remote_taps_url = CappyTaffy::Db.remote_taps_url(options)
59
+ exec("taps #{options[:direction]} #{options[:local_database_url]} #{remote_taps_url}")
60
+ end
61
+ end
62
+
63
+ Capistrano::Configuration.instance.load do
64
+ namespace :db do
65
+ task :detect, :roles => :app do
66
+ @remote_taps_url = CappyTaffy::Db.remote_taps_url
67
+ @local_database_url = CappyTaffy::Db.local_database_url('development')
68
+ end
69
+
70
+ desc <<-DESC
71
+ Push a local database into the app's remote database.
72
+
73
+ Performs push from local development database to remote production database.
74
+ Opens a Taps server on port 5000. (Ensure port is opened on the remote server).
75
+
76
+ # alternately, specify a different port
77
+ cap db:push -s taps_port=4321
78
+
79
+ For the security conscious:
80
+
81
+ # use ssh local forwarding (ensure [port] is available on both endpoints)
82
+ ssh -N -L[port]:127.0.0.1:[port] [user]@[remote-server]
83
+
84
+ # then push locally
85
+ cap db:push -s taps_port=[port] -s local=true
86
+ DESC
87
+ # task :push do
88
+ # detect
89
+ #
90
+ # login = fetch(:user)
91
+ # password = CappyTaffy::Db.tmp_pass(login)
92
+ #
93
+ # logger = Capistrano::Logger.new
94
+ # logger.important "Auto-detected remote database: #{@remote_taps_url}" if @remote_taps_url != ''
95
+ # logger.important "Auto-detected local database: #{@local_database_url}" if @local_database_url != ''
96
+ #
97
+ # options = {:direction => "push",:remote_taps_url => @remote_taps_url, :login => login, :password => password, :local_database_url => @local_database_url, :port => variables[:taps_port]}
98
+ #
99
+ # CappyTaffy::Db.run(self, options)
100
+ # end
101
+
102
+ desc <<-DESC
103
+ Pull the app's database into a local database.
104
+
105
+ Performs pull from remote production database to local development database.
106
+
107
+ # alternately, specify a different port (default 5000)
108
+ cap db:pull -s taps_port=4321
109
+ DESC
110
+ task :pull do
111
+ detect
112
+
113
+ login = fetch(:user)
114
+ password = CappyTaffy::Db.tmp_pass(login)
115
+
116
+ logger = Capistrano::Logger.new
117
+ logger.important "Auto-detected remote database: #{@remote_taps_url}" if @remote_taps_url != ''
118
+ logger.important "Auto-detected local database: #{@local_database_url}" if @local_database_url != ''
119
+
120
+ options = {:direction => "pull",:remote_taps_url => @remote_taps_url, :login => login, :password => password, :local_database_url => @local_database_url, :port => variables[:taps_port]}
121
+
122
+ CappyTaffy::Db.run(self, options)
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,84 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+ require 'uri'
4
+
5
+ module CappyTaffy
6
+ class Parse
7
+ class << self
8
+ attr_accessor :instance
9
+
10
+ # Modified from :parse_database_yml in heroku/command/db.rb
11
+ def database_url(environment=nil)
12
+ cwd = Dir.pwd
13
+ #TODO: Remove static cwd
14
+ # cwd = '/Users/ericboehs/Dropbox/Projects/Digimedia/digistore_new/administrators'
15
+
16
+ return "" unless File.exists?(cwd + '/config/database.yml')
17
+
18
+ unless environment
19
+ environment = ENV['RAILS_ENV'] || ENV['MERB_ENV'] || ENV['RACK_ENV']
20
+ environment = 'development' if environment.nil? or environment.empty?
21
+ end
22
+
23
+ conf = YAML.load(File.read(cwd + '/config/database.yml'))[environment]
24
+ case conf['adapter']
25
+ when 'sqlite3'
26
+ return "sqlite://#{conf['database']}"
27
+ when 'postgresql'
28
+ uri_hash = conf_to_uri_hash(conf)
29
+ uri_hash['scheme'] = 'postgres'
30
+ return uri_hash_to_url(uri_hash)
31
+ else
32
+ return uri_hash_to_url(conf_to_uri_hash(conf))
33
+ end
34
+ rescue Exception => ex
35
+ puts "Error parsing database.yml: #{ex.message}"
36
+ puts ex.backtrace
37
+ ""
38
+ end
39
+
40
+ # Part of heroku/command/db.rb
41
+ def conf_to_uri_hash(conf)
42
+ uri = {}
43
+ uri['scheme'] = conf['adapter']
44
+ uri['username'] = conf['user'] || conf['username']
45
+ uri['password'] = conf['password']
46
+ uri['host'] = conf['host'] || conf['hostname']
47
+ uri['port'] = conf['port']
48
+ uri['path'] = conf['database']
49
+
50
+ conf['encoding'] = 'utf8' if conf['encoding'] == 'unicode' or conf['encoding'].nil?
51
+ uri['query'] = "encoding=#{conf['encoding']}"
52
+
53
+ uri
54
+ end
55
+
56
+ # Part of heroku/command/db.rb
57
+ def userinfo_from_uri(uri)
58
+ username = uri['username'].to_s
59
+ password = uri['password'].to_s
60
+ return nil if username == ''
61
+
62
+ userinfo = ""
63
+ userinfo << username
64
+ userinfo << ":" << password if password.length > 0
65
+ userinfo
66
+ end
67
+
68
+ # Part of heroku/command/db.rb
69
+ def uri_hash_to_url(uri)
70
+ uri_parts = {
71
+ :scheme => uri['scheme'],
72
+ :userinfo => userinfo_from_uri(uri),
73
+ :password => uri['password'],
74
+ :host => uri['host'] || '127.0.0.1',
75
+ :port => uri['port'],
76
+ :path => "/%s" % uri['path'],
77
+ :query => uri['query'],
78
+ }
79
+
80
+ URI::Generic.build(uri_parts).to_s
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,5 @@
1
+ module Cappy
2
+ module Taffy
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cappy-taffy
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Eric Boehs
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-31 00:00:00 -06:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Cappy Taffy is based on cap taffy which uses the heroku gem to generate the database and taps urls; this gem however does not depend on the heroku gem.
23
+ email:
24
+ - ericboehs@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - Rakefile
35
+ - cappy-taffy.gemspec
36
+ - lib/cappy-taffy.rb
37
+ - lib/cappy-taffy/db.rb
38
+ - lib/cappy-taffy/parse.rb
39
+ - lib/cappy-taffy/version.rb
40
+ has_rdoc: true
41
+ homepage: ""
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ requirements: []
68
+
69
+ rubyforge_project: cappy-taffy
70
+ rubygems_version: 1.4.2
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Capistrano task to pull production database to local using taps
74
+ test_files: []
75
+