Skip to content

Commit fb644d4

Browse files
committed
Package task
This change adds a `package` rake task to the buildpack. This task creates a .tar.gz of the buildpack, suitable to use with `cf create- buildpack` and `cf update-buildpack`. The task is configurable allowing the user to change the version string embedded in the name of the output file. It can also be configured to create an offline buildpack which embeds the latest version of its dependencies and disables remote downloads. [#67852640]
1 parent 3041fb4 commit fb644d4

10 files changed

Lines changed: 215 additions & 152 deletions

File tree

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,39 @@ To learn how to configure various properties of the buildpack, follow the "Confi
6666
* [Java Test Applications](https://github.com/cloudfoundry/java-test-applications)
6767
* [Java Buildpack System Tests](https://github.com/cloudfoundry/java-buildpack-system-test)
6868

69+
## Building Packages
70+
The buildpack can be packaged up so that it can uploaded to Cloud Foundry using the `cf create-buildpack` and `cf update-buildpack` commands. In order to create these packages, the rake `package` task is used.
71+
72+
### Online Package
73+
The online package is a version of the buildpack that is as minimal as possible and is configured to connect to the network for all dependencies. This package is about 50K in size. To create the online package, run:
74+
75+
```bash
76+
bundle install
77+
bundle exec rake package
78+
...
79+
Creating build/java-buildpack-cfd6b17.tar.gz
80+
```
81+
82+
### Offline Package
83+
The offline package is a version of the buildpack designed to run without access to a network. It packages the latest version of each dependency (as configured in the [`config/` directory][]) and [disables `remote_downloads`][]. This package is about 180M in size. To create the offline package, use the `OFFLINE=true` argument:
84+
85+
```bash
86+
bundle install
87+
bundle exec rake package OFFLINE=true
88+
...
89+
Creating build/java-buildpack-offline-cfd6b17.tar.gz
90+
```
91+
92+
### Package Versioning
93+
Keeping track of different versions of the buildpack can be difficult. To help with this, the rake `package` task puts a version discriminator in the name of the created package file. The default value for this discriminator is the current Git hash (e.g. `cfd6b17`). To change the version when creating a package, use the `VERSION=<VERSION>` argument:
94+
95+
```bash
96+
bundle install
97+
bundle exec rake package VERSION=2.1
98+
...
99+
Creating build/java-buildpack-2.1.tar.gz
100+
```
101+
69102
## Running Tests
70103
To run the tests, do the following:
71104

@@ -82,9 +115,11 @@ bundle exec rake
82115
## License
83116
This buildpack is released under version 2.0 of the [Apache License][].
84117

118+
[`config/` directory]: config
85119
[Apache License]: http://www.apache.org/licenses/LICENSE-2.0
86120
[Cloud Foundry]: http://www.cloudfoundry.com
87121
[contributor guidelines]: CONTRIBUTING.md
122+
[disables `remote_downloads`]: docs/extending-caches.md#configuration
88123
[GitHub's forking functionality]: https://help.github.com/articles/fork-a-repo
89124
[Grails]: http://grails.org
90125
[Groovy]: http://groovy.codehaus.org

Rakefile

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

17-
$LOAD_PATH.unshift File.expand_path('../rakelib', __FILE__)
18-
1917
require 'rake/clean'
2018

2119
require 'rspec/core/rake_task'
@@ -36,26 +34,13 @@ task :check_api_doc do
3634
abort "\nFailed due to undocumented public API:\n\n#{output}" if output !~ /100.00% documented/
3735
end
3836

39-
require 'pathname'
40-
require_relative 'rakelib/dependency_cache_task'
41-
require_relative 'rakelib/offline'
42-
require_relative 'rakelib/stage_buildpack_task'
43-
require_relative 'rakelib/tar_file_task'
44-
45-
CLOBBER << Offline::BUILD_DIR
46-
CLEAN << Offline::STAGING_DIR
47-
48-
dependency_cache_task = Offline::DependencyCacheTask.new
49-
stage_files_task = Offline::StageBuildpackTask.new(Dir['bin/**/*', 'config/**/*', 'lib/**/*', 'resources/**/*']
50-
.reject { |f| File.directory? f })
51-
tar_file_task = Offline::TarFileTask.new(dependency_cache_task, stage_files_task)
52-
53-
file "#{Offline::STAGING_DIR}/config/cache.yml" do |t|
54-
content = Pathname.new(t.source).read.gsub(/enabled/, 'disabled')
55-
Pathname.new(t.name).open('w') { |file| file.write content }
56-
end
57-
58-
desc 'Create a buildpack for use offline'
59-
task offline: [tar_file_task.targets]
37+
$LOAD_PATH.unshift File.expand_path('..', __FILE__)
38+
require 'rakelib/dependency_cache_task'
39+
require 'rakelib/stage_buildpack_task'
40+
require 'rakelib/package_task'
41+
Package::DependencyCacheTask.new
42+
Package::StageBuildpackTask.new(Dir['bin/**/*', 'config/**/*', 'lib/**/*', 'resources/**/*']
43+
.reject { |f| File.directory? f })
44+
Package::PackageTask.new
6045

6146
task default: %w(rubocop check_api_doc spec)

lib/java_buildpack/buildpack.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def release
9393

9494
private
9595

96-
DEFAULT_BUILDPACK_MESSAGE = '-----> Java Buildpack source: system'.freeze
96+
DEFAULT_BUILDPACK_MESSAGE = '-----> Java Buildpack source: unknown'.freeze
9797

9898
GIT_DIR = Pathname.new(__FILE__).dirname + '../../.git'
9999

@@ -125,7 +125,7 @@ def component_detection(components)
125125

126126
def diagnose_git_info(print)
127127
if system("git --git-dir=#{GIT_DIR} status 2>/dev/null 1>/dev/null")
128-
remote_url = diagnose_remotes
128+
remote_url = diagnose_remote
129129
head_commit_sha = diagnose_head_commit
130130
puts "-----> Java Buildpack source: #{remote_url}##{head_commit_sha}" if print
131131
else
@@ -135,17 +135,17 @@ def diagnose_git_info(print)
135135
end
136136

137137
def diagnose_head_commit
138-
git 'log HEAD^!', 'git HEAD commit: %s'
138+
git 'rev-parse --short HEAD', 'git HEAD commit: %s'
139139
end
140140

141-
def diagnose_remotes
142-
git 'remote -v', 'git remotes: %s'
141+
def diagnose_remote
142+
git 'config --get remote.origin.url', 'git remote: %s'
143143
end
144144

145145
def git(command, message)
146-
result = `git --git-dir=#{GIT_DIR} #{command}`
146+
result = `git --git-dir=#{GIT_DIR} #{command}`.chomp
147147
@logger.debug { message % result }
148-
result.split(' ')[1]
148+
result
149149
end
150150

151151
def instantiate(components, additional_libraries, application, java_home, java_opts, root)

lib/java_buildpack/logging/logger_factory.rb

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

17+
require 'fileutils'
1718
require 'java_buildpack/logging'
1819
require 'java_buildpack/logging/delegating_logger'
1920
require 'java_buildpack/util/configuration_utils'
@@ -107,6 +108,8 @@ def console_logger
107108
end
108109

109110
def file_logger
111+
FileUtils.mkdir_p File.dirname(@log_file)
112+
110113
logger = Logger.new(@log_file)
111114
logger.level = ::Logger::DEBUG
112115
logger.formatter = lambda do |severity, datetime, klass, message|

rakelib/dependency_cache_task.rb

Lines changed: 88 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -21,131 +21,136 @@
2121
require 'java_buildpack/util/configuration_utils'
2222
require 'java_buildpack/util/cache/download_cache'
2323
require 'java_buildpack/util/snake_case'
24-
require 'offline'
24+
require 'rake/tasklib'
25+
require 'rakelib/package'
2526
require 'pathname'
2627
require 'yaml'
2728

28-
module Offline
29+
module Package
2930

3031
class DependencyCacheTask < Rake::TaskLib
31-
include Offline
32-
33-
attr_reader :targets
32+
include Package
3433

3534
def initialize
36-
JavaBuildpack::Logging::LoggerFactory.instance.setup "#{BUILD_DIR}/"
35+
if OFFLINE
36+
JavaBuildpack::Logging::LoggerFactory.instance.setup "#{BUILD_DIR}/"
3737

38-
@default_repository_root = configuration('repository')['default_repository_root'].chomp('/')
39-
@cache = cache
38+
@default_repository_root = default_repository_root
39+
@cache = cache
4040

41-
configurations = component_ids.map { |component_id| configurations(configuration(component_id)) }.flatten
42-
@targets = uris(configurations).each { |uri| create_task(uri) }
41+
configurations = component_ids.map { |component_id| configurations(configuration(component_id)) }.flatten
42+
uris(configurations).each { |uri| create_task(uri) }
43+
end
4344
end
4445

45-
end
46+
private
4647

47-
private
48+
ARCHITECTURE_PATTERN = /\{architecture\}/.freeze
4849

49-
ARCHITECTURE_PATTERN = /\{architecture\}/.freeze
50+
DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/.freeze
5051

51-
DEFAULT_REPOSITORY_ROOT_PATTERN = /\{default.repository.root\}/.freeze
52+
PLATFORM_PATTERN = /\{platform\}/.freeze
5253

53-
PLATFORM_PATTERN = /\{platform\}/.freeze
54+
def augment(raw, pattern, candidates, &block)
55+
if raw.respond_to? :map
56+
raw.map(&block)
57+
else
58+
raw =~ pattern ? candidates.map { |p| raw.gsub pattern, p } : raw
59+
end
60+
end
5461

55-
def augment(raw, pattern, candidates, &block)
56-
if raw.respond_to? :map
57-
raw.map(&block)
58-
else
59-
raw =~ pattern ? candidates.map { |p| raw.gsub pattern, p } : raw
62+
def augment_architecture(raw)
63+
augment(raw, ARCHITECTURE_PATTERN, ARCHITECTURES) { |r| augment_architecture r }
6064
end
61-
end
6265

63-
def augment_architecture(raw)
64-
augment(raw, ARCHITECTURE_PATTERN, ARCHITECTURES) { |r| augment_architecture r }
65-
end
66+
def augment_path(raw)
67+
if raw.respond_to? :map
68+
raw.map { |r| augment_path r }
69+
else
70+
"#{raw.chomp('/')}/index.yml"
71+
end
72+
end
6673

67-
def augment_path(raw)
68-
if raw.respond_to? :map
69-
raw.map { |r| augment_path r }
70-
else
71-
"#{raw.chomp('/')}/index.yml"
74+
def augment_platform(raw)
75+
augment(raw, PLATFORM_PATTERN, PLATFORMS) { |r| augment_platform r }
7276
end
73-
end
7477

75-
def augment_platform(raw)
76-
augment(raw, PLATFORM_PATTERN, PLATFORMS) { |r| augment_platform r }
77-
end
78+
def augment_repository_root(raw)
79+
if raw.respond_to? :map
80+
raw.map { |r| augment_repository_root r }
81+
else
82+
raw.gsub DEFAULT_REPOSITORY_ROOT_PATTERN, @default_repository_root
83+
end
84+
end
7885

79-
def augment_repository_root(raw)
80-
if raw.respond_to? :map
81-
raw.map { |r| augment_repository_root r }
82-
else
83-
raw.gsub DEFAULT_REPOSITORY_ROOT_PATTERN, @default_repository_root
86+
def cache
87+
JavaBuildpack::Util::Cache::DownloadCache.new(Pathname.new("#{STAGING_DIR}/resources/cache")).freeze
8488
end
85-
end
8689

87-
def cache
88-
JavaBuildpack::Util::Cache::DownloadCache.new(Pathname.new("#{STAGING_DIR}/resources/cache")).freeze
89-
end
90+
def component_ids
91+
configuration('components').values.flatten.map { |component| component.split('::').last.snake_case }
92+
end
9093

91-
def component_ids
92-
configuration('components').values.flatten.map { |component| component.split('::').last.snake_case }
93-
end
94+
def configuration(id)
95+
JavaBuildpack::Util::ConfigurationUtils.load id, false
96+
end
9497

95-
def configuration(id)
96-
JavaBuildpack::Util::ConfigurationUtils.load(id, false)
97-
end
98+
def configurations(configuration)
99+
configurations = []
98100

99-
def configurations(configuration)
100-
configurations = []
101+
if repository_configuration?(configuration)
102+
configurations << configuration
103+
else
104+
configurations << configuration.values.map { |v| configurations(v) }
105+
end
101106

102-
if repository_configuration?(configuration)
103-
configurations << configuration
104-
else
105-
configurations << configuration.values.map { |v| configurations(v) }
107+
configurations
106108
end
107109

108-
configurations
109-
end
110+
def default_repository_root
111+
configuration('repository')['default_repository_root'].chomp('/')
112+
end
110113

111-
def index_uris(configuration)
112-
[configuration['repository_root']]
113-
.map { |r| augment_repository_root r }
114-
.map { |r| augment_platform r }
115-
.map { |r| augment_architecture r }
116-
.map { |r| augment_path r }.flatten
117-
end
114+
def index_uris(configuration)
115+
[configuration['repository_root']]
116+
.map { |r| augment_repository_root r }
117+
.map { |r| augment_platform r }
118+
.map { |r| augment_architecture r }
119+
.map { |r| augment_path r }.flatten
120+
end
118121

119-
def repository_configuration?(configuration)
120-
configuration['version'] && configuration['repository_root']
121-
end
122+
def repository_configuration?(configuration)
123+
configuration['version'] && configuration['repository_root']
124+
end
122125

123-
def uris(configurations)
124-
uris = []
126+
def uris(configurations)
127+
uris = []
125128

126-
configurations.each do |configuration|
127-
index_uris(configuration).each do |index_uri|
128-
@cache.get(index_uri) do |file|
129-
index = YAML.load(file)
130-
uris << index[version(configuration, index).to_s]
129+
configurations.each do |configuration|
130+
index_uris(configuration).each do |index_uri|
131+
@cache.get(index_uri) do |f|
132+
index = YAML.load f
133+
uris << index[version(configuration, index).to_s]
134+
end
131135
end
132136
end
137+
138+
uris
133139
end
134140

135-
uris
136-
end
141+
def version(configuration, index)
142+
JavaBuildpack::Repository::VersionResolver.resolve(JavaBuildpack::Util::TokenizedVersion.new(configuration['version']), index.keys)
143+
end
137144

138-
def version(configuration, index)
139-
JavaBuildpack::Repository::VersionResolver.resolve(JavaBuildpack::Util::TokenizedVersion.new(configuration['version']), index.keys)
140-
end
145+
def create_task(uri)
146+
task uri do |t|
147+
rake_output_message "Caching #{t.name}"
148+
cache.get(t.name) {}
149+
end
141150

142-
def create_task(uri)
143-
task uri do |t|
144-
rake_output_message "Caching #{t.name}"
145-
cache.get(t.name)
151+
task PACKAGE_NAME => [uri]
146152
end
147153

148-
uri
149154
end
150155

151156
end

0 commit comments

Comments
 (0)