reflection 0.3.1 → 0.4.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.
data/Rakefile CHANGED
@@ -5,9 +5,9 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "reflection"
8
- gem.summary = %Q{Helps you keeping your development machine in sync with production.}
8
+ gem.summary = %Q{Keep your development machine in sync with production.}
9
9
  gem.description = %Q{
10
- Reflection is designed to keep your production assets (database comming soon) in sync with your development system.
10
+ Reflection is designed to keep your development system in sync with your production system's files and database (by dumping).
11
11
  It uses a shared git repository to store these files, which allows you to mirror your production environment without the need of
12
12
  direct access to your production servers.
13
13
  }
data/Reflection.gemspec CHANGED
@@ -5,14 +5,14 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{reflection}
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andreas Wolff"]
12
- s.date = %q{2009-11-17}
12
+ s.date = %q{2009-11-18}
13
13
  s.default_executable = %q{reflection}
14
14
  s.description = %q{
15
- Reflection is designed to keep your production assets (database comming soon) in sync with your development system.
15
+ Reflection is designed to keep your development system in sync with your production system's files and database (by dumping).
16
16
  It uses a shared git repository to store these files, which allows you to mirror your production environment without the need of
17
17
  direct access to your production servers.
18
18
  }
@@ -42,6 +42,7 @@ Gem::Specification.new do |s|
42
42
  "lib/reflection/directory.rb",
43
43
  "lib/reflection/directory/base.rb",
44
44
  "lib/reflection/directory/stash.rb",
45
+ "lib/reflection/rails.rb",
45
46
  "lib/reflection/repository.rb",
46
47
  "lib/reflection/support.rb",
47
48
  "lib/reflection/support/home.rb",
@@ -52,6 +53,7 @@ Gem::Specification.new do |s|
52
53
  "spec/reflection/config_spec.rb",
53
54
  "spec/reflection/directory/base_spec.rb",
54
55
  "spec/reflection/directory/stash_spec.rb",
56
+ "spec/reflection/rails_spec.rb",
55
57
  "spec/reflection/repository_spec.rb",
56
58
  "spec/reflection/support/home_spec.rb",
57
59
  "spec/reflection/support_spec.rb",
@@ -63,13 +65,14 @@ Gem::Specification.new do |s|
63
65
  s.rdoc_options = ["--charset=UTF-8"]
64
66
  s.require_paths = ["lib"]
65
67
  s.rubygems_version = %q{1.3.5}
