cappy-taffy 1.0.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.
@@ -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
+