buildpack-support 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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