dynport_tools 0.2.19 → 0.2.20

Sign up to get free protection for your applications and to get access to all the features.
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