right_scraper 1.0.26 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/Gemfile +16 -0
  2. data/README.rdoc +9 -28
  3. data/Rakefile +51 -39
  4. data/lib/right_scraper/builders/base.rb +64 -0
  5. data/lib/right_scraper/builders/filesystem.rb +96 -0
  6. data/lib/right_scraper/builders/union.rb +57 -0
  7. data/lib/right_scraper/logger.rb +102 -0
  8. data/lib/right_scraper/loggers/noisy.rb +85 -0
  9. data/lib/right_scraper/processes/ssh.rb +188 -0
  10. data/lib/right_scraper/repositories/base.rb +299 -0
  11. data/lib/right_scraper/repositories/download.rb +90 -0
  12. data/lib/right_scraper/repositories/git.rb +92 -0
  13. data/lib/right_scraper/repositories/mock.rb +70 -0
  14. data/lib/right_scraper/repositories/svn.rb +96 -0
  15. data/lib/right_scraper/resources/base.rb +70 -0
  16. data/{spec/scraper_base_spec.rb → lib/right_scraper/resources/cookbook.rb} +9 -23
  17. data/lib/right_scraper/resources/workflow.rb +55 -0
  18. data/lib/right_scraper/retrievers/base.rb +114 -0
  19. data/lib/right_scraper/retrievers/checkout.rb +79 -0
  20. data/lib/right_scraper/retrievers/download.rb +97 -0
  21. data/lib/right_scraper/retrievers/git.rb +140 -0
  22. data/lib/right_scraper/retrievers/svn.rb +87 -0
  23. data/lib/right_scraper/scanners/base.rb +111 -0
  24. data/lib/right_scraper/scanners/cookbook_manifest.rb +59 -0
  25. data/lib/right_scraper/scanners/cookbook_metadata.rb +69 -0
  26. data/lib/right_scraper/scanners/cookbook_s3_upload.rb +84 -0
  27. data/lib/right_scraper/scanners/union.rb +89 -0
  28. data/lib/right_scraper/scanners/workflow_manifest.rb +86 -0
  29. data/lib/right_scraper/scanners/workflow_metadata.rb +70 -0
  30. data/lib/right_scraper/scanners/workflow_s3_upload.rb +85 -0
  31. data/lib/right_scraper/scraper.rb +81 -57
  32. data/lib/right_scraper/scraper_logger.rb +61 -0
  33. data/lib/right_scraper/scrapers/base.rb +262 -0
  34. data/lib/right_scraper/scrapers/cookbook.rb +73 -0
  35. data/lib/right_scraper/scrapers/workflow.rb +88 -0
  36. data/lib/right_scraper/svn_client.rb +101 -0
  37. data/lib/right_scraper/version.rb +28 -0
  38. data/lib/right_scraper.rb +35 -11
  39. data/right_scraper.gemspec +26 -13
  40. data/right_scraper.rconf +13 -0
  41. data/spec/builder_spec.rb +50 -0
  42. data/spec/cookbook_helper.rb +73 -0
  43. data/spec/cookbook_manifest_spec.rb +55 -0
  44. data/spec/cookbook_s3_upload_spec.rb +152 -0
  45. data/spec/download/download_retriever_spec.rb +118 -0
  46. data/spec/download/download_retriever_spec_helper.rb +72 -0
  47. data/spec/download/download_spec.rb +130 -0
  48. data/spec/download/multi_dir_spec.rb +106 -0
  49. data/spec/download/multi_dir_spec_helper.rb +40 -0
  50. data/spec/git/cookbook_spec.rb +166 -0
  51. data/spec/git/demokey +27 -0
  52. data/spec/git/demokey.pub +1 -0
  53. data/spec/git/password_key +30 -0
  54. data/spec/git/password_key.pub +1 -0
  55. data/spec/git/repository_spec.rb +110 -0
  56. data/spec/git/retriever_spec.rb +505 -0
  57. data/spec/git/retriever_spec_helper.rb +112 -0
  58. data/spec/git/scraper_spec.rb +136 -0
  59. data/spec/git/ssh_spec.rb +170 -0
  60. data/spec/git/url_spec.rb +103 -0
  61. data/spec/logger_spec.rb +185 -0
  62. data/spec/repository_spec.rb +89 -23
  63. data/spec/{scraper_spec_helper_base.rb → retriever_spec_helper.rb} +41 -27
  64. data/spec/scanner_spec.rb +61 -0
  65. data/spec/scraper_helper.rb +96 -0
  66. data/spec/scraper_spec.rb +123 -45
  67. data/spec/spec_helper.rb +87 -14
  68. data/spec/svn/cookbook_spec.rb +97 -0
  69. data/spec/svn/multi_svn_spec.rb +64 -0
  70. data/spec/svn/multi_svn_spec_helper.rb +40 -0
  71. data/spec/svn/repository_spec.rb +72 -0
  72. data/spec/svn/retriever_spec.rb +261 -0
  73. data/spec/svn/scraper_spec.rb +90 -0
  74. data/spec/svn/{svn_scraper_spec_helper.rb → svn_retriever_spec_helper.rb} +46 -27
  75. data/spec/svn/url_spec.rb +47 -0
  76. data/spec/url_spec.rb +164 -0
  77. metadata +203 -31
  78. data/lib/right_scraper/linux/process_monitor.rb +0 -84
  79. data/lib/right_scraper/repository.rb +0 -78
  80. data/lib/right_scraper/scraper_base.rb +0 -175
  81. data/lib/right_scraper/scrapers/download_scraper.rb +0 -67
  82. data/lib/right_scraper/scrapers/git_scraper.rb +0 -283
  83. data/lib/right_scraper/scrapers/svn_scraper.rb +0 -119
  84. data/lib/right_scraper/watcher.rb +0 -158
  85. data/lib/right_scraper/win32/process_monitor.rb +0 -98
  86. data/spec/download/download_scraper_spec.rb +0 -94
  87. data/spec/git/git_scraper_spec.rb +0 -165
  88. data/spec/git/git_scraper_spec_helper.rb +0 -72
  89. data/spec/rcov.opts +0 -1
  90. data/spec/spec.opts +0 -2
  91. data/spec/svn/svn_scraper_spec.rb +0 -148
  92. data/spec/watcher_spec.rb +0 -74
