travis_dpl_test 2.0.3.beta.4.ror
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/CHANGELOG.md +172 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +392 -0
- data/Gemfile +32 -0
- data/Gemfile.lock +611 -0
- data/LICENSE +19 -0
- data/README.md +2744 -0
- data/Rakefile +210 -0
- data/bin/dpl +11 -0
- data/config/transliterate.yml +733 -0
- data/dpl.gemspec +23 -0
- data/lib/dpl/assets/atlas/install +19 -0
- data/lib/dpl/assets/convox/install +11 -0
- data/lib/dpl/assets/dpl/README.erb.md +138 -0
- data/lib/dpl/assets/dpl/git_ssh +8 -0
- data/lib/dpl/assets/git/detect_private_key +8 -0
- data/lib/dpl/assets/hephy/filter_log +3 -0
- data/lib/dpl/assets/pypi/install +4 -0
- data/lib/dpl/assets/scalingo/install +6 -0
- data/lib/dpl/cli.rb +100 -0
- data/lib/dpl/ctx/bash.rb +549 -0
- data/lib/dpl/ctx/test.rb +255 -0
- data/lib/dpl/ctx.rb +4 -0
- data/lib/dpl/helper/assets.rb +38 -0
- data/lib/dpl/helper/cmd.rb +169 -0
- data/lib/dpl/helper/config_file.rb +49 -0
- data/lib/dpl/helper/cookbook_site_streaming_uploader.rb +249 -0
- data/lib/dpl/helper/env.rb +92 -0
- data/lib/dpl/helper/github.rb +22 -0
- data/lib/dpl/helper/interpolate.rb +160 -0
- data/lib/dpl/helper/memoize.rb +23 -0
- data/lib/dpl/helper/squiggle.rb +24 -0
- data/lib/dpl/helper/transliterate.rb +13 -0
- data/lib/dpl/helper/wrap.rb +11 -0
- data/lib/dpl/helper/zip.rb +71 -0
- data/lib/dpl/provider/dsl.rb +410 -0
- data/lib/dpl/provider/examples.rb +132 -0
- data/lib/dpl/provider/status.rb +61 -0
- data/lib/dpl/provider.rb +651 -0
- data/lib/dpl/providers/anynines.rb +71 -0
- data/lib/dpl/providers/azure_web_apps.rb +63 -0
- data/lib/dpl/providers/bintray.rb +324 -0
- data/lib/dpl/providers/bluemixcloudfoundry.rb +98 -0
- data/lib/dpl/providers/boxfuse.rb +52 -0
- data/lib/dpl/providers/cargo.rb +32 -0
- data/lib/dpl/providers/chef_supermarket.rb +132 -0
- data/lib/dpl/providers/cloud66.rb +46 -0
- data/lib/dpl/providers/cloudfiles.rb +62 -0
- data/lib/dpl/providers/cloudformation.rb +281 -0
- data/lib/dpl/providers/cloudfoundry.rb +89 -0
- data/lib/dpl/providers/codedeploy.rb +190 -0
- data/lib/dpl/providers/convox.rb +130 -0
- data/lib/dpl/providers/datica.rb +64 -0
- data/lib/dpl/providers/ecr.rb +129 -0
- data/lib/dpl/providers/elasticbeanstalk.rb +207 -0
- data/lib/dpl/providers/engineyard.rb +113 -0
- data/lib/dpl/providers/firebase.rb +45 -0
- data/lib/dpl/providers/flynn.rb +35 -0
- data/lib/dpl/providers/gae.rb +78 -0
- data/lib/dpl/providers/gcs.rb +132 -0
- data/lib/dpl/providers/git_push.rb +273 -0
- data/lib/dpl/providers/gleis.rb +74 -0
- data/lib/dpl/providers/hackage.rb +53 -0
- data/lib/dpl/providers/hephy.rb +107 -0
- data/lib/dpl/providers/heroku/api.rb +123 -0
- data/lib/dpl/providers/heroku/git.rb +54 -0
- data/lib/dpl/providers/heroku.rb +111 -0
- data/lib/dpl/providers/lambda.rb +211 -0
- data/lib/dpl/providers/launchpad.rb +80 -0
- data/lib/dpl/providers/netlify.rb +38 -0
- data/lib/dpl/providers/npm.rb +130 -0
- data/lib/dpl/providers/nuget.rb +41 -0
- data/lib/dpl/providers/openshift.rb +52 -0
- data/lib/dpl/providers/opsworks.rb +146 -0
- data/lib/dpl/providers/packagecloud.rb_ +194 -0
- data/lib/dpl/providers/pages/api.rb +106 -0
- data/lib/dpl/providers/pages/git.rb +262 -0
- data/lib/dpl/providers/pages.rb +18 -0
- data/lib/dpl/providers/puppetforge.rb +50 -0
- data/lib/dpl/providers/pypi.rb +125 -0
- data/lib/dpl/providers/releases.rb +234 -0
- data/lib/dpl/providers/rubygems.rb +97 -0
- data/lib/dpl/providers/s3.rb +251 -0
- data/lib/dpl/providers/scalingo.rb +69 -0
- data/lib/dpl/providers/script.rb +32 -0
- data/lib/dpl/providers/snap.rb +68 -0
- data/lib/dpl/providers/surge.rb +59 -0
- data/lib/dpl/providers/testfairy.rb +101 -0
- data/lib/dpl/providers/transifex.rb +72 -0
- data/lib/dpl/providers.rb +48 -0
- data/lib/dpl/string_ext.rb +23 -0
- data/lib/dpl/support/aws_sdk_patch.rb +26 -0
- data/lib/dpl/support/gems.rb +73 -0
- data/lib/dpl/support/gstore_patch.rb +8 -0
- data/lib/dpl/support/version.rb +84 -0
- data/lib/dpl/version.rb +5 -0
- data/lib/dpl.rb +23 -0
- data/status.json +237 -0
- metadata +161 -0
data/lib/dpl/ctx/bash.rb
ADDED
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'English'
|
|
4
|
+
require 'cl'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'logger'
|
|
7
|
+
require 'open3'
|
|
8
|
+
require 'tmpdir'
|
|
9
|
+
require 'securerandom'
|
|
10
|
+
require 'dpl/support/version'
|
|
11
|
+
|
|
12
|
+
module Dpl
|
|
13
|
+
module Ctx
|
|
14
|
+
class Bash < Cl::Ctx
|
|
15
|
+
include FileUtils
|
|
16
|
+
|
|
17
|
+
attr_accessor :folds, :stdout, :stderr, :last_out, :last_err
|
|
18
|
+
|
|
19
|
+
def initialize(stdout = $stdout, stderr = $stderr)
|
|
20
|
+
@stdout = stdout
|
|
21
|
+
@stderr = stderr
|
|
22
|
+
@folds = 0
|
|
23
|
+
super('dpl', abort: false)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Folds any log output from the given block
|
|
27
|
+
#
|
|
28
|
+
# Starts a log fold with the given fold message, calls the block, and
|
|
29
|
+
# closes the fold.
|
|
30
|
+
#
|
|
31
|
+
# @param msg [String] the message that will appear on the log fold
|
|
32
|
+
def fold(msg)
|
|
33
|
+
self.folds += 1
|
|
34
|
+
print "travis_fold:start:dpl.#{folds}\r\e[K"
|
|
35
|
+
time do
|
|
36
|
+
info "\e[33m#{msg}\e[0m"
|
|
37
|
+
yield
|
|
38
|
+
end
|
|
39
|
+
ensure
|
|
40
|
+
print "\ntravis_fold:end:dpl.#{folds}\r\e[K"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Times the given block
|
|
44
|
+
#
|
|
45
|
+
# Starts a travis time log tag, calls the block, and closes the tag,
|
|
46
|
+
# including timing information. This makes a timing badge appear on
|
|
47
|
+
# the surrounding log fold.
|
|
48
|
+
def time
|
|
49
|
+
id = SecureRandom.hex[0, 8]
|
|
50
|
+
start = Time.now.to_i * (10**9)
|
|
51
|
+
print "travis_time:start:#{id}\r\e[K"
|
|
52
|
+
yield
|
|
53
|
+
ensure
|
|
54
|
+
finish = Time.now.to_i * (10**9)
|
|
55
|
+
duration = finish - start
|
|
56
|
+
print "\ntravis_time:end:#{id}:start=#{start},finish=#{finish},duration=#{duration}\r\e[K"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Outputs a deprecation warning for a given deprecated option key to stderr.
|
|
60
|
+
#
|
|
61
|
+
# @param key [Symbol] the deprecated option key
|
|
62
|
+
# @param msg [String or Symbol] the deprecation message. if given a Symbol this will be wrapped into the string "Please use #{symbol}".
|
|
63
|
+
def deprecate_opt(key, msg)
|
|
64
|
+
msg = "please use #{msg}" if msg.is_a?(Symbol)
|
|
65
|
+
warn "Deprecated option #{key} used (#{msg})."
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Outputs an info level message to stdout.
|
|
69
|
+
def info(*msgs)
|
|
70
|
+
stdout.puts(*msgs)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Prints an info level message to stdout.
|
|
74
|
+
#
|
|
75
|
+
# This method does not append a newline character to the given message,
|
|
76
|
+
# which usually is not the desired behaviour. The method is intended to
|
|
77
|
+
# be used if an initial, partial message is supposed to be printed, which
|
|
78
|
+
# will be completed later (using the method `info`).
|
|
79
|
+
#
|
|
80
|
+
# For example:
|
|
81
|
+
#
|
|
82
|
+
# print 'Starting a long running task ...'
|
|
83
|
+
# run_long_running_task
|
|
84
|
+
# info 'done.'
|
|
85
|
+
def print(chars)
|
|
86
|
+
stdout.print(chars)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Outputs an warning message to stderr
|
|
90
|
+
#
|
|
91
|
+
# This method is intended to be used for warning messages that are
|
|
92
|
+
# supposed to show up in the build log, but do not qualify as errors that
|
|
93
|
+
# would abort the deployment process. The warning will be highlighted as
|
|
94
|
+
# yellow text. Use sparingly.
|
|
95
|
+
def warn(*msgs)
|
|
96
|
+
msgs = msgs.join("\n").lines
|
|
97
|
+
msgs.each { |msg| stderr.puts("\e[33;1m#{msg}\e[0m") }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Raises an exception, halting the deployment process.
|
|
101
|
+
#
|
|
102
|
+
# The calling executable `bin/dpl` will catch the exception, and abort
|
|
103
|
+
# the ruby process with the given error message.
|
|
104
|
+
#
|
|
105
|
+
# This method is intended to be used for all error conditions that
|
|
106
|
+
# require the deployment process to be aborted.
|
|
107
|
+
def error(message)
|
|
108
|
+
raise Error, message
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Returns a logger
|
|
112
|
+
#
|
|
113
|
+
# Returns a logger instance, with the given log level set. This can be
|
|
114
|
+
# used to pass to clients that accept a Ruby logger, such as Faraday,
|
|
115
|
+
# for debugging purposes.
|
|
116
|
+
#
|
|
117
|
+
# Use with care.
|
|
118
|
+
#
|
|
119
|
+
# @param level [Symbol] the Ruby logger log level
|
|
120
|
+
def logger(level = :info)
|
|
121
|
+
logger = Logger.new(stderr)
|
|
122
|
+
logger.level = Logger.const_get(level.to_s.upcase)
|
|
123
|
+
logger
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def validate_runtimes(runtimes)
|
|
127
|
+
failed = runtimes.reject(&method(:validate_runtime))
|
|
128
|
+
failed = failed.map { |name, versions| "#{name} (#{versions.join(', ')})" }
|
|
129
|
+
error "Failed validating runtimes: #{failed.join(', ')}" if failed.any?
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def validate_runtime(args)
|
|
133
|
+
name, required = *args
|
|
134
|
+
info "Validating required runtime version: #{name} (#{required.join(', ')})"
|
|
135
|
+
version = name == :node_js ? node_version : python_version
|
|
136
|
+
required.all? { |required| Version.new(version).satisfies?(required) }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def apts_get(packages)
|
|
140
|
+
packages = packages.reject { |name, cmd = name| which(cmd || name) }
|
|
141
|
+
return unless packages.any?
|
|
142
|
+
|
|
143
|
+
apt_update
|
|
144
|
+
packages.each { |package, cmd| apt_get(package, cmd || package, update: false) }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Installs an APT package
|
|
148
|
+
#
|
|
149
|
+
# Installs the APT package with the given name, unless the command is already
|
|
150
|
+
# available (as determined by `which [cmd]`.
|
|
151
|
+
#
|
|
152
|
+
# @param package [String] the package name
|
|
153
|
+
# @param cmd [String] an executable installed by the package, defaults to the package name
|
|
154
|
+
def apt_get(package, cmd = package, opts = {})
|
|
155
|
+
return if which(cmd)
|
|
156
|
+
|
|
157
|
+
apt_update unless opts[:update].is_a?(FalseClass)
|
|
158
|
+
shell "sudo apt-get -qq install #{package}", retry: true
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def apt_update
|
|
162
|
+
shell 'sudo apt-get update', retry: true
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Requires source files from Ruby gems, installing them on demand if required
|
|
166
|
+
#
|
|
167
|
+
# Installs the Ruby gems with the given version, if not already installed, and
|
|
168
|
+
# requires the specified source files from that gem.
|
|
169
|
+
#
|
|
170
|
+
# This happens using the bundler/inline API.
|
|
171
|
+
#
|
|
172
|
+
# @param gems [Array<String, String, Hash>] Array of gem requirements: gem name, version, and options (`require`: A single path or a list of paths to source files to require from this Ruby gem)
|
|
173
|
+
#
|
|
174
|
+
# @see https://bundler.io/v2.0/guides/bundler_in_a_single_file_ruby_script.html
|
|
175
|
+
def gems_require(gems)
|
|
176
|
+
# A local Gemfile.lock might interfer with bundler/inline, even though
|
|
177
|
+
# it should not. Switching to a temporary dir fixes this.
|
|
178
|
+
Dir.chdir(tmp_dir) do
|
|
179
|
+
require 'bundler/inline'
|
|
180
|
+
info "Installing gem dependencies: #{gems.map { |name, version, _| "#{name} #{"(#{version})" if version}".strip }.join(', ')}"
|
|
181
|
+
env = ENV.to_h
|
|
182
|
+
# Bundler.reset!
|
|
183
|
+
# Gem.loaded_specs.clear
|
|
184
|
+
gemfile do
|
|
185
|
+
source 'https://rubygems.org'
|
|
186
|
+
gems.each { |g| gem(*g) }
|
|
187
|
+
end
|
|
188
|
+
# https://github.com/bundler/bundler/issues/7181
|
|
189
|
+
ENV.replace(env)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Installs an NPM package
|
|
194
|
+
#
|
|
195
|
+
# Installs the NPM package with the given name, unless the command is already
|
|
196
|
+
# available (as determined by `which [cmd]`.
|
|
197
|
+
#
|
|
198
|
+
# @param package [String] the package name
|
|
199
|
+
# @param cmd [String] an executable installed by the package, defaults to the package name
|
|
200
|
+
def npm_install(package, cmd = package)
|
|
201
|
+
shell "npm install -g #{package}", retry: true unless which(cmd)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Installs a Python package
|
|
205
|
+
#
|
|
206
|
+
# Installs the Python package with the given name. A previously installed
|
|
207
|
+
# package is uninstalled before that, but only if `version` was given.
|
|
208
|
+
#
|
|
209
|
+
# @param package [String] Package name (required).
|
|
210
|
+
# @param cmd [String] Executable command installed by that package (optional, defaults to the package name).
|
|
211
|
+
# @param version [String] Package version (optional).
|
|
212
|
+
def pip_install(package, cmd = package, version = nil)
|
|
213
|
+
ENV['VIRTUAL_ENV'] = File.expand_path('~/dpl_venv')
|
|
214
|
+
ENV['PATH'] = File.expand_path("~/dpl_venv/bin:#{ENV['PATH']}")
|
|
215
|
+
shell 'virtualenv --no-site-packages ~/dpl_venv', echo: true
|
|
216
|
+
shell 'pip install urllib3[secure]'
|
|
217
|
+
cmd = "pip install #{package}"
|
|
218
|
+
cmd << pip_version(version) if version
|
|
219
|
+
shell cmd, retry: true
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def pip_version(version)
|
|
223
|
+
version =~ /^\d+/ ? "==#{version}" : version
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Generates an SSH key
|
|
227
|
+
#
|
|
228
|
+
# @param name [String] the key name
|
|
229
|
+
# @param file [String] path to the key file
|
|
230
|
+
def ssh_keygen(name, file)
|
|
231
|
+
shell %(ssh-keygen -t rsa -N "" -C #{name} -f #{file})
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Runs a single shell command
|
|
235
|
+
#
|
|
236
|
+
# This the is the central point of executing any shell commands. It allows two
|
|
237
|
+
# strategies for running commands in subprocesses:
|
|
238
|
+
#
|
|
239
|
+
# * Using [Kernel#system](https://ruby-doc.org/core-2.6.3/Kernel.html#method-i-system)
|
|
240
|
+
# which is the default strategy, and should be used when possible. The stdout
|
|
241
|
+
# and stderr streams will not be captured, but streamed directly to the parent
|
|
242
|
+
# process (so any output on these streams appears in the build log as soon as
|
|
243
|
+
# possible).
|
|
244
|
+
#
|
|
245
|
+
# * Using [Open3.capture3](https://ruby-doc.org/stdlib-2.6.3/libdoc/open3/rdoc/Open3.html#method-c-capture3)
|
|
246
|
+
# which captures both stdout and stderr, and does not automatically output it
|
|
247
|
+
# to the build log. Implementors can choose to display it after the shell command
|
|
248
|
+
# has completed, using the `%{out}` and `%{err}` interpolation variables. Use
|
|
249
|
+
# sparingly.
|
|
250
|
+
#
|
|
251
|
+
# The method accepts the following options:
|
|
252
|
+
#
|
|
253
|
+
# @param cmd [String] the shell command to execute
|
|
254
|
+
# @param opts [Hash] options
|
|
255
|
+
#
|
|
256
|
+
# @option opts [Boolean] :echo output the command to stdout before running it
|
|
257
|
+
# @option opts [Boolean] :silence silence all log output by redirecting stdout and stderr to `/dev/null`
|
|
258
|
+
# @option opts [Boolean] :capture use `Open3.capture3` to capture stdout and stderr
|
|
259
|
+
# @option opts [String] :python wrap the command into Bash code that enforces the given Python version to be used
|
|
260
|
+
# @option opts [String] :retry retries the command 2 more times if it fails
|
|
261
|
+
# @option opts [String] :info message to output to stdout if the command has exited with the exit code 0 (supports the interpolation variable `${out}` for stdout in case it was captured.
|
|
262
|
+
# @option opts [String] :assert error message to be raised if the command has exited with a non-zero exit code (supports the interpolation variable `${out}` for stdout in case it was captured.
|
|
263
|
+
#
|
|
264
|
+
# @return [Boolean] whether or not the command was successful (has exited with the exit code 0)
|
|
265
|
+
def shell(cmd, opts = {})
|
|
266
|
+
cmd = Cmd.new(nil, cmd, opts) if cmd.is_a?(String)
|
|
267
|
+
info cmd.msg if cmd.msg?
|
|
268
|
+
info cmd.echo if cmd.echo?
|
|
269
|
+
|
|
270
|
+
@last_out, @last_err, @last_status = retrying(cmd.retry ? 2 : 0) do
|
|
271
|
+
send(cmd.capture? ? :open3 : :system, cmd.cmd, cmd.opts)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
info format(cmd.success, out: last_out) if success? && cmd.success?
|
|
275
|
+
error format(cmd.error, err: last_err) if failed? && cmd.assert?
|
|
276
|
+
|
|
277
|
+
success? && cmd.capture? ? last_out.chomp : @last_status
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def retrying(max, tries = 0, status = false)
|
|
281
|
+
loop do
|
|
282
|
+
tries += 1
|
|
283
|
+
out, err, status = yield
|
|
284
|
+
return [out, err, status] if status || tries > max
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Runs a shell command and captures stdout, stderr, and the exit status
|
|
289
|
+
#
|
|
290
|
+
# Runs the given command using `Open3.capture3`, which will capture the
|
|
291
|
+
# stdout and stderr streams, as well as the exit status. I.e. this will
|
|
292
|
+
# *not* stream log output in real time, but capture the output, and allow
|
|
293
|
+
# implementors to display it later (using the `%{out}` and `%{err}`
|
|
294
|
+
# interpolation variables.
|
|
295
|
+
#
|
|
296
|
+
# Use sparingly.
|
|
297
|
+
#
|
|
298
|
+
# @option chdir [String] directory temporarily to change to before running the command
|
|
299
|
+
def open3(cmd, opts)
|
|
300
|
+
opts = [opts[:chdir] ? only(opts, :chdir) : nil].compact
|
|
301
|
+
out, err, status = Open3.capture3(cmd, *opts)
|
|
302
|
+
[out, err, status.success?]
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Runs a shell command, streaming any stdout or stderr output, and
|
|
306
|
+
# returning the exit status
|
|
307
|
+
#
|
|
308
|
+
# This is the default method for executing shell commands. The stdout and
|
|
309
|
+
# stderr will not be captured, but streamed directly to the parent process.
|
|
310
|
+
#
|
|
311
|
+
# @option chdir [String] directory temporarily to change to before running the command
|
|
312
|
+
def system(cmd, opts = {})
|
|
313
|
+
opts = [opts[:chdir] ? only(opts, :chdir) : nil].compact
|
|
314
|
+
Kernel.system(cmd, *opts)
|
|
315
|
+
['', '', last_process_status]
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Whether or not the last executed shell command was successful.
|
|
319
|
+
def success?
|
|
320
|
+
!!@last_status
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# Whether or not the last executed shell command has failed.
|
|
324
|
+
def failed?
|
|
325
|
+
!success?
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Returns the last child process' exit status
|
|
329
|
+
#
|
|
330
|
+
# Internal, and not to be used by implementors. $? is a read-only
|
|
331
|
+
# variable, so we use a method that we can stub during tests.
|
|
332
|
+
def last_process_status
|
|
333
|
+
$CHILD_STATUS.success?
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Whether or not the current Ruby process runs with superuser priviledges.
|
|
337
|
+
def sudo?
|
|
338
|
+
Process::UID.eid.zero?
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Returns current repository name
|
|
342
|
+
#
|
|
343
|
+
# Uses the environment variable `TRAVIS_REPO_SLUG` if present, or the
|
|
344
|
+
# current directory's base name.
|
|
345
|
+
#
|
|
346
|
+
# Note that this might return an unexpected string outside of the context
|
|
347
|
+
# of Travis CI build environments if the method is called at a time when
|
|
348
|
+
# the current working directory has changed.
|
|
349
|
+
def repo_name
|
|
350
|
+
ENV['TRAVIS_REPO_SLUG'] ? ENV['TRAVIS_REPO_SLUG'].split('/').last : File.basename(Dir.pwd)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# Returns current repository slug
|
|
354
|
+
#
|
|
355
|
+
# Uses the environment variable `TRAVIS_REPO_SLUG` if present, or the
|
|
356
|
+
# last two segmens of the current working directory's path.
|
|
357
|
+
#
|
|
358
|
+
# Note that this might return an unexpected string outside of the context
|
|
359
|
+
# of Travis CI build environments if the method is called at a time when
|
|
360
|
+
# the current working directory has changed.
|
|
361
|
+
def repo_slug
|
|
362
|
+
ENV['TRAVIS_REPO_SLUG'] || Dir.pwd.split('/')[-2, 2].join('/')
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Returns the current build directory
|
|
366
|
+
#
|
|
367
|
+
# Uses the environment variable `TRAVIS_REPO_SLUG` if present, and
|
|
368
|
+
# defaults to `.` otherwise.
|
|
369
|
+
#
|
|
370
|
+
# Note that this might return an unexpected string outside of the context
|
|
371
|
+
# of Travis CI build environments if the method is called at a time when
|
|
372
|
+
# the current working directory has changed.
|
|
373
|
+
def build_dir
|
|
374
|
+
ENV['TRAVIS_BUILD_DIR'] || '.'
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
# Returns the current build number
|
|
378
|
+
#
|
|
379
|
+
# Returns the value of the environment variable `TRAVIS_BUILD_NUMBER` if
|
|
380
|
+
# present.
|
|
381
|
+
def build_number
|
|
382
|
+
ENV['TRAVIS_BUILD_NUMBER'] || raise('TRAVIS_BUILD_NUMBER not set')
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Returns the encoding of the given file, as determined by `file`.
|
|
386
|
+
def encoding(path)
|
|
387
|
+
case `file '#{path}'`
|
|
388
|
+
when /gzip compressed/
|
|
389
|
+
'gzip'
|
|
390
|
+
when /compress'd/
|
|
391
|
+
'compress'
|
|
392
|
+
when /text/
|
|
393
|
+
'text'
|
|
394
|
+
when /data/
|
|
395
|
+
# shrugs?
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# Returns the current branch name
|
|
400
|
+
def git_branch
|
|
401
|
+
ENV['TRAVIS_BRANCH'] || git_rev_parse('HEAD')
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
# Returns the message of the commit `git_sha`.
|
|
405
|
+
def git_commit_msg
|
|
406
|
+
`git log #{git_sha} -n 1 --pretty=%B`.chomp
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# Returns the committer name of the commit `git_sha`.
|
|
410
|
+
def git_author_name
|
|
411
|
+
`git log #{git_sha} -n 1 --pretty=%an`.chomp
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
# Returns the comitter email of the commit `git_sha`.
|
|
415
|
+
def git_author_email
|
|
416
|
+
`git log #{git_sha} -n 1 --pretty=%ae`.chomp
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
# Whether or not the git working directory is dirty or has new or deleted files
|
|
420
|
+
def git_dirty?
|
|
421
|
+
!`git status --short`.chomp.empty?
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
# Returns the output of `git log`, using the given args.
|
|
425
|
+
def git_log(args)
|
|
426
|
+
`git log #{args}`.chomp
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
# Returns the Git log, separated by NULs
|
|
430
|
+
#
|
|
431
|
+
# Returns the output of `git ls-files -z`, which separates log entries by
|
|
432
|
+
# NULs, rather than newline characters.
|
|
433
|
+
def git_ls_files
|
|
434
|
+
`git ls-files -z`.split("\x0")
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
# Returns true if the given ref exists remotely
|
|
438
|
+
def git_ls_remote?(url, ref)
|
|
439
|
+
Kernel.system("git ls-remote --exit-code #{url} #{ref} > /dev/null 2>&1")
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
# Returns known Git remote URLs
|
|
443
|
+
def git_remote_urls
|
|
444
|
+
`git remote -v`.scan(/\t[^\s]+\s/).map(&:strip).uniq
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# Returns the sha for the given Git ref
|
|
448
|
+
def git_rev_parse(ref)
|
|
449
|
+
`git rev-parse #{ref}`.strip
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
# Returns the latest tag name, if any
|
|
453
|
+
def git_tag
|
|
454
|
+
`git describe --tags --exact-match 2>/dev/null`.chomp
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
# Returns the current commit sha
|
|
458
|
+
def git_sha
|
|
459
|
+
ENV['TRAVIS_COMMIT'] || `git rev-parse HEAD`.chomp
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
# Returns the local machine's hostname
|
|
463
|
+
def machine_name
|
|
464
|
+
`hostname`.strip
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# Returns the current Node.js version
|
|
468
|
+
def node_version
|
|
469
|
+
`node -v`.sub(/^v/, '').chomp
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
# Returns the current NPM version
|
|
473
|
+
def npm_version
|
|
474
|
+
`npm --version`
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
# Returns the current Node.js version
|
|
478
|
+
def python_version
|
|
479
|
+
`python --version 2>&1`.sub(/^Python /, '').chomp
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
# Returns true or false depending if the given command can be found
|
|
483
|
+
def which(cmd)
|
|
484
|
+
!`which #{cmd}`.chomp.empty? if cmd
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
# Returns a unique temporary directory name
|
|
488
|
+
def tmp_dir
|
|
489
|
+
@tmp_dir ||= Dir.mktmpdir
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# Returns the size of the given file path
|
|
493
|
+
def file_size(path)
|
|
494
|
+
File.size(path)
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
def move_files(paths)
|
|
498
|
+
paths.each do |path|
|
|
499
|
+
target = "#{tmp_dir}/#{File.basename(path)}"
|
|
500
|
+
mv(path, target) if File.exist?(path)
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def unmove_files(paths)
|
|
505
|
+
paths.each do |path|
|
|
506
|
+
source = "#{tmp_dir}/#{File.basename(path)}"
|
|
507
|
+
mv(source, path) if File.exist?(source)
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
def mv(src, dest)
|
|
512
|
+
Kernel.system("sudo mv #{src} #{dest} 2> /dev/null")
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# Writes the given content to the given file path
|
|
516
|
+
def write_file(path, content, chmod = nil)
|
|
517
|
+
path = File.expand_path(path)
|
|
518
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
519
|
+
File.open(path, 'w+') { |f| f.write(content) }
|
|
520
|
+
FileUtils.chmod(chmod, path) if chmod
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
# Writes the given machine, login, and password to ~/.netrc
|
|
524
|
+
def write_netrc(machine, login, password)
|
|
525
|
+
require 'netrc'
|
|
526
|
+
netrc = Netrc.read
|
|
527
|
+
netrc[machine] = [login, password]
|
|
528
|
+
netrc.save
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
def sleep(sec)
|
|
532
|
+
Kernel.sleep(sec)
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
def tty?
|
|
536
|
+
$stdout.isatty
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
# Returns a copy of the given hash, reduced to the given keys
|
|
540
|
+
def only(hash, *keys)
|
|
541
|
+
hash.select { |key, _| keys.include?(key) }.to_h
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def test?
|
|
545
|
+
false
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
end
|