dynport_tools 0.2.19 → 0.2.20

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/Gemfile CHANGED
@@ -21,4 +21,8 @@ group :development do
21
21
  gem "autotest-growl"
22
22
  gem "ruby-debug"
23
23
  gem "timecop"
24
+ gem "guard"
25
+ gem "growl"
26
+ gem "rb-fsevent"
27
+ gem "spork"
24
28
  end
data/Gemfile.lock CHANGED
@@ -8,6 +8,9 @@ GEM
8
8
  columnize (0.3.4)
9
9
  diff-lcs (1.1.2)
10
10
  git (1.2.5)
11
+ growl (1.0.3)
12
+ guard (0.8.4)
13
+ thor (~> 0.14.6)
11
14
  jeweler (1.6.4)
12
15
  bundler (~> 1.0)
13
16
  git (>= 1.2.5)
@@ -17,6 +20,7 @@ GEM
17
20
  mime-types (1.16)
18
21
  nokogiri (1.5.0)
19
22
  rake (0.9.2)
23
+ rb-fsevent (0.4.3.1)
20
24
  rbx-require-relative (0.0.5)
21
25
  rcov (0.9.9)
22
26
  redis (2.2.1)
@@ -33,7 +37,9 @@ GEM
33
37
  ruby-debug-base (~> 0.10.4.0)
34
38
  ruby-debug-base (0.10.4)
35
39
  linecache (>= 0.3)
40
+ spork (0.8.5)
36
41
  term-ansicolor (1.0.5)
42
+ thor (0.14.6)
37
43
  timecop (0.3.5)
38
44
  typhoeus (0.2.4)
39
45
  mime-types
@@ -48,12 +54,16 @@ DEPENDENCIES
48
54
  autotest-growl
49
55
  bundler (~> 1.0.0)
50
56
  diff-lcs
57
+ growl
58
+ guard
51
59
  jeweler (~> 1.6.4)
52
60
  nokogiri
61
+ rb-fsevent
53
62
  rcov
54
63
  redis
55
64
  rspec (~> 2.3.0)
56
65
  ruby-debug
66
+ spork
57
67
  term-ansicolor
58
68
  timecop
59
69
  typhoeus
