whistle 0.1

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.
Files changed (53) hide show
  1. data/History.txt +3 -0
  2. data/README.txt +38 -0
  3. data/bin/whistle +90 -0
  4. data/lib/config.rb +19 -0
  5. data/lib/phash.rb +16 -0
  6. data/lib/relay.rb +24 -0
  7. data/lib/resource.rb +113 -0
  8. data/lib/ssl_patch.rb +15 -0
  9. data/lib/switchbox.rb +54 -0
  10. data/lib/time_ext.rb +30 -0
  11. data/lib/version.rb +3 -0
  12. data/sample/config.yml +12 -0
  13. data/vendor/rscm-0.5.1-patched-stripped/README +218 -0
  14. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm.rb +14 -0
  15. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/abstract_log_parser.rb +35 -0
  16. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/base.rb +289 -0
  17. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/command_line.rb +146 -0
  18. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/difftool.rb +44 -0
  19. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/line_editor.rb +46 -0
  20. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/mockit.rb +157 -0
  21. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/parser.rb +39 -0
  22. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/path_converter.rb +60 -0
  23. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/platform.rb +26 -0
  24. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/revision.rb +103 -0
  25. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/revision_file.rb +85 -0
  26. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/revision_poller.rb +93 -0
  27. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/revisions.rb +79 -0
  28. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/clearcase.rb +182 -0
  29. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/cvs.rb +374 -0
  30. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/cvs_log_parser.rb +154 -0
  31. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/darcs.rb +120 -0
  32. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/darcs_log_parser.rb +65 -0
  33. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/monotone.rb +338 -0
  34. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/monotone_log_parser.rb +109 -0
  35. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/mooky.rb +6 -0
  36. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/perforce.rb +216 -0
  37. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/star_team.rb +104 -0
  38. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/subversion.rb +397 -0
  39. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/scm/subversion_log_parser.rb +165 -0
  40. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/tempdir.rb +17 -0
  41. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/time_ext.rb +11 -0
  42. data/vendor/rscm-0.5.1-patched-stripped/lib/rscm/version.rb +13 -0
  43. data/vendor/ruby-feedparser-0.5-stripped/README +14 -0
  44. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser.rb +28 -0
  45. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser/feedparser.rb +300 -0
  46. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser/filesizes.rb +12 -0
  47. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser/html-output.rb +126 -0
  48. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser/html2text-parser.rb +409 -0
  49. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser/rexml_patch.rb +28 -0
  50. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser/sgml-parser.rb +332 -0
  51. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser/text-output.rb +83 -0
  52. data/vendor/ruby-feedparser-0.5-stripped/lib/feedparser/textconverters.rb +120 -0
  53. metadata +132 -0
