buildpack-support 1.0.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/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
|
@@ -0,0 +1,78 @@
|
|
|
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/application_cache'
|
|
17
|
+
require 'buildpack_support/component'
|
|
18
|
+
require 'buildpack_support/component/downloads'
|
|
19
|
+
require 'buildpack_support/format_duration'
|
|
20
|
+
require 'buildpack_support/space_case'
|
|
21
|
+
require 'fileutils'
|
|
22
|
+
|
|
23
|
+
module BuildpackSupport
|
|
24
|
+
module Component
|
|
25
|
+
|
|
26
|
+
# A convenience base class for all components in the buildpack. This base class ensures that the contents of the
|
|
27
|
+
# +context+ are assigned to instance variables matching their keys. It also ensures that all contract methods are
|
|
28
|
+
# implemented.
|
|
29
|
+
class BaseComponent
|
|
30
|
+
include Downloads
|
|
31
|
+
|
|
32
|
+
# Creates an instance. The contents of +context+ are assigned to the instance variables matching their keys.
|
|
33
|
+
#
|
|
34
|
+
# @param [Hash] context a collection of utilities used by components
|
|
35
|
+
# @option context [BuildpackSupport::Component::Application] :application the application
|
|
36
|
+
# @option context [Hash] :configuration the component's configuration
|
|
37
|
+
# @option context [BuildpackSupport::Component::Droplet] :droplet the droplet
|
|
38
|
+
def initialize(context)
|
|
39
|
+
@application = context[:application]
|
|
40
|
+
@component_name = self.class.to_s.space_case
|
|
41
|
+
@configuration = context[:configuration]
|
|
42
|
+
@droplet = context[:droplet]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# If the component should be used when staging an application
|
|
46
|
+
#
|
|
47
|
+
# @return [Array<String>, String, nil] If the component should be used when staging the application, a +String+ or
|
|
48
|
+
# an +Array<String>+ that uniquely identifies the component (e.g.
|
|
49
|
+
# +open_jdk=1.7.0_40+). Otherwise, +nil+.
|
|
50
|
+
def detect
|
|
51
|
+
fail "Method 'detect' must be defined"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Modifies the application's file system. The component is expected to transform the application's file system in
|
|
55
|
+
# whatever way is necessary (e.g. downloading files or creating symbolic links) to support the function of the
|
|
56
|
+
# component. Status output written to +STDOUT+ is expected as part of this invocation.
|
|
57
|
+
#
|
|
58
|
+
# @return [Void]
|
|
59
|
+
def compile
|
|
60
|
+
fail "Method 'compile' must be defined"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Modifies the application's runtime configuration. The component is expected to transform members of the +context+
|
|
64
|
+
# (e.g. +@java_home+, +@java_opts+, etc.) in whatever way is necessary to support the function of the component.
|
|
65
|
+
#
|
|
66
|
+
# Container components are also expected to create the command required to run the application. These components
|
|
67
|
+
# are expected to read the +context+ values and take them into account when creating the command.
|
|
68
|
+
#
|
|
69
|
+
# @return [void, String] components other than containers are not expected to return any value. Container
|
|
70
|
+
# components are expected to return the command required to run the application.
|
|
71
|
+
def release
|
|
72
|
+
fail "Method 'release' must be defined"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
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/component'
|
|
17
|
+
require 'buildpack_support/directory_finder'
|
|
18
|
+
require 'buildpack_support/logging/logger_factory'
|
|
19
|
+
require 'buildpack_support/filtering_pathname'
|
|
20
|
+
require 'fileutils'
|
|
21
|
+
require 'pathname'
|
|
22
|
+
|
|
23
|
+
module BuildpackSupport
|
|
24
|
+
module Component
|
|
25
|
+
|
|
26
|
+
# An abstraction around the droplet that will be created and used at runtime. This abstraction is intended to hide
|
|
27
|
+
# the work done by components within their own sandboxes, while exposing changes made to the user's application.
|
|
28
|
+
# Think of this as a mutable representation of a component's sandbox and the application that was uploaded.
|
|
29
|
+
#
|
|
30
|
+
# A new instance of this type should be created for each component.
|
|
31
|
+
class BaseDroplet
|
|
32
|
+
extend BuildpackSupport::DirectoryFinder
|
|
33
|
+
|
|
34
|
+
# @!attribute [r] component_id
|
|
35
|
+
# @return [String] the id of component using this droplet
|
|
36
|
+
attr_reader :component_id
|
|
37
|
+
|
|
38
|
+
# @!attribute [r] root
|
|
39
|
+
# @return [BuildpackSupport::FilteringPathname] the root of the droplet's fileystem filtered so that it
|
|
40
|
+
# excludes files in the sandboxes of other components
|
|
41
|
+
attr_reader :root
|
|
42
|
+
|
|
43
|
+
# @!attribute [r] sandbox
|
|
44
|
+
# @return [Pathname] the root of the component's sandbox
|
|
45
|
+
attr_reader :sandbox
|
|
46
|
+
|
|
47
|
+
# Creates a new instance of the droplet abstraction
|
|
48
|
+
#
|
|
49
|
+
# @param [String] component_id the id of the component that will use this +Droplet+
|
|
50
|
+
# @param [Pathname] root the root of the droplet
|
|
51
|
+
def initialize(component_id, root)
|
|
52
|
+
@component_id = component_id
|
|
53
|
+
@logger = BuildpackSupport::Logging::LoggerFactory.instance.get_logger self.class
|
|
54
|
+
|
|
55
|
+
buildpack_root = root + '.buildpack'
|
|
56
|
+
sandbox_root = buildpack_root + component_id
|
|
57
|
+
|
|
58
|
+
@sandbox = BuildpackSupport::FilteringPathname.new(sandbox_root, ->(path) { in?(path, sandbox_root) }, true)
|
|
59
|
+
@root = BuildpackSupport::FilteringPathname.new(root,
|
|
60
|
+
->(path) { !in?(path, buildpack_root) || in?(path, @sandbox) },
|
|
61
|
+
true)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Copy resources from a components resources directory to a directory
|
|
65
|
+
#
|
|
66
|
+
# @param [Pathname] target_directory the directory to copy to. Defaults to the component's +sandbox+.
|
|
67
|
+
# @return [Void]
|
|
68
|
+
def copy_resources(target_directory = @sandbox)
|
|
69
|
+
resources = RESOURCES_DIRECTORY + @component_id
|
|
70
|
+
|
|
71
|
+
if resources.exist?
|
|
72
|
+
FileUtils.mkdir_p target_directory
|
|
73
|
+
FileUtils.cp_r("#{resources}/.", target_directory)
|
|
74
|
+
@logger.debug { "Resources #{resources} found" }
|
|
75
|
+
else
|
|
76
|
+
@logger.debug { "No resources #{resources} found" }
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
RESOURCES_DIRECTORY = BaseDroplet.load_path_peer('resources').freeze
|
|
83
|
+
|
|
84
|
+
private_constant :RESOURCES_DIRECTORY
|
|
85
|
+
|
|
86
|
+
def in?(path, root)
|
|
87
|
+
path.ascend do |parent|
|
|
88
|
+
return true if parent == root
|
|
89
|
+
end
|
|
90
|
+
false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
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/component'
|
|
17
|
+
require 'buildpack_support/component/with_timing'
|
|
18
|
+
require 'buildpack_support/shell'
|
|
19
|
+
|
|
20
|
+
module BuildpackSupport
|
|
21
|
+
module Component
|
|
22
|
+
|
|
23
|
+
# A mixin that provides methods for downloading, caching, and unpacking files
|
|
24
|
+
module Downloads
|
|
25
|
+
include BuildpackSupport::Shell
|
|
26
|
+
include WithTiming
|
|
27
|
+
|
|
28
|
+
# Downloads an item with the given name and version from the given URI, then yields the resultant file to the given
|
|
29
|
+
# block.
|
|
30
|
+
#
|
|
31
|
+
# @param [BuildpackSupport::TokenizedVersion] version
|
|
32
|
+
# @param [String] uri
|
|
33
|
+
# @param [String] name an optional name for the download. Defaults to +@component_name+.
|
|
34
|
+
# @return [Void]
|
|
35
|
+
def download(version, uri, name = @component_name)
|
|
36
|
+
download_start_time = Time.now
|
|
37
|
+
print "-----> Downloading #{name} #{version} from #{uri} "
|
|
38
|
+
|
|
39
|
+
BuildpackSupport::Cache::ApplicationCache.new.get(uri) do |file, downloaded|
|
|
40
|
+
puts downloaded ? "(#{(Time.now - download_start_time).duration})" : '(found in cache)'
|
|
41
|
+
yield file
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Downloads a given TAR file and expands it.
|
|
46
|
+
#
|
|
47
|
+
# @param [String] version the version of the download
|
|
48
|
+
# @param [String] uri the uri of the download
|
|
49
|
+
# @param [Pathname] target_directory the directory to expand the TAR file to. Defaults to the component's sandbox.
|
|
50
|
+
# @param [String] name an optional name for the download and expansion. Defaults to +@component_name+.
|
|
51
|
+
# @return [Void]
|
|
52
|
+
def download_tar(version, uri, target_directory = @droplet.sandbox, name = @component_name)
|
|
53
|
+
download(version, uri, name) do |file|
|
|
54
|
+
with_timing "Expanding #{name} to #{target_directory.relative_path_from(@droplet.root)}" do
|
|
55
|
+
FileUtils.mkdir_p target_directory
|
|
56
|
+
shell "tar xzf #{file.path} -C #{target_directory} --strip 1 2>&1"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Downloads a given ZIP file and expands it.
|
|
62
|
+
#
|
|
63
|
+
# @param [Boolean] strip_top_level whether to strip the top-level directory when expanding. Defaults to +true+.
|
|
64
|
+
# @param [Pathname] target_directory the directory to expand the ZIP file to. Defaults to the component's sandbox.
|
|
65
|
+
# @param [String] name an optional name for the download. Defaults to +@component_name+.
|
|
66
|
+
# @return [Void]
|
|
67
|
+
def download_zip(version, uri, strip_top_level = true, target_directory = @droplet.sandbox, name = @component_name)
|
|
68
|
+
download(version, uri, name) do |file|
|
|
69
|
+
with_timing "Expanding #{name} to #{target_directory.relative_path_from(@droplet.root)}" do
|
|
70
|
+
if strip_top_level
|
|
71
|
+
Dir.mktmpdir do |root|
|
|
72
|
+
shell "unzip -qq #{file.path} -d #{root} 2>&1"
|
|
73
|
+
|
|
74
|
+
FileUtils.mkdir_p target_directory.parent
|
|
75
|
+
FileUtils.mv Pathname.new(root).children.first, target_directory
|
|
76
|
+
end
|
|
77
|
+
else
|
|
78
|
+
FileUtils.mkdir_p target_directory
|
|
79
|
+
shell "unzip -qq #{file.path} -d #{target_directory} 2>&1"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
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/component'
|
|
17
|
+
require 'buildpack_support/logging/logger_factory'
|
|
18
|
+
|
|
19
|
+
module BuildpackSupport
|
|
20
|
+
module Component
|
|
21
|
+
|
|
22
|
+
# An abstraction encapsulating the +VCAP_SERVICES+ of an application.
|
|
23
|
+
#
|
|
24
|
+
# A new instance of this type should be created once for the application.
|
|
25
|
+
class Services < Array
|
|
26
|
+
|
|
27
|
+
def initialize(raw)
|
|
28
|
+
concat raw.values.flatten
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Compares the name, label, and tags of each service to the given +filter+. The method returns +true+ if the
|
|
32
|
+
# +filter+ matches exactly one service, +false+ otherwise.
|
|
33
|
+
#
|
|
34
|
+
# @param [Regexp, String] filter a +RegExp+ or +String+ to match against the name, label, and tags of the services
|
|
35
|
+
# @param [String] required_credentials an optional list of keys that must exist in the credentials payload of
|
|
36
|
+
# the candidate service
|
|
37
|
+
# @return [Boolean] +true+ if the +filter+ matches exactly one service with the required credentials, +false+
|
|
38
|
+
# otherwise.
|
|
39
|
+
def one_service?(filter, *required_credentials)
|
|
40
|
+
candidates = select(&matcher(filter))
|
|
41
|
+
|
|
42
|
+
match = false
|
|
43
|
+
if candidates.one?
|
|
44
|
+
if credentials?(candidates.first['credentials'], required_credentials)
|
|
45
|
+
match = true
|
|
46
|
+
else
|
|
47
|
+
logger = BuildpackSupport::Logging::LoggerFactory.instance.get_logger Services
|
|
48
|
+
logger.warn do
|
|
49
|
+
"A service with a name label or tag matching #{filter} was found, but was missing one of the required" \
|
|
50
|
+
" credentials #{required_credentials}"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
match
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Compares the name, label, and tags of each service to the given +filter+. The method returns the first service
|
|
59
|
+
# that the +filter+ matches. If no service matches, returns +nil+
|
|
60
|
+
#
|
|
61
|
+
# @param [Regexp, String] filter a +RegExp+ or +String+ to match against the name, label, and tags of the services
|
|
62
|
+
# @return [Hash, nil] the first service that +filter+ matches. If no service matches, returns +nil+.
|
|
63
|
+
def find_service(filter)
|
|
64
|
+
find(&matcher(filter))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def credentials?(candidate, required_keys)
|
|
70
|
+
required_keys.all? { |k| candidate.key? k }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def matcher(filter)
|
|
74
|
+
filter = Regexp.new(filter) unless filter.kind_of?(Regexp)
|
|
75
|
+
|
|
76
|
+
lambda do |service|
|
|
77
|
+
service['name'] =~ filter || service['label'] =~ filter || service['tags'].any? { |tag| tag =~ filter }
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
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/component'
|
|
17
|
+
require 'buildpack_support/component/base_component'
|
|
18
|
+
require 'buildpack_support/component/versioned_downloads'
|
|
19
|
+
require 'buildpack_support/dash_case'
|
|
20
|
+
require 'buildpack_support/repository/configured_item'
|
|
21
|
+
require 'fileutils'
|
|
22
|
+
require 'tmpdir'
|
|
23
|
+
|
|
24
|
+
module BuildpackSupport
|
|
25
|
+
module Component
|
|
26
|
+
|
|
27
|
+
# A convenience base class for all components that have a versioned dependency. In addition to the functionality
|
|
28
|
+
# inherited from +BaseComponent+ this class also ensures that managed dependencies are handled in a uniform manner.
|
|
29
|
+
class VersionedDependencyComponent < BaseComponent
|
|
30
|
+
include VersionedDownloads
|
|
31
|
+
|
|
32
|
+
# Creates an instance. In addition to the functionality inherited from +BaseComponent+, +@version+ and +@uri+
|
|
33
|
+
# instance variables are exposed.
|
|
34
|
+
#
|
|
35
|
+
# @param [Hash] context a collection of utilities used by components
|
|
36
|
+
# @param [Block, nil] version_validator an optional version validation block
|
|
37
|
+
def initialize(context, configured_item = BuildpackSupport::Repository::ConfiguredItem.new, &version_validator)
|
|
38
|
+
super(context)
|
|
39
|
+
|
|
40
|
+
if supports?
|
|
41
|
+
@version, @uri = configured_item.find_item(@component_name, @configuration, &version_validator)
|
|
42
|
+
else
|
|
43
|
+
@version = nil
|
|
44
|
+
@uri = nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# (see BuildpackSupport::Component::BaseComponent#detect)
|
|
49
|
+
def detect
|
|
50
|
+
@version ? id(@version) : nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
protected
|
|
54
|
+
|
|
55
|
+
# Whether or not this component supports this application
|
|
56
|
+
#
|
|
57
|
+
# @return [Boolean] whether or not this component supports this application
|
|
58
|
+
def supports?
|
|
59
|
+
fail "Method 'supports?' must be defined"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def id(version)
|
|
65
|
+
"#{self.class.to_s.dash_case}=#{version}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
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/component'
|
|
17
|
+
require 'buildpack_support/component/downloads'
|
|
18
|
+
require 'buildpack_support/shell'
|
|
19
|
+
|
|
20
|
+
module BuildpackSupport
|
|
21
|
+
module Component
|
|
22
|
+
|
|
23
|
+
# A mixin that provides methods for downloading, caching, and unpacking files where a version and uri are available
|
|
24
|
+
module VersionedDownloads
|
|
25
|
+
include BuildpackSupport::Shell
|
|
26
|
+
include Downloads
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
alias_method :super_download_tar, :download_tar
|
|
31
|
+
alias_method :super_download_zip, :download_zip
|
|
32
|
+
|
|
33
|
+
public
|
|
34
|
+
|
|
35
|
+
# Downloads a given TAR file and expands it.
|
|
36
|
+
#
|
|
37
|
+
# @param [Pathname] target_directory the directory to expand the TAR file to. Defaults to the component's sandbox.
|
|
38
|
+
# @param [String] name an optional name for the download and expansion. Defaults to +@component_name+.
|
|
39
|
+
# @return [Void]
|
|
40
|
+
def download_tar(target_directory = @droplet.sandbox, name = @component_name)
|
|
41
|
+
super_download_tar @version, @uri, target_directory, name
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Downloads a given ZIP file and expands it.
|
|
45
|
+
#
|
|
46
|
+
# @param [Boolean] strip_top_level whether to strip the top-level directory when expanding. Defaults to +true+.
|
|
47
|
+
# @param [Pathname] target_directory the directory to expand the ZIP file to. Defaults to the component's sandbox.
|
|
48
|
+
# @param [String] name an optional name for the download. Defaults to +@component_name+.
|
|
49
|
+
# @return [Void]
|
|
50
|
+
def download_zip(strip_top_level = true, target_directory = @droplet.sandbox, name = @component_name)
|
|
51
|
+
super_download_zip @version, @uri, strip_top_level, target_directory, name
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|