right_scraper 3.0.4 → 3.2.3
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 +7 -8
- data/README.rdoc +3 -1
- data/lib/right_scraper/logger.rb +2 -2
- data/lib/right_scraper/processes/ssh.rb +103 -71
- data/lib/right_scraper/resources/cookbook.rb +35 -2
- data/lib/right_scraper/retrievers/checkout.rb +3 -3
- data/lib/right_scraper/retrievers/download.rb +81 -18
- data/lib/right_scraper/retrievers/git.rb +37 -3
- data/lib/right_scraper/retrievers/svn.rb +7 -16
- data/lib/right_scraper/scanners/cookbook_manifest.rb +2 -2
- data/lib/right_scraper/scanners/cookbook_s3_upload.rb +8 -7
- data/lib/right_scraper/scraper.rb +4 -4
- data/lib/right_scraper/svn_client.rb +73 -11
- data/right_scraper.gemspec +18 -18
- data/right_scraper.rconf +1 -1
- data/spec/cookbook_manifest_spec.rb +43 -5
- data/spec/cookbook_s3_upload_spec.rb +8 -3
- data/spec/download/download_spec.rb +3 -5
- data/spec/git/cookbook_spec.rb +6 -7
- data/spec/git/retriever_spec.rb +5 -5
- data/spec/git/scraper_spec.rb +16 -1
- data/spec/git/ssh_spec.rb +5 -2
- data/spec/retriever_spec_helper.rb +2 -2
- data/spec/scraper_helper.rb +0 -10
- data/spec/spec_helper.rb +5 -5
- data/spec/svn/cookbook_spec.rb +5 -6
- data/spec/svn/svn_retriever_spec_helper.rb +5 -6
- metadata +60 -48
@@ -95,12 +95,12 @@ module RightScraper
|
|
95
95
|
@resources += scraper.scrape
|
96
96
|
end
|
97
97
|
end
|
98
|
-
|
99
|
-
# 3. Cleanup if temporary
|
100
|
-
FileUtils.remove_entry_secure(@options[:basedir]) if @temporary
|
101
|
-
rescue
|
98
|
+
rescue Exception
|
102
99
|
# logger handles communication with the end user and appending
|
103
100
|
# to our error list, we just need to keep going.
|
101
|
+
ensure
|
102
|
+
# ensure basedir is always removed if temporary (even with errors).
|
103
|
+
::FileUtils.remove_entry_secure(@options[:basedir]) rescue nil if @temporary
|
104
104
|
end
|
105
105
|
@logger.callback = nil
|
106
106
|
errors.size == errorlen
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright: Copyright (c) 2010-
|
2
|
+
# Copyright: Copyright (c) 2010-2013 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
|
@@ -20,7 +20,9 @@
|
|
20
20
|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
21
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
|
-
|
23
|
+
|
24
|
+
require 'right_popen'
|
25
|
+
require 'right_popen/safe_output_buffer'
|
24
26
|
|
25
27
|
module RightScraper
|
26
28
|
# Simplified interface to the process of creating SVN client
|
@@ -34,11 +36,22 @@ module RightScraper
|
|
34
36
|
# ...
|
35
37
|
# end
|
36
38
|
module SvnClient
|
39
|
+
|
40
|
+
class SvnClientError < Exception; end
|
41
|
+
|
37
42
|
def calculate_version
|
38
43
|
unless @svn_version
|
39
|
-
|
40
|
-
|
41
|
-
|
44
|
+
begin
|
45
|
+
cmd = 'svn --version --quiet'
|
46
|
+
out = `#{cmd}`
|
47
|
+
if $?.success?
|
48
|
+
@svn_version = out.chomp.split('.').map {|e| e.to_i}
|
49
|
+
else
|
50
|
+
raise SvnClientError, "Unable to determine svn version: #{cmd.inspect} exited with #{$?.exitstatus}"
|
51
|
+
end
|
52
|
+
rescue Errno::ENOENT => e
|
53
|
+
raise SvnClientError, "Unable to determine svn version: #{e.message}"
|
54
|
+
end
|
42
55
|
end
|
43
56
|
@svn_version
|
44
57
|
end
|
@@ -74,16 +87,65 @@ module RightScraper
|
|
74
87
|
end
|
75
88
|
|
76
89
|
def run_svn_no_chdir(*args)
|
77
|
-
|
78
|
-
repo_dir, @max_bytes || -1, @max_seconds || -1) do |phase, operation, exception|
|
79
|
-
#$stderr.puts "#{phase} #{operation} #{exception}"
|
80
|
-
end
|
90
|
+
run_svn_with(nil, :safe_output_svn_client, *args)
|
81
91
|
end
|
82
92
|
|
83
93
|
def run_svn(*args)
|
84
|
-
|
85
|
-
|
94
|
+
run_svn_with(repo_dir, :safe_output_svn_client, *args)
|
95
|
+
end
|
96
|
+
|
97
|
+
def run_svn_with_buffered_output(*args)
|
98
|
+
run_svn_with(repo_dir, :unsafe_output_svn_client, *args)
|
99
|
+
end
|
100
|
+
|
101
|
+
# runs svn client with safe buffering (by default).
|
102
|
+
#
|
103
|
+
# === Parameters
|
104
|
+
# @param [Array] args for svn client command line
|
105
|
+
#
|
106
|
+
# === Return
|
107
|
+
# @return [Array] lines of output or empty
|
108
|
+
def run_svn_with(initial_directory, output_handler, *args)
|
109
|
+
@output = ::RightScale::RightPopen::SafeOutputBuffer.new
|
110
|
+
cmd = ['svn', args, svn_arguments].flatten
|
111
|
+
::RightScale::RightPopen.popen3_sync(
|
112
|
+
cmd,
|
113
|
+
:target => self,
|
114
|
+
:directory => initial_directory,
|
115
|
+
:timeout_handler => :timeout_svn_client,
|
116
|
+
:size_limit_handler => :size_limit_svn_client,
|
117
|
+
:exit_handler => :exit_svn_client,
|
118
|
+
:stderr_handler => output_handler,
|
119
|
+
:stdout_handler => output_handler,
|
120
|
+
:inherit_io => true, # avoid killing any rails connection
|
121
|
+
:watch_directory => repo_dir,
|
122
|
+
:size_limit_bytes => @max_bytes,
|
123
|
+
:timeout_seconds => @max_seconds)
|
124
|
+
@output.buffer
|
125
|
+
end
|
126
|
+
|
127
|
+
def safe_output_svn_client(data)
|
128
|
+
@output.safe_buffer_data(data)
|
129
|
+
end
|
130
|
+
|
131
|
+
def unsafe_output_svn_client(data)
|
132
|
+
@output.buffer << data.chomp
|
133
|
+
end
|
134
|
+
|
135
|
+
def timeout_svn_client
|
136
|
+
raise SvnClientError, "svn client timed out"
|
137
|
+
end
|
138
|
+
|
139
|
+
def size_limit_svn_client
|
140
|
+
raise SvnClientError, "svn client exceeded size limit"
|
141
|
+
end
|
142
|
+
|
143
|
+
def exit_svn_client(status)
|
144
|
+
unless status.success?
|
145
|
+
self.method(@output_handler).call("Exit code = #{status.exitstatus}")
|
146
|
+
raise SvnClientError, "svn client failed: #{@output.display_text}"
|
86
147
|
end
|
148
|
+
true
|
87
149
|
end
|
88
150
|
|
89
151
|
# Fetch the tag from the repository, or nil if one doesn't
|
data/right_scraper.gemspec
CHANGED
@@ -24,8 +24,8 @@ require 'rubygems'
|
|
24
24
|
|
25
25
|
Gem::Specification.new do |spec|
|
26
26
|
spec.name = 'right_scraper'
|
27
|
-
spec.version = '3.
|
28
|
-
spec.authors = ['Graham Hughes', 'Raphael Simon']
|
27
|
+
spec.version = '3.2.3'
|
28
|
+
spec.authors = ['Graham Hughes', 'Raphael Simon', 'Scott Messier']
|
29
29
|
spec.email = 'raphael@rightscale.com'
|
30
30
|
spec.homepage = 'https://github.com/rightscale/right_scraper'
|
31
31
|
spec.platform = Gem::Platform::RUBY
|
@@ -37,29 +37,29 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.rubyforge_project = %q{right_scraper}
|
38
38
|
spec.require_path = 'lib'
|
39
39
|
|
40
|
-
spec.add_dependency('json', '
|
41
|
-
spec.add_dependency('git', '
|
42
|
-
spec.add_dependency('libarchive', '>= 0.1.1')
|
40
|
+
spec.add_dependency('json', '~> 1.4')
|
41
|
+
spec.add_dependency('blackwinter-git', '~> 1.2.7')
|
43
42
|
spec.add_dependency('right_aws', '>= 2.0')
|
44
|
-
spec.add_dependency('
|
43
|
+
spec.add_dependency('right_popen', '~> 1.1.1')
|
44
|
+
spec.add_dependency('right_support', '~> 2.6')
|
45
45
|
|
46
|
-
spec.requirements << 'libarchive, 2.8.4'
|
47
46
|
spec.requirements << 'curl command line client'
|
47
|
+
spec.requirements << 'git command line client'
|
48
48
|
spec.requirements << 'Subversion command line client'
|
49
49
|
|
50
|
-
spec.add_development_dependency('rspec')
|
51
|
-
spec.add_development_dependency('flexmock')
|
52
|
-
spec.add_development_dependency('rtags')
|
50
|
+
spec.add_development_dependency('rspec', '~> 2.0')
|
51
|
+
spec.add_development_dependency('flexmock', '~> 0.9')
|
52
|
+
spec.add_development_dependency('rtags', '~> 0.97')
|
53
53
|
|
54
54
|
spec.description = <<-EOF
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
RightScraper provides a simple interface to download and keep local copies of remote
|
56
|
+
repositories up-to-date using the following protocols:
|
57
|
+
* git: RightScraper will clone then pull repos from git
|
58
|
+
* SVN: RightScraper will checkout then update SVN repositories
|
59
|
+
* tarballs: RightScraper will download, optionally uncompress and expand a given tar file
|
60
|
+
On top of retrieving remote repositories, right_scraper also include "scrapers" that
|
61
|
+
will analyze the repository content and instantiate "resources" as a result. Currently
|
62
|
+
supported resources are Chef cookbooks and RightScale workflow definitions.
|
63
63
|
EOF
|
64
64
|
|
65
65
|
candidates = Dir.glob("{lib,spec}/**/*") +
|
data/right_scraper.rconf
CHANGED
@@ -29,8 +29,8 @@ module RightScraper::Scanners
|
|
29
29
|
describe CookbookManifest do
|
30
30
|
it 'should accumulate files' do
|
31
31
|
resource = flexmock(:resource)
|
32
|
-
resource.should_receive(:manifest=).with({"foo" => Digest::
|
33
|
-
"baz" => Digest::
|
32
|
+
resource.should_receive(:manifest=).with({"foo" => Digest::MD5.hexdigest("bar"),
|
33
|
+
"baz" => Digest::MD5.hexdigest("quux")
|
34
34
|
}).once
|
35
35
|
manifest = CookbookManifest.new
|
36
36
|
manifest.notice("foo") { "bar" }
|
@@ -39,10 +39,10 @@ module RightScraper::Scanners
|
|
39
39
|
end
|
40
40
|
it 'should keep different resources separated' do
|
41
41
|
resource = flexmock(:resource)
|
42
|
-
resource.should_receive(:manifest=).with({"foo" => Digest::
|
43
|
-
"baz" => Digest::
|
42
|
+
resource.should_receive(:manifest=).with({"foo" => Digest::MD5.hexdigest("bar"),
|
43
|
+
"baz" => Digest::MD5.hexdigest("quux")
|
44
44
|
}).once
|
45
|
-
resource.should_receive(:manifest=).with({"bar" => Digest::
|
45
|
+
resource.should_receive(:manifest=).with({"bar" => Digest::MD5.hexdigest("fred")
|
46
46
|
}).once
|
47
47
|
manifest = CookbookManifest.new
|
48
48
|
manifest.notice("foo") { "bar" }
|
@@ -51,5 +51,43 @@ module RightScraper::Scanners
|
|
51
51
|
manifest.notice("bar") { "fred" }
|
52
52
|
manifest.end(resource)
|
53
53
|
end
|
54
|
+
it 'should hash to the same value despite resource order' do
|
55
|
+
cookbook1 = RightScraper::Resources::Cookbook.new('<empty>', '')
|
56
|
+
cookbook2 = RightScraper::Resources::Cookbook.new('<empty>', '')
|
57
|
+
|
58
|
+
manifest = CookbookManifest.new
|
59
|
+
|
60
|
+
manifest.notice("foo") {"bar"}
|
61
|
+
manifest.notice("baz") {"quux"}
|
62
|
+
manifest.notice("bar/none") {"fred"}
|
63
|
+
manifest.notice("bar/all") {"fred"}
|
64
|
+
manifest.notice("a/really/deep/directory/fox") {"stray"}
|
65
|
+
manifest.end(cookbook1)
|
66
|
+
|
67
|
+
manifest.notice("bar/none") {"fred"}
|
68
|
+
manifest.notice("a/really/deep/directory/fox") {"stray"}
|
69
|
+
manifest.notice("foo") {"bar"}
|
70
|
+
manifest.notice("baz") {"quux"}
|
71
|
+
manifest.notice("bar/all") {"fred"}
|
72
|
+
manifest.end(cookbook2)
|
73
|
+
|
74
|
+
cookbook1.resource_hash.should == cookbook2.resource_hash
|
75
|
+
end
|
76
|
+
it 'should hash to the same value despite repository location' do
|
77
|
+
cookbook1 = RightScraper::Resources::Cookbook.new('git://github.com/somerepo', '')
|
78
|
+
cookbook2 = RightScraper::Resources::Cookbook.new('svn://mycompany/rss/myrepo', '')
|
79
|
+
|
80
|
+
manifest = CookbookManifest.new
|
81
|
+
|
82
|
+
manifest.notice("foo") {"bar"}
|
83
|
+
manifest.notice("baz") {"quux"}
|
84
|
+
manifest.end(cookbook1)
|
85
|
+
|
86
|
+
manifest.notice("foo") {"bar"}
|
87
|
+
manifest.notice("baz") {"quux"}
|
88
|
+
manifest.end(cookbook2)
|
89
|
+
|
90
|
+
cookbook1.resource_hash.should == cookbook2.resource_hash
|
91
|
+
end
|
54
92
|
end
|
55
93
|
end
|
@@ -120,7 +120,11 @@ describe RightScraper::Scanners::CookbookS3Upload do
|
|
120
120
|
s3 = RightAws::S3.new(aws_access_key_id=ENV['AWS_ACCESS_KEY_ID'],
|
121
121
|
aws_secret_access_key=ENV['AWS_SECRET_ACCESS_KEY'],
|
122
122
|
:logger => RightScraper::Logger.new)
|
123
|
-
|
123
|
+
|
124
|
+
# create=true is prone to the too-many-buckets error even when the bucket
|
125
|
+
# already exists. since the bucket always exists for the test account
|
126
|
+
# there is no need to try creating it programmatically and fail specs.
|
127
|
+
@bucket = s3.bucket(bucket_name, create=false)
|
124
128
|
FileUtils.rm_rf(RightScraper::Retrievers::Base.repo_dir(@repo_path, @repo))
|
125
129
|
end
|
126
130
|
|
@@ -137,8 +141,9 @@ describe RightScraper::Scanners::CookbookS3Upload do
|
|
137
141
|
it 'the cookbook should exist' do
|
138
142
|
s3cookbook = @bucket.get(File.join('Cooks', @cookbook.resource_hash))
|
139
143
|
s3cookbook.should_not be_nil
|
144
|
+
::Digest::MD5.hexdigest(s3cookbook).should == @cookbook.resource_hash
|
145
|
+
s3cookbook.should_not == ::RightScraper::Resources::Cookbook::EMPTY_MANIFEST_JSON
|
140
146
|
hash = JSON.parse(s3cookbook)
|
141
|
-
hash["metadata"].should == @cookbook.metadata
|
142
147
|
hash["manifest"].should == @cookbook.manifest
|
143
148
|
end
|
144
149
|
|
@@ -146,7 +151,7 @@ describe RightScraper::Scanners::CookbookS3Upload do
|
|
146
151
|
@cookbook.manifest.each do |key, value|
|
147
152
|
file = @bucket.get(File.join('Files', value))
|
148
153
|
file.should_not be_nil
|
149
|
-
Digest::
|
154
|
+
value.should == Digest::MD5.hexdigest(file)
|
150
155
|
end
|
151
156
|
end
|
152
157
|
end
|
@@ -54,10 +54,8 @@ describe RightScraper::Resources::Cookbook do
|
|
54
54
|
it_should_behave_like 'a download repository'
|
55
55
|
|
56
56
|
it 'should have a cookbook hash' do
|
57
|
-
checkout_hash =
|
58
|
-
Digest::SHA1.hexdigest("1\000download\000http://a.site/foo/bar/baz\000")
|
59
57
|
example_cookbook(@repository).resource_hash.should ==
|
60
|
-
Digest::
|
58
|
+
Digest::MD5.hexdigest(RightScraper::Resources::Cookbook::EMPTY_MANIFEST_JSON)
|
61
59
|
end
|
62
60
|
|
63
61
|
it 'should have a cookbook hash invariant under credential changes' do
|
@@ -66,8 +64,8 @@ describe RightScraper::Resources::Cookbook do
|
|
66
64
|
example_cookbook(@repository).resource_hash.should == old_hash
|
67
65
|
end
|
68
66
|
|
69
|
-
it 'should have a cookbook hash
|
70
|
-
example_cookbook(@repository, "foo").resource_hash.
|
67
|
+
it 'should have a cookbook hash invariant under position changes' do
|
68
|
+
example_cookbook(@repository, "foo").resource_hash.should ==
|
71
69
|
example_cookbook(@repository, "bar").resource_hash
|
72
70
|
end
|
73
71
|
end
|
data/spec/git/cookbook_spec.rb
CHANGED
@@ -76,7 +76,7 @@ describe RightScraper::Resources::Cookbook do
|
|
76
76
|
ensure
|
77
77
|
FileUtils.remove_entry_secure(@tmpdir)
|
78
78
|
end
|
79
|
-
}.should raise_exception(
|
79
|
+
}.should raise_exception(::RightScraper::Processes::SSHAgent::SSHAgentError, /Attempted to use credentials that require passwords; bailing/)
|
80
80
|
ENV['SSH_AGENT_PID'].should == oldpid
|
81
81
|
end
|
82
82
|
end
|
@@ -124,9 +124,8 @@ describe RightScraper::Resources::Cookbook do
|
|
124
124
|
end
|
125
125
|
|
126
126
|
it 'should have a cookbook hash' do
|
127
|
-
repo_hash = Digest::SHA1.hexdigest("1\000git\000http://a.site/foo/bar/baz\000master")
|
128
127
|
example_cookbook(@repository).resource_hash.should ==
|
129
|
-
Digest::
|
128
|
+
Digest::MD5.hexdigest(RightScraper::Resources::Cookbook::EMPTY_MANIFEST_JSON)
|
130
129
|
end
|
131
130
|
|
132
131
|
it 'should have a cookbook hash invariant under credential changes' do
|
@@ -135,14 +134,14 @@ describe RightScraper::Resources::Cookbook do
|
|
135
134
|
example_cookbook(@repository).resource_hash.should == old_hash
|
136
135
|
end
|
137
136
|
|
138
|
-
it 'should have a cookbook hash
|
137
|
+
it 'should have a cookbook hash invariant under tag changes' do
|
139
138
|
old_hash = example_cookbook(@repository).resource_hash
|
140
139
|
@repository.tag = "tag"
|
141
|
-
example_cookbook(@repository).resource_hash.
|
140
|
+
example_cookbook(@repository).resource_hash.should == old_hash
|
142
141
|
end
|
143
142
|
|
144
|
-
it 'should have a cookbook hash
|
145
|
-
example_cookbook(@repository, "foo").resource_hash.
|
143
|
+
it 'should have a cookbook hash invariant under position changes' do
|
144
|
+
example_cookbook(@repository, "foo").resource_hash.should ==
|
146
145
|
example_cookbook(@repository, "bar").resource_hash
|
147
146
|
end
|
148
147
|
end
|
data/spec/git/retriever_spec.rb
CHANGED
@@ -23,7 +23,6 @@
|
|
23
23
|
|
24
24
|
require File.expand_path(File.join(File.dirname(__FILE__), 'retriever_spec_helper'))
|
25
25
|
require 'set'
|
26
|
-
require 'libarchive_ruby'
|
27
26
|
|
28
27
|
describe RightScraper::Retrievers::Git do
|
29
28
|
include RightScraper::SpecHelpers::DevelopmentModeEnvironment
|
@@ -206,8 +205,8 @@ describe RightScraper::Retrievers::Git do
|
|
206
205
|
|
207
206
|
context 'with a subcookbook' do
|
208
207
|
before(:each) do
|
209
|
-
subdir = File.join(@helper.repo_path, "cookbook")
|
210
|
-
secondary_cookbook(subdir)
|
208
|
+
@subdir = File.join(@helper.repo_path, "cookbook")
|
209
|
+
secondary_cookbook(@subdir)
|
211
210
|
@helper.commit_content("subcookbook added")
|
212
211
|
end
|
213
212
|
|
@@ -221,7 +220,8 @@ describe RightScraper::Retrievers::Git do
|
|
221
220
|
|
222
221
|
it 'should have the subcookbook in the manifest' do
|
223
222
|
cookbook = @scraper.next_resource
|
224
|
-
|
223
|
+
contents = ::File.read(::File.join(@subdir, "metadata.json"))
|
224
|
+
cookbook.manifest["cookbook/metadata.json"].should == ::Digest::MD5.hexdigest(contents)
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
@@ -335,7 +335,7 @@ describe RightScraper::Retrievers::Git do
|
|
335
335
|
end
|
336
336
|
|
337
337
|
after(:each) do
|
338
|
-
@scraper.close
|
338
|
+
@scraper.close if @scraper
|
339
339
|
@scraper = nil
|
340
340
|
end
|
341
341
|
|
data/spec/git/scraper_spec.rb
CHANGED
@@ -33,8 +33,23 @@ describe RightScraper::Scraper do
|
|
33
33
|
include RightScraper::SharedExamples
|
34
34
|
|
35
35
|
before(:each) do
|
36
|
-
|
36
|
+
# ulimit is a /usr/bin file on the Mac but only a shell command in Linux.
|
37
|
+
# invoking `sh -c ulimit -a` only returns the last token of output, in fact
|
38
|
+
# invoking 'ulimit -a' programmatically seems to omit the 'open files' field
|
39
|
+
# in which we are actually interested (whereas it is visible when run
|
40
|
+
# manually in bash). the more specific 'ulimit -n' appears to work as
|
41
|
+
# expected on mac and linux platforms *but* calling `sh -c ulimit -n`
|
42
|
+
# returns a nonsensical 'unlimited' token in ruby so we have to jump the
|
43
|
+
# additional hurdle of outputing to a temp file to get the right answer :@
|
37
44
|
@tmpdir = Dir.mktmpdir
|
45
|
+
output_file_path = File.join(@tmpdir, "ulimit_n.txt")
|
46
|
+
system('sh', '-c', "ulimit -n>#{output_file_path}")
|
47
|
+
ulimit = File.read(output_file_path).to_i
|
48
|
+
File.delete(output_file_path)
|
49
|
+
if ulimit < 512
|
50
|
+
raise "Cannot run this spec because ulimit -n is only #{ulimit}; need 512 minimum!"
|
51
|
+
end
|
52
|
+
@stream = StringIO.new()
|
38
53
|
@scraper = RightScraper::Scraper.new(:basedir => @tmpdir, :kind => :cookbook)
|
39
54
|
end
|
40
55
|
|
data/spec/git/ssh_spec.rb
CHANGED
@@ -148,11 +148,14 @@ FULLOUTPUT
|
|
148
148
|
lambda {
|
149
149
|
RightScraper::Processes::SSHAgent.with do |agent|
|
150
150
|
pid = ENV['SSH_AGENT_PID'].to_i
|
151
|
+
pid.should_not == 0
|
151
152
|
demofile = File.expand_path(File.join(File.dirname(__FILE__), 'password_key'))
|
152
153
|
File.chmod(0600, demofile)
|
153
|
-
agent.add_keyfile(demofile)
|
154
|
+
agent.add_keyfile(demofile) # will fail due to missing password
|
154
155
|
end
|
155
|
-
}.should raise_exception(
|
156
|
+
}.should raise_exception(::RightScraper::Processes::SSHAgent::SSHAgentError, /Attempted to use credentials that require passwords; bailing/)
|
157
|
+
|
158
|
+
# the .with statement must ensure that the ssh-agent process terminates.
|
156
159
|
lambda {
|
157
160
|
Process.kill(0, pid)
|
158
161
|
}.should raise_exception(Errno::ESRCH)
|
@@ -63,7 +63,7 @@ module RightScraper
|
|
63
63
|
def manifest
|
64
64
|
hash = {}
|
65
65
|
scan(@repo_content, hash, nil)
|
66
|
-
hash['metadata.json'] = Digest::
|
66
|
+
hash['metadata.json'] = Digest::MD5.hexdigest(@repo_content.to_json + "\n")
|
67
67
|
hash
|
68
68
|
end
|
69
69
|
|
@@ -76,7 +76,7 @@ module RightScraper
|
|
76
76
|
end
|
77
77
|
else
|
78
78
|
relative_position = position ? File.join(position, object) : object
|
79
|
-
hash[relative_position] = Digest::
|
79
|
+
hash[relative_position] = Digest::MD5.hexdigest(object + "\n")
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
data/spec/scraper_helper.rb
CHANGED
@@ -76,16 +76,6 @@ module RightScraper
|
|
76
76
|
|
77
77
|
end
|
78
78
|
module ScraperHelper
|
79
|
-
def archive_skeleton(archive)
|
80
|
-
files = Set.new
|
81
|
-
Archive.read_open_memory(archive) do |ar|
|
82
|
-
while entry = ar.next_header
|
83
|
-
files << [entry.pathname, ar.read_data]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
files
|
87
|
-
end
|
88
|
-
|
89
79
|
def check_resource(resource, params={})
|
90
80
|
position = params[:position] || "."
|
91
81
|
resource.should_not == nil
|
data/spec/spec_helper.rb
CHANGED
@@ -170,11 +170,11 @@ module RightScraper
|
|
170
170
|
@scraper.resources.should_not == []
|
171
171
|
@scraper.resources.size.should == 1
|
172
172
|
@scraper.resources[0].manifest.should == {
|
173
|
-
"folder1/file3"=>"
|
174
|
-
"file1"=>"
|
175
|
-
"folder2/folder3/file4"=>"
|
176
|
-
"metadata.json"=>"
|
177
|
-
"folder1/file2"=>"
|
173
|
+
"folder1/file3"=>"60b91f1875424d3b4322b0fdd0529d5d",
|
174
|
+
"file1"=>"5149d403009a139c7e085405ef762e1a",
|
175
|
+
"folder2/folder3/file4"=>"857c6673d7149465c8ced446769b523c",
|
176
|
+
"metadata.json"=>"7c72b234162002a96f4ba60f0db38601",
|
177
|
+
"folder1/file2"=>"3d709e89c8ce201e3c928eb917989aef"}
|
178
178
|
@scraper.resources[0].metadata.should == [{"folder1"=>["file2", "file3"]},
|
179
179
|
{"folder2"=>[{"folder3"=>["file4"]}]},
|
180
180
|
"file1"]
|
data/spec/svn/cookbook_spec.rb
CHANGED
@@ -54,9 +54,8 @@ describe RightScraper::Resources::Cookbook do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'should have a cookbook hash' do
|
57
|
-
repo_hash = Digest::SHA1.hexdigest("1\000svn\000http://a.site/foo/bar/baz\000HEAD")
|
58
57
|
example_cookbook(@repository).resource_hash.should ==
|
59
|
-
Digest::
|
58
|
+
Digest::MD5.hexdigest(RightScraper::Resources::Cookbook::EMPTY_MANIFEST_JSON)
|
60
59
|
end
|
61
60
|
|
62
61
|
it 'should have a cookbook hash invariant under credential changes' do
|
@@ -65,14 +64,14 @@ describe RightScraper::Resources::Cookbook do
|
|
65
64
|
example_cookbook(@repository).resource_hash.should == old_hash
|
66
65
|
end
|
67
66
|
|
68
|
-
it 'should have a cookbook hash
|
67
|
+
it 'should have a cookbook hash invariant under tag changes' do
|
69
68
|
old_hash = example_cookbook(@repository).resource_hash
|
70
69
|
@repository.tag = "tag"
|
71
|
-
example_cookbook(@repository).resource_hash.
|
70
|
+
example_cookbook(@repository).resource_hash.should == old_hash
|
72
71
|
end
|
73
72
|
|
74
|
-
it 'should have a cookbook hash
|
75
|
-
example_cookbook(@repository, "foo").resource_hash.
|
73
|
+
it 'should have a cookbook hash invariant under position changes' do
|
74
|
+
example_cookbook(@repository, "foo").resource_hash.should ==
|
76
75
|
example_cookbook(@repository, "bar").resource_hash
|
77
76
|
end
|
78
77
|
end
|
@@ -22,7 +22,6 @@
|
|
22
22
|
#++
|
23
23
|
|
24
24
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'retriever_spec_helper'))
|
25
|
-
require 'process_watcher'
|
26
25
|
|
27
26
|
module RightScraper
|
28
27
|
|
@@ -44,7 +43,7 @@ module RightScraper
|
|
44
43
|
|
45
44
|
def repo_url
|
46
45
|
file_prefix = 'file://'
|
47
|
-
file_prefix += '/' if RUBY_PLATFORM =~ /mswin/
|
46
|
+
file_prefix += '/' if RUBY_PLATFORM =~ /mswin|mingw/
|
48
47
|
url = "#{file_prefix}#{svn_repo_path}"
|
49
48
|
end
|
50
49
|
|
@@ -57,8 +56,8 @@ module RightScraper
|
|
57
56
|
:display_name => 'test repo',
|
58
57
|
:repo_type => :svn,
|
59
58
|
:url => repo_url)
|
60
|
-
output
|
61
|
-
raise "Can't create repo: #{output}"
|
59
|
+
output = `svnadmin create #{svn_repo_path}`
|
60
|
+
raise "Can't create repo: #{output}" unless $?.success?
|
62
61
|
run_svn_no_chdir "checkout", repo_url, repo_path
|
63
62
|
make_cookbooks
|
64
63
|
commit_content
|
@@ -78,9 +77,9 @@ module RightScraper
|
|
78
77
|
end
|
79
78
|
|
80
79
|
def commit_id(index_from_last=0)
|
81
|
-
|
80
|
+
lines = run_svn_with_buffered_output "log", "-l", (index_from_last + 1).to_s, "-r", "HEAD:0"
|
82
81
|
id = nil
|
83
|
-
|
82
|
+
lines.each do |line|
|
84
83
|
if line =~ /^r(\d+)/
|
85
84
|
id = $1
|
86
85
|
end
|