Skip to content

Commit 037675d

Browse files
committed
Improve common distZip-style code
This change is a refactoring to get the common distZip style code into a better state. There are 4 distZip-style containers; Ratpack, Spring Boot, generic distZip, and Play Framework. Those containers (except for the massively complicated Play Framework one) now extend off of a DistZipLike container that contains most of their functionality. This means that implementations of this style of container (likely to show up more and more) only need to implement detection algorithms and id values (some would output with a version, others not). In addition, this sorts out a bug where the distZip container was incorrectly detecting for Ratpack applications. [#69332450]
1 parent 2960ba2 commit 037675d

File tree

34 files changed

+607
-169
lines changed

34 files changed

+607
-169
lines changed

.idea/dictionaries/bhale.xml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi
3737
* [Java Main](docs/container-java_main.md) ([Configuration](docs/container-java_main.md#configuration))
3838
* [Play Framework](docs/container-play_framework.md)
3939
* [Ratpack](docs/container-ratpack.md)
40+
* [Spring Boot](docs/container-spring_boot.md)
4041
* [Spring Boot CLI](docs/container-spring_boot_cli.md) ([Configuration](docs/container-spring_boot_cli.md#configuration))
4142
* [Tomcat](docs/container-tomcat.md) ([Configuration](docs/container-tomcat.md#configuration))
4243
* Standard Frameworks

config/components.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ containers:
2121
- "JavaBuildpack::Container::JavaMain"
2222
- "JavaBuildpack::Container::PlayFramework"
2323
- "JavaBuildpack::Container::Ratpack"
24+
- "JavaBuildpack::Container::SpringBoot"
2425
- "JavaBuildpack::Container::SpringBootCLI"
2526
- "JavaBuildpack::Container::Tomcat"
2627

docs/container-dist_zip.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ The Dist Zip Container allows applications packaged in [`distZip`-style][] to be
66
<td><strong>Detection Criteria</strong></td>
77
<td><ul>
88
<li>A start script in the <tt>bin/</tt> subdirectory of the application directory or one of its immediate subdirectories (but not in both), and</li>
9-
<li>A JAR file in the <tt>lib/</tt> subdirectory of the application directory or one of its immediate subdirectories (but not in both), and</li>
10-
<li>Not a Play Framework application</li>
9+
<li>A JAR file in the <tt>lib/</tt> subdirectory of the application directory or one of its immediate subdirectories (but not in both)</li>
1110
</ul></td>
1211
</tr>
1312
<tr>

docs/container-ratpack.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Ratpack Container
2-
The Ratpack Container allows [Ratpack][r] applications to be run.
2+
The Ratpack Container allows [Ratpack][r] applications, packaged `distZip`-style to be run.
33

44
<table>
55
<tr>
6-
<td><strong>Detection Criteria</strong></td><td>The <tt>app/Ratpack.groovy</tt> or <tt>app/ratpack.groovy</tt> configuration file exists in either the top-level directory or an immediate subdirectory of the application.</td>
6+
<td><strong>Detection Criteria</strong></td>
7+
<td>The <tt>lib/ratpack-core-.*.jar</tt> file exists in either the top-level directory or an immediate subdirectory of the application.</td>
78
</tr>
89
<tr>
910
<td><strong>Tags</strong></td>

docs/container-spring_boot.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Spring Boot Container
2+
The Spring Boot Container allows [Spring Boot][s] applications, packaged `distZip`-style to be run. **Note** All styles of Sping Boot can be run (e.g. self-executable JAR, WAR file, `distZip`-style). This is just explicit support for the `distZip` style.
3+
4+
<table>
5+
<tr>
6+
<td><strong>Detection Criteria</strong></td>
7+
<td>The <tt>lib/spring-boot-.*.jar</tt> file exists in either the top-level directory or an immediate subdirectory of the application.</td>
8+
</tr>
9+
<tr>
10+
<td><strong>Tags</strong></td>
11+
<td><tt>spring-boot=&lt;version&gt;</tt></td>
12+
</tr>
13+
</table>
14+
Tags are printed to standard output by the buildpack detect script
15+
16+
The container expects to run the application creating by running [`gradle distZip`][d] in an application built with the Spring Boot Gradle plugin.
17+
18+
## Configuration
19+
The Spring Boot Container cannot be configured.
20+
21+
[d]: http://docs.spring.io/spring-boot/docs/1.0.1.RELEASE/reference/htmlsingle/#using-boot-gradle
22+
[s]: http://projects.spring.io/spring-boot/

lib/java_buildpack/container/dist_zip.rb

Lines changed: 16 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -14,75 +14,38 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
require 'java_buildpack/component/base_component'
1817
require 'java_buildpack/container'
18+
require 'java_buildpack/container/dist_zip_like'
1919
require 'java_buildpack/util/dash_case'
20-
require 'java_buildpack/util/find_single_directory'
2120
require 'java_buildpack/util/play/factory'
22-
require 'java_buildpack/util/qualify_path'
23-
require 'java_buildpack/util/start_script'
21+
require 'java_buildpack/util/ratpack_utils'
22+
require 'java_buildpack/util/spring_boot_utils'
2423

2524
module JavaBuildpack
2625
module Container
2726

2827
# Encapsulates the detect, compile, and release functionality for +distZip+ style applications.
29-
class DistZip < JavaBuildpack::Component::BaseComponent
30-
include JavaBuildpack::Util
28+
class DistZip < JavaBuildpack::Container::DistZipLike
3129

32-
# Creates an instance
33-
#
34-
# @param [Hash] context a collection of utilities used the component
35-
def initialize(context)
36-
super(context)
37-
end
38-
39-
# (see JavaBuildpack::Component::BaseComponent#detect)
40-
def detect
41-
supports? ? DistZip.to_s.dash_case : nil
42-
end
30+
protected
4331

44-
# (see JavaBuildpack::Component::BaseComponent#compile)
45-
def compile
46-
start_script.chmod 0755
47-
augment_classpath
32+
# (see JavaBuildpack::Container::DistZipLike#id)
33+
def id
34+
DistZip.to_s.dash_case
4835
end
4936

50-
# (see JavaBuildpack::Component::BaseComponent#release)
51-
def release
52-
[
53-
@droplet.java_home.as_env_var,
54-
@droplet.java_opts.as_env_var,
55-
'SERVER_PORT=$PORT',
56-
qualify_path(start_script, @droplet.root)
57-
].flatten.compact.join(' ')
37+
# (see JavaBuildpack::Container::DistZipLike#supports?)
38+
def supports?
39+
start_script(root) &&
40+
start_script(root).exist? &&
41+
jars? &&
42+
!JavaBuildpack::Util::RatpackUtils.is?(@application) &&
43+
!JavaBuildpack::Util::SpringBootUtils.is?(@application) &&
44+
!JavaBuildpack::Util::Play::Factory.create(@droplet)
5845
end
5946

6047
private
6148

62-
PATTERN_APP_CLASSPATH = /^declare -r app_classpath=\"(.*)\"$/
63-
64-
PATTERN_CLASSPATH = /^CLASSPATH=(.*)$/.freeze
65-
66-
def augment_classpath
67-
content = start_script.read
68-
69-
if content =~ PATTERN_CLASSPATH
70-
additional_classpath = @droplet.additional_libraries.sort.map do |additional_library|
71-
"$APP_HOME/#{additional_library.relative_path_from(root)}"
72-
end
73-
74-
update_file start_script, content,
75-
PATTERN_CLASSPATH, "CLASSPATH=#{additional_classpath.join(':')}:\\1"
76-
elsif content =~ PATTERN_APP_CLASSPATH
77-
additional_classpath = @droplet.additional_libraries.sort.map do |additional_library|
78-
"$app_home/#{additional_library.relative_path_from(start_script.dirname)}"
79-
end
80-
81-
update_file start_script, content,
82-
PATTERN_APP_CLASSPATH, "declare -r app_classpath=\"#{additional_classpath.join(':')}:\\1\""
83-
end
84-
end
85-
8649
def jars?
8750
(lib_dir + '*.jar').glob.any?
8851
end
@@ -91,25 +54,6 @@ def lib_dir
9154
root + 'lib'
9255
end
9356

94-
def root
95-
find_single_directory || @droplet.root
96-
end
97-
98-
def start_script
99-
JavaBuildpack::Util.start_script root
100-
end
101-
102-
def supports?
103-
start_script && start_script.exist? && jars? && !JavaBuildpack::Util::Play::Factory.create(@droplet)
104-
end
105-
106-
def update_file(path, content, pattern, replacement)
107-
path.open('w') do |f|
108-
f.write content.gsub pattern, replacement
109-
f.fsync
110-
end
111-
end
112-
11357
end
11458

11559
end
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
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/component/base_component'
18+
require 'java_buildpack/container'
19+
require 'java_buildpack/util/find_single_directory'
20+
require 'java_buildpack/util/qualify_path'
21+
require 'java_buildpack/util/start_script'
22+
23+
module JavaBuildpack
24+
module Container
25+
26+
# Encapsulates the detect, compile, and release functionality for selecting a `distZip`-like container.
27+
class DistZipLike < JavaBuildpack::Component::BaseComponent
28+
include JavaBuildpack::Util
29+
30+
# (see JavaBuildpack::Component::BaseComponent#detect)
31+
def detect
32+
supports? ? id : nil
33+
end
34+
35+
# (see JavaBuildpack::Component::BaseComponent#compile)
36+
def compile
37+
start_script(root).chmod 0755
38+
augment_classpath_content
39+
end
40+
41+
# (see JavaBuildpack::Component::BaseComponent#release)
42+
def release
43+
[
44+
@droplet.java_home.as_env_var,
45+
@droplet.java_opts.as_env_var,
46+
qualify_path(start_script(root), @droplet.root)
47+
].flatten.compact.join(' ')
48+
end
49+
50+
protected
51+
52+
# The id of this container
53+
#
54+
# @return [String] the id of this container
55+
def id
56+
fail "Method 'id' must be defined"
57+
end
58+
59+
# The root directory of the application
60+
#
61+
# @return [Pathname] the root directory of the application
62+
def root
63+
find_single_directory || @droplet.root
64+
end
65+
66+
# Whether or not this component supports this application
67+
#
68+
# @return [Boolean] whether or not this component supports this application
69+
def supports?
70+
fail "Method 'supports?' must be defined"
71+
end
72+
73+
private
74+
75+
PATTERN_APP_CLASSPATH = /^declare -r app_classpath=\"(.*)\"$/
76+
77+
PATTERN_CLASSPATH = /^CLASSPATH=(.*)$/.freeze
78+
79+
private_constant :PATTERN_APP_CLASSPATH, :PATTERN_CLASSPATH
80+
81+
def augment_app_classpath(content)
82+
additional_classpath = @droplet.additional_libraries.sort.map do |additional_library|
83+
"$app_home/#{additional_library.relative_path_from(start_script(root).dirname)}"
84+
end
85+
86+
update_file start_script(root), content,
87+
PATTERN_APP_CLASSPATH, "declare -r app_classpath=\"#{additional_classpath.join(':')}:\\1\""
88+
end
89+
90+
def augment_classpath(content)
91+
additional_classpath = @droplet.additional_libraries.sort.map do |additional_library|
92+
"$APP_HOME/#{additional_library.relative_path_from(root)}"
93+
end
94+
95+
update_file start_script(root), content,
96+
PATTERN_CLASSPATH, "CLASSPATH=#{additional_classpath.join(':')}:\\1"
97+
end
98+
99+
def augment_classpath_content
100+
content = start_script(root).read
101+
102+
if content =~ PATTERN_CLASSPATH
103+
augment_classpath content
104+
elsif content =~ PATTERN_APP_CLASSPATH
105+
augment_app_classpath content
106+
end
107+
end
108+
109+
def update_file(path, content, pattern, replacement)
110+
path.open('w') do |f|
111+
f.write content.gsub pattern, replacement
112+
f.fsync
113+
end
114+
end
115+
116+
end
117+
118+
end
119+
end

lib/java_buildpack/container/ratpack.rb

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,65 +14,33 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
require 'java_buildpack/component/base_component'
1817
require 'java_buildpack/container'
18+
require 'java_buildpack/container/dist_zip_like'
1919
require 'java_buildpack/util/dash_case'
2020
require 'java_buildpack/util/ratpack_utils'
21-
require 'java_buildpack/util/start_script'
2221

2322
module JavaBuildpack
2423
module Container
2524

2625
# Encapsulates the detect, compile, and release functionality for Ratpack applications.
27-
class Ratpack < JavaBuildpack::Component::BaseComponent
28-
include JavaBuildpack::Util
26+
class Ratpack < JavaBuildpack::Container::DistZipLike
2927

30-
def initialize(context)
31-
super(context)
32-
end
33-
34-
# (see JavaBuildpack::Component::BaseComponent#detect)
35-
def detect
36-
JavaBuildpack::Util::RatpackUtils.is?(@application) ? id(version) : nil
37-
end
38-
39-
# (see JavaBuildpack::Component::BaseComponent#compile)
40-
def compile
41-
@droplet.additional_libraries.link_to lib_dir
42-
end
43-
44-
# (see JavaBuildpack::Component::BaseComponent#release)
45-
def release
46-
@droplet.java_opts.add_system_property 'ratpack.port', '$PORT'
47-
48-
[
49-
@droplet.java_home.as_env_var,
50-
@droplet.java_opts.as_env_var,
51-
"$PWD/#{start_script(root).relative_path_from(@application.root)}"
52-
].flatten.compact.join(' ')
53-
end
54-
55-
private
56-
57-
RATPACK_CORE_FILE_PATTERN = 'lib/ratpack-core-*.jar'.freeze
28+
protected
5829

59-
private_constant :RATPACK_CORE_FILE_PATTERN
60-
61-
def id(version)
30+
# (see JavaBuildpack::Container::DistZipLike#id)
31+
def id
6232
"#{Ratpack.to_s.dash_case}=#{version}"
6333
end
6434

65-
def lib_dir
66-
root + 'lib'
35+
# (see JavaBuildpack::Container::DistZipLike#supports?)
36+
def supports?
37+
JavaBuildpack::Util::RatpackUtils.is? @application
6738
end
6839

69-
def root
70-
roots = (@droplet.root + '*').glob.select { |child| child.directory? }
71-
roots.size == 1 ? roots.first : @droplet.root
72-
end
40+
private
7341

7442
def version
75-
(root + RATPACK_CORE_FILE_PATTERN).glob.first.to_s.match(/.*ratpack-core-(.*)\.jar/)[1]
43+
JavaBuildpack::Util::RatpackUtils.version @application
7644
end
7745

7846
end

0 commit comments

Comments
 (0)