buildpack-packager 2.3.4
Sign up to get free protection for your applications and to get access to all the features.
- 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,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'buildpack/packager/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'buildpack-packager'
|
8
|
+
spec.version = Buildpack::Packager::VERSION
|
9
|
+
spec.authors = ['Cloud Foundry Buildpacks Team']
|
10
|
+
spec.email = ['cf-buildpacks-eng@pivotal.io']
|
11
|
+
spec.summary = 'Tool that packages your buildpacks based on a manifest'
|
12
|
+
spec.description = 'Tool that packages your Cloud Foundry buildpacks based on a manifest'
|
13
|
+
spec.homepage = 'https://github.com/cloudfoundry/buildpack-packager'
|
14
|
+
spec.license = 'Apache-2.0'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.required_ruby_version = '~> 2.2'
|
22
|
+
|
23
|
+
spec.add_dependency 'activesupport', '~> 4.1'
|
24
|
+
spec.add_dependency 'kwalify', '~> 0'
|
25
|
+
spec.add_dependency 'terminal-table', '~> 1.4'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.5'
|
30
|
+
spec.add_development_dependency 'rubyzip', '~> 1.2'
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 0'
|
32
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.5'
|
33
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Disconnected environments
|
2
|
+
|
3
|
+
### Deploying Apps on disconnected environments
|
4
|
+
Cached buildpacks only ensure that a the buildpacks dependencies are cached, not your applications.
|
5
|
+
|
6
|
+
When you work with a disconnected environment, it's important to use your package manager
|
7
|
+
to 'vendor' your applications dependencies.
|
8
|
+
|
9
|
+
The specific mechanism varies between platforms. See your buildpack's documentation for 'vendoring' advice.
|
10
|
+
|
11
|
+
## Building a cached buildpack
|
12
|
+
1. Make sure you have fetched submodules
|
13
|
+
|
14
|
+
```shell
|
15
|
+
git submodule update --init
|
16
|
+
```
|
17
|
+
|
18
|
+
1. Get the latest buildpack dependencies
|
19
|
+
|
20
|
+
```shell
|
21
|
+
BUNDLE_GEMFILE=cf.Gemfile bundle
|
22
|
+
```
|
23
|
+
|
24
|
+
1. Build the buildpack
|
25
|
+
|
26
|
+
```shell
|
27
|
+
BUNDLE_GEMFILE=cf.Gemfile bundle exec buildpack-packager [ uncached | cached ]
|
28
|
+
```
|
29
|
+
|
30
|
+
This produces a buildpack for use on Cloud Foundry.
|
31
|
+
|
32
|
+
'cached' generates a zip with all the dependencies cached.
|
33
|
+
|
34
|
+
'uncached' does not include the dependencies, however it excludes some files as specified
|
35
|
+
in manifest.yml.
|
36
|
+
|
37
|
+
1. Use in Cloud Foundry
|
38
|
+
|
39
|
+
Currently, you can only specify cached buildpacks by creating Cloud Foundry Admin Buildpacks.
|
40
|
+
|
41
|
+
This means you need admin rights. See the
|
42
|
+
[Open source admin documentation](http://docs.cloudfoundry.org/adminguide/buildpacks.html)
|
43
|
+
for more information.
|
44
|
+
|
45
|
+
Upload the buildpack to your Cloud Foundry and specify it by name:
|
46
|
+
|
47
|
+
```shell
|
48
|
+
cf create-buildpack custom_ruby_buildpack ruby_buildpack-cached-custom.zip 1
|
49
|
+
```
|
50
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Buildpack
|
2
|
+
class ManifestDependency
|
3
|
+
attr_reader :name, :version
|
4
|
+
|
5
|
+
def initialize(name, version)
|
6
|
+
@name = name
|
7
|
+
@version = version
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(other_object)
|
11
|
+
name == other_object.name && version == other_object.version
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'kwalify'
|
2
|
+
require 'kwalify/parser/yaml-patcher'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
require 'buildpack/manifest_dependency'
|
6
|
+
|
7
|
+
module Buildpack
|
8
|
+
class ManifestValidator
|
9
|
+
class ManifestValidationError < StandardError; end
|
10
|
+
|
11
|
+
SCHEMA_FILE = File.join(File.dirname(__FILE__), 'packager', 'manifest_schema.yml')
|
12
|
+
|
13
|
+
attr_reader :errors
|
14
|
+
|
15
|
+
def initialize(manifest_path)
|
16
|
+
@manifest_path = manifest_path
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?
|
20
|
+
validate
|
21
|
+
errors.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate
|
27
|
+
schema = Kwalify::Yaml.load_file(SCHEMA_FILE)
|
28
|
+
validator = Kwalify::Validator.new(schema)
|
29
|
+
parser = Kwalify::Yaml::Parser.new(validator)
|
30
|
+
manifest_data = parser.parse_file(@manifest_path)
|
31
|
+
|
32
|
+
@errors = {}
|
33
|
+
@errors[:manifest_parser_errors] = parser.errors unless parser.errors.empty?
|
34
|
+
|
35
|
+
if manifest_data['default_versions'] && !@errors[:manifest_parser_errors]
|
36
|
+
default_version_errors = validate_default_versions(manifest_data)
|
37
|
+
@errors[:default_version] = default_version_errors unless default_version_errors.empty?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def validate_default_versions(manifest_data)
|
42
|
+
error_messages = []
|
43
|
+
|
44
|
+
default_versions = create_manifest_dependencies(manifest_data['default_versions'])
|
45
|
+
dependency_versions = create_manifest_dependencies(manifest_data['dependencies'])
|
46
|
+
|
47
|
+
error_messages += validate_no_duplicate_names(default_versions)
|
48
|
+
error_messages += validate_defaults_in_dependencies(default_versions, dependency_versions)
|
49
|
+
wrap_errors_with_common_text(error_messages)
|
50
|
+
|
51
|
+
error_messages
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_manifest_dependencies(dependency_entries)
|
55
|
+
dependency_entries.map do |dependency|
|
56
|
+
ManifestDependency.new(dependency['name'], dependency['version'])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_no_duplicate_names(default_versions)
|
61
|
+
default_versions_names = default_versions.map { |default_version| default_version.name }
|
62
|
+
duplicate_names = default_versions_names.find_all { |dep| default_versions_names.count(dep) > 1 }.uniq
|
63
|
+
|
64
|
+
duplicate_names.map do |name|
|
65
|
+
"- #{name} had more than one 'default_versions' entry in the buildpack manifest."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_defaults_in_dependencies(default_versions, dependency_versions)
|
70
|
+
unmatched_dependencies = default_versions.select { |d| !dependency_versions.include?(d) }
|
71
|
+
|
72
|
+
unmatched_dependencies.map do |dependency|
|
73
|
+
name_version = "#{dependency.name} #{dependency.version}"
|
74
|
+
|
75
|
+
"- a 'default_versions' entry for #{name_version} was specified by the buildpack manifest, " +
|
76
|
+
"but no 'dependencies' entry for #{name_version} was found in the buildpack manifest."
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def wrap_errors_with_common_text(error_messages)
|
81
|
+
if error_messages.any?
|
82
|
+
error_messages.unshift('The buildpack manifest is malformed:')
|
83
|
+
error_messages<< 'For more information, see https://docs.cloudfoundry.org/buildpacks/custom.html#specifying-default-versions'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'buildpack/packager/version'
|
2
|
+
require 'buildpack/packager/table_presentation'
|
3
|
+
require 'buildpack/packager/dependencies_presenter'
|
4
|
+
require 'buildpack/packager/default_versions_presenter'
|
5
|
+
require 'buildpack/packager/package'
|
6
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
7
|
+
require 'open3'
|
8
|
+
require 'fileutils'
|
9
|
+
require 'tmpdir'
|
10
|
+
require 'yaml'
|
11
|
+
require 'shellwords'
|
12
|
+
|
13
|
+
module Buildpack
|
14
|
+
module Packager
|
15
|
+
class CheckSumError < StandardError; end
|
16
|
+
|
17
|
+
def self.package(options)
|
18
|
+
check_for_zip
|
19
|
+
|
20
|
+
package = Package.new(options)
|
21
|
+
|
22
|
+
Dir.mktmpdir do |temp_dir|
|
23
|
+
package.copy_buildpack_to_temp_dir(temp_dir)
|
24
|
+
|
25
|
+
package.build_dependencies(temp_dir) if options[:mode] == :cached
|
26
|
+
|
27
|
+
package.build_zip_file(temp_dir)
|
28
|
+
end
|
29
|
+
|
30
|
+
buildpack_type = options[:mode] == :cached ? "Cached" : "Uncached"
|
31
|
+
human_readable_size = `du -h #{package.zip_file_path} | cut -f1`
|
32
|
+
puts "#{buildpack_type} buildpack created and saved as #{package.zip_file_path} with a size of #{human_readable_size.strip}"
|
33
|
+
|
34
|
+
package
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.list(options)
|
38
|
+
package = Package.new(options)
|
39
|
+
package.list
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.defaults(options)
|
43
|
+
package = Package.new(options)
|
44
|
+
package.defaults
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.check_for_zip
|
48
|
+
_, _, status = Open3.capture3('which zip')
|
49
|
+
|
50
|
+
if status.to_s.include?('exit 1')
|
51
|
+
raise "Zip is not installed\nTry: apt-get install zip\nAnd then rerun"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'terminal-table'
|
2
|
+
|
3
|
+
module Buildpack
|
4
|
+
module Packager
|
5
|
+
class DefaultVersionsPresenter < Struct.new(:default_versions)
|
6
|
+
include TablePresentation
|
7
|
+
|
8
|
+
attr_reader :default_versions
|
9
|
+
|
10
|
+
def initialize(default_versions)
|
11
|
+
default_versions = [] if default_versions.nil?
|
12
|
+
@default_versions = default_versions
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect
|
16
|
+
table = Terminal::Table.new do |table|
|
17
|
+
default_versions.sort_by do |dependency|
|
18
|
+
sort_string_for dependency
|
19
|
+
end.each do |dependency|
|
20
|
+
columns = [
|
21
|
+
dependency['name'],
|
22
|
+
sanitize_version_string(dependency['version'])
|
23
|
+
]
|
24
|
+
table.add_row columns
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
table.headings = %w(name version)
|
29
|
+
|
30
|
+
table.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def present
|
34
|
+
to_markdown(inspect)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'terminal-table'
|
2
|
+
|
3
|
+
module Buildpack
|
4
|
+
module Packager
|
5
|
+
class DependenciesPresenter < Struct.new(:dependencies)
|
6
|
+
include TablePresentation
|
7
|
+
|
8
|
+
def inspect
|
9
|
+
has_modules = dependencies.any? { |dependency| dependency['modules'] }
|
10
|
+
|
11
|
+
table = Terminal::Table.new do |table|
|
12
|
+
dependencies.sort_by do |dependency|
|
13
|
+
sort_string_for dependency
|
14
|
+
end.each do |dependency|
|
15
|
+
columns = [
|
16
|
+
dependency['name'],
|
17
|
+
sanitize_version_string(dependency['version']),
|
18
|
+
dependency['cf_stacks'].sort.join(',')
|
19
|
+
]
|
20
|
+
if has_modules
|
21
|
+
columns += [dependency.fetch('modules', []).sort.join(', ')]
|
22
|
+
end
|
23
|
+
table.add_row columns
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
table.headings = if has_modules
|
28
|
+
%w(name version cf_stacks modules)
|
29
|
+
else
|
30
|
+
%w(name version cf_stacks)
|
31
|
+
end
|
32
|
+
|
33
|
+
table.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def present
|
37
|
+
to_markdown(inspect)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
type: map
|
2
|
+
mapping:
|
3
|
+
"language":
|
4
|
+
type: str
|
5
|
+
required: yes
|
6
|
+
"url_to_dependency_map":
|
7
|
+
type: seq
|
8
|
+
required: yes
|
9
|
+
sequence:
|
10
|
+
- type: map
|
11
|
+
mapping:
|
12
|
+
"match":
|
13
|
+
type: str
|
14
|
+
required: yes
|
15
|
+
"name":
|
16
|
+
type: str
|
17
|
+
required: yes
|
18
|
+
"version":
|
19
|
+
type: text
|
20
|
+
required: yes
|
21
|
+
"dependencies":
|
22
|
+
type: seq
|
23
|
+
required: yes
|
24
|
+
sequence:
|
25
|
+
- type: map
|
26
|
+
mapping:
|
27
|
+
"name":
|
28
|
+
type: str
|
29
|
+
required: yes
|
30
|
+
"version":
|
31
|
+
type: text
|
32
|
+
required: yes
|
33
|
+
"uri":
|
34
|
+
type: str
|
35
|
+
required: yes
|
36
|
+
"modules":
|
37
|
+
type: seq
|
38
|
+
required: no
|
39
|
+
sequence:
|
40
|
+
- type: str
|
41
|
+
"md5":
|
42
|
+
type: str
|
43
|
+
required: yes
|
44
|
+
"cf_stacks":
|
45
|
+
type: seq
|
46
|
+
required: yes
|
47
|
+
sequence:
|
48
|
+
- type: str
|
49
|
+
enum: [ lucid64, cflinuxfs2 ]
|
50
|
+
"exclude_files":
|
51
|
+
type: seq
|
52
|
+
required: yes
|
53
|
+
sequence:
|
54
|
+
- type: str
|
55
|
+
"default_versions":
|
56
|
+
type: seq
|
57
|
+
required: no
|
58
|
+
sequence:
|
59
|
+
- type: map
|
60
|
+
required: yes
|
61
|
+
mapping:
|
62
|
+
"name":
|
63
|
+
type: str
|
64
|
+
required: yes
|
65
|
+
"version":
|
66
|
+
type: text
|
67
|
+
required: yes
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
2
|
+
require 'open3'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'yaml'
|
6
|
+
require 'shellwords'
|
7
|
+
require 'buildpack/packager/zip_file_excluder'
|
8
|
+
|
9
|
+
module Buildpack
|
10
|
+
module Packager
|
11
|
+
class Package < Struct.new(:options)
|
12
|
+
def copy_buildpack_to_temp_dir(temp_dir)
|
13
|
+
FileUtils.cp_r(File.join(options[:root_dir], '.'), temp_dir)
|
14
|
+
FileUtils.cp(options[:manifest_path], File.join(temp_dir, 'manifest.yml'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_dependencies(temp_dir)
|
18
|
+
local_cache_directory = options[:cache_dir] || "#{ENV['HOME']}/.buildpack-packager/cache"
|
19
|
+
FileUtils.mkdir_p(local_cache_directory)
|
20
|
+
|
21
|
+
dependency_dir = File.join(temp_dir, "dependencies")
|
22
|
+
FileUtils.mkdir_p(dependency_dir)
|
23
|
+
|
24
|
+
download_dependencies(manifest[:dependencies], local_cache_directory, dependency_dir)
|
25
|
+
end
|
26
|
+
|
27
|
+
def download_dependencies(dependencies, local_cache_directory, dependency_dir)
|
28
|
+
dependencies.each do |dependency|
|
29
|
+
safe_uri = uri_without_credentials(dependency['uri'])
|
30
|
+
translated_filename = uri_cache_path(safe_uri)
|
31
|
+
local_cached_file = File.expand_path(File.join(local_cache_directory, translated_filename))
|
32
|
+
|
33
|
+
if options[:force_download] || !File.exist?(local_cached_file)
|
34
|
+
puts "Downloading #{dependency['name']} version #{dependency['version']} from: #{safe_uri}"
|
35
|
+
download_file(dependency['uri'], local_cached_file)
|
36
|
+
human_readable_size = `du -h #{local_cached_file} | cut -f1`.strip
|
37
|
+
puts " Using #{dependency['name']} version #{dependency['version']} with size #{human_readable_size}"
|
38
|
+
|
39
|
+
from_local_cache = false
|
40
|
+
else
|
41
|
+
human_readable_size = `du -h #{local_cached_file} | cut -f1`.strip
|
42
|
+
puts "Using #{dependency['name']} version #{dependency['version']} from local cache at: #{local_cached_file} with size #{human_readable_size}"
|
43
|
+
from_local_cache = true
|
44
|
+
end
|
45
|
+
|
46
|
+
ensure_correct_dependency_checksum({
|
47
|
+
local_cached_file: local_cached_file,
|
48
|
+
dependency: dependency,
|
49
|
+
from_local_cache: from_local_cache
|
50
|
+
})
|
51
|
+
|
52
|
+
FileUtils.cp(local_cached_file, dependency_dir)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_zip_file(temp_dir)
|
57
|
+
FileUtils.rm_rf(zip_file_path)
|
58
|
+
zip_files(temp_dir, zip_file_path, manifest[:exclude_files])
|
59
|
+
end
|
60
|
+
|
61
|
+
def list
|
62
|
+
DependenciesPresenter.new(manifest['dependencies']).present
|
63
|
+
end
|
64
|
+
|
65
|
+
def defaults
|
66
|
+
DefaultVersionsPresenter.new(manifest['default_versions']).present
|
67
|
+
end
|
68
|
+
|
69
|
+
def zip_file_path
|
70
|
+
Shellwords.escape(File.join(options[:root_dir], zip_file_name))
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def uri_without_credentials(uri_string)
|
76
|
+
uri = URI(uri_string)
|
77
|
+
if uri.userinfo
|
78
|
+
uri.user = "-redacted-" if uri.user
|
79
|
+
uri.password = "-redacted-" if uri.password
|
80
|
+
end
|
81
|
+
uri.to_s.sub("file:", "file://")
|
82
|
+
end
|
83
|
+
|
84
|
+
def uri_cache_path uri
|
85
|
+
uri.gsub(/[:\/\?&]/, '_')
|
86
|
+
end
|
87
|
+
|
88
|
+
def manifest
|
89
|
+
@manifest ||= YAML.load_file(options[:manifest_path]).with_indifferent_access
|
90
|
+
end
|
91
|
+
|
92
|
+
def zip_file_name
|
93
|
+
"#{manifest[:language]}_buildpack#{cached_identifier}-v#{buildpack_version}.zip"
|
94
|
+
end
|
95
|
+
|
96
|
+
def buildpack_version
|
97
|
+
File.read("#{options[:root_dir]}/VERSION").chomp
|
98
|
+
end
|
99
|
+
|
100
|
+
def cached_identifier
|
101
|
+
return '' unless options[:mode] == :cached
|
102
|
+
'-cached'
|
103
|
+
end
|
104
|
+
|
105
|
+
def ensure_correct_dependency_checksum(local_cached_file:, dependency:, from_local_cache:)
|
106
|
+
if dependency['md5'] != Digest::MD5.file(local_cached_file).hexdigest
|
107
|
+
if from_local_cache
|
108
|
+
FileUtils.rm_rf(local_cached_file)
|
109
|
+
|
110
|
+
download_file(dependency['uri'], local_cached_file)
|
111
|
+
ensure_correct_dependency_checksum({
|
112
|
+
local_cached_file: local_cached_file,
|
113
|
+
dependency: dependency,
|
114
|
+
from_local_cache: false
|
115
|
+
})
|
116
|
+
else
|
117
|
+
raise CheckSumError,
|
118
|
+
"File: #{dependency['name']}, version: #{dependency['version']} downloaded at location #{dependency['uri']}\n\tis reporting a different checksum than the one specified in the manifest."
|
119
|
+
end
|
120
|
+
else
|
121
|
+
puts " #{dependency['name']} version #{dependency['version']} matches the manifest provided md5 checksum of #{dependency['md5']}\n\n"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def download_file(url, file)
|
126
|
+
raise "Failed to download file from #{url}" unless system("curl #{url} -o #{file} -L --fail -f")
|
127
|
+
end
|
128
|
+
|
129
|
+
def zip_files(source_dir, zip_file_path, excluded_files)
|
130
|
+
excluder = ZipFileExcluder.new
|
131
|
+
manifest_exclusions = excluder.generate_manifest_exclusions excluded_files
|
132
|
+
gitfile_exclusions = excluder.generate_exclusions_from_git_files source_dir
|
133
|
+
all_exclusions = manifest_exclusions + ' ' + gitfile_exclusions
|
134
|
+
`cd #{source_dir} && zip -r #{zip_file_path} ./ #{all_exclusions}`
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|