buildpack-packager 2.3.4
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/Gemfile +5 -0
- data/LICENSE +176 -0
- data/README.md +180 -0
- data/Rakefile +6 -0
- data/bin/buildpack-packager +79 -0
- data/buildpack-packager.gemspec +33 -0
- data/doc/disconnected_environments.md +50 -0
- data/lib/buildpack/manifest_dependency.rb +14 -0
- data/lib/buildpack/manifest_validator.rb +88 -0
- data/lib/buildpack/packager.rb +55 -0
- data/lib/buildpack/packager/default_versions_presenter.rb +38 -0
- data/lib/buildpack/packager/dependencies_presenter.rb +41 -0
- data/lib/buildpack/packager/manifest_schema.yml +67 -0
- data/lib/buildpack/packager/package.rb +139 -0
- data/lib/buildpack/packager/table_presentation.rb +21 -0
- data/lib/buildpack/packager/version.rb +5 -0
- data/lib/buildpack/packager/zip_file_excluder.rb +31 -0
- data/lib/kwalify/parser/yaml-patcher.rb +70 -0
- data/spec/buildpack/packager_spec.rb +7 -0
- data/spec/fixtures/buildpack-with-uri-credentials/VERSION +1 -0
- data/spec/fixtures/buildpack-with-uri-credentials/manifest.yml +36 -0
- data/spec/fixtures/buildpack-without-uri-credentials/VERSION +1 -0
- data/spec/fixtures/buildpack-without-uri-credentials/manifest.yml +36 -0
- data/spec/fixtures/manifests/manifest_invalid-md6.yml +18 -0
- data/spec/fixtures/manifests/manifest_invalid-md6_and_defaults.yml +21 -0
- data/spec/fixtures/manifests/manifest_valid.yml +19 -0
- data/spec/helpers/cache_directory_helpers.rb +15 -0
- data/spec/helpers/fake_binary_hosting_helpers.rb +21 -0
- data/spec/helpers/file_system_helpers.rb +35 -0
- data/spec/integration/bin/buildpack_packager/download_caching_spec.rb +85 -0
- data/spec/integration/bin/buildpack_packager_spec.rb +378 -0
- data/spec/integration/buildpack/directory_name_spec.rb +89 -0
- data/spec/integration/buildpack/packager_spec.rb +454 -0
- data/spec/integration/default_versions_spec.rb +170 -0
- data/spec/integration/output_spec.rb +70 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/unit/buildpack/packager/zip_file_excluder_spec.rb +68 -0
- data/spec/unit/manifest_dependency_spec.rb +41 -0
- data/spec/unit/manifest_validator_spec.rb +35 -0
- data/spec/unit/packager/package_spec.rb +196 -0
- metadata +235 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'terminal-table'
|
2
|
+
|
3
|
+
module Buildpack
|
4
|
+
module Packager
|
5
|
+
module TablePresentation
|
6
|
+
def to_markdown(table_contents)
|
7
|
+
table_contents.split("\n")[1...-1].tap { |lines| lines[1].tr!('+', '|') }.join("\n")
|
8
|
+
end
|
9
|
+
|
10
|
+
def sanitize_version_string(version)
|
11
|
+
version == 0 ? '-' : version
|
12
|
+
end
|
13
|
+
|
14
|
+
def sort_string_for(dependency)
|
15
|
+
interpreter_names = %w(ruby jruby php hhvm python go node)
|
16
|
+
sort_index = interpreter_names.index(dependency['name']) || 9999
|
17
|
+
sprintf '%s-%s-%s', sort_index, dependency['name'], dependency['version']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Buildpack
|
2
|
+
module Packager
|
3
|
+
class ZipFileExcluder
|
4
|
+
def generate_manifest_exclusions(excluded_files)
|
5
|
+
generate_exclusion_string excluded_files
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_exclusions_from_git_files(dir)
|
9
|
+
Dir.chdir dir do
|
10
|
+
git_files = Dir.glob('**/.git*').map do |elt|
|
11
|
+
File.directory?(elt) ? "#{elt}/" : elt
|
12
|
+
end
|
13
|
+
|
14
|
+
generate_exclusion_string git_files
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_exclusion_string(file_list)
|
21
|
+
file_list.map do |file|
|
22
|
+
if file.chars.last == '/'
|
23
|
+
"-x #{file}\\* -x \\*/#{file}\\*"
|
24
|
+
else
|
25
|
+
"-x #{file} -x \\*/#{file}"
|
26
|
+
end
|
27
|
+
end.join(' ')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class Kwalify::Yaml::Parser < Kwalify::BaseParser
|
2
|
+
def parse_block_value(level, rule, path, uniq_table, container)
|
3
|
+
skip_spaces_and_comments
|
4
|
+
## nil
|
5
|
+
return nil if @column < level || (@column == level && !match?(/-\s+/)) || eos?
|
6
|
+
## anchor and alias
|
7
|
+
name = nil
|
8
|
+
if scan(/\&([-\w]+)/)
|
9
|
+
name = parse_anchor(rule, path, uniq_table, container)
|
10
|
+
elsif scan(/\*([-\w]+)/)
|
11
|
+
return parse_alias(rule, path, uniq_table, container)
|
12
|
+
end
|
13
|
+
## type
|
14
|
+
skip_spaces_and_comments if scan(/!!?\w+/)
|
15
|
+
## sequence
|
16
|
+
if match?(/-\s+/)
|
17
|
+
if rule && !rule.sequence
|
18
|
+
# _validate_error("sequence is not expected.", path)
|
19
|
+
rule = nil
|
20
|
+
end
|
21
|
+
seq = create_sequence(rule, @linenum, @column)
|
22
|
+
@anchors[name] = seq if name
|
23
|
+
parse_block_seq(seq, rule, path, uniq_table)
|
24
|
+
return seq
|
25
|
+
end
|
26
|
+
## mapping
|
27
|
+
if match?(MAPKEY_PATTERN)
|
28
|
+
if rule && !rule.mapping
|
29
|
+
# _validate_error("mapping is not expected.", path)
|
30
|
+
rule = nil
|
31
|
+
end
|
32
|
+
map = create_mapping(rule, @linenum, @column)
|
33
|
+
@anchors[name] = map if name
|
34
|
+
parse_block_map(map, rule, path, uniq_table)
|
35
|
+
return map
|
36
|
+
end
|
37
|
+
## sequence (flow-style)
|
38
|
+
if match?(/\[/)
|
39
|
+
if rule && !rule.sequence
|
40
|
+
# _validate_error("sequence is not expected.", path)
|
41
|
+
rule = nil
|
42
|
+
end
|
43
|
+
seq = create_sequence(rule, @linenum, @column)
|
44
|
+
@anchors[name] = seq if name
|
45
|
+
parse_flow_seq(seq, rule, path, uniq_table)
|
46
|
+
return seq
|
47
|
+
end
|
48
|
+
## mapping (flow-style)
|
49
|
+
if match?(/\{/)
|
50
|
+
if rule && !rule.mapping
|
51
|
+
# _validate_error("mapping is not expected.", path)
|
52
|
+
rule = nil
|
53
|
+
end
|
54
|
+
map = create_mapping(rule, @linenum, @column)
|
55
|
+
@anchors[name] = map if name
|
56
|
+
parse_flow_map(map, rule, path, uniq_table)
|
57
|
+
return map
|
58
|
+
end
|
59
|
+
## block text
|
60
|
+
if match?(/[|>]/)
|
61
|
+
text = parse_block_text(level, rule, path, uniq_table)
|
62
|
+
@anchors[name] = text if name
|
63
|
+
return text
|
64
|
+
end
|
65
|
+
## scalar
|
66
|
+
scalar = parse_block_scalar(rule, path, uniq_table)
|
67
|
+
@anchors[name] = scalar if name
|
68
|
+
scalar
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
1.7.8
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
language: go
|
3
|
+
url_to_dependency_map:
|
4
|
+
- match: go(\d+\.\d+(.*))
|
5
|
+
name: go
|
6
|
+
version: "$1"
|
7
|
+
- match: godep
|
8
|
+
name: godep
|
9
|
+
version: v74
|
10
|
+
dependencies:
|
11
|
+
- name: go
|
12
|
+
version: 1.6.3
|
13
|
+
uri: https://login:password@buildpacks.cloudfoundry.org/concourse-binaries/go/go1.6.3.linux-amd64.tar.gz
|
14
|
+
md5: 5f7bf9d61d2b0dd75c9e2cd7a87272cc
|
15
|
+
cf_stacks:
|
16
|
+
- cflinuxfs2
|
17
|
+
- name: godep
|
18
|
+
version: v74
|
19
|
+
uri: https://api-token:x-oauth-basic@buildpacks.cloudfoundry.org/concourse-binaries/godep/godep-v74-linux-x64.tgz
|
20
|
+
md5: 70220eee9f9e654e0b85887f696b6add
|
21
|
+
cf_stacks:
|
22
|
+
- cflinuxfs2
|
23
|
+
exclude_files:
|
24
|
+
- ".git/"
|
25
|
+
- ".gitignore"
|
26
|
+
- ".gitmodules"
|
27
|
+
- cf_spec/
|
28
|
+
- log/
|
29
|
+
- bin/package
|
30
|
+
- buildpack-packager/
|
31
|
+
- test-godir/
|
32
|
+
- test/
|
33
|
+
- Makefile
|
34
|
+
- PULL_REQUEST_TEMPLATE
|
35
|
+
- ISSUE_TEMPLATE
|
36
|
+
- go_buildpack-*v*.zip
|
@@ -0,0 +1 @@
|
|
1
|
+
1.7.8
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
language: go
|
3
|
+
url_to_dependency_map:
|
4
|
+
- match: go(\d+\.\d+(.*))
|
5
|
+
name: go
|
6
|
+
version: "$1"
|
7
|
+
- match: godep
|
8
|
+
name: godep
|
9
|
+
version: v74
|
10
|
+
dependencies:
|
11
|
+
- name: go
|
12
|
+
version: 1.6.3
|
13
|
+
uri: https://buildpacks.cloudfoundry.org/concourse-binaries/go/go1.6.3.linux-amd64.tar.gz
|
14
|
+
md5: 5f7bf9d61d2b0dd75c9e2cd7a87272cc
|
15
|
+
cf_stacks:
|
16
|
+
- cflinuxfs2
|
17
|
+
- name: godep
|
18
|
+
version: v74
|
19
|
+
uri: https://pivotal-buildpacks.s3.amazonaws.com/concourse-binaries/godep/godep-v74-linux-x64.tgz
|
20
|
+
md5: 70220eee9f9e654e0b85887f696b6add
|
21
|
+
cf_stacks:
|
22
|
+
- cflinuxfs2
|
23
|
+
exclude_files:
|
24
|
+
- ".git/"
|
25
|
+
- ".gitignore"
|
26
|
+
- ".gitmodules"
|
27
|
+
- cf_spec/
|
28
|
+
- log/
|
29
|
+
- bin/package
|
30
|
+
- buildpack-packager/
|
31
|
+
- test-godir/
|
32
|
+
- test/
|
33
|
+
- Makefile
|
34
|
+
- PULL_REQUEST_TEMPLATE
|
35
|
+
- ISSUE_TEMPLATE
|
36
|
+
- go_buildpack-*v*.zip
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
language: go
|
3
|
+
|
4
|
+
url_to_dependency_map:
|
5
|
+
- match: go(\d+\.\d+(\.\d+)?)
|
6
|
+
name: go
|
7
|
+
version: $1
|
8
|
+
dependencies:
|
9
|
+
- name: go
|
10
|
+
version: 1.2
|
11
|
+
uri: http://go.googlecode.com/files/go1.2.linux-amd64.tar.gz
|
12
|
+
md6: 68901bbf8a04e71e0b30aa19c3946b21
|
13
|
+
cf_stacks:
|
14
|
+
- lucid64
|
15
|
+
- cflinuxfs2
|
16
|
+
|
17
|
+
exclude_files:
|
18
|
+
- .git/
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
language: go
|
3
|
+
|
4
|
+
url_to_dependency_map:
|
5
|
+
- match: go(\d+\.\d+(\.\d+)?)
|
6
|
+
name: go
|
7
|
+
version: $1
|
8
|
+
default_versions:
|
9
|
+
- name: go
|
10
|
+
version: 1.3
|
11
|
+
dependencies:
|
12
|
+
- name: go
|
13
|
+
version: 1.2
|
14
|
+
uri: http://go.googlecode.com/files/go1.2.linux-amd64.tar.gz
|
15
|
+
md6: 68901bbf8a04e71e0b30aa19c3946b21
|
16
|
+
cf_stacks:
|
17
|
+
- lucid64
|
18
|
+
- cflinuxfs2
|
19
|
+
|
20
|
+
exclude_files:
|
21
|
+
- .git/
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
language: go
|
3
|
+
|
4
|
+
url_to_dependency_map:
|
5
|
+
- match: go(\d+\.\d+(\.\d+)?)
|
6
|
+
name: go
|
7
|
+
version: $1
|
8
|
+
|
9
|
+
dependencies:
|
10
|
+
- name: go
|
11
|
+
version: 1.2
|
12
|
+
uri: http://go.googlecode.com/files/go1.2.linux-amd64.tar.gz
|
13
|
+
md5: 68901bbf8a04e71e0b30aa19c3946b21
|
14
|
+
cf_stacks:
|
15
|
+
- lucid64
|
16
|
+
- cflinuxfs2
|
17
|
+
|
18
|
+
exclude_files:
|
19
|
+
- .git/
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module CacheDirectoryHelpers
|
2
|
+
BUILDPACK_PACKAGER_CACHE_DIR = File.join(ENV['HOME'], '.buildpack-packager', 'cache')
|
3
|
+
|
4
|
+
def uri_to_cache_filename(uri)
|
5
|
+
uri.gsub(/[\/:]/, '_')
|
6
|
+
end
|
7
|
+
|
8
|
+
def uri_to_cache_path(uri)
|
9
|
+
File.join(BUILDPACK_PACKAGER_CACHE_DIR, uri_to_cache_filename(uri))
|
10
|
+
end
|
11
|
+
|
12
|
+
def remove_from_cache_dir(uri)
|
13
|
+
FileUtils.rm_f(uri_to_cache_path(uri))
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module FakeBinaryHostingHelpers
|
2
|
+
def upstream_host_dir
|
3
|
+
@upstream_host_dir ||= Dir.mktmpdir('upstream_host_')
|
4
|
+
end
|
5
|
+
|
6
|
+
def create_upstream_file(file_name, file_content)
|
7
|
+
file_path = generate_upstream_file_path(file_name)
|
8
|
+
File.write(file_path, file_content)
|
9
|
+
file_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def remove_upstream_file(file_name)
|
13
|
+
FileUtils.rm_f(generate_upstream_file_path(file_name))
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def generate_upstream_file_path(file_name)
|
19
|
+
File.join(upstream_host_dir, file_name)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'zip'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module FileSystemHelpers
|
5
|
+
def run_packager_binary(buildpack_dir, flags)
|
6
|
+
packager_binary_file = File.join(`pwd`.chomp, 'bin', 'buildpack-packager')
|
7
|
+
Open3.capture2e("cd #{buildpack_dir} && #{packager_binary_file} #{flags}")
|
8
|
+
end
|
9
|
+
|
10
|
+
def make_fake_files(root, file_list)
|
11
|
+
file_list.each do |file|
|
12
|
+
full_path = File.join(root, file)
|
13
|
+
FileUtils.mkdir_p(File.dirname(full_path))
|
14
|
+
File.write(full_path, 'a')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def all_files(root)
|
19
|
+
Dir["#{root}/*"].map do |filename|
|
20
|
+
filename.gsub(root, '').gsub(/^\//, '')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_zip_contents(zip_path)
|
25
|
+
Zip::File.open(zip_path) do |zip_file|
|
26
|
+
zip_file
|
27
|
+
.map(&:name)
|
28
|
+
.select { |name| name[/\/$/].nil? }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_md5_of_file(path)
|
33
|
+
Digest::MD5.file(path).hexdigest
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Special note
|
4
|
+
# =============
|
5
|
+
#
|
6
|
+
# There are two uses of the term 'caching' in buildpack packager.
|
7
|
+
# 1. A 'cached' buildpack is a buildpack zipball that contains the buildpacks dependencies
|
8
|
+
# 2. 'Download caching' is where the packager keeps a copy of downloaded dependencies for
|
9
|
+
# the next time it is run.
|
10
|
+
#
|
11
|
+
# This integration test is concerned with 'Download caching'
|
12
|
+
|
13
|
+
describe 'reusing previously downloaded files' do
|
14
|
+
let(:upstream_file_path) do
|
15
|
+
create_upstream_file('sample_download.ignore_me',
|
16
|
+
'sample_download original text')
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:upstream_file_uri) { "file://#{upstream_file_path}" }
|
20
|
+
|
21
|
+
let(:buildpack_dir) { Dir.mktmpdir('buildpack_') }
|
22
|
+
|
23
|
+
let(:md5) { get_md5_of_file(upstream_file_path) }
|
24
|
+
let(:manifest) do
|
25
|
+
{
|
26
|
+
'exclude_files' => [],
|
27
|
+
'language' => 'sample',
|
28
|
+
'url_to_dependency_map' => [],
|
29
|
+
'dependencies' => [{
|
30
|
+
'version' => '1.0',
|
31
|
+
'name' => 'sample_download.ignore_me',
|
32
|
+
'cf_stacks' => [],
|
33
|
+
'md5' => md5,
|
34
|
+
'uri' => upstream_file_uri
|
35
|
+
}]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
before do
|
40
|
+
File.write(File.join(buildpack_dir, 'manifest.yml'), manifest.to_yaml)
|
41
|
+
|
42
|
+
`echo "1.2.3" > #{File.join(buildpack_dir, 'VERSION')}`
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'the file is not in the cache' do
|
46
|
+
specify 'the file should be kept in a cache when it is downloaded' do
|
47
|
+
_, status = run_packager_binary(buildpack_dir, '--cached')
|
48
|
+
|
49
|
+
expect(status).to be_success
|
50
|
+
expect(File).to exist(uri_to_cache_path(upstream_file_uri))
|
51
|
+
|
52
|
+
expect(File.read(uri_to_cache_path(upstream_file_uri))).to include('sample_download original text')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'the file has been downloaded before' do
|
57
|
+
specify 'the file in the cache should be used instead of downloading' do
|
58
|
+
run_packager_binary(buildpack_dir, '--cached')
|
59
|
+
|
60
|
+
remove_upstream_file('sample_download.ignore_me') # taking this away means packager must use the cache
|
61
|
+
|
62
|
+
_, status = run_packager_binary(buildpack_dir, '--cached')
|
63
|
+
|
64
|
+
expect(status).to be_success
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'however the file has changed, and the manifest is updated to reflect the new md5' do
|
68
|
+
before do
|
69
|
+
run_packager_binary(buildpack_dir, '--cached')
|
70
|
+
|
71
|
+
create_upstream_file('sample_download.ignore_me', 'sample_download updated text')
|
72
|
+
new_md5 = get_md5_of_file(upstream_file_path)
|
73
|
+
manifest['dependencies'].first['md5'] = new_md5
|
74
|
+
File.write(File.join(buildpack_dir, 'manifest.yml'), manifest.to_yaml)
|
75
|
+
end
|
76
|
+
|
77
|
+
specify 'the cache should now contain the new upstream file' do
|
78
|
+
output, status = run_packager_binary(buildpack_dir, '--cached')
|
79
|
+
|
80
|
+
expect(status).to be_success
|
81
|
+
expect(File.read(uri_to_cache_path(upstream_file_uri))).to include('sample_download updated text')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|