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.
Files changed (122) hide show
  1. data/LICENSE +202 -0
  2. data/NOTICE +2 -0
  3. data/docs/cache.md +77 -0
  4. data/docs/component.md +1 -0
  5. data/docs/configuration.md +27 -0
  6. data/docs/logging.md +54 -0
  7. data/docs/other.md +1 -0
  8. data/docs/rake.md +1 -0
  9. data/docs/repository.md +116 -0
  10. data/docs/test.md +1 -0
  11. data/lib/buildpack_support.rb +18 -0
  12. data/lib/buildpack_support/base_buildpack.rb +166 -0
  13. data/lib/buildpack_support/buildpack_version.rb +124 -0
  14. data/lib/buildpack_support/cache.rb +24 -0
  15. data/lib/buildpack_support/cache/application_cache.rb +41 -0
  16. data/lib/buildpack_support/cache/cached_file.rb +103 -0
  17. data/lib/buildpack_support/cache/download_cache.rb +280 -0
  18. data/lib/buildpack_support/cache/inferred_network_failure.rb +26 -0
  19. data/lib/buildpack_support/cache/internet_availability.rb +64 -0
  20. data/lib/buildpack_support/component.rb +24 -0
  21. data/lib/buildpack_support/component/application.rb +76 -0
  22. data/lib/buildpack_support/component/base_component.rb +78 -0
  23. data/lib/buildpack_support/component/base_droplet.rb +96 -0
  24. data/lib/buildpack_support/component/downloads.rb +88 -0
  25. data/lib/buildpack_support/component/services.rb +84 -0
  26. data/lib/buildpack_support/component/versioned_dependency_component.rb +71 -0
  27. data/lib/buildpack_support/component/versioned_downloads.rb +57 -0
  28. data/lib/buildpack_support/component/with_timing.rb +40 -0
  29. data/lib/buildpack_support/configuration_utils.rb +58 -0
  30. data/lib/buildpack_support/constantize.rb +46 -0
  31. data/lib/buildpack_support/dash_case.rb +29 -0
  32. data/lib/buildpack_support/directory_finder.rb +45 -0
  33. data/lib/buildpack_support/filtering_pathname.rb +227 -0
  34. data/lib/buildpack_support/format_duration.rb +57 -0
  35. data/lib/buildpack_support/logging.rb +22 -0
  36. data/lib/buildpack_support/logging/delegating_logger.rb +48 -0
  37. data/lib/buildpack_support/logging/logger_factory.rb +148 -0
  38. data/lib/buildpack_support/qualify_path.rb +36 -0
  39. data/lib/buildpack_support/rake.rb +22 -0
  40. data/lib/buildpack_support/rake/buildpack_stage_task.rb +86 -0
  41. data/lib/buildpack_support/rake/cached_artifact_finder.rb +99 -0
  42. data/lib/buildpack_support/rake/check_api_doc_task.rb +70 -0
  43. data/lib/buildpack_support/rake/dependency_cache_task.rb +87 -0
  44. data/lib/buildpack_support/rake/disable_remote_downloads_task.rb +80 -0
  45. data/lib/buildpack_support/rake/package_task.rb +133 -0
  46. data/lib/buildpack_support/rake/package_zip_task.rb +80 -0
  47. data/lib/buildpack_support/rake/repository_configuration_finder.rb +66 -0
  48. data/lib/buildpack_support/rake/write_version_file_task.rb +82 -0
  49. data/lib/buildpack_support/repository.rb +24 -0
  50. data/lib/buildpack_support/repository/configured_item.rb +81 -0
  51. data/lib/buildpack_support/repository/repository_index.rb +98 -0
  52. data/lib/buildpack_support/repository/wildcard_version_resolver.rb +75 -0
  53. data/lib/buildpack_support/shell.rb +41 -0
  54. data/lib/buildpack_support/snake_case.rb +30 -0
  55. data/lib/buildpack_support/space_case.rb +29 -0
  56. data/lib/buildpack_support/test/application_helper.rb +41 -0
  57. data/lib/buildpack_support/test/base_component_helper.rb +59 -0
  58. data/lib/buildpack_support/test/base_droplet_helper.rb +36 -0
  59. data/lib/buildpack_support/test/console_helper.rb +57 -0
  60. data/lib/buildpack_support/test/environment_helper.rb +32 -0
  61. data/lib/buildpack_support/test/internet_availability_helper.rb +29 -0
  62. data/lib/buildpack_support/test/logging_helper.rb +50 -0
  63. data/lib/buildpack_support/test/scratch_helper.rb +32 -0
  64. data/lib/buildpack_support/test/versioned_dependency_component_helper.rb +32 -0
  65. data/lib/buildpack_support/test/with_load_path_helper.rb +27 -0
  66. data/lib/buildpack_support/to_b.rb +38 -0
  67. data/lib/buildpack_support/tokenized_version.rb +157 -0
  68. data/lib/buildpack_support/version.rb +23 -0
  69. data/spec/buildpack_support/base_buildpack_spec.rb +112 -0
  70. data/spec/buildpack_support/buildpack_version_spec.rb +122 -0
  71. data/spec/buildpack_support/cache/application_cache_spec.rb +56 -0
  72. data/spec/buildpack_support/cache/cached_file_spec.rb +94 -0
  73. data/spec/buildpack_support/cache/download_cache_spec.rb +293 -0
  74. data/spec/buildpack_support/cache/internet_availability_spec.rb +57 -0
  75. data/spec/buildpack_support/cache/yield_file_with_content.rb +30 -0
  76. data/spec/buildpack_support/component/application_spec.rb +81 -0
  77. data/spec/buildpack_support/component/base_component_spec.rb +81 -0
  78. data/spec/buildpack_support/component/base_droplet_spec.rb +72 -0
  79. data/spec/buildpack_support/component/downloads_spec.rb +63 -0
  80. data/spec/buildpack_support/component/services_spec.rb +80 -0
  81. data/spec/buildpack_support/component/versioned_dependency_component_spec.rb +58 -0
  82. data/spec/buildpack_support/component/versioned_downloads_spec.rb +58 -0
  83. data/spec/buildpack_support/component/with_timing_spec.rb +30 -0
  84. data/spec/buildpack_support/configuration_utils_spec.rb +39 -0
  85. data/spec/buildpack_support/constantize_spec.rb +34 -0
  86. data/spec/buildpack_support/dash_case_spec.rb +41 -0
  87. data/spec/buildpack_support/directory_finder_spec.rb +41 -0
  88. data/spec/buildpack_support/filtering_pathname_spec.rb +443 -0
  89. data/spec/buildpack_support/format_duration_spec.rb +60 -0
  90. data/spec/buildpack_support/logging/delegating_logger_spec.rb +62 -0
  91. data/spec/buildpack_support/logging/logger_factory_spec.rb +262 -0
  92. data/spec/buildpack_support/qualify_path_spec.rb +42 -0
  93. data/spec/buildpack_support/rake/buildpack_stage_task_spec.rb +88 -0
  94. data/spec/buildpack_support/rake/cached_artifact_finder_spec.rb +73 -0
  95. data/spec/buildpack_support/rake/check_api_doc_task_spec.rb +69 -0
  96. data/spec/buildpack_support/rake/dependency_cache_task_spec.rb +133 -0
  97. data/spec/buildpack_support/rake/disable_remote_downloads_task_spec.rb +91 -0
  98. data/spec/buildpack_support/rake/package_task_spec.rb +335 -0
  99. data/spec/buildpack_support/rake/package_zip_task_spec.rb +91 -0
  100. data/spec/buildpack_support/rake/repository_configuration_finder_spec.rb +61 -0
  101. data/spec/buildpack_support/rake/write_version_file_task_spec.rb +96 -0
  102. data/spec/buildpack_support/repository/configured_item_spec.rb +78 -0
  103. data/spec/buildpack_support/repository/repository_index_spec.rb +118 -0
  104. data/spec/buildpack_support/repository/wildcard_version_resolver_spec.rb +73 -0
  105. data/spec/buildpack_support/shell_spec.rb +32 -0
  106. data/spec/buildpack_support/snake_case_spec.rb +45 -0
  107. data/spec/buildpack_support/space_case_spec.rb +41 -0
  108. data/spec/buildpack_support/to_b_spec.rb +41 -0
  109. data/spec/buildpack_support/tokenized_version_spec.rb +132 -0
  110. data/spec/fixtures/application/test-file +0 -0
  111. data/spec/fixtures/config/found-config.yml +2 -0
  112. data/spec/fixtures/droplet-resources/droplet-resource +0 -0
  113. data/spec/fixtures/stub-download-with-top-level.zip +0 -0
  114. data/spec/fixtures/stub-download.tar.gz +0 -0
  115. data/spec/fixtures/stub-download.zip +0 -0
  116. data/spec/fixtures/test-cache.yml +18 -0
  117. data/spec/fixtures/test-index.yml +2 -0
  118. data/spec/fixtures/test_component.rb +0 -0
  119. data/spec/fixtures/zip-contents/test-directory/test-deep-file +0 -0
  120. data/spec/fixtures/zip-contents/test-file +0 -0
  121. data/spec/spec_helper.rb +30 -0
  122. 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