Skip to content

Commit 24aeb3f

Browse files
committed
Merge 57494488-subclassing to master
[Completes #57494488]
2 parents acae5fa + 956f236 commit 24aeb3f

31 files changed

Lines changed: 808 additions & 730 deletions

Gemfile.lock

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ GEM
33
specs:
44
addressable (2.3.5)
55
ast (1.1.0)
6-
backports (3.3.4)
7-
codeclimate-test-reporter (0.0.8)
6+
codeclimate-test-reporter (0.1.1)
87
simplecov (>= 0.7.1, < 1.0.0)
98
crack (0.4.1)
109
safe_yaml (~> 0.9.0)
@@ -22,15 +21,14 @@ GEM
2221
rspec-expectations (~> 2.14.0)
2322
rspec-mocks (~> 2.14.0)
2423
rspec-core (2.14.5)
25-
rspec-expectations (2.14.2)
24+
rspec-expectations (2.14.3)
2625
diff-lcs (>= 1.1.3, < 2.0)
2726
rspec-mocks (2.14.3)
28-
rubocop (0.13.0)
29-
backports (~> 3.3.3)
27+
rubocop (0.13.1)
3028
parser (~> 2.0.0.pre6)
3129
powerpack (~> 0.0.6)
3230
rainbow (>= 1.1.4)
33-
safe_yaml (0.9.6)
31+
safe_yaml (0.9.7)
3432
simplecov (0.7.1)
3533
multi_json (~> 1.0)
3634
simplecov-html (~> 0.7.1)
@@ -39,7 +37,7 @@ GEM
3937
webmock (1.13.0)
4038
addressable (>= 2.2.7)
4139
crack (>= 0.3.2)
42-
yard (0.8.7.1)
40+
yard (0.8.7.2)
4341

4442
PLATFORMS
4543
ruby

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,12 @@ The buildpack supports configuration and extension through the use of Git reposi
3131
* [Spring Auto Reconfiguration](docs/framework-spring-auto-reconfiguration.md) ([Configuration](docs/framework-spring-auto-reconfiguration.md#configuration))
3232
* Standard JREs
3333
* [OpenJDK](docs/jre-openjdk.md) ([Configuration](docs/jre-openjdk.md#configuration))
34-
* Extending
35-
* [Containers](docs/extending-containers.md)
36-
* [JREs](docs/extending-jres.md)
37-
* [Frameworks](docs/extending-frameworks.md)
34+
* [Extending](docs/extending.md)
3835
* Utilities
3936
* [Caches](docs/util-caches.md) ([Configuration](docs/util-caches.md#configuration))
40-
* [Logging](docs/logging.md) ([Configuration](docs/logging.md#configuration))
37+
* [Logging](docs/logging.md) ([Configuration](docs/logging.md#configuration))
4138
* [Repositories](docs/util-repositories.md)
39+
* [Other Utiltities](docs/util-other.md)
4240
* [Repository Builder](docs/util-repository-builder.md)
4341
* [Test Applications](docs/util-test-applications.md)
4442

docs/extending-containers.md

Lines changed: 0 additions & 41 deletions
This file was deleted.

docs/extending-frameworks.md

Lines changed: 0 additions & 40 deletions
This file was deleted.

docs/extending-jres.md

Lines changed: 0 additions & 40 deletions
This file was deleted.

docs/extending.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Extending
2+
To add a component, its class file must be put in a specific location and the class name added to [`config/components.yml`][].
3+
4+
| Component Type | Location
5+
| -------------- | --------
6+
| Container | [`lib/java_buildpack/container`][]
7+
| Framework | [`lib/java_buildpack/framework`][]
8+
| JRE | [`lib/java_buildpack/jre`][]
9+
10+
11+
## Component Class Contract
12+
Each component class must satisfy a contract defined by the following methods:
13+
14+
```ruby
15+
# If the component should be used when staging an application
16+
#
17+
# @return [Array<String>, String, nil] If the component should be used when staging the application, a +String+ or
18+
# an +Array<String>+ that uniquely identifies the component (e.g.
19+
# +openjdk-1.7.0_40+). Otherwise, +nil+.
20+
def detect
21+
22+
# Modifies the application's file system. The component is expected to transform the application's file system in
23+
# whatever way is necessary (e.g. downloading files or creating symbolic links) to support the function of the
24+
# component. Status output written to +STDOUT+ is expected as part of this invocation.
25+
#
26+
# @return [void]
27+
def compile
28+
29+
# Modifies the application's runtime configuration. The component is expected to transform members of the +context+
30+
# (e.g. +@java_home+, +@java_opts+, etc.) in whatever way is necessary to support the function of the component.
31+
#
32+
# Container components are also expected to create the command required to run the application. These components
33+
# are expected to read the +context+ values and take them into account when creating the command.
34+
#
35+
# @return [void, String] components other than containers are not expected to return any value. Container
36+
# compoonents are expected to return the command required to run the application.
37+
def release
38+
```
39+
40+
41+
## Component Context
42+
Each component class must have an `initialize` method that takes a `Hash` containg contextual information about the application. It is this "whiteboard" that is used by the components to communicate with one another. The context contains the following entries:
43+
44+
| Name | Type | Description
45+
| ---- | ---- | -----------
46+
| `app_dir` | `String` | The directory that the application exists in
47+
| `configuration` | `Hash` | The component configuration provided by the user via `config/<component-name>.yml`
48+
| `environment` | `Hash` | A hash containing all environment variables except `VCAP_APPLICATION` and `VCAP_SERVICES`. Those values are available separately in parsed form.
49+
| `java_home` | `String` | The directory that acts as `JAVA_HOME`
50+
| `java_opts` | `Array<String>` | An array that Java options can be added to
51+
| `lib_directory` | `String` | The directory that additional libraries are placed in
52+
| `vcap_application` | `Hash` | The contents of the `VCAP_APPLICATION` environment variable
53+
| `vcap_services` | `Hash` | The contents of the `VCAP_SERVICES` environment variable
54+
55+
56+
## Base Classes
57+
The buildpack provides a collection of base classes that may help you implement a component.
58+
59+
### [`lib/java_buildpack/base_component`][]
60+
This base class is recommended for use by all components. It ensures that each component has a name, that the context is available at `@context` and that each key in the `context` is exposed as an instance variable (e.g. `context[:java_home]` is available as `@java_home`). In addition it provides two helper methods for downloading files as part of the component's operation.
61+
62+
### [`lib/java_buildpack/versioned_dependency_component`][]
63+
This base class is recommended for use by any component that uses the buildpack [repository support][] to download a dependency. It ensures that each component has a `@version` and `@uri` that were resolved from the repository specified in the component's configuration. It also implements the `detect` method with an standard implementation.
64+
65+
[`config/components.yml`]: ../config/components.yml
66+
[`lib/java_buildpack/base_component`]: ../lib/java_buildpack/base_component
67+
[`lib/java_buildpack/container`]: ../lib/java_buildpack/container
68+
[`lib/java_buildpack/framework`]: ../lib/java_buildpack/framework
69+
[`lib/java_buildpack/jre`]: ../lib/java_buildpack/jre
70+
[`lib/java_buildpack/versioned_dependency_component`]: ../lib/java_buildpack/versioned_dependency_component
71+
[repository support]: util-repositories.md

docs/util-other.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Other Utiltities
2+
The buildpack provides a number of other utilities that may help in implementing components.
3+
4+
5+
## [`JavaBuildpack::Util::GroovyUtils`][]
6+
The `GroovyUtils` class provides a set of methods for finding groovy files and determing if they are of any special kind (e.g. they have a main method, they are a pogo, etc.).
7+
8+
## [`JavaBuildpack::Util::PlayUtils`][]
9+
The `PlayUtils` class provides a set of methods for determing information about a Play Framework application.
10+
11+
## [`JavaBuildpack::Util::Properties`][]
12+
The `Properties` class provides a Ruby class that can read in a Java properties file and acts as a `Hash` with that data.
13+
14+
## [`JavaBuildpack::Util::ResourceUtils`][]
15+
The `ResourceUtils` class provides an abstract around the `resources` directory of the buildpack. It eanbles the reading and copying of files located in that directory.
16+
17+
## [`JavaBuildpack::Util::ServiceUtils`][]
18+
The `ServiceUtils` class provides a set of methods for finding a given service in the `VCAP_SERVICES` payload.
19+
20+
21+
[`JavaBuildpack::Util::GroovyUtils`]: ../lib/java_buildpack/util/groovy_utils.rb
22+
[`JavaBuildpack::Util::PlayUtils`]: ../lib/java_buildpack/util/play_utils.rb
23+
[`JavaBuildpack::Util::Properties`]: ../lib/java_buildpack/util/properties.rb
24+
[`JavaBuildpack::Util::ResourceUtils`]: ../lib/java_buildpack/util/resource_utils.rb
25+
[`JavaBuildpack::Util::ServiceUtils`]: ../lib/java_buildpack/util/service_utils.rb
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Encoding: utf-8
2+
# Cloud Foundry Java Buildpack
3+
# Copyright 2013 the original author or authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
require 'java_buildpack'
18+
require 'java_buildpack/util/application_cache'
19+
20+
module JavaBuildpack
21+
22+
# A convenience base class for all components in the buildpack. This base class ensures that the contents of the
23+
# +context+ are assigned to instance variables matching their keys. It also ensures that all contract methods are
24+
# implemented.
25+
class BaseComponent
26+
27+
# Creates an instance. The contents of +context+ are assigned to instance variables matching their keys.
28+
# +component_name+ and +context+ are exposed via +@component_name+ and +@context+ respectively for any component
29+
# that wishes to use them.
30+
#
31+
# @param [Hash] context A shared context provided to all components
32+
def initialize(component_name, context)
33+
@component_name = component_name
34+
@context = context
35+
@context.each { |key, value| instance_variable_set("@#{key}", value) }
36+
end
37+
38+
# If the component should be used when staging an application
39+
#
40+
# @return [Array<String>, String, nil] If the component should be used when staging the application, a +String+ or
41+
# an +Array<String>+ that uniquely identifies the component (e.g.
42+
# +openjdk-1.7.0_40+). Otherwise, +nil+.
43+
def detect
44+
fail "Method 'detect' must be defined"
45+
end
46+
47+
# Modifies the application's file system. The component is expected to transform the application's file system in
48+
# whatever way is necessary (e.g. downloading files or creating symbolic links) to support the function of the
49+
# component. Status output written to +STDOUT+ is expected as part of this invocation.
50+
#
51+
# @return [void]
52+
def compile
53+
fail "Method 'compile' must be defined"
54+
end
55+
56+
# Modifies the application's runtime configuration. The component is expected to transform members of the +context+
57+
# (e.g. +@java_home+, +@java_opts+, etc.) in whatever way is necessary to support the function of the component.
58+
#
59+
# Container components are also expected to create the command required to run the application. These components
60+
# are expected to read the +context+ values and take them into account when creating the command.
61+
#
62+
# @return [void, String] components other than containers are not expected to return any value. Container
63+
# compoonents are expected to return the command required to run the application.
64+
def release
65+
fail "Method 'release' must be defined"
66+
end
67+
68+
protected
69+
70+
# Downloads an item with the given name and version from the given URI, then yields the resultant file to the given
71+
# block.
72+
#
73+
# @param [JavaBuildpack::Util::TokenizedVersion] version
74+
# @param [String] uri
75+
# @param [String] description an optional description for the download. Defaults to +@component_name+.
76+
# @return [void]
77+
def download(version, uri, description = @component_name, &block)
78+
download_start_time = Time.now
79+
print "-----> Downloading #{description} #{version} from #{uri} "
80+
81+
JavaBuildpack::Util::ApplicationCache.new.get(uri) do |file| # TODO: Use global cache #50175265
82+
puts "(#{(Time.now - download_start_time).duration})"
83+
yield file
84+
end
85+
end
86+
87+
# Downloads a given JAR and copies it to a given destination.
88+
#
89+
# @param [JavaBuildpack::Util::TokenizedVersion] version the version of the item
90+
# @param [String] uri the URI of the item
91+
# @param [String] jar_name the filename of the item
92+
# @param [String] target_directory the path of the directory into which to download the item. Defaults to
93+
# +@lib_directory+
94+
# @param [String] description an optional description for the download. Defaults to +@component_name+.
95+
def download_jar(version, uri, jar_name, target_directory = @lib_directory, description = @component_name)
96+
download(version, uri, description) { |file| system "cp #{file.path} #{File.join(target_directory, jar_name)}" }
97+
end
98+
99+
end
100+
101+
end

0 commit comments

Comments
 (0)