@@ -0,0 +1,262 @@
1
+ #--
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ module RightScraper
25
+ module Scrapers
26
+
27
+ # Base class for all scrapers. Subclasses should override
28
+ # #find_next which instantiates the resource from the file system.
29
+ class Base
30
+
31
+ # Scraped resources
32
+ attr_reader :resources
33
+
34
+ # Initialize scraper
35
+ #
36
+ # === Options
37
+ # <tt>:kind</tt>:: Scraper type, one of :cookbook or :workflow
38
+ # <tt>:repo_dir</tt>:: Required, path to directory containing files
39
+ # to be scraped
40
+ # <tt>:ignorable_paths</tt>:: List of directory names that should
41
+ # be ignored by scraper
42
+ # <tt>:scanners</tt>:: List of Scanner classes to use, optional
43
+ # <tt>:builders</tt>:: List of Builder classes to use, optional
44
+ #
45
+ # === Return
46
+ # scraper(Scrapers::Base):: Corresponding scraper instance
47
+ def self.scraper(options)
48
+ scraper_kind = options.delete(:kind)
49
+ scraper_class = @@types[scraper_kind]
50
+ raise "Can't understand how to build scraper #{scraper_kind}" if scraper_class.nil?
51
+ scraper = scraper_class.new(options)
52
+ end
53
+
54
+ # Do the scrape!
55
+ # Extract all resources from directory
56
+ # Call this method or call 'next_resource' to retrieve
57
+ # resources one by one (you must then call 'close' yourself)
58
+ # Fill @resources
59
+ #
60
+ # === Return
61
+ # resources<Array>:: List of all scraped resources
62
+ def scrape
63
+ @resources = []
64
+ begin
65
+ resource = next_resource
66
+ until resource.nil?
67
+ @resources << resource
68
+ resource = next_resource
69
+ end
70
+ ensure
71
+ close
72
+ end
73
+ @resources
74
+ end
75
+
76
+ # Return the next resource in the filesystem, or nil if none. As
77
+ # a part of building the resources, invokes the builders.
78
+ # A resource can be a cookbook, a workflow, a RightScript etc.
79
+ #
80
+ # === Returns
81
+ # Object:: next resource in filesystem, or nil if none.
82
+ def next_resource
83
+ @logger.operation(:next) do
84
+ next nil if @next.nil?
85
+
86
+ value = @next
87
+ @next = search_dirs
88
+ while @next.nil? && !@queue.empty?
89
+ pop_queue
90
+ end
91
+ value
92
+ end
93
+ end
94
+
95
+ # Close any opened file descriptor
96
+ #
97
+ # === Return
98
+ # true:: Always return true
99
+ def close
100
+ @builder.finish
101
+ if @stack && !@stack.empty?
102
+ @stack.each {|s| s.close}
103
+ @stack = []
104
+ end
105
+ true
106
+ end
107
+
108
+ protected
109
+
110
+ # Directory containing files to be scraped
111
+ attr_reader :repo_dir
112
+
113
+ # (Hash) Lookup table from textual description of scraper type
114
+ # ('cookbook' or 'workflow' currently) to the class that
115
+ # represents that scraper.
116
+ @@types = {} unless class_variable_defined?(:@@types)
117
+
118
+ # Initialize scraper
119
+ #
120
+ # === Options
121
+ # <tt>:repository</tt>:: Required, original repository containing scraped
122
+ # files
123
+ # <tt>:repo_dir</tt>:: Required, path to directory containing files
124
+ # to be scraped
125
+ # <tt>:ignorable_paths</tt>:: List of directory names that should
126
+ # be ignored by scraper
127
+ # <tt>:scanners</tt>:: List of Scanner classes to use, defaulting
128
+ # to RightScraper::Scanners::ResourceManifest and
129
+ # RightScraper::Scanners::CookbookMetadata
130
+ # <tt>:builders</tt>:: List of Builder classes to use, defaulting to
131
+ # RightScaper::Builders::Filesystem
132
+ #
133
+ def initialize(options)
134
+ raise "Repository required when initializing a scraper" unless options[:repository]
135
+ raise "Repository directory required when initializing a scraper" unless options[:repo_dir]
136
+ @repository = options[:repository]
137
+ @logger = options[:logger] || ScraperLogger.new
138
+ @repo_dir = options[:repo_dir]
139
+ @ignorable_paths = options[:ignorable_paths]
140
+ @stack = []
141
+ @queue = (@repository.resources_path || [""]).reverse
142
+ @resources = []
143
+ scanners = options[:scanners] || default_scanners
144
+ @scanner = RightScraper::Scanners::Union.new(scanners, options)
145
+ builders = options[:builders] || default_builders
146
+ @builder = RightScraper::Builders::Union.new(builders, :ignorable_paths => @ignorable_paths,
147
+ :scanner => @scanner,
148
+ :logger => @logger,
149
+ :max_bytes => @max_bytes,
150
+ :max_seconds => @max_seconds)
151
+ pop_queue # Initialize @next
152
+ end
153
+
154
+ # List of default scanners for this scaper
155
+ #
156
+ # === Return
157
+ # Array<Scanner>:: Default scanners
158
+ def default_scanners
159
+ end
160
+
161
+ # List of default builders for this scaper
162
+ #
163
+ # === Return
164
+ # Array<Builder>:: Default builders
165
+ def default_brokers
166
+ end
167
+
168
+ # Find the interesting item in given directory
169
+ # Override in actual scraper implementation
170
+ #
171
+ # === Parameters
172
+ # dir(Dir):: directory to begin search in
173
+ def find_next(dir)
174
+ raise NotImplementedError
175
+ end
176
+
177
+ # Return the position of the scraper. Here, the position is the
178
+ # path relative from the top of the temporary directory. Akin to
179
+ # IO#pos or IO#tell.
180
+ def pos
181
+ strip_repo_dir(@stack.last.path)
182
+ end
183
+ alias_method :tell, :pos
184
+
185
+ # Turn path from an absolute filesystem location to a relative
186
+ # file location from #repo_dir.
187
+ #
188
+ # === Parameters
189
+ # path(String):: absolute path to relativize
190
+ #
191
+ # === Returns
192
+ # res(String):: relative pathname for path
193
+ def strip_repo_dir(path)
194
+ res = path[repo_dir.length+1..-1]
195
+ if res == nil || res == ""
196
+ "."
197
+ else
198
+ res
199
+ end
200
+ end
201
+ private :strip_repo_dir
202
+
203
+ # Test if the entry given is ignorable. By default just uses
204
+ # #ignorable_paths
205
+ #
206
+ # === Parameters
207
+ # entry(String):: file name to check
208
+ #
209
+ # === Returns
210
+ # Boolean:: true if the entry should be ignored
211
+ def ignorable?(entry)
212
+ @ignorable_paths.include?(entry)
213
+ end
214
+
215
+ # Initialize @next with the next resource
216
+ #
217
+ # === Returns
218
+ # @next(Resources::Base):: Next resource
219
+ def pop_queue
220
+ until @queue.empty?
221
+ nextdir = @queue.pop
222
+ if File.directory?(File.join(repo_dir, nextdir))
223
+ @next = find_next(Dir.new(File.join(repo_dir, nextdir)))
224
+ return @next
225
+ else
226
+ @logger.warn("When processing in #{@repository}, no such path #{nextdir}")
227
+ end
228
+ end
229
+ @next = nil
230
+ end
231
+
232
+ # Search the directory stack looking for the next resource.
233
+ def search_dirs
234
+ @logger.operation(:searching) do
235
+ until @stack.empty?
236
+ dir = @stack.last
237
+ entry = dir.read
238
+ if entry == nil
239
+ dir.close
240
+ @stack.pop
241
+ next
242
+ end
243
+
244
+ next if entry == '.' || entry == '..'
245
+ next if ignorable?(entry)
246
+
247
+ fullpath = File.join(dir.path, entry)
248
+
249
+ if File.directory?(fullpath)
250
+ result = find_next(Dir.new(fullpath))
251
+ break
252
+ end
253
+ end
254
+ result
255
+ end
256
+ end
257
+ private :search_dirs
258
+
259
+ end
260
+ end
261
+ end
262
+
@@ -0,0 +1,73 @@
1
+ #--
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require File.expand_path(File.join(File.dirname(__FILE__), 'base'))
25
+
26
+ module RightScraper
27
+ module Scrapers
28
+
29
+ # Chef cookbook scraper
30
+ class Cookbook < Base
31
+
32
+ # Find the next cookbook, starting in dir.
33
+ #
34
+ # === Parameters
35
+ # dir(Dir):: directory to begin search in
36
+ def find_next(dir)
37
+ @logger.operation(:finding_next_cookbook, "in #{dir.path}") do
38
+ if File.exists?(File.join(dir.path, 'metadata.json'))
39
+ @logger.operation(:reading_cookbook, "from #{dir.path}") do
40
+ cookbook = RightScraper::Resources::Cookbook.new(@repository, strip_repo_dir(dir.path))
41
+ @builder.go(dir.path, cookbook)
42
+ cookbook
43
+ end
44
+ else
45
+ @stack << dir
46
+ search_dirs
47
+ end
48
+ end
49
+ end
50
+
51
+ # List of default scanners for this scaper
52
+ #
53
+ # === Return
54
+ # Array<Scanner>:: Default scanners
55
+ def default_scanners
56
+ [RightScraper::Scanners::CookbookMetadata,
57
+ RightScraper::Scanners::CookbookManifest]
58
+ end
59
+
60
+ # List of default builders for this scaper
61
+ #
62
+ # === Return
63
+ # Array<Builder>:: Default builders
64
+ def default_builders
65
+ [RightScraper::Builders::Filesystem]
66
+ end
67
+
68
+ # Add this scraper to the list of available types.
69
+ @@types[:cookbook] = RightScraper::Scrapers::Cookbook
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,88 @@
1
+ #--
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require File.expand_path(File.join(File.dirname(__FILE__), 'base'))
25
+
26
+ module RightScraper
27
+ module Scrapers
28
+
29
+ # Workflow scraper
30
+ class Workflow < Base
31
+
32
+ # Initialize list of known workflows on top of
33
+ def initialize(options)
34
+ @known_workflows = []
35
+ super(options)
36
+ end
37
+
38
+ # Find the next workflows, starting in dir.
39
+ #
40
+ # === Parameters
41
+ # dir(Dir):: directory to begin search in
42
+ def find_next(dir)
43
+ @logger.operation(:finding_next_workflow, "in #{dir.path}") do
44
+ def_ext = RightScraper::Resources::Workflow::DEFINITION_EXT
45
+ meta_ext = RightScraper::Resources::Workflow::METADATA_EXT
46
+ potentials = Dir[File.join(dir.path, "*#{def_ext}")]
47
+ potentials.reject! { |wdef| !File.exists?(wdef.chomp(File.extname(wdef)) + meta_ext) }
48
+ potentials.reject! { |wdef| @known_workflows.include?(wdef) }
49
+ unless potentials.empty?
50
+ wdef = potentials.first
51
+ relative_def = strip_repo_dir(wdef)
52
+ @logger.operation(:reading_workflow, "#{relative_def}") do
53
+ workflow = RightScraper::Resources::Workflow.new(@repository, relative_def)
54
+ @builder.go(File.dirname(wdef), workflow)
55
+ @known_workflows << wdef
56
+ workflow
57
+ end
58
+ else
59
+ @stack << dir
60
+ search_dirs
61
+ end
62
+ end
63
+ end
64
+
65
+ # List of default scanners for this scaper
66
+ #
67
+ # === Return
68
+ # Array<Scanner>:: Default scanners
69
+ def default_scanners
70
+ [RightScraper::Scanners::WorkflowMetadata,
71
+ RightScraper::Scanners::WorkflowManifest]
72
+ end
73
+
74
+ # List of default builders for this scaper
75
+ #
76
+ # === Return
77
+ # Array<Builder>:: Default builders
78
+ def default_builders
79
+ [RightScraper::Builders::Filesystem]
80
+ end
81
+
82
+ # Add this scraper to the list of available types.
83
+ @@types[:workflow] = RightScraper::Scrapers::Workflow
84
+
85
+ end
86
+ end
87
+ end
88
+
@@ -0,0 +1,101 @@
1
+ #--
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+ require 'process_watcher'
24
+
25
+ module RightScraper
26
+ # Simplified interface to the process of creating SVN client
27
+ # contexts.
28
+ #
29
+ # SVN client contexts are needed for almost every nontrivial SVN
30
+ # operation, and the authentication procedure is truly baroque.
31
+ # Thus, when you need a client context, do something like this:
32
+ # client = SvnClient.new(repository)
33
+ # client.with_context do |ctx|
34
+ # ...
35
+ # end
36
+ module SvnClient
37
+ def calculate_version
38
+ unless @svn_version
39
+ out = ProcessWatcher.watch("svn", ["--version", "--quiet"],
40
+ repo_dir, @max_bytes || -1, @max_seconds || -1)
41
+ @svn_version = out.chomp.split(".").map {|e| e.to_i}
42
+ end
43
+ @svn_version
44
+ end
45
+
46
+ def svn_arguments
47
+ version = calculate_version
48
+ case
49
+ when version[0] != 1
50
+ raise "SVN major revision is not 1, cannot be sure it will run properly."
51
+ when version[1] < 4
52
+ raise "SVN minor revision < 4; cannot be sure it will run properly."
53
+ when version[1] < 6
54
+ # --trust-server-cert is a 1.6ism
55
+ args = ["--no-auth-cache", "--non-interactive"]
56
+ else
57
+ args = ["--no-auth-cache", "--non-interactive", "--trust-server-cert"]
58
+ end
59
+ if repository.first_credential && repository.second_credential
60
+ args << "--username"
61
+ args << repository.first_credential
62
+ args << "--password"
63
+ args << repository.second_credential
64
+ end
65
+ args
66
+ end
67
+
68
+ def get_tag_argument
69
+ if repository.tag
70
+ tag_cmd = ["-r", get_tag.to_s]
71
+ else
72
+ tag_cmd = ["-r", "HEAD"]
73
+ end
74
+ end
75
+
76
+ def run_svn_no_chdir(*args)
77
+ ProcessWatcher.watch("svn", [args, svn_arguments].flatten,
78
+ repo_dir, @max_bytes || -1, @max_seconds || -1) do |phase, operation, exception|
79
+ #$stderr.puts "#{phase} #{operation} #{exception}"
80
+ end
81
+ end
82
+
83
+ def run_svn(*args)
84
+ Dir.chdir(repo_dir) do
85
+ run_svn_no_chdir(*args)
86
+ end
87
+ end
88
+
89
+ # Fetch the tag from the repository, or nil if one doesn't
90
+ # exist. This is a separate method because the repo tag should
91
+ # be a number but is a string in the database.
92
+ def get_tag
93
+ case repository.tag
94
+ when Fixnum then repository.tag
95
+ when /^\d+$/ then repository.tag.to_i
96
+ else
97
+ repository.tag
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,28 @@
1
+ #-- -*- mode: ruby; encoding: utf-8 -*-
2
+ # Copyright: Copyright (c) 2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ module RightScraper
25
+ # (Fixnum) protocol versioning scheme; prepended to hashes to
26
+ # prevent collisions.
27
+ PROTOCOL_VERSION = 1
28
+ end
data/lib/right_scraper.rb CHANGED
@@ -1,18 +1,18 @@
1
1
  #--
