bosh_cli 0.16
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -0
- data/Rakefile +55 -0
- data/bin/bosh +17 -0
- data/lib/cli.rb +76 -0
- data/lib/cli/cache.rb +44 -0
- data/lib/cli/changeset_helper.rb +142 -0
- data/lib/cli/command_definition.rb +52 -0
- data/lib/cli/commands/base.rb +245 -0
- data/lib/cli/commands/biff.rb +300 -0
- data/lib/cli/commands/blob.rb +125 -0
- data/lib/cli/commands/cloudcheck.rb +169 -0
- data/lib/cli/commands/deployment.rb +147 -0
- data/lib/cli/commands/job.rb +42 -0
- data/lib/cli/commands/job_management.rb +117 -0
- data/lib/cli/commands/log_management.rb +81 -0
- data/lib/cli/commands/maintenance.rb +131 -0
- data/lib/cli/commands/misc.rb +240 -0
- data/lib/cli/commands/package.rb +112 -0
- data/lib/cli/commands/property_management.rb +125 -0
- data/lib/cli/commands/release.rb +469 -0
- data/lib/cli/commands/ssh.rb +271 -0
- data/lib/cli/commands/stemcell.rb +184 -0
- data/lib/cli/commands/task.rb +213 -0
- data/lib/cli/commands/user.rb +28 -0
- data/lib/cli/commands/vms.rb +53 -0
- data/lib/cli/config.rb +154 -0
- data/lib/cli/core_ext.rb +145 -0
- data/lib/cli/dependency_helper.rb +62 -0
- data/lib/cli/deployment_helper.rb +263 -0
- data/lib/cli/deployment_manifest_compiler.rb +28 -0
- data/lib/cli/director.rb +633 -0
- data/lib/cli/director_task.rb +64 -0
- data/lib/cli/errors.rb +48 -0
- data/lib/cli/event_log_renderer.rb +351 -0
- data/lib/cli/job_builder.rb +226 -0
- data/lib/cli/package_builder.rb +254 -0
- data/lib/cli/packaging_helper.rb +248 -0
- data/lib/cli/release.rb +176 -0
- data/lib/cli/release_builder.rb +215 -0
- data/lib/cli/release_compiler.rb +178 -0
- data/lib/cli/release_tarball.rb +272 -0
- data/lib/cli/runner.rb +771 -0
- data/lib/cli/stemcell.rb +83 -0
- data/lib/cli/task_log_renderer.rb +40 -0
- data/lib/cli/templates/help_message.erb +75 -0
- data/lib/cli/validation.rb +42 -0
- data/lib/cli/version.rb +7 -0
- data/lib/cli/version_calc.rb +48 -0
- data/lib/cli/versions_index.rb +126 -0
- data/lib/cli/yaml_helper.rb +62 -0
- data/spec/assets/biff/bad_gateway_config.yml +28 -0
- data/spec/assets/biff/good_simple_config.yml +63 -0
- data/spec/assets/biff/good_simple_golden_config.yml +63 -0
- data/spec/assets/biff/good_simple_template.erb +69 -0
- data/spec/assets/biff/multiple_subnets_config.yml +40 -0
- data/spec/assets/biff/network_only_template.erb +34 -0
- data/spec/assets/biff/no_cc_config.yml +27 -0
- data/spec/assets/biff/no_range_config.yml +27 -0
- data/spec/assets/biff/no_subnet_config.yml +16 -0
- data/spec/assets/biff/ok_network_config.yml +30 -0
- data/spec/assets/biff/properties_template.erb +6 -0
- data/spec/assets/deployment.MF +0 -0
- data/spec/assets/plugins/bosh/cli/commands/echo.rb +43 -0
- data/spec/assets/plugins/bosh/cli/commands/ruby.rb +24 -0
- data/spec/assets/release/jobs/cacher.tgz +0 -0
- data/spec/assets/release/jobs/cacher/config/file1.conf +0 -0
- data/spec/assets/release/jobs/cacher/config/file2.conf +0 -0
- data/spec/assets/release/jobs/cacher/job.MF +6 -0
- data/spec/assets/release/jobs/cacher/monit +1 -0
- data/spec/assets/release/jobs/cleaner.tgz +0 -0
- data/spec/assets/release/jobs/cleaner/job.MF +4 -0
- data/spec/assets/release/jobs/cleaner/monit +1 -0
- data/spec/assets/release/jobs/sweeper.tgz +0 -0
- data/spec/assets/release/jobs/sweeper/config/test.conf +1 -0
- data/spec/assets/release/jobs/sweeper/job.MF +5 -0
- data/spec/assets/release/jobs/sweeper/monit +1 -0
- data/spec/assets/release/packages/mutator.tar.gz +0 -0
- data/spec/assets/release/packages/stuff.tgz +0 -0
- data/spec/assets/release/release.MF +17 -0
- data/spec/assets/release_invalid_checksum.tgz +0 -0
- data/spec/assets/release_invalid_jobs.tgz +0 -0
- data/spec/assets/release_no_name.tgz +0 -0
- data/spec/assets/release_no_version.tgz +0 -0
- data/spec/assets/stemcell/image +1 -0
- data/spec/assets/stemcell/stemcell.MF +6 -0
- data/spec/assets/stemcell_invalid_mf.tgz +0 -0
- data/spec/assets/stemcell_no_image.tgz +0 -0
- data/spec/assets/valid_release.tgz +0 -0
- data/spec/assets/valid_stemcell.tgz +0 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/unit/base_command_spec.rb +66 -0
- data/spec/unit/biff_spec.rb +135 -0
- data/spec/unit/cache_spec.rb +36 -0
- data/spec/unit/cli_commands_spec.rb +481 -0
- data/spec/unit/config_spec.rb +139 -0
- data/spec/unit/core_ext_spec.rb +77 -0
- data/spec/unit/dependency_helper_spec.rb +52 -0
- data/spec/unit/deployment_manifest_compiler_spec.rb +63 -0
- data/spec/unit/director_spec.rb +511 -0
- data/spec/unit/director_task_spec.rb +48 -0
- data/spec/unit/event_log_renderer_spec.rb +171 -0
- data/spec/unit/hash_changeset_spec.rb +73 -0
- data/spec/unit/job_builder_spec.rb +454 -0
- data/spec/unit/package_builder_spec.rb +567 -0
- data/spec/unit/release_builder_spec.rb +65 -0
- data/spec/unit/release_spec.rb +66 -0
- data/spec/unit/release_tarball_spec.rb +33 -0
- data/spec/unit/runner_spec.rb +140 -0
- data/spec/unit/ssh_spec.rb +78 -0
- data/spec/unit/stemcell_spec.rb +17 -0
- data/spec/unit/version_calc_spec.rb +27 -0
- data/spec/unit/versions_index_spec.rb +132 -0
- metadata +338 -0
@@ -0,0 +1,226 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Cli
|
4
|
+
class JobBuilder
|
5
|
+
include PackagingHelper
|
6
|
+
|
7
|
+
attr_reader :name, :version, :packages, :templates,
|
8
|
+
:release_dir, :built_packages, :tarball_path
|
9
|
+
|
10
|
+
def self.run_prepare_script(script_path)
|
11
|
+
unless File.exists?(script_path)
|
12
|
+
raise InvalidJob, "Prepare script at `#{script_path}' doesn't exist"
|
13
|
+
end
|
14
|
+
|
15
|
+
unless File.executable?(script_path)
|
16
|
+
raise InvalidJob, "Prepare script at `#{script_path}' is not executable"
|
17
|
+
end
|
18
|
+
|
19
|
+
old_env = ENV
|
20
|
+
|
21
|
+
script_dir = File.dirname(script_path)
|
22
|
+
script_name = File.basename(script_path)
|
23
|
+
|
24
|
+
begin
|
25
|
+
# We need to temporarily delete some rubygems related artefacts
|
26
|
+
# because preparation scripts shouldn't share any assumptions
|
27
|
+
# with CLI itself
|
28
|
+
%w{ BUNDLE_GEMFILE RUBYOPT }.each { |key| ENV.delete(key) }
|
29
|
+
|
30
|
+
Dir.chdir(script_dir) do
|
31
|
+
cmd = "./#{script_name} 2>&1"
|
32
|
+
say("Running #{cmd}...")
|
33
|
+
script_output = `#{cmd}`
|
34
|
+
script_output.split("\n").each do |line|
|
35
|
+
say("> #{line}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
unless $?.exitstatus == 0
|
40
|
+
raise InvalidJob, "`#{script_path}' script failed"
|
41
|
+
end
|
42
|
+
ensure
|
43
|
+
ENV.each_pair { |k, v| ENV[k] = old_env[k] }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(spec, release_dir, final, blobstore, built_packages = [])
|
48
|
+
spec = load_yaml_file(spec) if spec.is_a?(String) && File.file?(spec)
|
49
|
+
|
50
|
+
@name = spec["name"]
|
51
|
+
@packages = spec["packages"].to_a
|
52
|
+
@built_packages = built_packages.to_a
|
53
|
+
@release_dir = release_dir
|
54
|
+
@templates_dir = File.join(job_dir, "templates")
|
55
|
+
@tarballs_dir = File.join(release_dir, "tmp", "jobs")
|
56
|
+
@final = final
|
57
|
+
@blobstore = blobstore
|
58
|
+
@artefact_type = "job"
|
59
|
+
|
60
|
+
case spec["templates"]
|
61
|
+
when Hash
|
62
|
+
@templates = spec["templates"].keys
|
63
|
+
else
|
64
|
+
raise InvalidJob, "Incorrect templates section in `#{@name}' " +
|
65
|
+
"job spec (should resolve to a hash)"
|
66
|
+
end
|
67
|
+
|
68
|
+
if @name.blank?
|
69
|
+
raise InvalidJob, "Job name is missing"
|
70
|
+
end
|
71
|
+
|
72
|
+
if @templates.nil?
|
73
|
+
raise InvalidJob, "Please include templates section with at least 1 " +
|
74
|
+
"(possibly dummy) file into `#{@name}' job spec"
|
75
|
+
end
|
76
|
+
|
77
|
+
unless @name.bosh_valid_id?
|
78
|
+
raise InvalidJob, "`#{@name}' is not a valid BOSH identifier"
|
79
|
+
end
|
80
|
+
|
81
|
+
unless File.exists?(File.join(job_dir, "spec"))
|
82
|
+
raise InvalidJob, "Cannot find spec file for '#{name}'"
|
83
|
+
end
|
84
|
+
|
85
|
+
if missing_packages.size > 0
|
86
|
+
raise InvalidJob, "Some packages required by '#{name}' job " +
|
87
|
+
"are missing: %s" % [missing_packages.join(", ")]
|
88
|
+
end
|
89
|
+
|
90
|
+
if missing_templates.size > 0
|
91
|
+
raise InvalidJob, "Some template files required by '#{name}' job " +
|
92
|
+
"are missing: %s" % [missing_templates.join(", ")]
|
93
|
+
end
|
94
|
+
|
95
|
+
if extra_templates.size > 0
|
96
|
+
raise InvalidJob, "There are unused template files for job " +
|
97
|
+
"'#{name}': %s" % [extra_templates.join(", ")]
|
98
|
+
end
|
99
|
+
|
100
|
+
unless monit_files.size > 0
|
101
|
+
raise InvalidJob, "Cannot find monit file for '#{name}'"
|
102
|
+
end
|
103
|
+
|
104
|
+
@dev_builds_dir = File.join(@release_dir, ".dev_builds", "jobs", @name)
|
105
|
+
@final_builds_dir = File.join(@release_dir, ".final_builds",
|
106
|
+
"jobs", @name)
|
107
|
+
|
108
|
+
FileUtils.mkdir_p(job_dir)
|
109
|
+
FileUtils.mkdir_p(@dev_builds_dir)
|
110
|
+
FileUtils.mkdir_p(@final_builds_dir)
|
111
|
+
|
112
|
+
at_exit { FileUtils.rm_rf(build_dir) }
|
113
|
+
|
114
|
+
init_indices
|
115
|
+
end
|
116
|
+
|
117
|
+
def copy_files
|
118
|
+
FileUtils.mkdir_p(File.join(build_dir, "templates"))
|
119
|
+
copied = 0
|
120
|
+
|
121
|
+
templates.each do |template|
|
122
|
+
src = File.join(@templates_dir, template)
|
123
|
+
dst = File.join(build_dir, "templates", template)
|
124
|
+
FileUtils.mkdir_p(File.dirname(dst))
|
125
|
+
|
126
|
+
FileUtils.cp(src, dst, :preserve => true)
|
127
|
+
copied += 1
|
128
|
+
end
|
129
|
+
|
130
|
+
monit_files.each do |file|
|
131
|
+
FileUtils.cp(file, build_dir, :preserve => true)
|
132
|
+
copied += 1
|
133
|
+
end
|
134
|
+
|
135
|
+
FileUtils.cp(File.join(job_dir, "spec"), File.join(build_dir, "job.MF"),
|
136
|
+
:preserve => true)
|
137
|
+
copied += 1
|
138
|
+
copied
|
139
|
+
end
|
140
|
+
|
141
|
+
def prepare_files
|
142
|
+
preparation_script = File.join(job_dir, "prepare")
|
143
|
+
end
|
144
|
+
|
145
|
+
def build_dir
|
146
|
+
@build_dir ||= Dir.mktmpdir
|
147
|
+
end
|
148
|
+
|
149
|
+
def job_dir
|
150
|
+
File.join(@release_dir, "jobs", @name)
|
151
|
+
end
|
152
|
+
|
153
|
+
def dev_builds_dir
|
154
|
+
File.join(@release_dir, ".dev_builds", "jobs", name)
|
155
|
+
end
|
156
|
+
|
157
|
+
def final_builds_dir
|
158
|
+
File.join(@release_dir, ".final_builds", "jobs", name)
|
159
|
+
end
|
160
|
+
|
161
|
+
def fingerprint
|
162
|
+
@fingerprint ||= make_fingerprint
|
163
|
+
end
|
164
|
+
|
165
|
+
def monit_files
|
166
|
+
glob = File.join(job_dir, '*.monit')
|
167
|
+
files = Dir.glob(glob)
|
168
|
+
monit = File.join(job_dir, "monit")
|
169
|
+
files << monit if File.exist?(monit)
|
170
|
+
files
|
171
|
+
end
|
172
|
+
|
173
|
+
def reload
|
174
|
+
@fingerprint = nil
|
175
|
+
@build_dir = nil
|
176
|
+
self
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
def make_fingerprint
|
182
|
+
contents = ""
|
183
|
+
|
184
|
+
# templates, monit, spec
|
185
|
+
files = templates.map do |template|
|
186
|
+
File.join(@templates_dir, template)
|
187
|
+
end.sort
|
188
|
+
|
189
|
+
files += monit_files
|
190
|
+
files << File.join(job_dir, "spec")
|
191
|
+
|
192
|
+
files.each do |filename|
|
193
|
+
path = File.basename(filename)
|
194
|
+
digest = Digest::SHA1.file(filename).hexdigest
|
195
|
+
contents << "%s%s%s" % [path, digest, tracked_permissions(filename)]
|
196
|
+
end
|
197
|
+
|
198
|
+
Digest::SHA1.hexdigest(contents)
|
199
|
+
end
|
200
|
+
|
201
|
+
def missing_packages
|
202
|
+
@missing_packages ||= packages - built_packages
|
203
|
+
end
|
204
|
+
|
205
|
+
def missing_templates
|
206
|
+
templates.select do |template|
|
207
|
+
!File.exists?(File.join(@templates_dir, template))
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def extra_templates
|
212
|
+
return [] if !File.directory?(@templates_dir)
|
213
|
+
|
214
|
+
Dir.chdir(@templates_dir) do
|
215
|
+
Dir["**/*"].reject do |file|
|
216
|
+
File.directory?(file) || templates.include?(file)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def in_build_dir(&block)
|
222
|
+
Dir.chdir(build_dir) { yield }
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Cli
|
4
|
+
class PackageBuilder
|
5
|
+
include PackagingHelper
|
6
|
+
|
7
|
+
attr_reader :name, :globs, :version, :dependencies, :tarball_path
|
8
|
+
# We have two ways of getting/storing a package:
|
9
|
+
# development versions of packages, kept in release directory
|
10
|
+
# final versions of packages, kept in blobstore
|
11
|
+
# development packages and their metadata should always be gitignored
|
12
|
+
# final build tarballs should be ignored as well
|
13
|
+
# final builds metadata should be checked in
|
14
|
+
|
15
|
+
def initialize(spec, release_dir, final, blobstore,
|
16
|
+
sources_dir = nil, blobs_dir = nil)
|
17
|
+
spec = load_yaml_file(spec) if spec.is_a?(String) && File.file?(spec)
|
18
|
+
|
19
|
+
@name = spec["name"]
|
20
|
+
@globs = spec["files"]
|
21
|
+
@dependencies = Array(spec["dependencies"])
|
22
|
+
@release_dir = release_dir
|
23
|
+
@sources_dir = sources_dir || File.join(@release_dir, "src")
|
24
|
+
@blobs_dir = blobs_dir || File.join(@release_dir, "blobs")
|
25
|
+
@final = final
|
26
|
+
@blobstore = blobstore
|
27
|
+
@artefact_type = "package"
|
28
|
+
|
29
|
+
@metadata_files = %w(packaging pre_packaging)
|
30
|
+
|
31
|
+
if @name.blank?
|
32
|
+
raise InvalidPackage, "Package name is missing"
|
33
|
+
end
|
34
|
+
|
35
|
+
unless @name.bosh_valid_id?
|
36
|
+
raise InvalidPackage, "Package name should be a valid BOSH identifier"
|
37
|
+
end
|
38
|
+
|
39
|
+
unless @globs.is_a?(Array) && @globs.size > 0
|
40
|
+
raise InvalidPackage, "Package '#{@name}' doesn't include any files"
|
41
|
+
end
|
42
|
+
|
43
|
+
@dev_builds_dir = File.join(@release_dir, ".dev_builds",
|
44
|
+
"packages", @name)
|
45
|
+
@final_builds_dir = File.join(@release_dir, ".final_builds",
|
46
|
+
"packages", @name)
|
47
|
+
|
48
|
+
FileUtils.mkdir_p(package_dir)
|
49
|
+
FileUtils.mkdir_p(@dev_builds_dir)
|
50
|
+
FileUtils.mkdir_p(@final_builds_dir)
|
51
|
+
|
52
|
+
at_exit { FileUtils.rm_rf(build_dir) }
|
53
|
+
|
54
|
+
init_indices
|
55
|
+
end
|
56
|
+
|
57
|
+
def reload # Mostly for tests
|
58
|
+
@fingerprint = nil
|
59
|
+
@resolved_globs = nil
|
60
|
+
init_indices
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def fingerprint
|
65
|
+
@fingerprint ||= make_fingerprint
|
66
|
+
end
|
67
|
+
|
68
|
+
def resolved_globs
|
69
|
+
@resolved_globs ||= resolve_globs
|
70
|
+
end
|
71
|
+
|
72
|
+
def source_files
|
73
|
+
resolved_globs[:source]
|
74
|
+
end
|
75
|
+
|
76
|
+
def blob_files
|
77
|
+
resolved_globs[:blob]
|
78
|
+
end
|
79
|
+
|
80
|
+
def files
|
81
|
+
(resolved_globs[:blob] + resolved_globs[:source]).sort
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_dir
|
85
|
+
@build_dir ||= Dir.mktmpdir
|
86
|
+
end
|
87
|
+
|
88
|
+
def package_dir
|
89
|
+
File.join(@release_dir, "packages", name)
|
90
|
+
end
|
91
|
+
|
92
|
+
def copy_files
|
93
|
+
copied = 0
|
94
|
+
|
95
|
+
files.each do |filename|
|
96
|
+
file_path = get_file_path(filename)
|
97
|
+
destination = File.join(build_dir, filename)
|
98
|
+
|
99
|
+
if File.directory?(file_path)
|
100
|
+
FileUtils.mkdir_p(destination)
|
101
|
+
else
|
102
|
+
FileUtils.mkdir_p(File.dirname(destination))
|
103
|
+
FileUtils.cp(file_path, destination, :preserve => true)
|
104
|
+
copied += 1
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
in_package_dir do
|
109
|
+
@metadata_files.each do |filename|
|
110
|
+
destination = File.join(build_dir, filename)
|
111
|
+
next unless File.exists?(filename)
|
112
|
+
if File.exists?(destination)
|
113
|
+
raise InvalidPackage, "Package '#{name}' has '#{filename}' file " +
|
114
|
+
"which conflicts with BOSH packaging"
|
115
|
+
end
|
116
|
+
FileUtils.cp(filename, destination, :preserve => true)
|
117
|
+
copied += 1
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
pre_package
|
122
|
+
copied
|
123
|
+
end
|
124
|
+
|
125
|
+
def pre_package
|
126
|
+
pre_packaging_script = File.join(package_dir, "pre_packaging")
|
127
|
+
|
128
|
+
if File.exists?(pre_packaging_script)
|
129
|
+
|
130
|
+
say("Pre-packaging...")
|
131
|
+
FileUtils.cp(pre_packaging_script, build_dir, :preserve => true)
|
132
|
+
|
133
|
+
old_env = ENV
|
134
|
+
|
135
|
+
begin
|
136
|
+
ENV.delete_if { |key, _| key[0, 7] == "BUNDLE_" }
|
137
|
+
if ENV["RUBYOPT"]
|
138
|
+
ENV["RUBYOPT"] = ENV["RUBYOPT"].sub("-rbundler/setup", "")
|
139
|
+
end
|
140
|
+
ENV["BUILD_DIR"] = build_dir
|
141
|
+
in_build_dir do
|
142
|
+
pre_packaging_out = `bash -x pre_packaging 2>&1`
|
143
|
+
pre_packaging_out.split("\n").each do |line|
|
144
|
+
say("> #{line}")
|
145
|
+
end
|
146
|
+
unless $?.exitstatus == 0
|
147
|
+
raise InvalidPackage, "`#{name}' pre-packaging failed"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
ensure
|
152
|
+
ENV.delete("BUILD_DIR")
|
153
|
+
old_env.each { |k, v| ENV[k] = old_env[k] }
|
154
|
+
end
|
155
|
+
|
156
|
+
FileUtils.rm(File.join(build_dir, "pre_packaging"))
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def get_file_path(file)
|
163
|
+
file_path = File.join(@sources_dir, file)
|
164
|
+
if !File.exists?(file_path)
|
165
|
+
file_path = File.join(@blobs_dir, file)
|
166
|
+
unless File.exists?(file_path)
|
167
|
+
raise InvalidPackage, "#{file} cannot be found"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
file_path
|
171
|
+
end
|
172
|
+
|
173
|
+
def make_fingerprint
|
174
|
+
contents = ""
|
175
|
+
|
176
|
+
signatures = files.map do |file|
|
177
|
+
path = get_file_path(file)
|
178
|
+
unless File.directory?(path)
|
179
|
+
file_digest = Digest::SHA1.file(path).hexdigest
|
180
|
+
end
|
181
|
+
|
182
|
+
"%s%s%s" % [file, file_digest, tracked_permissions(path)]
|
183
|
+
end
|
184
|
+
contents << signatures.join("")
|
185
|
+
|
186
|
+
in_package_dir do
|
187
|
+
@metadata_files.each do |file|
|
188
|
+
if File.file?(file)
|
189
|
+
file_digest = Digest::SHA1.file(file).hexdigest
|
190
|
+
contents << "%s%s" % [file, file_digest]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
contents << @dependencies.sort.join(",")
|
196
|
+
|
197
|
+
Digest::SHA1.hexdigest(contents)
|
198
|
+
end
|
199
|
+
|
200
|
+
def resolve_globs
|
201
|
+
glob_map = { :blob => [], :source => [] }
|
202
|
+
blob_list = []
|
203
|
+
source_list = []
|
204
|
+
|
205
|
+
@globs.each do |glob|
|
206
|
+
matching_source = []
|
207
|
+
matching_blob = []
|
208
|
+
|
209
|
+
in_sources_dir do
|
210
|
+
matching_source = Dir.glob(glob, File::FNM_DOTMATCH).reject do |fn|
|
211
|
+
[".", ".."].include?(File.basename(fn))
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
in_blobs_dir do
|
216
|
+
matching_blob = Dir.glob(glob, File::FNM_DOTMATCH).reject do |fn|
|
217
|
+
[".", ".."].include?(File.basename(fn))
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
if matching_blob.size == 0 && matching_source.size ==0
|
222
|
+
raise InvalidPackage, "`#{name}' has a glob that " +
|
223
|
+
"resolves to an empty file list: #{glob}"
|
224
|
+
end
|
225
|
+
|
226
|
+
blob_list << matching_blob
|
227
|
+
source_list << matching_source
|
228
|
+
end
|
229
|
+
glob_map[:blob] = blob_list.flatten.sort
|
230
|
+
glob_map[:source] = source_list.flatten.sort
|
231
|
+
glob_map
|
232
|
+
end
|
233
|
+
|
234
|
+
def in_blobs_dir(&block)
|
235
|
+
# old release does not have 'blob'
|
236
|
+
if File.directory?(@blobs_dir)
|
237
|
+
Dir.chdir(@blobs_dir) { yield }
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def in_sources_dir(&block)
|
242
|
+
Dir.chdir(@sources_dir) { yield }
|
243
|
+
end
|
244
|
+
|
245
|
+
def in_build_dir(&block)
|
246
|
+
Dir.chdir(build_dir) { yield }
|
247
|
+
end
|
248
|
+
|
249
|
+
def in_package_dir(&block)
|
250
|
+
Dir.chdir(package_dir) { yield }
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
end
|