harvixture 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Jeremy Friesen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,50 @@
1
+ = harvixture
2
+
3
+ * FIX (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ Harvixture is a tool that can be used to extract data, in the form of fixtures,
8
+ from a Rails project. It is done by pointing the harvixture at a request_path
9
+ and dumping fixtures for all "found" ActiveRecord objects.
10
+
11
+ == SYNOPSIS:
12
+
13
+ $ cd path/to/rails/project
14
+ $ . harvixture run --request_path=/calendars/1 --output_dir=./bug_100 --rails_env=production
15
+ ./bug_100/users.yml
16
+ ./bug_100/calendars.yml
17
+
18
+ == REQUIREMENTS:
19
+
20
+ gem main, activerecord, mocha (for tests)
21
+ a Rails project
22
+
23
+ == INSTALL:
24
+
25
+ sudo gem install harvixture
26
+
27
+ == LICENSE:
28
+
29
+ (The MIT License)
30
+
31
+ Copyright (c) 2008 FIX
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining
34
+ a copy of this software and associated documentation files (the
35
+ 'Software'), to deal in the Software without restriction, including
36
+ without limitation the rights to use, copy, modify, merge, publish,
37
+ distribute, sublicense, and/or sell copies of the Software, and to
38
+ permit persons to whom the Software is furnished to do so, subject to
39
+ the following conditions:
40
+
41
+ The above copyright notice and this permission notice shall be
42
+ included in all copies or substantial portions of the Software.
43
+
44
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
45
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
47
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
48
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
49
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
50
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/bin/harvixture ADDED
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'date'
4
+ require 'rubygems'
5
+ require 'harvixture'
6
+ gem 'harvixture'
7
+ require 'harvixture/command'
8
+ gem 'main'
9
+ require 'main'
10
+
11
+ Main {
12
+ description <<-txt
13
+ Harvixture is a tool to help you capture fixtures from a system
14
+ txt
15
+
16
+ mode(:run) {
17
+ description <<-txt
18
+ Point harvixture to a URI and gather the fixtures.
19
+ txt
20
+ example <<-txt
21
+ ./harvixture --request_path=/calendars/1 --output_dir=./bug_100 --rails_env=production
22
+ txt
23
+ mixin :option_output_dir, :option_rails_env, :option_request_path, :option_user_id, :option_rails_root
24
+ run {
25
+ Harvixture::Command.process!(
26
+ :rails_root => rails_root,
27
+ :output_dir => output_dir,
28
+ :request_path => request_path,
29
+ :rails_env => rails_env,
30
+ :user_id => user_id
31
+ )
32
+ }
33
+ }
34
+
35
+ mixin :option_rails_root do
36
+ option(:r, :rails_root){
37
+ required
38
+ defaults './'
39
+ argument :required
40
+ desc 'path to rails root'
41
+ attr
42
+ }
43
+ end
44
+ mixin :option_output_dir do
45
+ option(:o,:output_dir){
46
+ required
47
+ defaults "./test/fixtures/scenario_for_#{Date.today.strftime('%Y_%m_%d')}"
48
+ argument :required
49
+ desc 'directory name where fixtures will be written'
50
+ attr
51
+ }
52
+ end
53
+
54
+ mixin :option_rails_env do
55
+ option(:e,:rails_env){
56
+ required
57
+ defaults 'production'
58
+ argument :required
59
+ desc 'script/server environment to use'
60
+ attr
61
+ }
62
+ end
63
+
64
+ mixin :option_request_path do
65
+ option(:p,:request_path){
66
+ required
67
+ argument :required
68
+ desc 'path to request from the script/server'
69
+ attr
70
+ }
71
+ end
72
+
73
+ mixin :option_user_id do
74
+ option(:u,:user_id){
75
+ argument :optional
76
+ desc 'authenticate with user_id'
77
+ attr
78
+ }
79
+ end
80
+
81
+ run{ help! }
82
+ }
83
+
data/lib/harvixture.rb ADDED
@@ -0,0 +1,13 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Harvixture
5
+
6
+ end
7
+ require 'rubygems'
8
+ require 'activerecord'
9
+ require 'harvixture/config'
10
+ require 'harvixture/active_record_extension'
11
+ require 'harvixture/command'
12
+ require 'harvixture/model'
13
+ require 'harvixture/preparer'
@@ -0,0 +1,37 @@
1
+ module Harvixture
2
+ module ActiveRecordExtension
3
+ def after_find
4
+ harvixture_model.write_fixture
5
+ end
6
+ def to_harvixture
7
+ lines = attributes.to_yaml.split("\n")
8
+ lines.shift
9
+ "\n#{self.class.table_name}_#{self.id}:\n " + lines.join("\n ")
10
+ end
11
+
12
+ protected
13
+ def harvixture_model
14
+ @harvixture_model ||= Harvixture::Model.new(self)
15
+ end
16
+
17
+ end
18
+ end
19
+
20
+ ActiveRecord::Base.send(:include, Harvixture::ActiveRecordExtension) unless ActiveRecord::Base.included_modules.include?(Harvixture::ActiveRecordExtension)
21
+
22
+ class << ActiveRecord::Base
23
+ # Oh the trickery!
24
+ def method_added(method_name)
25
+ return true if @__adjusting_after_find
26
+ super
27
+ if method_name == :after_find
28
+ @__adjusting_after_find = true
29
+ after_find_method = self.instance_method(:after_find)
30
+ define_method(:after_find) do
31
+ super
32
+ after_find_method.bind(self).call
33
+ end
34
+ @__adjusting_after_find = false
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ require 'open-uri'
2
+ module Harvixture
3
+ module Command
4
+ class << self
5
+ # :rails_root
6
+ # :output_dir
7
+ # :request_path
8
+ # :rails_env
9
+ # :user_id
10
+ def process!(options={})
11
+ process = nil
12
+ Preparer.do_it!(options[:rails_root])
13
+ Config.update(options)
14
+ process = Process.fork do
15
+ Signal.trap('HUP') { exit }
16
+ stdin = open '/dev/null', 'r'
17
+ stdout = open '/dev/null', 'w'
18
+ stderr = open '/dev/null', 'w'
19
+ STDIN.reopen stdin
20
+ STDOUT.reopen stdout
21
+ STDERR.reopen stderr
22
+ exec %(ruby script/server -e harvixture -p 8675)
23
+ end
24
+ # Wait for the script server to reload
25
+ sleep(5)
26
+ open(File.join('http://localhost:8675', Config.request_path))
27
+ rescue Exception => e
28
+ puts e
29
+ puts e.backtrace
30
+ ensure
31
+ Process.kill('HUP', process) if process
32
+ Process.wait
33
+ Process.exit!
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,59 @@
1
+ module Harvixture
2
+ class Config
3
+ class << self
4
+ def rails_env
5
+ values['rails_env']
6
+ end
7
+ def request_path
8
+ values['request_path']
9
+ end
10
+ def output_dir
11
+ values['output_dir']
12
+ end
13
+ def user_id
14
+ values['user_id']
15
+ end
16
+
17
+ def update(attributes = {})
18
+ new_values = {
19
+ 'output_dir' => attributes[:output_dir] || attributes['output_dir'] || output_dir,
20
+ 'rails_env' => attributes[:rails_env] || attributes['rails_env'] || rails_env,
21
+ 'request_path' => attributes[:request_path] || attributes['request_path'] || request_path,
22
+ 'user_id' => attributes[:user_id] || attributes['user_id'] || user_id,
23
+ }
24
+ File.open(filename, 'w+') {|f| f.puts YAML.dump(new_values)}
25
+ Dir.glob(File.join(output_dir, '*.yml')).each {|f| File.delete(f) if File.exist?(f)}
26
+ @values = nil
27
+ values
28
+ end
29
+
30
+ def filename
31
+ File.join(home, '.harvixture_config.yml')
32
+ end
33
+
34
+ protected
35
+ def home
36
+ ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
37
+ end
38
+ def values
39
+ return @values if @values
40
+ begin
41
+ @values = YAML::load(open(filename)) || write_template
42
+ rescue
43
+ @values = write_template
44
+ end
45
+
46
+ @values
47
+ end
48
+
49
+ def write_template
50
+ open(filename,'w').write(template)
51
+ YAML::load open(filename)
52
+ end
53
+
54
+ def template
55
+ %(---\n output_dir: ./test/fixtures/harvixture_scenario\n user_id: \n rails_env: production\n request_path: )
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,21 @@
1
+ require 'fileutils'
2
+ module Harvixture
3
+ class Model
4
+ attr_reader :object
5
+ def initialize(object)
6
+ @object = object
7
+ end
8
+
9
+ def write_fixture
10
+ FileUtils.mkdir_p(File.dirname(filename))
11
+ File.open(filename, 'w+') { |file| file.print '---' } unless File.exist?(filename)
12
+ File.open(filename, 'a+') do |file|
13
+ file.puts object.to_harvixture
14
+ end
15
+ end
16
+
17
+ def filename
18
+ File.join(RAILS_ROOT, Config.output_dir, "#{object.class.table_name}.yml")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module Harvixture
2
+ class Preparer
3
+ class << self
4
+
5
+ # Install the necessary files on the rails project
6
+ def do_it!(rails_root)
7
+ self.new(rails_root)
8
+ end
9
+ end
10
+ attr_reader :rails_root
11
+ def initialize(rails_root)
12
+ @rails_root = rails_root
13
+ create_environment_harvixture
14
+ update_database_yml
15
+ end
16
+
17
+ protected
18
+
19
+ def create_environment_harvixture
20
+ filename = File.join(rails_root, 'config', 'environments', 'harvixture.rb')
21
+ return if File.exist?(filename)
22
+ File.open(filename, 'w+') do |file|
23
+ file.puts '#START DO NOT MODIFY'
24
+ file.puts 'require "harvixture"'
25
+ file.puts '"#{File.read(File.join(File.dirname(__FILE__), "#{Harvixture::Config.rails_env}.rb"))}"'
26
+ file.puts '#END DO NOT MODIFY'
27
+ end
28
+ end
29
+ def update_database_yml
30
+ config = File.read(File.join(rails_root, 'config', 'database.yml'))
31
+ return if config.match(/^harvixture:/)
32
+ puts 'updating database.yml'
33
+ config.gsub!(/^(\w*): *$/, '\1: &\1')
34
+ File.open(File.join(rails_root, 'config', 'database.yml'), 'w+') do |file|
35
+ file.puts "#{config}\n\nharvixture:\n <<: *<%= Harvixture::Config.rails_env rescue 'production' %>"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ class Harvixture::ActiveRecordExtensionTest < Test::Unit::TestCase
3
+ class AbstractUnit < ActiveRecord::Base
4
+ def self.columns; []; end
5
+ def attributes
6
+ {'name' => 'my name', 'id' => id }
7
+ end
8
+ def id; 8675309; end
9
+ end
10
+
11
+ class AbstractUnitWithAfterFind < AbstractUnit
12
+ def after_find
13
+ @after_find_called = true
14
+ end
15
+ def after_find_called?
16
+ @after_find_called
17
+ end
18
+ end
19
+
20
+ def test_after_find_with_inheritance
21
+ abstract_unit = AbstractUnitWithAfterFind.new
22
+ abstract_unit.send(:harvixture_model).expects(:write_fixture)
23
+ abstract_unit.after_find
24
+ end
25
+
26
+ def test_after_find_with_inheritance_calls_defined_inheritance_model
27
+ abstract_unit = AbstractUnitWithAfterFind.new
28
+ abstract_unit.send(:harvixture_model).stubs(:write_fixture)
29
+ abstract_unit.after_find
30
+ assert abstract_unit.after_find_called?
31
+ end
32
+
33
+ def test_after_find_should_write_to_the_harvixture_model
34
+ abstract_unit = AbstractUnit.new
35
+ abstract_unit.send(:harvixture_model).expects(:write_fixture).returns(:expected_value)
36
+ abstract_unit.after_find
37
+ end
38
+
39
+ def test_to_harvixture
40
+ abstract_unit = AbstractUnit.new
41
+ assert_equal abstract_unit.to_harvixture, "\nabstract_units_8675309:\n name: my name\n id: 8675309"
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Harvixture::ModelTest < Test::Unit::TestCase
4
+ class AbstractModel
5
+ class << self
6
+ def table_name
7
+ 'abstract_models'
8
+ end
9
+ end
10
+ def to_harvixture
11
+ %(
12
+ abstract_model_1:
13
+ name: hello)
14
+ end
15
+ end
16
+ def test_fixtures
17
+ @harvixture_model = Harvixture::Model.new(mock_model)
18
+ def @harvixture_model.filename
19
+ File.join(File.dirname(__FILE__), 'tmp.yml')
20
+ end
21
+ @harvixture_model.write_fixture
22
+ assert YAML.load(File.read(@harvixture_model.filename))['abstract_model_1']
23
+ ensure
24
+ FIle.delete(File.dirname(__FILE__), 'tmp.yml') rescue true
25
+ end
26
+
27
+ def mock_model
28
+ @abstract_model ||= AbstractModel.new
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/harvixture'
3
+ require 'mocha'
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: harvixture
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Friesen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-04-28 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: main
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.8.0
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: activerecord
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 2.0.0
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: mocha
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.5.6
41
+ version:
42
+ description: Harvixture is a tool that can be used to extract data, in the form of fixtures, from a Rails project. It is done by pointing the harvixture at a request_path and dumping fixtures for all "found" ActiveRecord objects.
43
+ email: jeremyf@lightsky.com
44
+ executables:
45
+ - harvixture
46
+ extensions: []
47
+
48
+ extra_rdoc_files:
49
+ - README
50
+ files:
51
+ - lib/harvixture/active_record_extension.rb
52
+ - lib/harvixture/command.rb
53
+ - lib/harvixture/config.rb
54
+ - lib/harvixture/model.rb
55
+ - lib/harvixture/preparer.rb
56
+ - lib/harvixture.rb
57
+ - bin/harvixture
58
+ - test/test_harvixture_active_record_extension.rb
59
+ - test/test_harvixture_model.rb
60
+ - test/test_helper.rb
61
+ - README
62
+ - License.txt
63
+ has_rdoc: true
64
+ homepage: http://github.com/jeremyf/harvixture
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --main
68
+ - README
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.0.1
87
+ signing_key:
88
+ specification_version: 2
89
+ summary: A tool for harvesting fixtures from production data
90
+ test_files:
91
+ - test/test_harvixture_active_record_extension.rb
92
+ - test/test_harvixture_model.rb
93
+ - test/test_helper.rb