2
- # Copyright: Copyright (c) 2010 RightScale, Inc.
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
6
6
  # 'Software'), to deal in the Software without restriction, including
7
7
  # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
9
  # permit persons to whom the Software is furnished to do so, subject to
10
10
  # the following conditions:
11
11
  #
12
12
  # The above copyright notice and this permission notice shall be
13
13
  # included in all copies or substantial portions of the Software.
14
14
  #
15
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
16
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
17
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
18
  # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
@@ -21,12 +21,36 @@
21
21
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- # Explicitely list required files to make IDEs happy
24
+ # Explicitly list required files to make IDEs happy
25
25
  require 'fileutils'
26
- require File.join(File.dirname(__FILE__), 'right_scraper', 'scraper_base')
27
- require File.join(File.dirname(__FILE__), 'right_scraper', 'scrapers', 'download_scraper')
28
- require File.join(File.dirname(__FILE__), 'right_scraper', 'scrapers', 'git_scraper')
29
- require File.join(File.dirname(__FILE__), 'right_scraper', 'scrapers', 'svn_scraper')
30
- require File.join(File.dirname(__FILE__), 'right_scraper', 'repository')
31
- require File.join(File.dirname(__FILE__), 'right_scraper', 'scraper')
32
- require File.join(File.dirname(__FILE__), 'right_scraper', 'watcher')
26
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'builders', 'base'))
27
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'builders', 'filesystem'))
28
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'builders', 'union'))
29
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'logger'))
30
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'processes', 'ssh'))
31
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'repositories', 'base'))
32
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'repositories', 'download'))
33
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'repositories', 'git'))
34
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'repositories', 'svn'))
35
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'resources', 'base'))
36
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'resources', 'cookbook'))
37
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'resources', 'workflow'))
38
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'retrievers', 'base'))
39
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'retrievers', 'checkout'))
40
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'retrievers', 'download'))
41
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'retrievers', 'git'))
42
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'retrievers', 'svn'))
43
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scanners', 'base'))
44
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scanners', 'cookbook_manifest'))
45
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scanners', 'cookbook_metadata'))
46
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scanners', 'cookbook_s3_upload'))
47
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scanners', 'union'))
48
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scanners', 'workflow_manifest'))
49
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scanners', 'workflow_metadata'))
50
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scraper'))
51
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scraper_logger'))
52
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scrapers', 'base'))
53
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scrapers', 'cookbook'))
54
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'scrapers', 'workflow'))
55
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'svn_client'))
56
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_scraper', 'version'))