data/Guardfile ADDED
@@ -0,0 +1,104 @@
1
+ require "guard/guard"
2
+
3
+ SPORK_CONFIG = {
4
+ # "SPORK_INTEGRATION" => 8987,
5
+ # "SPORK_LIGHT" => 8988,
6
+ "SPORK_DEFAULT" => 8989
7
+ }
8
+
9
+ module ::Guard
10
+ class Multispork < ::Guard::Guard
11
+ def start
12
+ ENV["AUTOTEST"] = "true"
13
+ SPORK_CONFIG.each do |env_key, port|
14
+ Process.fork do
15
+ ENV[env_key] = "true"
16
+ cmd = "spork -p #{port}"
17
+ puts "running: #{cmd} with #{ENV[env_key]}=true"
18
+ system cmd
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ module ::Guard
26
+ class Simplespec < ::Guard::Guard
27
+ def run_all
28
+ puts "running all"
29
+ end
30
+
31
+ def run_on_change(paths)
32
+ paths = paths.select { |path| File.exists?(path) }.uniq
33
+ if paths.any?
34
+ started = Time.now
35
+ cmd = "rspec #{paths.join(" ")}"
36
+ port = nil
37
+ if paths.first.include?("spec/integration")
38
+ port = SPORK_CONFIG["SPORK_INTEGRATION"]
39
+ elsif paths.length == 1 && File.read(paths.first).match(/^# (SPORK_.*?)\n/)
40
+ port = SPORK_CONFIG[$1]
41
+ end
42
+ cmd << " --drb"
43
+ # cmd << " --drb --port #{port || SPORK_CONFIG["SPORK_DEFAULT"]} --color"
44
+ cmd << " --color"
45
+ puts "-" * 100
46
+ stats = run_specs(cmd)
47
+ # status = :success #!!out.match(/ 0 failure/) ? :success : :failed
48
+ diff = Time.now - started
49
+ puts "-" * 100
50
+ time_s = "#{diff} (#{diff - stats[:time]} overhead)"
51
+ puts "total time: #{time_s}"
52
+ ::Guard::Notifier.notify("#{stats[:status]} in #{time_s}", :title => "RSpec #{stats[:examples]} examples", :image => stats[:status])
53
+ end
54
+ end
55
+
56
+ def run_specs(cmd)
57
+ puts "running #{cmd}"
58
+ chars = ""
59
+ IO.popen(cmd, "r") do |f|
60
+ until f.eof?
61
+ char = f.readchar.chr
62
+ print char
63
+ $stdout.flush
64
+ chars << char
65
+ end
66
+ end
67
+ { :time => chars[/Finished in ([\d|\.]+)/, 1].to_f, :examples => chars[/(\d+) examples/].to_i }.tap do |stats|
68
+ if !chars.include?(" 0 failures")
69
+ stats.merge!(:status => :failed)
70
+ # elsif !chars.include?(" 0 pending")
71
+ # :pending
72
+ else
73
+ stats.merge!(:status => :success)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ group "spork" do
81
+ guard "multispork" do
82
+ end
83
+ end
84
+
85
+ group "spec" do
86
+ guard "simplespec" do
87
+ watch(%r{^spec/.*_spec.rb})
88
+ watch(%r{^spec/.+_spec\.rb$})
89
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
90
+ # watch('spec/spec_helper.rb') { "spec" }
91
+
92
+ # Rails example
93
+ watch(%r{^spec/.+_spec\.rb$})
94
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
95
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
96
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
97
+ # watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
98
+ # watch('spec/spec_helper.rb') { "spec" }
99
+ # watch('config/routes.rb') { "spec/routing" }
100
+ # watch('app/controllers/application_controller.rb') { "spec/controllers" }
101
+ # Capybara request specs
102
+ # watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
103
+ end
104
+ end
data/README.rdoc CHANGED
@@ -1,6 +1,10 @@
1
1
  = dynport_tools
2
2
 
3
- Description goes here.
3
+ == LogTracer ==
4
+ DynportTools::LogTracer.setup(Rails.logger)
5
+
6
+ Rails.logger.register_tracer(/SELECT.*?FROM.*?users/) do |arr|
7
+ end
4
8
 
5
9
  == Contributing to dynport_tools
6
10
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.19
1
+ 0.2.20
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{dynport_tools}
8
- s.version = "0.2.19"
7
+ s.name = "dynport_tools"
8
+ s.version = "0.2.20"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tobias Schwab"]
12
- s.date = %q{2011-09-14}
13
- s.description = %q{Collection of various tools}
14
- s.email = %q{tobias.schwab@dynport.de}
12
+ s.date = "2012-01-31"
13
+ s.description = "Collection of various tools"
14
+ s.email = "tobias.schwab@dynport.de"
15
15
  s.executables = ["xmldiff", "redis_dumper"]
16
16
  s.extra_rdoc_files = [
17
17
  "LICENSE.txt",
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  ".rspec",
25
25
  "Gemfile",
26
26
  "Gemfile.lock",
27
+ "Guardfile",
27
28
  "LICENSE.txt",
28
29
  "README.rdoc",
29
30
  "Rakefile",
@@ -38,24 +39,30 @@ Gem::Specification.new do |s|
38
39
  "lib/dynport_tools/differ.rb",
39
40
  "lib/dynport_tools/embedded_redis.rb",
40
41
  "lib/dynport_tools/eta.rb",
42
+ "lib/dynport_tools/features.rb",
41
43
  "lib/dynport_tools/have_attributes.rb",
42
44
  "lib/dynport_tools/jenkins.rb",
43
45
  "lib/dynport_tools/job_dsl.rb",
44
46
  "lib/dynport_tools/log_tracer.rb",
45
47
  "lib/dynport_tools/redis_dumper.rb",
46
48
  "lib/dynport_tools/redis_q.rb",
49
+ "lib/dynport_tools/services.rb",
50
+ "lib/dynport_tools/settings.rb",
47
51
  "lib/dynport_tools/xml_file.rb",
48
52
  "spec/dynport_tools/ascii_table_spec.rb",
49
53
  "spec/dynport_tools/deep_merger_spec.rb",
50
54
  "spec/dynport_tools/differ_spec.rb",
51
55
  "spec/dynport_tools/embedded_redis_spec.rb",
52
56
  "spec/dynport_tools/eta_spec.rb",
57
+ "spec/dynport_tools/features_spec.rb",
53
58
  "spec/dynport_tools/have_attributes_spec.rb",
54
59
  "spec/dynport_tools/jenkins_spec.rb",
55
60
  "spec/dynport_tools/job_dsl_spec.rb",
56
61
  "spec/dynport_tools/log_tracer_spec.rb",
57
62
  "spec/dynport_tools/redis_dumper_spec.rb",
58
63
  "spec/dynport_tools/redis_q_spec.rb",
64
+ "spec/dynport_tools/services_spec.rb",
65
+ "spec/dynport_tools/settings_spec.rb",
59
66
  "spec/dynport_tools/xml_file_spec.rb",
60
67
  "spec/dynport_tools_spec.rb",
61
68
  "spec/fixtures/file_a.xml",
@@ -63,11 +70,11 @@ Gem::Specification.new do |s|
63
70
  "spec/spec_helper.rb",
64
71
  "spec/xml_diff_spec.rb"
65
72
  ]
66
- s.homepage = %q{http://github.com/tobstarr/dynport_tools}
73
+ s.homepage = "http://github.com/tobstarr/dynport_tools"
67
74
  s.licenses = ["MIT"]
68
75
  s.require_paths = ["lib"]
69
- s.rubygems_version = %q{1.6.2}
70
- s.summary = %q{Collection of various tools}
76
+ s.rubygems_version = "1.8.11"
77
+ s.summary = "Collection of various tools"
71
78
 
72
79
  if s.respond_to? :specification_version then
73
80
  s.specification_version = 3
@@ -87,6 +94,10 @@ Gem::Specification.new do |s|
87
94
  s.add_development_dependency(%q<autotest-growl>, [">= 0"])
88
95
  s.add_development_dependency(%q<ruby-debug>, [">= 0"])
89
96
  s.add_development_dependency(%q<timecop>, [">= 0"])
97
+ s.add_development_dependency(%q<guard>, [">= 0"])
98
+ s.add_development_dependency(%q<growl>, [">= 0"])
99
+ s.add_development_dependency(%q<rb-fsevent>, [">= 0"])
100
+ s.add_development_dependency(%q<spork>, [">= 0"])
90
101
  else
91
102
  s.add_dependency(%q<nokogiri>, [">= 0"])
92
103
  s.add_dependency(%q<redis>, [">= 0"])
@@ -102,6 +113,10 @@ Gem::Specification.new do |s|
102
113
  s.add_dependency(%q<autotest-growl>, [">= 0"])
103
114
  s.add_dependency(%q<ruby-debug>, [">= 0"])
104
115
  s.add_dependency(%q<timecop>, [">= 0"])
116
+ s.add_dependency(%q<guard>, [">= 0"])
117
+ s.add_dependency(%q<growl>, [">= 0"])
118
+ s.add_dependency(%q<rb-fsevent>, [">= 0"])
119
+ s.add_dependency(%q<spork>, [">= 0"])
105
120
  end
106
121
  else
107
122
  s.add_dependency(%q<nokogiri>, [">= 0"])
@@ -118,6 +133,10 @@ Gem::Specification.new do |s|
118
133
  s.add_dependency(%q<autotest-growl>, [">= 0"])
119
134
  s.add_dependency(%q<ruby-debug>, [">= 0"])
120
135
  s.add_dependency(%q<timecop>, [">= 0"])
136
+ s.add_dependency(%q<guard>, [">= 0"])
137
+ s.add_dependency(%q<growl>, [">= 0"])
138
+ s.add_dependency(%q<rb-fsevent>, [">= 0"])
139
+ s.add_dependency(%q<spork>, [">= 0"])
121
140
  end
122
141
  end
123
142
 
data/lib/dynport_tools.rb CHANGED
@@ -8,4 +8,4 @@ require "cgi"
8
8
  require "term/ansicolor"
9
9
  require "diff/lcs"
10
10
 
11
- %w(deep_merger differ jenkins redis_dumper xml_file have_attributes redis_q eta ascii_table embedded_redis job_dsl log_tracer).map { |m| require "dynport_tools/#{m}" }
11
+ %w(settings features deep_merger differ jenkins redis_dumper xml_file have_attributes redis_q eta ascii_table embedded_redis job_dsl log_tracer).map { |m| require "dynport_tools/#{m}" }
@@ -0,0 +1,24 @@
1
+ class DynportTools::Features
2
+ class << self
3
+ attr_accessor :features, :redis
4
+
5
+ def feature(name)
6
+ self.features ||= Array.new
7
+ self.features << name
8
+ self.class.send(:define_method, :"#{name}_enabled_for?") do |user, &block|
9
+ enabled = !user.nil? && redis.sismember("features/#{name}/users", user.id.to_s)
10
+ block.call if enabled && block
11
+ enabled
12
+ end
13
+ end
14
+
15
+ def add_user(feature, user)
16
+ raise "feature #{feature} not defined" if !(features || []).include?(feature)
17
+ redis.sadd("features/#{feature}/users", user.id)
18
+ end
19
+
20
+ def remove_user(feature, user)
21
+ redis.srem("features/#{feature}/users", user.id)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,130 @@
1
+ class DynportTools::Services
2
+ DEFAULTS = {
3
+ :solr_url => "http://localhost:8983/solr/",
4
+ :solr_data_root => "/opt/solr",
5
+ :solr_xml => %(
6
+ <?xml version="1.0" encoding="UTF-8" ?>
7
+ <solr sharedLib="lib" persistent="true">
8
+ <cores adminPath="/admin/cores">
9
+ </cores>
10
+ </solr>
11
+ ).gsub(/^\s+/, "")
12
+ }
13
+
14
+ # solr
15
+ attr_writer :solr_url
16
+ attr_accessor :solr_instance_path, :solr_data_root
17
+
18
+ def solr_data_root
19
+ @solr_data_root || DEFAULTS[:solr_data_root]
20
+ end
21
+
22
+ def solr_xml_path
23
+ "#{solr_data_root}/solr.xml"
24
+ end
25
+
26
+ def solr_bootstrapped?
27
+ File.exists?(solr_xml_path)
28
+ end
29
+
30
+ def bootstrap_solr
31
+ raise "#{solr_xml_path} already exists" if solr_bootstrapped?
32
+ write_solr_xml_when_possible
33
+ end
34
+
35
+ def write_solr_xml_when_possible
36
+ raise "please create #{solr_data_root} first" if !File.directory?(solr_data_root)
37
+ write_solr_xml
38
+ end
39
+
40
+ def write_solr_xml
41
+ File.open(solr_xml_path, "w") do |f|
42
+ f.puts(DEFAULTS[:solr_xml])
43
+ end
44
+ end
45
+
46
+ def head(url)
47
+ if code = system_call(%(curl -s -I "#{url}" | head -n 1)).to_s.split(" ").at(1)
48
+ code.to_i
49
+ end
50
+ end
51
+
52
+ def post(url)
53
+ system_call(%(curl -s -I -XPOST "#{url}"))
54
+ end
55
+
56
+ def solr_url
57
+ @solr_url || DEFAULTS[:solr_url]
58
+ end
59
+
60
+ def solr_running?
61
+ head(self.solr_url) == 200
62
+ end
63
+
64
+ def solr_core_exists?(core_name)
65
+ head("#{solr_url}#{core_name}/admin/") == 200
66
+ end
67
+
68
+ def create_solr_core(core_name)
69
+ raise "please set solr_instance_path first!" if self.solr_instance_path.nil?
70
+ raise "please set solr_data_root first!" if self.solr_data_root.nil?
71
+ post("#{solr_url}admin/cores?action=CREATE&name=#{core_name}&instanceDir=#{solr_instance_path}&dataDir=#{solr_data_root}/#{core_name}")
72
+ end
73
+
74
+ def unload_solr_core(core_name)
75
+ post("#{solr_url}admin/cores?action=UNLOAD&core=#{core_name}")
76
+ end
77
+
78
+ # redis
79
+ attr_writer :redis_path_prefix, :redis_config_path, :redis_config_hash
80
+
81
+ def redis_running?
82
+ system_call(%(echo "info" | redis-cli -s #{redis_socket_path} 2> /dev/null | grep uptime_in_seconds)).include?("uptime_in_seconds")
83
+ end
84
+
85
+ def redis_path_prefix
86
+ @redis_path_prefix or raise "redis_path_prefix not set!"
87
+ end
88
+
89
+ def redis_socket_path
90
+ "#{redis_path_prefix}.socket"
91
+ end
92
+
93
+ def redis_config_path
94
+ "#{redis_path_prefix}.conf"
95
+ end
96
+
97
+ def redis_log_path
98
+ "#{redis_path_prefix}.log"
99
+ end
100
+
101
+ def redis_config_hash
102
+ {
103
+ :unixsocket => redis_socket_path,
104
+ :port => 0,
105
+ :logfile => redis_log_path,
106
+ :daemonize => "yes"
107
+ }.merge(@redis_config_hash || {})
108
+ end
109
+
110
+ def redis_config
111
+ (redis_config_hash || {}).map { |key, value| "#{key} #{value}" if !value.nil? }.compact.join("\n")
112
+ end
113
+
114
+ def write_redis_config
115
+ raise "please set redis_config_path first!" if redis_config_path.nil?
116
+ File.open(redis_config_path, "w") do |f|
117
+ f.puts(redis_config)
118
+ end
119
+ end
120
+
121
+ def start_redis
122
+ write_redis_config
123
+ system_call("redis-server #{redis_config_path}")
124
+ end
125
+
126
+ def system_call(cmd)
127
+ puts "executing: #{cmd}"
128
+ Kernel.send(:`, cmd)
129
+ end
130
+ end
@@ -0,0 +1,93 @@
1
+ class DynportTools::Settings
2
+ SETTINGS_KEY = "settings"
3
+ SETTINGS_UPDATED_AT_KEY = "#{SETTINGS_KEY}/updated_at"
4
+
5
+ class << self
6
+ attr_accessor :redis, :defaults
7
+
8
+ def set(key_or_hash, default_or_nil = nil)
9
+ self.defaults ||= Hash.new
10
+ if key_or_hash.is_a?(Hash)
11
+ key_or_hash.each do |key, default|
12
+ self.defaults[key.to_sym] = default
13
+ define_methods_for_key_and_default(key.to_sym, default)
14
+ end
15
+ elsif !default_or_nil.nil?
16
+ self.defaults[key_or_hash.to_sym] = default_or_nil
17
+ define_methods_for_key_and_default(key_or_hash.to_sym, default_or_nil)
18
+ end
19
+ end
20
+
21
+ def define_methods_for_key_and_default(key, default)
22
+ self.class.send(:define_method, key) do
23
+ get(key)
24
+ end
25
+
26
+ self.class.send(:define_method, :"set_#{key}") do |value|
27
+ set_value(key, value)
28
+ end
29
+
30
+ # bool methods
31
+ if [true, false].include?(default)
32
+ self.class.send(:define_method, "#{key}?") do
33
+ get(key)
34
+ end
35
+
36
+ self.class.send(:define_method, :"disable_#{key}!") do
37
+ set_value(key, false)
38
+ end
39
+
40
+ self.class.send(:define_method, :"enable_#{key}!") do
41
+ set_value(key, true)
42
+ end
43
+ end
44
+ end
45
+
46
+ def set_value(key, value)
47
+ time = Time.now
48
+ redis.multi do
49
+ redis.hset(SETTINGS_KEY, key, value)
50
+ redis.set(SETTINGS_UPDATED_AT_KEY, time.to_i)
51
+ end
52
+ reload!(time)
53
+ end
54
+
55
+ def convert_value_for_key(key, value)
56
+ if defaults[key].is_a?(Numeric)
57
+ value.to_i
58
+ elsif [true, false].include?(defaults[key])
59
+ value == "true"
60
+ else
61
+ value.to_s
62
+ end
63
+ end
64
+
65
+ def get(key)
66
+ if value = all[key.to_s]
67
+ convert_value_for_key(key, value)
68
+ else
69
+ defaults[key]
70
+ end
71
+ end
72
+
73
+ def all
74
+ if @all.nil? || expired?
75
+ reload!
76
+ end
77
+ @all
78
+ end
79
+
80
+ def reload!(timestamp = nil)
81
+ @all = redis.hgetall(SETTINGS_KEY)
82
+ @cached_at = timestamp || Time.now
83
+ end
84
+
85
+ def expired?
86
+ @cached_at && Time.now - @cached_at > 60
87
+ end
88
+
89
+ def changed?
90
+ @cached_at.nil? || redis.get(SETTINGS_UPDATED_AT_KEY).to_i != @cached_at.to_i
91
+ end
92
+ end
93
+ end