@@ -0,0 +1,44 @@
1
+ require 'rscm/tempdir'
2
+ require 'rscm/path_converter'
3
+ require 'rscm/difftool'
4
+
5
+ module RSCM
6
+ module Difftool
7
+ # assertion method that reports differences as diff.
8
+ # useful when comparing big strings
9
+ def assert_equal_with_diff(expected, actual, message="", temp_basedir=File.dirname(__FILE__) + "/../../target")
10
+ diff(expected, actual, temp_basedir) do |diff_io, cmd|
11
+ diff_string = diff_io.read
12
+ if(diff_string.strip != "")
13
+ flunk "#{message}\nThere were differences\ndiff command: #{cmd}\ndiff:\n#{diff_string}"
14
+ end
15
+ end
16
+ end
17
+ module_function :assert_equal_with_diff
18
+
19
+ def diff(expected, actual, temp_basedir, &block)
20
+ dir = RSCM.new_temp_dir("diff", temp_basedir)
21
+
22
+ expected_file = nil
23
+ if(File.exist?(expected))
24
+ expected_file = expected
25
+ else
26
+ expected_file = "#{dir}/expected"
27
+ File.open(expected_file, "w") {|io| io.write(expected)}
28
+ end
29
+
30
+ actual_file = "#{dir}/actual"
31
+ File.open(actual_file, "w") {|io| io.write(actual)}
32
+
33
+ difftool = WINDOWS ? File.dirname(__FILE__) + "/../../bin/diff.exe" : "diff"
34
+ e = RSCM::PathConverter.filepath_to_nativepath(expected_file, false)
35
+ a = RSCM::PathConverter.filepath_to_nativepath(actual_file, false)
36
+ cmd = "#{difftool} --ignore-space-change #{e} #{a}"
37
+ IO.popen(cmd) do |io|
38
+ yield io, cmd
39
+ end
40
+ end
41
+ module_function :diff
42
+
43
+ end
44
+ end
@@ -0,0 +1,46 @@
1
+ require 'tempfile'
2
+ require 'ftools'
3
+
4
+ module RSCM
5
+ module LineEditor
6
+ # Comments out line by line if they match the line_regex.
7
+ # Does not comment out already commented out lines.
8
+ # If comment_template is nil, the matching lines will be deleted
9
+ # Returns true if at least one line is commented out or changed
10
+ def comment_out(original, line_regex, comment_template, output)
11
+ did_comment_out = false
12
+ already_commented_exp = /^[#{comment_template}]/ unless comment_template.nil?
13
+ original.each_line do |line|
14
+ out_line = nil
15
+ if(line_regex =~ line)
16
+ if(already_commented_exp && already_commented_exp =~ line)
17
+ out_line = line
18
+ else
19
+ did_comment_out = true
20
+ out_line = "#{comment_template}#{line}" unless comment_template.nil?
21
+ end
22
+ else
23
+ out_line = line
24
+ end
25
+ output << out_line unless out_line.nil?
26
+ end
27
+ did_comment_out
28
+ end
29
+ module_function :comment_out
30
+ end
31
+ end
32
+
33
+ class File
34
+
35
+ def File.comment_out(path, line_regex, comment_template)
36
+ temp_file = Tempfile.new(File.basename(path))
37
+ temp_file_path = temp_file.path
38
+ original = File.new(path)
39
+ RSCM::LineEditor.comment_out(original, line_regex, comment_template, temp_file)
40
+
41
+ temp_file.close
42
+ original.close
43
+
44
+ File.copy(temp_file_path, path)
45
+ end
46
+ end
@@ -0,0 +1,157 @@
1
+ require 'test/unit/assertions'
2
+
3
+ module Test #:nodoc:
4
+ module Unit #:nodoc:
5
+ class TestCase #:nodoc:
6
+ def setup_with_mocks
7
+ @to_verify = []
8
+ end
9
+ alias_method :setup, :setup_with_mocks
10
+
11
+ def teardown_with_mocks
12
+ if(@test_passed && @to_verify)
13
+ @to_verify.each{|m| m.__verify}
14
+ end
15
+ end
16
+ alias_method :teardown, :teardown_with_mocks
17
+
18
+ def self.method_added(method)
19
+ case method.to_s
20
+ when 'setup'
21
+ unless method_defined?(:setup_without_mocks)
22
+ alias_method :setup_without_mocks, :setup
23
+ define_method(:setup) do
24
+ setup_with_mocks
25
+ setup_without_mocks
26
+ end
27
+ end
28
+ when 'teardown'
29
+ unless method_defined?(:teardown_without_mocks)
30
+ alias_method :teardown_without_mocks, :teardown
31
+ define_method(:teardown) do
32
+ teardown_without_mocks
33
+ teardown_with_mocks
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def new_mock
40
+ mock = MockIt::Mock.new
41
+ @to_verify = [] unless @to_verify
42
+ @to_verify << mock
43
+ mock
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+
50
+ module MockIt
51
+ class Mock
52
+ include Test::Unit::Assertions
53
+
54
+ def initialize
55
+ @expected_methods=[]
56
+ @expected_validation_procs=[]
57
+ @setup_call_procs={}
58
+ @unexpected_calls = []
59
+ end
60
+
61
+ def __expect(method, &validation_proc)
62
+ validation_proc=Proc.new {|*args| nil} if validation_proc.nil?
63
+ @expected_methods<<method
64
+ @expected_validation_procs<<validation_proc
65
+ self
66
+ end
67
+
68
+ def __setup(method, &proc)
69
+ proc=Proc.new {|*args| nil} if proc.nil?
70
+ @setup_call_procs[method]=proc
71
+ self
72
+ end
73
+
74
+ def __verify
75
+ begin
76
+ assert_no_unexpected_calls
77
+ assert_all_expected_methods_called
78
+ ensure
79
+ initialize
80
+ end
81
+ end
82
+
83
+ def method_missing(method, *args, &proc)
84
+ if(is_expected_call(method))
85
+ handle_expected_call(method, *args, &proc)
86
+ elsif(is_setup_call(method))
87
+ handle_setup_call(method, *args, &proc)
88
+ else
89
+ handle_unexpected_call(method)
90
+ end
91
+ end
92
+
93
+ def respond_to?(method)
94
+ return super.respond_to?(method) if super.respond_to?(method)
95
+ method = symbol(method)
96
+ return true if is_setup_call(method)
97
+ return true if currently_expected_method == method
98
+ false
99
+ end
100
+
101
+ private
102
+
103
+ def symbol(string)
104
+ return nil if string==""
105
+ if string.is_a? String then string.intern else string end
106
+ end
107
+
108
+ def assert_no_unexpected_calls
109
+ assert_equal([], @unexpected_calls, "got unexpected call")
110
+ end
111
+
112
+ def assert_all_expected_methods_called
113
+ assert(@expected_validation_procs.empty?, "not all expected methods called, calls left: #{@expected_methods.inspect}")
114
+ end
115
+
116
+ def is_expected_call(method)
117
+ @expected_methods.index(method)
118
+ end
119
+
120
+ def is_setup_call(method)
121
+ not @setup_call_procs[method].nil?
122
+ end
123
+
124
+ def handle_setup_call(method, *args, &proc)
125
+ @setup_call_procs[method].call(*args, &proc)
126
+ end
127
+
128
+ def handle_expected_call(method, *args, &proc)
129
+ assert_equal(currently_expected_method, method, "got unexpected call")
130
+ validation_proc = current_validation_proc
131
+ next_call
132
+ validation_proc.call(*args, &proc)
133
+ end
134
+
135
+ def handle_unexpected_call(method)
136
+ @unexpected_calls << method
137
+ flunk("Unexpected method invocation: #{method}")
138
+ end
139
+
140
+ def currently_expected_method
141
+ if @expected_methods.empty? then nil
142
+ else @expected_methods[0] end
143
+ end
144
+
145
+ def current_validation_proc
146
+ if @expected_validation_procs.empty? then nil
147
+ else @expected_validation_procs[0] end
148
+ end
149
+
150
+ def next_call
151
+ @expected_methods.delete_at(0)
152
+ @expected_validation_procs.delete_at(0)
153
+ end
154
+
155
+ end
156
+ end
157
+
@@ -0,0 +1,39 @@
1
+ module RSCM
2
+ class Parser
3
+
4
+ def initialize(break_regexp)
5
+ @break_regexp = break_regexp
6
+ end
7
+
8
+ def parse(io, skip_line_parsing=false, &line_proc)
9
+ parse_until_regexp_matches(io, skip_line_parsing, &line_proc)
10
+ if(skip_line_parsing)
11
+ nil
12
+ else
13
+ next_result
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def parse_line(line)
20
+ raise "Must override parse_line(line)"
21
+ end
22
+
23
+ def next_result
24
+ raise "Must override next_result(line)"
25
+ end
26
+
27
+ private
28
+
29
+ def parse_until_regexp_matches(io, skip_line_parsing, &line_proc)
30
+ io.each_line { |line|
31
+ yield line if block_given?
32
+ if line =~ @break_regexp
33
+ return
34
+ end
35
+ parse_line(line) unless skip_line_parsing
36
+ }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,60 @@
1
+ WIN32 = RUBY_PLATFORM == "i386-mswin32"
2
+ CYGWIN = RUBY_PLATFORM == "i386-cygwin"
3
+ WINDOWS = WIN32 || CYGWIN
4
+
5
+ require 'fileutils'
6
+
7
+ # Utility for converting between win32 and cygwin paths. Does nothing on *nix.
8
+ module RSCM
9
+ module PathConverter
10
+ def filepath_to_nativepath(path, escaped)
11
+ return nil if path.nil?
12
+ path = File.expand_path(path)
13
+ if(WIN32)
14
+ escaped ? path.gsub(/\//, "\\\\\\\\") : path.gsub(/\//, "\\")
15
+ elsif(CYGWIN)
16
+ cygpath = `cygpath --windows #{path}`.chomp
17
+ escaped ? cygpath.gsub(/\\/, "\\\\\\\\") : cygpath
18
+ else
19
+ path
20
+ end
21
+ end
22
+ module_function :filepath_to_nativepath
23
+
24
+ def filepath_to_nativeurl(path)
25
+ return nil if path.nil?
26
+ if(WINDOWS)
27
+ urlpath = filepath_to_nativepath(path, false).gsub(/\\/, "/")
28
+ "file:///#{urlpath}"
29
+ else
30
+ "file://#{File.expand_path(path)}"
31
+ end
32
+ end
33
+ module_function :filepath_to_nativeurl
34
+
35
+ def nativepath_to_filepath(path)
36
+ return nil if path.nil?
37
+ path = File.expand_path(path)
38
+ if(WIN32)
39
+ path.gsub(/\//, "\\")
40
+ elsif(CYGWIN)
41
+ path = path.gsub(/\\/, "/")
42
+ `cygpath --unix #{path}`.chomp
43
+ else
44
+ path
45
+ end
46
+ end
47
+ module_function :nativepath_to_filepath
48
+
49
+ def ensure_trailing_slash(url)
50
+ return nil if url.nil?
51
+ if(url && url[-1..-1] != "/")
52
+ "#{url}/"
53
+ else
54
+ url
55
+ end
56
+ end
57
+ module_function :ensure_trailing_slash
58
+
59
+ end
60
+ end
@@ -0,0 +1,26 @@
1
+ require 'rbconfig'
2
+
3
+ module RSCM
4
+ module Platform
5
+ def family
6
+ target_os = Config::CONFIG["target_os"] or ""
7
+ return "powerpc-darwin" if target_os.downcase =~ /darwin/
8
+ return "mswin32" if target_os.downcase =~ /32/
9
+ return "cygwin" if target_os.downcase =~ /cyg/
10
+ return "freebsd" if target_os.downcase =~ /freebsd/
11
+ return "freebsd" if target_os.downcase =~ /linux/
12
+ return "unknown"
13
+ end
14
+ module_function :family
15
+
16
+ def user
17
+ family == "mswin32" ? ENV['USERNAME'] : ENV['USER']
18
+ end
19
+ module_function :user
20
+
21
+ def prompt(dir=Dir.pwd)
22
+ prompt = "#{dir.gsub(/\//, File::SEPARATOR)} #{user}$"
23
+ end
24
+ module_function :prompt
25
+ end
26
+ end
@@ -0,0 +1,103 @@
1
+ require 'rscm/time_ext'
2
+ require 'rscm/revision_file'
3
+ require 'yaml'
4
+
5
+ module RSCM
6
+ # Represents a collection of RevisionFile that were committed at the
7
+ # same time, or "more or less at the same time" for non-atomic
8
+ # SCMs (such as CVS and StarTeam). See Revisions for how to emulate
9
+ # atomicity for non-atomic SCMs.
10
+ class Revision
11
+ include Enumerable
12
+
13
+ attr_writer :identifier
14
+ attr_accessor :developer
15
+ attr_accessor :message
16
+
17
+ def initialize(identifier=nil, time=nil)
18
+ @identifier = identifier
19
+ @time = time
20
+ @files = []
21
+ end
22
+
23
+ def add(file)
24
+ raise "Can't add #{file} to this revision" unless accept? file
25
+ @files << file
26
+ self.developer = file.developer if file.developer
27
+ self.message = file.message if file.message
28
+ end
29
+
30
+ def identifier(min_or_max = :max)
31
+ @identifier || time(min_or_max)
32
+ end
33
+
34
+ # The time of this revision. Depending on the value of +min_or_max+,
35
+ # (should be :min or :max), returns the min or max time of this
36
+ # revision. (min or max only matters for non-transactional scms)
37
+ def time(min_or_max = :max)
38
+ @time || self.collect{|file| file.time}.__send__(min_or_max)
39
+ end
40
+
41
+ # Sets the time for this revision. Should only be used by atomic SCMs.
42
+ # Non-atomic SCMs should <b>not</b> invoke this method, but instead create
43
+ # revisions by adding RscmFile objects to a Revisions object.
44
+ def time=(t)
45
+ raise "time must be a Time object - it was a #{t.class.name} with the string value #{t}" unless t.is_a?(Time)
46
+ raise "can't set time to an inferiour value than the previous value" if @time && (t < @time)
47
+ @time = t
48
+ end
49
+
50
+ # Whether +file+ can be added to this instance.
51
+ def accept?(file) #:nodoc:
52
+ return true if empty? || @time
53
+
54
+ close_enough_to_min = (time(:min) - file.time).abs <= 60
55
+ close_enough_to_max = (time(:max) - file.time).abs <= 60
56
+ close_enough = close_enough_to_min or close_enough_to_max
57
+
58
+ close_enough and
59
+ self.developer == file.developer and
60
+ self.message == file.message
61
+ end
62
+
63
+ def ==(other)
64
+ self.to_s == other.to_s
65
+ end
66
+
67
+ # String representation that can be used for debugging.
68
+ def to_s
69
+ if(@to_s.nil?)
70
+ min = time(:min)
71
+ max = time(:max)
72
+ t = (min==max) ? min : "#{min}-#{max}"
73
+ @to_s = "#{identifier} | #{developer} | #{t} | #{message}\n"
74
+ self.each do |file|
75
+ @to_s << " " << file.to_s << "\n"
76
+ end
77
+ @to_s
78
+ end
79
+ @to_s
80
+ end
81
+
82
+ def each(&block)
83
+ @files.each(&block)
84
+ end
85
+
86
+ def [](n)
87
+ @files[n]
88
+ end
89
+
90
+ def length
91
+ @files.length
92
+ end
93
+
94
+ def pop
95
+ @files.pop
96
+ end
97
+
98
+ def empty?
99
+ @files.empty?
100
+ end
101
+
102
+ end
103
+ end