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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE +176 -0
  6. data/README.md +180 -0
  7. data/Rakefile +6 -0
  8. data/bin/buildpack-packager +79 -0
  9. data/buildpack-packager.gemspec +33 -0
  10. data/doc/disconnected_environments.md +50 -0
  11. data/lib/buildpack/manifest_dependency.rb +14 -0
  12. data/lib/buildpack/manifest_validator.rb +88 -0
  13. data/lib/buildpack/packager.rb +55 -0
  14. data/lib/buildpack/packager/default_versions_presenter.rb +38 -0
  15. data/lib/buildpack/packager/dependencies_presenter.rb +41 -0
  16. data/lib/buildpack/packager/manifest_schema.yml +67 -0
  17. data/lib/buildpack/packager/package.rb +139 -0
  18. data/lib/buildpack/packager/table_presentation.rb +21 -0
  19. data/lib/buildpack/packager/version.rb +5 -0
  20. data/lib/buildpack/packager/zip_file_excluder.rb +31 -0
  21. data/lib/kwalify/parser/yaml-patcher.rb +70 -0
  22. data/spec/buildpack/packager_spec.rb +7 -0
  23. data/spec/fixtures/buildpack-with-uri-credentials/VERSION +1 -0
  24. data/spec/fixtures/buildpack-with-uri-credentials/manifest.yml +36 -0
  25. data/spec/fixtures/buildpack-without-uri-credentials/VERSION +1 -0
  26. data/spec/fixtures/buildpack-without-uri-credentials/manifest.yml +36 -0
  27. data/spec/fixtures/manifests/manifest_invalid-md6.yml +18 -0
  28. data/spec/fixtures/manifests/manifest_invalid-md6_and_defaults.yml +21 -0
  29. data/spec/fixtures/manifests/manifest_valid.yml +19 -0
  30. data/spec/helpers/cache_directory_helpers.rb +15 -0
  31. data/spec/helpers/fake_binary_hosting_helpers.rb +21 -0
  32. data/spec/helpers/file_system_helpers.rb +35 -0
  33. data/spec/integration/bin/buildpack_packager/download_caching_spec.rb +85 -0
  34. data/spec/integration/bin/buildpack_packager_spec.rb +378 -0
  35. data/spec/integration/buildpack/directory_name_spec.rb +89 -0
  36. data/spec/integration/buildpack/packager_spec.rb +454 -0
  37. data/spec/integration/default_versions_spec.rb +170 -0
  38. data/spec/integration/output_spec.rb +70 -0
  39. data/spec/spec_helper.rb +12 -0
  40. data/spec/unit/buildpack/packager/zip_file_excluder_spec.rb +68 -0
  41. data/spec/unit/manifest_dependency_spec.rb +41 -0
  42. data/spec/unit/manifest_validator_spec.rb +35 -0
  43. data/spec/unit/packager/package_spec.rb +196 -0
  44. 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,5 @@
1
+ module Buildpack
2
+ module Packager
3
+ VERSION = '2.3.4'.freeze
4
+ end
5
+ 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,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Buildpack::Packager do
4
+ it 'has a version number' do
5
+ expect(Buildpack::Packager::VERSION).not_to be nil
6
+ end
7
+ end
@@ -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,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