buildpack-support 1.0.0 → 1.1.0
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/lib/buildpack_support/cache/cached_file.rb +7 -5
- data/lib/buildpack_support/cache/download_cache.rb +10 -10
- data/lib/buildpack_support/cache/internet_availability.rb +21 -2
- data/lib/buildpack_support/test/application_helper.rb +1 -0
- data/lib/buildpack_support/test/base_component_helper.rb +2 -0
- data/lib/buildpack_support/test/repository_helper.rb +38 -0
- data/lib/buildpack_support/version.rb +1 -1
- data/spec/buildpack_support/cache/cached_file_spec.rb +26 -2
- data/spec/buildpack_support/cache/download_cache_spec.rb +2 -2
- data/spec/buildpack_support/cache/internet_availability_spec.rb +18 -0
- metadata +7 -3
|
@@ -29,13 +29,15 @@ module BuildpackSupport
|
|
|
29
29
|
#
|
|
30
30
|
# @param [Pathname] cache_root the filesystem root for the file created and expected by this class
|
|
31
31
|
# @param [String] uri a uri which uniquely identifies the file in the cache
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
key = URI.escape(uri, '/')
|
|
32
|
+
# @param [Boolean] mutable whether the cached file should be mutable
|
|
33
|
+
def initialize(cache_root, uri, mutable)
|
|
34
|
+
key = URI.escape(uri, ':/')
|
|
36
35
|
@cached = cache_root + "#{key}.cached"
|
|
37
36
|
@etag = cache_root + "#{key}.etag"
|
|
38
37
|
@last_modified = cache_root + "#{key}.last_modified"
|
|
38
|
+
@mutable = mutable
|
|
39
|
+
|
|
40
|
+
FileUtils.mkdir_p cache_root if mutable
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
# Opens the cached file
|
|
@@ -58,7 +60,7 @@ module BuildpackSupport
|
|
|
58
60
|
|
|
59
61
|
# Destroys the cached file
|
|
60
62
|
def destroy
|
|
61
|
-
[@cached, @etag, @last_modified].each { |f| f.delete if f.exist? }
|
|
63
|
+
[@cached, @etag, @last_modified].each { |f| f.delete if f.exist? } if @mutable
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
# Opens the etag file
|
|
@@ -66,7 +66,7 @@ module BuildpackSupport
|
|
|
66
66
|
cached_file, downloaded = from_immutable_caches(uri), false unless cached_file
|
|
67
67
|
|
|
68
68
|
fail "Unable to find cached file for #{uri}" unless cached_file
|
|
69
|
-
cached_file.cached(File::RDONLY, downloaded, &block)
|
|
69
|
+
cached_file.cached(File::RDONLY | File::BINARY, downloaded, &block)
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
# Removes an item from the mutable cache.
|
|
@@ -74,7 +74,7 @@ module BuildpackSupport
|
|
|
74
74
|
# @param [String] uri the URI of the item
|
|
75
75
|
# @return [Void]
|
|
76
76
|
def evict(uri)
|
|
77
|
-
CachedFile.new(@mutable_cache_root, uri).destroy
|
|
77
|
+
CachedFile.new(@mutable_cache_root, uri, true).destroy
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
private
|
|
@@ -138,7 +138,7 @@ module BuildpackSupport
|
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
def cache_content(response, cached_file)
|
|
141
|
-
cached_file.cached(File::CREAT | File::WRONLY) do |f|
|
|
141
|
+
cached_file.cached(File::CREAT | File::WRONLY | File::BINARY) do |f|
|
|
142
142
|
@logger.debug { "Persisting content to #{f.path}" }
|
|
143
143
|
|
|
144
144
|
f.truncate(0)
|
|
@@ -156,7 +156,7 @@ module BuildpackSupport
|
|
|
156
156
|
|
|
157
157
|
@logger.debug { "Persisting etag: #{etag}" }
|
|
158
158
|
|
|
159
|
-
cached_file.etag(File::CREAT | File::WRONLY) do |f|
|
|
159
|
+
cached_file.etag(File::CREAT | File::WRONLY | File::BINARY) do |f|
|
|
160
160
|
f.truncate(0)
|
|
161
161
|
f.write etag
|
|
162
162
|
f.fsync
|
|
@@ -170,7 +170,7 @@ module BuildpackSupport
|
|
|
170
170
|
|
|
171
171
|
@logger.debug { "Persisting last-modified: #{last_modified}" }
|
|
172
172
|
|
|
173
|
-
cached_file.last_modified(File::CREAT | File::WRONLY) do |f|
|
|
173
|
+
cached_file.last_modified(File::CREAT | File::WRONLY | File::BINARY) do |f|
|
|
174
174
|
f.truncate(0)
|
|
175
175
|
f.write last_modified
|
|
176
176
|
f.fsync
|
|
@@ -178,7 +178,7 @@ module BuildpackSupport
|
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
def from_mutable_cache(uri)
|
|
181
|
-
cached_file = CachedFile.new
|
|
181
|
+
cached_file = CachedFile.new @mutable_cache_root, uri, true
|
|
182
182
|
cached = update URI(uri), cached_file
|
|
183
183
|
[cached_file, cached]
|
|
184
184
|
rescue => e
|
|
@@ -188,7 +188,7 @@ module BuildpackSupport
|
|
|
188
188
|
|
|
189
189
|
def from_immutable_caches(uri)
|
|
190
190
|
@immutable_cache_roots.each do |cache_root|
|
|
191
|
-
candidate = CachedFile.new cache_root, uri
|
|
191
|
+
candidate = CachedFile.new cache_root, uri, false
|
|
192
192
|
|
|
193
193
|
next unless candidate.cached?
|
|
194
194
|
|
|
@@ -226,11 +226,11 @@ module BuildpackSupport
|
|
|
226
226
|
request = Net::HTTP::Get.new(uri.request_uri)
|
|
227
227
|
|
|
228
228
|
if cached_file.etag?
|
|
229
|
-
cached_file.etag(File::RDONLY) { |f| request['If-None-Match'] = File.read(f) }
|
|
229
|
+
cached_file.etag(File::RDONLY | File::BINARY) { |f| request['If-None-Match'] = File.read(f) }
|
|
230
230
|
end
|
|
231
231
|
|
|
232
232
|
if cached_file.last_modified?
|
|
233
|
-
cached_file.last_modified(File::RDONLY) { |f| request['If-Modified-Since'] = File.read(f) }
|
|
233
|
+
cached_file.last_modified(File::RDONLY | File::BINARY) { |f| request['If-Modified-Since'] = File.read(f) }
|
|
234
234
|
end
|
|
235
235
|
|
|
236
236
|
@logger.debug { "Request: #{request.path}, #{request.to_hash}" }
|
|
@@ -265,7 +265,7 @@ module BuildpackSupport
|
|
|
265
265
|
def validate_size(expected_size, cached_file)
|
|
266
266
|
return unless expected_size
|
|
267
267
|
|
|
268
|
-
actual_size = cached_file.cached(File::RDONLY) { |f| f.size }
|
|
268
|
+
actual_size = cached_file.cached(File::RDONLY | File::BINARY) { |f| f.size }
|
|
269
269
|
@logger.debug { "Validated content size #{actual_size} is #{expected_size}" }
|
|
270
270
|
|
|
271
271
|
return if expected_size.to_i == actual_size
|
|
@@ -45,15 +45,34 @@ module BuildpackSupport
|
|
|
45
45
|
#
|
|
46
46
|
# @param [Boolean] available whether the internet is available
|
|
47
47
|
# @param [String, nil] message an optional message to be printed when the availability is set
|
|
48
|
+
# @yields an environment with internet availability temporarily overridden if block given
|
|
48
49
|
def available(available, message = nil)
|
|
49
50
|
@monitor.synchronize do
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
if block_given?
|
|
52
|
+
preserve_availability do
|
|
53
|
+
@available = available
|
|
54
|
+
@logger.warn { "Internet availability temporarily set to #{available}: #{message}" } if message
|
|
55
|
+
|
|
56
|
+
yield
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
@available = available
|
|
60
|
+
@logger.warn { "Internet availability set to #{available}: #{message}" } if message
|
|
61
|
+
end
|
|
52
62
|
end
|
|
53
63
|
end
|
|
54
64
|
|
|
55
65
|
private
|
|
56
66
|
|
|
67
|
+
def preserve_availability
|
|
68
|
+
previous = @available
|
|
69
|
+
begin
|
|
70
|
+
yield
|
|
71
|
+
ensure
|
|
72
|
+
@available = previous
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
57
76
|
def remote_downloads?
|
|
58
77
|
BuildpackSupport::ConfigurationUtils.new.load('cache')['remote_downloads'] != 'disabled'
|
|
59
78
|
end
|
|
@@ -22,6 +22,7 @@ require 'buildpack_support/test/base_droplet_helper'
|
|
|
22
22
|
require 'buildpack_support/test/console_helper'
|
|
23
23
|
require 'buildpack_support/test/internet_availability_helper'
|
|
24
24
|
require 'buildpack_support/test/logging_helper'
|
|
25
|
+
require 'buildpack_support/test/repository_helper'
|
|
25
26
|
require 'buildpack_support/tokenized_version'
|
|
26
27
|
require 'pathname'
|
|
27
28
|
|
|
@@ -31,6 +32,7 @@ shared_context 'base_component_helper' do
|
|
|
31
32
|
include_context 'console_helper'
|
|
32
33
|
include_context 'internet_availability_helper'
|
|
33
34
|
include_context 'logging_helper'
|
|
35
|
+
include_context 'repository_helper'
|
|
34
36
|
|
|
35
37
|
let(:application_cache) { double('ApplicationCache') }
|
|
36
38
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Encoding: utf-8
|
|
2
|
+
# Copyright 2013-2014 the original author or authors.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require 'spec_helper'
|
|
17
|
+
require 'buildpack_support/repository/configured_item'
|
|
18
|
+
require 'buildpack_support/tokenized_version'
|
|
19
|
+
|
|
20
|
+
shared_context 'repository_helper' do
|
|
21
|
+
|
|
22
|
+
let(:configured_item) { double('configured_item') }
|
|
23
|
+
|
|
24
|
+
let(:uri) { 'test-uri' }
|
|
25
|
+
|
|
26
|
+
let(:version) { '0.0.0' }
|
|
27
|
+
|
|
28
|
+
before do
|
|
29
|
+
tokenized_version = BuildpackSupport::TokenizedVersion.new(version)
|
|
30
|
+
|
|
31
|
+
allow(BuildpackSupport::Repository::ConfiguredItem).to receive(:new).and_return configured_item
|
|
32
|
+
|
|
33
|
+
allow(configured_item).to receive(:find_item) do |&block|
|
|
34
|
+
block.call(tokenized_version) if block
|
|
35
|
+
end.and_return([tokenized_version, uri])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -22,12 +22,30 @@ require 'fileutils'
|
|
|
22
22
|
describe BuildpackSupport::Cache::CachedFile do
|
|
23
23
|
include_context 'scratch_helper'
|
|
24
24
|
|
|
25
|
-
let(:
|
|
25
|
+
let(:cache_root) { scratch_dir + 'cache/root' }
|
|
26
|
+
|
|
27
|
+
let(:file_cache) { described_class.new(scratch_dir, 'http://foo-uri/', true) }
|
|
26
28
|
|
|
27
29
|
it 'should not create any files on initialization' do
|
|
28
30
|
%w(cached etag last_modified).each { |extension| expect(cache_file(extension)).not_to exist }
|
|
29
31
|
end
|
|
30
32
|
|
|
33
|
+
it 'should create cache_root if mutable' do
|
|
34
|
+
expect(cache_root).not_to exist
|
|
35
|
+
|
|
36
|
+
described_class.new(cache_root, 'http://foo-uri/', true)
|
|
37
|
+
|
|
38
|
+
expect(cache_root).to exist
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'should not create cache_root if immutable' do
|
|
42
|
+
expect(cache_root).not_to exist
|
|
43
|
+
|
|
44
|
+
described_class.new(cache_root, 'http://foo-uri/', false)
|
|
45
|
+
|
|
46
|
+
expect(cache_root).not_to exist
|
|
47
|
+
end
|
|
48
|
+
|
|
31
49
|
it 'should not detect cached file' do
|
|
32
50
|
expect(file_cache.cached?).not_to be
|
|
33
51
|
end
|
|
@@ -62,6 +80,12 @@ describe BuildpackSupport::Cache::CachedFile do
|
|
|
62
80
|
%w(cached etag last_modified).each { |extension| expect(cache_file(extension)).not_to exist }
|
|
63
81
|
end
|
|
64
82
|
|
|
83
|
+
it 'should not destroy all files if immutable' do
|
|
84
|
+
described_class.new(scratch_dir, 'http://foo-uri/', false).destroy
|
|
85
|
+
|
|
86
|
+
%w(cached etag last_modified).each { |extension| expect(cache_file(extension)).to exist }
|
|
87
|
+
end
|
|
88
|
+
|
|
65
89
|
it 'should call the block with the content of the etag file' do
|
|
66
90
|
expect { |b| file_cache.etag(File::RDONLY, 'test-arg', &b) }.to yield_file_with_content(/foo-etag/)
|
|
67
91
|
end
|
|
@@ -80,7 +104,7 @@ describe BuildpackSupport::Cache::CachedFile do
|
|
|
80
104
|
end
|
|
81
105
|
|
|
82
106
|
def cache_file(extension)
|
|
83
|
-
scratch_dir + "http
|
|
107
|
+
scratch_dir + "http%3A%2F%2Ffoo-uri%2F.#{extension}"
|
|
84
108
|
end
|
|
85
109
|
|
|
86
110
|
def touch(extension, content = '')
|
|
@@ -242,11 +242,11 @@ describe BuildpackSupport::Cache::DownloadCache do
|
|
|
242
242
|
end
|
|
243
243
|
|
|
244
244
|
def cache_file(root, extension)
|
|
245
|
-
root + "http
|
|
245
|
+
root + "http%3A%2F%2Ffoo-uri%2F.#{extension}"
|
|
246
246
|
end
|
|
247
247
|
|
|
248
248
|
def credential_cache_file(root, extension)
|
|
249
|
-
root + "http
|
|
249
|
+
root + "http%3A%2F%2Ftest-username%3Atest-password@foo-uri%2F.#{extension}"
|
|
250
250
|
end
|
|
251
251
|
|
|
252
252
|
def expect_complete_cache(root)
|
|
@@ -54,4 +54,22 @@ describe BuildpackSupport::Cache::InternetAvailability do
|
|
|
54
54
|
expect(log_contents).to match(/Internet availability set to false: test message/)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
it 'should temporarily set internet unavailable' do
|
|
58
|
+
expect(described_class.instance.available?).to be
|
|
59
|
+
|
|
60
|
+
described_class.instance.available(false) { expect(described_class.instance.available?).not_to be }
|
|
61
|
+
|
|
62
|
+
expect(described_class.instance.available?).to be
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'should temporarily set internet available',
|
|
66
|
+
:disable_internet do
|
|
67
|
+
|
|
68
|
+
expect(described_class.instance.available?).not_to be
|
|
69
|
+
|
|
70
|
+
described_class.instance.available(true) { expect(described_class.instance.available?).to be }
|
|
71
|
+
|
|
72
|
+
expect(described_class.instance.available?).not_to be
|
|
73
|
+
end
|
|
74
|
+
|
|
57
75
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: buildpack-support
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2014-05-
|
|
12
|
+
date: 2014-05-27 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: bundler
|
|
@@ -261,6 +261,7 @@ files:
|
|
|
261
261
|
- lib/buildpack_support/test/environment_helper.rb
|
|
262
262
|
- lib/buildpack_support/test/internet_availability_helper.rb
|
|
263
263
|
- lib/buildpack_support/test/logging_helper.rb
|
|
264
|
+
- lib/buildpack_support/test/repository_helper.rb
|
|
264
265
|
- lib/buildpack_support/test/scratch_helper.rb
|
|
265
266
|
- lib/buildpack_support/test/versioned_dependency_component_helper.rb
|
|
266
267
|
- lib/buildpack_support/test/with_load_path_helper.rb
|
|
@@ -346,13 +347,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
346
347
|
version: '0'
|
|
347
348
|
segments:
|
|
348
349
|
- 0
|
|
349
|
-
hash:
|
|
350
|
+
hash: 2138916088248865313
|
|
350
351
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
351
352
|
none: false
|
|
352
353
|
requirements:
|
|
353
354
|
- - ! '>='
|
|
354
355
|
- !ruby/object:Gem::Version
|
|
355
356
|
version: '0'
|
|
357
|
+
segments:
|
|
358
|
+
- 0
|
|
359
|
+
hash: 2138916088248865313
|
|
356
360
|
requirements: []
|
|
357
361
|
rubyforge_project:
|
|
358
362
|
rubygems_version: 1.8.23.2
|