66
- s.summary = %q{Helps you keeping your development machine in sync with production.}
68
+ s.summary = %q{Keep your development machine in sync with production.}
67
69
  s.test_files = [
68
70
  "spec/reflection/cli_spec.rb",
69
71
  "spec/reflection/command/stash_spec.rb",
70
72
  "spec/reflection/config_spec.rb",
71
73
  "spec/reflection/directory/base_spec.rb",
72
74
  "spec/reflection/directory/stash_spec.rb",
75
+ "spec/reflection/rails_spec.rb",
73
76
  "spec/reflection/repository_spec.rb",
74
77
  "spec/reflection/support/home_spec.rb",
75
78
  "spec/reflection/support_spec.rb",
data/TODO CHANGED
@@ -1,8 +1,6 @@
1
- + Add config files ('$ reflection path/to/config')
2
- + Add DB Dumper (include in cli-opt-parser)
3
1
  + Remove stash directory if its empty (on reinit)
4
2
  + Add Logger (Reflection::Support.log)
5
- + After command callbacks: Twitter, Campfire on Serverside
3
+ + After command callbacks: Apphunk
6
4
  + List existing reflections in client side
7
5
  + Allow to apply any (git) version, not just the latest
8
6
  + Add cli option use tmp-apply (removes ~/.reflection/apply-dir after command)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
@@ -5,17 +5,23 @@ module Reflection
5
5
  class Apply < Reflection::Command::Base
6
6
 
7
7
  def validate!
8
- validate.existence_of options.directory
8
+ validate.existence_of config.directory
9
+ if config.rails_root
10
+ validate.existence_of config.rails_root
11
+ Reflection::Rails.validate_environment(config)
12
+ end
9
13
  end
10
14
 
11
15
  def run!
12
- stash_directory = Directory::Stash.new(Reflection::Repository.new(options.repository), 'apply')
13
- target_directory = Directory::Base.new(options.directory)
16
+ stash_directory = Directory::Stash.new(Reflection::Repository.new(config.repository), 'apply')
17
+ target_directory = Directory::Base.new(config.directory)
14
18
 
15
19
  get_user_approval_for_cleaning_target(target_directory)
20
+ get_user_approval_for_apply_database_dump if config.rails_root
21
+
16
22
  verify_that_target_is_not_a_repository(target_directory)
17
23
 
18
- Reflection.log.info "Applying '#{options.repository}' >> '#{options.directory}'.."
24
+ Reflection.log.info "Applying '#{config.repository}' >> '#{config.directory}'.."
19
25
 
20
26
  target_directory.clean!
21
27
 
@@ -32,6 +38,7 @@ module Reflection
32
38
  stash_directory.get_git_index_from(target_directory.path)
33
39
  end
34
40
 
41
+ Reflection::Rails.apply(config, target_directory)
35
42
  Reflection.log.info "Apply Command done."
36
43
  end
37
44
 
@@ -40,7 +47,18 @@ module Reflection
40
47
 
41
48
  def get_user_approval_for_cleaning_target(target_directory)
42
49
  puts "\nIn order to get a fresh copy of your files, Reflection will have to remove all files under '#{target_directory.path}'."
43
- puts "If you're sure, hit <enter> to proceed.."
50
+ puts "If you are sure, hit <enter> to proceed.."
51
+
52
+ unless STDIN.getc == 10
53
+ puts "Aborting.."
54
+ exit
55
+ end
56
+ end
57
+
58
+ def get_user_approval_for_apply_database_dump
59
+ puts "\nCaution: You've enabled Rails database dumping/applying."
60
+ puts "In order to apply a fresh dump, Reflection will override your database."
61
+ puts "If you are sure, hit <enter> to proceed.."
44
62
 
45
63
  unless STDIN.getc == 10
46
64
  puts "Aborting.."
@@ -1,16 +1,16 @@
1
1
  module Reflection
2
2
  module Command
3
3
  class Base
4
- attr_accessor :options
4
+ attr_accessor :config
5
5
 
6
- def self.run!(options)
7
- command = self.new(options)
6
+ def self.run!(config)
7
+ command = self.new(config)
8
8
  command.validate! if command.respond_to?(:validate!)
9
9
  command.run!
10
10
  end
11
11
 
12
- def initialize(new_options)
13
- self.options = new_options
12
+ def initialize(new_config)
13
+ self.config = new_config
14
14
  end
15
15
 
16
16
  def validate
@@ -5,14 +5,18 @@ module Reflection
5
5
  class Stash < Reflection::Command::Base
6
6
 
7
7
  def validate!
8
- validate.existence_of options.directory
8
+ validate.existence_of config.directory
9
+ if config.rails_root
10
+ validate.existence_of config.rails_root
11
+ Reflection::Rails.validate_environment(config)
12
+ end
9
13
  end
10
14
 
11
15
  def run!
12
- Reflection.log.info "Stashing '#{options.directory}'.."
16
+ Reflection.log.info "Stashing '#{config.directory}'.."
13
17
 
14
- stash_directory = Directory::Stash.new(Reflection::Repository.new(options.repository), 'stash')
15
- target_directory = Directory::Base.new(options.directory)
18
+ stash_directory = Directory::Stash.new(Reflection::Repository.new(config.repository), 'stash')
19
+ target_directory = Directory::Base.new(config.directory)
16
20
 
17
21
  verify_that_target_is_not_a_repository(target_directory)
18
22
 
@@ -34,8 +38,10 @@ module Reflection
34
38
 
35
39
  def stash_directory_into_repository(stash_directory, target_directory)
36
40
  copy_stash_repository_git_index_to_target(stash_directory.git_index, target_directory.path)
41
+ Reflection::Rails.stash(config, target_directory) if config.rails_root
37
42
  commit_and_push_files(target_directory.path, target_directory.name)
38
43
  move_stash_repository_git_index_back(target_directory.git_index, stash_directory.path)
44
+ Reflection::Rails.clean_target(target_directory) if config.rails_root
39
45
  end
40
46
 
41
47
 
@@ -11,6 +11,8 @@ module Reflection
11
11
  attr_accessor :command
12
12
  attr_accessor :directory
13
13
  attr_accessor :repository
14
+ attr_accessor :rails_root
15
+ attr_accessor :rails_environment
14
16
  attr_accessor :store_configuration_path
15
17
 
16
18
  def self.parse(args = [])
@@ -28,13 +30,21 @@ module Reflection
28
30
  end
29
31
 
30
32
  def to_hash
31
- { :command => self.command, :repository => self.repository, :directory => self.directory }
33
+ {
34
+ :command => self.command,
35
+ :repository => self.repository,
36
+ :directory => self.directory,
37
+ :rails_root => self.rails_root,
38
+ :rails_environment => self.rails_environment
39
+ }
32
40
  end
33
41
 
34
42
  def from_hash(hash)
35
43
  self.command = hash[:command]
36
44
  self.directory = hash[:directory]
37
45
  self.repository = hash[:repository]
46
+ self.rails_root = hash[:rails_root]
47
+ self.rails_environment = hash[:rails_environment]
38
48
  end
39
49
 
40
50
  def write(path)
@@ -61,8 +71,10 @@ module Reflection
61
71
 
62
72
  def parse_command_line_options(args)
63
73
  opt_parser = OptionParser.new do |opts|
64
- opts.banner = "Usage: reflection --COMMAND --repository=GIT_REPO --directory=PATH"
65
-
74
+ opts.banner = "Usage: reflection --COMMAND --repository=GIT_REPO --directory=PATH\n"
75
+ opts.banner << " -or-\n"
76
+ opts.banner << "Usage: reflection /path/to/reflection-config-file.yml"
77
+
66
78
  opts.separator " "
67
79
  opts.separator "On the server side:"
68
80
 
@@ -86,7 +98,16 @@ module Reflection
86
98
  end
87
99
 
88
100
  opts.separator " "
89
- opts.separator "Additional options for both:"
101
+ opts.separator "Additional options for both:"
102
+
103
+ opts.on("--rails [RAILS_ROOT]", "Enable dumping/applying of a Rails managed MySQL database") do |path|
104
+ self.rails_root = path || nil
105
+ end
106
+
107
+ opts.on("--rails-env [ENV]", "Rails environment to instrument") do |environment|
108
+ self.rails_environment = environment || nil
109
+ end
110
+
90
111
  opts.on("--write [FILE]", "Create a configuration FILE from the current commandline options") do |config_file_path|
91
112
  self.store_configuration_path = config_file_path if config_file_path
92
113
  end
@@ -0,0 +1,62 @@
1
+ module Reflection
2
+ module Rails
3
+ class << self
4
+
5
+ def validate_environment(config)
6
+ env_file_path = File.join(config.rails_root, 'config/environments', "#{config.rails_environment}.rb")
7
+ unless File.exist?(env_file_path)
8
+ Reflection::Support.exit_with_error("Rails environment '#{config.rails_environment}' doesn't exist in #{env_file_path}.")
9
+ end
10
+ end
11
+
12
+ def clean_target(target_directory)
13
+ target_file_path = File.join(target_directory.path, '_rails_database_dump.sql')
14
+ if File.exist?(target_file_path)
15
+ %x(rm #{target_file_path})
16
+ end
17
+ end
18
+
19
+ def database_command_line_options(database_config)
20
+ options = []
21
+ options << "-h #{database_config['host']}"
22
+ options << "-u #{database_config['username']}"
23
+ options << "-p #{database_config['password']}" if database_config['password'] && !database_config['password'].empty?
24
+ options << "#{database_config['database']}"
25
+ options.join(' ')
26
+ end
27
+
28
+ def read_database_configuration(config)
29
+ begin
30
+ database_path = File.join(config.rails_root, "config/database.yml")
31
+ if db_config = YAML.load_file(database_path)[config.rails_environment]
32
+ return db_config
33
+ else
34
+ Reflection.log.error("Rails database configuration for '#{config.rails_environment}' isn't available in #{database_path}")
35
+ return false
36
+ end
37
+ rescue => e
38
+ Reflection.log.error("Error while parsing Rails database configuration: #{e}")
39
+ return false
40
+ end
41
+ end
42
+
43
+ def stash(config, target_directory)
44
+ Reflection.log.debug "Stashing database dump.."
45
+ return unless database_config = read_database_configuration(config)
46
+ options = database_command_line_options(database_config)
47
+ target_file_path = File.join(target_directory.path, '_rails_database_dump.sql')
48
+ %x(mysqldump #{options} --add-drop-table > #{target_file_path})
49
+ end
50
+
51
+ def apply(config, target_directory)
52
+ Reflection.log.debug "Applying database dump.."
53
+ return unless database_config = read_database_configuration(config)
54
+ options = database_command_line_options(database_config)
55
+ target_file_path = File.join(target_directory.path, '_rails_database_dump.sql')
56
+ %x(mysql #{options} < #{target_file_path})
57
+ clean_target(target_directory)
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -10,6 +10,9 @@ module Reflection
10
10
  puts "** #{message}" if message && !message.empty?
11
11
  end
12
12
 
13
+ def error(message)
14
+ puts "!! #{message}" if message && !message.empty?
15
+ end
13
16
  end
14
17
  end
15
18
  end
data/lib/reflection.rb CHANGED
@@ -5,6 +5,7 @@ module Reflection
5
5
  autoload :Config, 'reflection/config'
6
6
  autoload :Command, 'reflection/command'
7
7
  autoload :Directory, 'reflection/directory'
8
+ autoload :Rails, 'reflection/rails'
8
9
  autoload :Repository, 'reflection/repository'
9
10
  autoload :Support, 'reflection/support'
10
11
  autoload :Validations, 'reflection/validations'
@@ -2,8 +2,8 @@ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe Reflection::Command::Stash do
4
4
  before(:each) do
5
- @options = OpenStruct.new({ :directory => '/home/tmp/fu_asset_directory', :command => :stash })
6
- @subject = Reflection::Command::Stash.new(@options)
5
+ @config = OpenStruct.new({ :directory => '/home/tmp/fu_asset_directory', :command => :stash })
6
+ @subject = Reflection::Command::Stash.new(@config)
7
7
  end
8
8
 
9
9
  describe 'validations' do
@@ -83,6 +83,13 @@ describe Reflection::Command::Stash do
83
83
  @subject.stash_directory_into_repository(@mock_stash_directory, @mock_target_directory)
84
84
  end
85
85
 
86
+ it 'should call the stash command on the database dumper if enabled' do
87
+ @config.rails_root = "/rails/root"
88
+ Reflection::Rails.should_receive(:stash).with(@config, @mock_target_directory)
89
+ @subject.stash_directory_into_repository(@mock_stash_directory, @mock_target_directory)
90
+ end
91
+
92
+
86
93
  it "should add and push the contents of directory to the repository" do
87
94
  @subject.should_receive(:commit_and_push_files).with("/home/tmp/assets", "assets")
88
95
  @subject.stash_directory_into_repository(@mock_stash_directory, @mock_target_directory)
@@ -2,7 +2,9 @@ require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe Reflection::Config do
4
4
  before(:each) do
5
- @valid_options = { :command => :stash, :repository => 'repo', :directory => 'dir' }
5
+ @valid_options = {
6
+ :command => :stash, :repository => 'repo', :directory => 'dir', :rails_root => "rails_root", :rails_environment => 'development'
7
+ }
6
8
  end
7
9
 
8
10
  describe 'parse' do
@@ -41,6 +43,8 @@ describe Reflection::Config do
41
43
  @config.command = :stash
42
44
  @config.repository = 'repo'
43
45
  @config.directory = 'dir'
46
+ @config.rails_root = 'rails_root'
47
+ @config.rails_environment = 'development'
44
48
  @config.to_hash.should == @valid_options
45
49
  end
46
50
  end
@@ -52,6 +56,8 @@ describe Reflection::Config do
52
56
  @config.command.should eql(:stash)
53
57
  @config.repository.should eql('repo')
54
58
  @config.directory.should eql('dir')
59
+ @config.rails_root.should eql('rails_root')
60
+ @config.rails_environment.should eql('development')
55
61
  end
56
62
  end
57
63
 
@@ -0,0 +1,55 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Reflection::Rails do
4
+ before(:each) do
5
+ @config = OpenStruct.new({ :rails_root => '/rails_root/', :rails_environment => 'development' })
6
+ @rails = Reflection::Rails
7
+ end
8
+
9
+ describe 'validate_environment' do
10
+ it "should fail if the specified environment does't exist" do
11
+ Reflection::Support.should_receive(:exit_with_error)
12
+ File.stub!(:exist?).and_return(false)
13
+ @rails.validate_environment(@config)
14
+ end
15
+ end
16
+
17
+ describe 'read_database_configuration' do
18
+ it 'should read the configuration for the specified environment' do
19
+ db_config = { "host" => "localhost", "username" => "root" }
20
+ YAML.should_receive(:load_file).with('/rails_root/config/database.yml').and_return({ "production" => {}, "development" => db_config })
21
+ db_config = @rails.read_database_configuration(@config)
22
+ db_config.should == db_config
23
+ end
24
+
25
+ it "should log an error and return false if the environment isn't configured" do
26
+ Reflection.log.should_receive(:error).with(/available/)
27
+ YAML.stub!(:load_file).and_return({ "production" => {} })
28
+ @rails.read_database_configuration(@config).should be_false
29
+ end
30
+
31
+ it "should log an error and return false if the database.yml cannot be found" do
32
+ Reflection.log.should_receive(:error).with(/Error/)
33
+ YAML.stub!(:load_file).and_raise(StandardError)
34
+ @rails.read_database_configuration(@config).should be_false
35
+ end
36
+ end
37
+
38
+ describe 'database_command_line_options' do
39
+ before(:each) do
40
+ @db_config = { "host" => "localhost", "database" => "test", "username" => "root", "password" => "secret" }
41
+ end
42
+
43
+ it 'should create options for the mysql command' do
44
+ @rails.database_command_line_options(@db_config).should == "-h localhost -u root -p secret test"
45
+ end
46
+
47
+ it 'should ignore the password option if its not available' do
48
+ @db_config['password'] = ""
49
+ @rails.database_command_line_options(@db_config).should == "-h localhost -u root test"
50
+
51
+ @db_config['password'] = nil
52
+ @rails.database_command_line_options(@db_config).should == "-h localhost -u root test"
53
+ end
54
+ end
55
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reflection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Wolff
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-17 00:00:00 +01:00
12
+ date: 2009-11-18 00:00:00 +01:00
13
13
  default_executable: reflection
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.2.5
34
34
  version:
35
- description: "\n Reflection is designed to keep your production assets (database comming soon) in sync with your development system.\n It uses a shared git repository to store these files, which allows you to mirror your production environment without the need of \n direct access to your production servers.\n "
35
+ description: "\n Reflection is designed to keep your development system in sync with your production system's files and database (by dumping).\n It uses a shared git repository to store these files, which allows you to mirror your production environment without the need of \n direct access to your production servers.\n "
36
36
  email: rubyphunk@gmail.com
37
37
  executables:
38
38
  - reflection
@@ -61,6 +61,7 @@ files:
61
61
  - lib/reflection/directory.rb
62
62
  - lib/reflection/directory/base.rb
63
63
  - lib/reflection/directory/stash.rb
64
+ - lib/reflection/rails.rb
64
65
  - lib/reflection/repository.rb
65
66
  - lib/reflection/support.rb
66
67
  - lib/reflection/support/home.rb
@@ -71,6 +72,7 @@ files:
71
72
  - spec/reflection/config_spec.rb
72
73
  - spec/reflection/directory/base_spec.rb
73
74
  - spec/reflection/directory/stash_spec.rb
75
+ - spec/reflection/rails_spec.rb
74
76
  - spec/reflection/repository_spec.rb
75
77
  - spec/reflection/support/home_spec.rb
76
78
  - spec/reflection/support_spec.rb
@@ -104,13 +106,14 @@ rubyforge_project:
104
106
  rubygems_version: 1.3.5
105
107
  signing_key:
106
108
  specification_version: 3
107
- summary: Helps you keeping your development machine in sync with production.
109
+ summary: Keep your development machine in sync with production.
108
110
  test_files:
109
111
  - spec/reflection/cli_spec.rb
110
112
  - spec/reflection/command/stash_spec.rb
111
113
  - spec/reflection/config_spec.rb
112
114
  - spec/reflection/directory/base_spec.rb
113
115
  - spec/reflection/directory/stash_spec.rb
116
+ - spec/reflection/rails_spec.rb
114
117
  - spec/reflection/repository_spec.rb
115
118
  - spec/reflection/support/home_spec.rb
116
119
  - spec/reflection/support_spec.rb