buildpack-support 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +202 -0
- data/NOTICE +2 -0
- data/docs/cache.md +77 -0
- data/docs/component.md +1 -0
- data/docs/configuration.md +27 -0
- data/docs/logging.md +54 -0
- data/docs/other.md +1 -0
- data/docs/rake.md +1 -0
- data/docs/repository.md +116 -0
- data/docs/test.md +1 -0
- data/lib/buildpack_support.rb +18 -0
- data/lib/buildpack_support/base_buildpack.rb +166 -0
- data/lib/buildpack_support/buildpack_version.rb +124 -0
- data/lib/buildpack_support/cache.rb +24 -0
- data/lib/buildpack_support/cache/application_cache.rb +41 -0
- data/lib/buildpack_support/cache/cached_file.rb +103 -0
- data/lib/buildpack_support/cache/download_cache.rb +280 -0
- data/lib/buildpack_support/cache/inferred_network_failure.rb +26 -0
- data/lib/buildpack_support/cache/internet_availability.rb +64 -0
- data/lib/buildpack_support/component.rb +24 -0
- data/lib/buildpack_support/component/application.rb +76 -0
- data/lib/buildpack_support/component/base_component.rb +78 -0
- data/lib/buildpack_support/component/base_droplet.rb +96 -0
- data/lib/buildpack_support/component/downloads.rb +88 -0
- data/lib/buildpack_support/component/services.rb +84 -0
- data/lib/buildpack_support/component/versioned_dependency_component.rb +71 -0
- data/lib/buildpack_support/component/versioned_downloads.rb +57 -0
- data/lib/buildpack_support/component/with_timing.rb +40 -0
- data/lib/buildpack_support/configuration_utils.rb +58 -0
- data/lib/buildpack_support/constantize.rb +46 -0
- data/lib/buildpack_support/dash_case.rb +29 -0
- data/lib/buildpack_support/directory_finder.rb +45 -0
- data/lib/buildpack_support/filtering_pathname.rb +227 -0
- data/lib/buildpack_support/format_duration.rb +57 -0
- data/lib/buildpack_support/logging.rb +22 -0
- data/lib/buildpack_support/logging/delegating_logger.rb +48 -0
- data/lib/buildpack_support/logging/logger_factory.rb +148 -0
- data/lib/buildpack_support/qualify_path.rb +36 -0
- data/lib/buildpack_support/rake.rb +22 -0
- data/lib/buildpack_support/rake/buildpack_stage_task.rb +86 -0
- data/lib/buildpack_support/rake/cached_artifact_finder.rb +99 -0
- data/lib/buildpack_support/rake/check_api_doc_task.rb +70 -0
- data/lib/buildpack_support/rake/dependency_cache_task.rb +87 -0
- data/lib/buildpack_support/rake/disable_remote_downloads_task.rb +80 -0
- data/lib/buildpack_support/rake/package_task.rb +133 -0
- data/lib/buildpack_support/rake/package_zip_task.rb +80 -0
- data/lib/buildpack_support/rake/repository_configuration_finder.rb +66 -0
- data/lib/buildpack_support/rake/write_version_file_task.rb +82 -0
- data/lib/buildpack_support/repository.rb +24 -0
- data/lib/buildpack_support/repository/configured_item.rb +81 -0
- data/lib/buildpack_support/repository/repository_index.rb +98 -0
- data/lib/buildpack_support/repository/wildcard_version_resolver.rb +75 -0
- data/lib/buildpack_support/shell.rb +41 -0
- data/lib/buildpack_support/snake_case.rb +30 -0
- data/lib/buildpack_support/space_case.rb +29 -0
- data/lib/buildpack_support/test/application_helper.rb +41 -0
- data/lib/buildpack_support/test/base_component_helper.rb +59 -0
- data/lib/buildpack_support/test/base_droplet_helper.rb +36 -0
- data/lib/buildpack_support/test/console_helper.rb +57 -0
- data/lib/buildpack_support/test/environment_helper.rb +32 -0
- data/lib/buildpack_support/test/internet_availability_helper.rb +29 -0
- data/lib/buildpack_support/test/logging_helper.rb +50 -0
- data/lib/buildpack_support/test/scratch_helper.rb +32 -0
- data/lib/buildpack_support/test/versioned_dependency_component_helper.rb +32 -0
- data/lib/buildpack_support/test/with_load_path_helper.rb +27 -0
- data/lib/buildpack_support/to_b.rb +38 -0
- data/lib/buildpack_support/tokenized_version.rb +157 -0
- data/lib/buildpack_support/version.rb +23 -0
- data/spec/buildpack_support/base_buildpack_spec.rb +112 -0
- data/spec/buildpack_support/buildpack_version_spec.rb +122 -0
- data/spec/buildpack_support/cache/application_cache_spec.rb +56 -0
- data/spec/buildpack_support/cache/cached_file_spec.rb +94 -0
- data/spec/buildpack_support/cache/download_cache_spec.rb +293 -0
- data/spec/buildpack_support/cache/internet_availability_spec.rb +57 -0
- data/spec/buildpack_support/cache/yield_file_with_content.rb +30 -0
- data/spec/buildpack_support/component/application_spec.rb +81 -0
- data/spec/buildpack_support/component/base_component_spec.rb +81 -0
- data/spec/buildpack_support/component/base_droplet_spec.rb +72 -0
- data/spec/buildpack_support/component/downloads_spec.rb +63 -0
- data/spec/buildpack_support/component/services_spec.rb +80 -0
- data/spec/buildpack_support/component/versioned_dependency_component_spec.rb +58 -0
- data/spec/buildpack_support/component/versioned_downloads_spec.rb +58 -0
- data/spec/buildpack_support/component/with_timing_spec.rb +30 -0
- data/spec/buildpack_support/configuration_utils_spec.rb +39 -0
- data/spec/buildpack_support/constantize_spec.rb +34 -0
- data/spec/buildpack_support/dash_case_spec.rb +41 -0
- data/spec/buildpack_support/directory_finder_spec.rb +41 -0
- data/spec/buildpack_support/filtering_pathname_spec.rb +443 -0
- data/spec/buildpack_support/format_duration_spec.rb +60 -0
- data/spec/buildpack_support/logging/delegating_logger_spec.rb +62 -0
- data/spec/buildpack_support/logging/logger_factory_spec.rb +262 -0
- data/spec/buildpack_support/qualify_path_spec.rb +42 -0
- data/spec/buildpack_support/rake/buildpack_stage_task_spec.rb +88 -0
- data/spec/buildpack_support/rake/cached_artifact_finder_spec.rb +73 -0
- data/spec/buildpack_support/rake/check_api_doc_task_spec.rb +69 -0
- data/spec/buildpack_support/rake/dependency_cache_task_spec.rb +133 -0
- data/spec/buildpack_support/rake/disable_remote_downloads_task_spec.rb +91 -0
- data/spec/buildpack_support/rake/package_task_spec.rb +335 -0
- data/spec/buildpack_support/rake/package_zip_task_spec.rb +91 -0
- data/spec/buildpack_support/rake/repository_configuration_finder_spec.rb +61 -0
- data/spec/buildpack_support/rake/write_version_file_task_spec.rb +96 -0
- data/spec/buildpack_support/repository/configured_item_spec.rb +78 -0
- data/spec/buildpack_support/repository/repository_index_spec.rb +118 -0
- data/spec/buildpack_support/repository/wildcard_version_resolver_spec.rb +73 -0
- data/spec/buildpack_support/shell_spec.rb +32 -0
- data/spec/buildpack_support/snake_case_spec.rb +45 -0
- data/spec/buildpack_support/space_case_spec.rb +41 -0
- data/spec/buildpack_support/to_b_spec.rb +41 -0
- data/spec/buildpack_support/tokenized_version_spec.rb +132 -0
- data/spec/fixtures/application/test-file +0 -0
- data/spec/fixtures/config/found-config.yml +2 -0
- data/spec/fixtures/droplet-resources/droplet-resource +0 -0
- data/spec/fixtures/stub-download-with-top-level.zip +0 -0
- data/spec/fixtures/stub-download.tar.gz +0 -0
- data/spec/fixtures/stub-download.zip +0 -0
- data/spec/fixtures/test-cache.yml +18 -0
- data/spec/fixtures/test-index.yml +2 -0
- data/spec/fixtures/test_component.rb +0 -0
- data/spec/fixtures/zip-contents/test-directory/test-deep-file +0 -0
- data/spec/fixtures/zip-contents/test-file +0 -0
- data/spec/spec_helper.rb +30 -0
- metadata +416 -0
data/docs/test.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
TODO: Document Test support code
|
@@ -0,0 +1,18 @@
|
|
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
|
+
# A module encapsulating all of the code for the Buildpack Support utilities
|
17
|
+
module BuildpackSupport
|
18
|
+
end
|
@@ -0,0 +1,166 @@
|
|
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 'buildpack_support'
|
17
|
+
require 'buildpack_support/space_case'
|
18
|
+
require 'buildpack_support/buildpack_version'
|
19
|
+
require 'buildpack_support/component/application'
|
20
|
+
require 'buildpack_support/logging/logger_factory'
|
21
|
+
require 'buildpack_support/snake_case'
|
22
|
+
|
23
|
+
module BuildpackSupport
|
24
|
+
|
25
|
+
# A base class for all buildpack implementations to extend from. This implementation provides a number of utility methods for dealing with components.
|
26
|
+
class BaseBuildpack
|
27
|
+
|
28
|
+
# Iterates over all of the components to detect if this buildpack can be used to run an application
|
29
|
+
#
|
30
|
+
# @return [Array<String>] An array of strings that identify the components and versions that will be used to run
|
31
|
+
# this application. If no container can run the application, the array will be empty
|
32
|
+
# (+[]+).
|
33
|
+
def detect
|
34
|
+
fail "Method 'detect' must be defined"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Transforms the application directory such that the engine, and frameworks can run the application
|
38
|
+
#
|
39
|
+
# @return [Void]
|
40
|
+
def compile
|
41
|
+
fail "Method 'compile' must be defined"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Generates the payload required to run the application. The payload format is defined by the
|
45
|
+
# {Heroku Buildpack API}[https://devcenter.heroku.com/articles/buildpack-api#buildpack-api].
|
46
|
+
#
|
47
|
+
# @return [String] The payload required to run the application.
|
48
|
+
def release
|
49
|
+
fail "Method 'release' must be defined"
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
# Returns the components that are detected for an application
|
55
|
+
#
|
56
|
+
# @param [String] type the type of components
|
57
|
+
# @param [String] components the candidate components
|
58
|
+
# @param [Boolean] unique whether there must be _exactly_ one component detected
|
59
|
+
# @return [Array<BuildpackSupport::Component::BaseComponent>] the collection of detected components
|
60
|
+
def component_detection(type, components, unique)
|
61
|
+
detected, _tags = detection type, components, unique
|
62
|
+
detected
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the components, and the tags from those components that are detected for an application
|
66
|
+
#
|
67
|
+
# @param [String] type the type of components
|
68
|
+
# @param [Array<BuildpackSupport::Component::BaseComponent>] components the candidate components
|
69
|
+
# @param [Boolean] unique whether there must be _exactly_ one component detected
|
70
|
+
# @return [Array<BuildpackSupport::Component::BaseComponent>] the collection of detected components
|
71
|
+
# @return [Array<String>] the collection of tags from the detected components
|
72
|
+
def detection(type, components, unique)
|
73
|
+
detected = []
|
74
|
+
tags = []
|
75
|
+
|
76
|
+
components.each do |component|
|
77
|
+
result = component.detect
|
78
|
+
|
79
|
+
next unless result
|
80
|
+
|
81
|
+
detected << component
|
82
|
+
tags << result
|
83
|
+
end
|
84
|
+
|
85
|
+
fail "Application can be run by more than one #{type}: #{names detected}" if unique && detected.size > 1
|
86
|
+
[detected, tags]
|
87
|
+
end
|
88
|
+
|
89
|
+
# +require+ a component based on its id
|
90
|
+
#
|
91
|
+
# @param [Pathname] load_root the +$LOAD_ROOT+ to load the component from
|
92
|
+
# @param [String] component the name of the component to load
|
93
|
+
def require_component(load_root, component)
|
94
|
+
file = load_root + "#{component.snake_case}.rb"
|
95
|
+
|
96
|
+
if file.exist?
|
97
|
+
require component.snake_case
|
98
|
+
@logger.debug { "Successfully required #{component}" }
|
99
|
+
else
|
100
|
+
@logger.debug { "Cannot require #{component} because #{file} does not exist" }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns the tags that are detected for an application
|
105
|
+
#
|
106
|
+
# @param [String] type the type of components
|
107
|
+
# @param [String] components the candidate components
|
108
|
+
# @param [Boolean] unique whether there must be _exactly_ one component detected
|
109
|
+
# @return [Array<String>] the collection of tags from the detected components
|
110
|
+
def tag_detection(type, components, unique)
|
111
|
+
_detected, tags = detection type, components, unique
|
112
|
+
tags
|
113
|
+
end
|
114
|
+
|
115
|
+
private_class_method :new
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def initialize(_app_dir, _application)
|
120
|
+
@logger = Logging::LoggerFactory.instance.get_logger self.class
|
121
|
+
@buildpack_version = BuildpackVersion.new
|
122
|
+
|
123
|
+
@logger.debug { "Environment Variables: #{ENV.to_hash}" }
|
124
|
+
end
|
125
|
+
|
126
|
+
def names(components)
|
127
|
+
components.map { |component| component.class.to_s.space_case }.join(', ')
|
128
|
+
end
|
129
|
+
|
130
|
+
class << self
|
131
|
+
|
132
|
+
# Main entry to the buildpack. Initializes the buildpack and all of its dependencies and yields a new instance
|
133
|
+
# to any given block. Any exceptions thrown as part of the buildpack setup or execution are handled
|
134
|
+
#
|
135
|
+
# @param [String] app_dir the path of the application directory
|
136
|
+
# @param [String] message an error message with an insert for the reason for failure
|
137
|
+
# @yield [Buildpack] the buildpack to work with
|
138
|
+
# @return [Object] the return value from the given block
|
139
|
+
def with_buildpack(app_dir, message)
|
140
|
+
app_dir = Pathname.new(File.expand_path(app_dir))
|
141
|
+
application = Component::Application.new(app_dir)
|
142
|
+
Logging::LoggerFactory.instance.setup app_dir
|
143
|
+
|
144
|
+
yield new(app_dir, application) if block_given?
|
145
|
+
rescue => e
|
146
|
+
handle_error(e, message)
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def handle_error(e, message)
|
152
|
+
if Logging::LoggerFactory.instance.initialized
|
153
|
+
logger = Logging::LoggerFactory.instance.get_logger BaseBuildpack
|
154
|
+
|
155
|
+
logger.error { message % e.inspect }
|
156
|
+
logger.debug { "Exception #{e.inspect} backtrace:\n#{e.backtrace.join("\n")}" }
|
157
|
+
end
|
158
|
+
|
159
|
+
abort e.message
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
@@ -0,0 +1,124 @@
|
|
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 'buildpack_support'
|
17
|
+
require 'buildpack_support/configuration_utils'
|
18
|
+
require 'buildpack_support/directory_finder'
|
19
|
+
require 'buildpack_support/to_b'
|
20
|
+
|
21
|
+
module BuildpackSupport
|
22
|
+
|
23
|
+
# A representation of the buildpack's version. The buildpack's version is determined using the following algorithm:
|
24
|
+
#
|
25
|
+
# 1. using the +config/version.yml+ file if it exists
|
26
|
+
# 2. using +git+ to determine the remote and hash if the buildpack is in a git repository
|
27
|
+
# 3. unknown
|
28
|
+
class BuildpackVersion
|
29
|
+
extend DirectoryFinder
|
30
|
+
|
31
|
+
# @!attribute [r] hash
|
32
|
+
# @return [String, nil] the Git hash of this version, or +nil+ if it cannot be determined
|
33
|
+
attr_reader :hash
|
34
|
+
|
35
|
+
# @!attribute [r] offline
|
36
|
+
# @return [Boolean] +true+ if the buildpack is offline, +false+ otherwise
|
37
|
+
attr_reader :offline
|
38
|
+
|
39
|
+
# @!attribute [r] remote
|
40
|
+
# @return [String, nil] the Git remote of this version, or +nil+ if it cannot be determined
|
41
|
+
attr_reader :remote
|
42
|
+
|
43
|
+
# @!attribute [r] version
|
44
|
+
# @return [String, nil] the version name of this version, or +nil+ if it cannot be determined
|
45
|
+
attr_reader :version
|
46
|
+
|
47
|
+
# Creates a new instance
|
48
|
+
def initialize(should_log = true)
|
49
|
+
configuration = ConfigurationUtils.new(should_log).load 'version'
|
50
|
+
@hash = configuration['hash'] || hash
|
51
|
+
@offline = configuration['offline'] || ENV['OFFLINE'].to_b
|
52
|
+
@remote = configuration['remote'] || remote
|
53
|
+
@version = configuration['version'] || ENV['VERSION'] || @hash
|
54
|
+
|
55
|
+
return unless should_log
|
56
|
+
|
57
|
+
logger = Logging::LoggerFactory.instance.get_logger BuildpackVersion
|
58
|
+
logger.debug { to_s }
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns a +Hash+ representation of the buildpack version.
|
62
|
+
#
|
63
|
+
# @return [Hash] a representation of the buildpack version
|
64
|
+
def to_hash
|
65
|
+
h = {}
|
66
|
+
|
67
|
+
h['hash'] = @hash if @hash
|
68
|
+
h['offline'] = @offline if @offline
|
69
|
+
h['remote'] = @remote if @remote
|
70
|
+
h['version'] = @version if @version
|
71
|
+
|
72
|
+
h
|
73
|
+
end
|
74
|
+
|
75
|
+
# Creates a string representation of the version. The string representation looks like the following:
|
76
|
+
# +[[<VERSION> [(offline)] | ] <REMOTE>#<HASH>] | [unknown]+. Some examples:
|
77
|
+
#
|
78
|
+
# +2.1.2 (offline) | https://github.com/cloudfoundry/java-buildpack.git#12345+ (custom version number, offline buildpack)
|
79
|
+
# +abcde | https://github.com/cloudfoundry/java-buildpack.git#abcde+ (default version number, online buildpack)
|
80
|
+
# +https://github.com/cloudfoundry/java-buildpack#12345+ (cloned buildpack)
|
81
|
+
# +unknown+ (un-packaged, un-cloned)
|
82
|
+
#
|
83
|
+
# @param [Boolean] human_readable whether the output should be human readable or machine readable
|
84
|
+
# @return [String] a +String+ representation of the version
|
85
|
+
def to_s(human_readable = true)
|
86
|
+
s = []
|
87
|
+
s << @version if @version
|
88
|
+
s << (human_readable ? '(offline)' : 'offline') if @offline
|
89
|
+
s << '|' if @version && human_readable
|
90
|
+
s << "#{@remote}##{@hash}" if @remote && @hash
|
91
|
+
s << 'unknown' if s.empty?
|
92
|
+
|
93
|
+
s.join(human_readable ? ' ' : '-')
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
GIT_DIR = BuildpackVersion.load_path_peer('.git').freeze
|
99
|
+
|
100
|
+
private_constant :GIT_DIR
|
101
|
+
|
102
|
+
def git(command)
|
103
|
+
`git --git-dir=#{GIT_DIR} #{command}`.chomp if git? && git_dir?
|
104
|
+
end
|
105
|
+
|
106
|
+
def git?
|
107
|
+
system 'which git > /dev/null'
|
108
|
+
end
|
109
|
+
|
110
|
+
def git_dir?
|
111
|
+
GIT_DIR.exist?
|
112
|
+
end
|
113
|
+
|
114
|
+
def hash
|
115
|
+
git 'rev-parse --short HEAD'
|
116
|
+
end
|
117
|
+
|
118
|
+
def remote
|
119
|
+
git 'config --get remote.origin.url'
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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 'buildpack_support'
|
17
|
+
|
18
|
+
module BuildpackSupport
|
19
|
+
|
20
|
+
# A module encapsulating all of the code for the cache utilities
|
21
|
+
module Cache
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
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 'buildpack_support/cache'
|
17
|
+
require 'buildpack_support/cache/download_cache'
|
18
|
+
|
19
|
+
module BuildpackSupport
|
20
|
+
module Cache
|
21
|
+
|
22
|
+
# An extension of {DownloadCache} that is configured to use the application cache. The application
|
23
|
+
# cache location is defined by the second argument (<tt>ARGV[1]</tt>) to the +compile+ script.
|
24
|
+
#
|
25
|
+
# <b>WARNING: This cache should only by used by code run by the +compile+ script</b>
|
26
|
+
class ApplicationCache < DownloadCache
|
27
|
+
|
28
|
+
# Creates an instance that is configured to use the application cache. The application cache location is defined
|
29
|
+
# by the second argument (<tt>ARGV[1]</tt>) to the +compile+ script.
|
30
|
+
#
|
31
|
+
# @raise if the second argument (<tt>ARGV[1]</tt>) to the +compile+ script is +nil+
|
32
|
+
def initialize
|
33
|
+
application_cache_directory = ARGV[1]
|
34
|
+
fail 'Application cache directory is undefined' if application_cache_directory.nil?
|
35
|
+
super(Pathname.new(application_cache_directory), CACHED_RESOURCES_DIRECTORY)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,103 @@
|
|
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 'fileutils'
|
17
|
+
require 'buildpack_support/cache'
|
18
|
+
|
19
|
+
module BuildpackSupport
|
20
|
+
module Cache
|
21
|
+
|
22
|
+
# Represents a file cached on a filesystem
|
23
|
+
#
|
24
|
+
# Note: this class is thread-safe, however access to the cached files is not
|
25
|
+
class CachedFile
|
26
|
+
|
27
|
+
# Creates an instance of the cached file. Files created and expected by this class will all be rooted at
|
28
|
+
# +cache_root+.
|
29
|
+
#
|
30
|
+
# @param [Pathname] cache_root the filesystem root for the file created and expected by this class
|
31
|
+
# @param [String] uri a uri which uniquely identifies the file in the cache
|
32
|
+
def initialize(cache_root, uri)
|
33
|
+
FileUtils.mkdir_p cache_root
|
34
|
+
|
35
|
+
key = URI.escape(uri, '/')
|
36
|
+
@cached = cache_root + "#{key}.cached"
|
37
|
+
@etag = cache_root + "#{key}.etag"
|
38
|
+
@last_modified = cache_root + "#{key}.last_modified"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Opens the cached file
|
42
|
+
#
|
43
|
+
# @param [String, integer] mode_enc the mode to open the file in. Can be a string like +"r"+ or an integer like
|
44
|
+
# +File::CREAT | File::WRONLY+.
|
45
|
+
# @param [Array] additional_args any additional arguments to be passed to the block
|
46
|
+
# @yield [file, additional_args] the cached file and any additional arguments passed in
|
47
|
+
# @return [Void]
|
48
|
+
def cached(mode_enc, *additional_args, &block)
|
49
|
+
@cached.open(mode_enc) { |f| block.call f, *additional_args }
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns whether or not data is cached.
|
53
|
+
#
|
54
|
+
# @return [Boolean] +true+ if and only if data is cached
|
55
|
+
def cached?
|
56
|
+
@cached.exist?
|
57
|
+
end
|
58
|
+
|
59
|
+
# Destroys the cached file
|
60
|
+
def destroy
|
61
|
+
[@cached, @etag, @last_modified].each { |f| f.delete if f.exist? }
|
62
|
+
end
|
63
|
+
|
64
|
+
# Opens the etag file
|
65
|
+
#
|
66
|
+
# @param [String, integer] mode_enc the mode to open the file in. Can be a string like +"r"+ or an integer like
|
67
|
+
# +File::CREAT | File::WRONLY+.
|
68
|
+
# @param [Array] additional_args any additional arguments to be passed to the block
|
69
|
+
# @yield [file] the etag file
|
70
|
+
# @return [Void]
|
71
|
+
def etag(mode_enc, *additional_args, &block)
|
72
|
+
@etag.open(mode_enc) { |f| block.call f, *additional_args }
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns whether or not an etag is stored.
|
76
|
+
#
|
77
|
+
# @return [Boolean] +true+ if and only if an etag is stored
|
78
|
+
def etag?
|
79
|
+
@etag.exist?
|
80
|
+
end
|
81
|
+
|
82
|
+
# Opens the last modified file
|
83
|
+
#
|
84
|
+
# @param [String, integer] mode_enc the mode to open the file in. Can be a string like +"r"+ or an integer like
|
85
|
+
# +File::CREAT | File::WRONLY+.
|
86
|
+
# @param [Array] additional_args any additional arguments to be passed to the block
|
87
|
+
# @yield [file] the last modified file
|
88
|
+
# @return [Void]
|
89
|
+
def last_modified(mode_enc, *additional_args, &block)
|
90
|
+
@last_modified.open(mode_enc) { |f| block.call f, *additional_args }
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns whether or not a last modified time stamp is stored.
|
94
|
+
#
|
95
|
+
# @return [Boolean] +true+ if and only if a last modified time stamp is stored
|
96
|
+
def last_modified?
|
97
|
+
@last_modified.exist?
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|