travis_dpl_test 2.0.3.beta.4.ror
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,410 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dpl/helper/squiggle'
|
4
|
+
require 'dpl/helper/wrap'
|
5
|
+
require 'dpl/provider/status'
|
6
|
+
|
7
|
+
# TODO: figure out how to allow adding domain specific behavior like this to Cl
|
8
|
+
class Cl::Opt
|
9
|
+
OPTS << :interpolate
|
10
|
+
|
11
|
+
def interpolate?
|
12
|
+
opts[:interpolate]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Dpl
|
17
|
+
class Provider < Cl::Cmd
|
18
|
+
# DSL available on the provider's class body.
|
19
|
+
#
|
20
|
+
# Use this to declare various features, requirements, and attributes that
|
21
|
+
# apply to your provider.
|
22
|
+
module Dsl
|
23
|
+
include Squiggle
|
24
|
+
|
25
|
+
# Declare the full name of the provider. Required if the proper provider
|
26
|
+
# name does not match the provider's class name.
|
27
|
+
#
|
28
|
+
# @param name [String] The provider's full name
|
29
|
+
# @return The previously declared full name if no argument is given
|
30
|
+
def full_name(name = nil)
|
31
|
+
name ? @full_name = name : @full_name || self.name.split('::').last
|
32
|
+
end
|
33
|
+
|
34
|
+
# Summary of the provider's functionality.
|
35
|
+
def summary(summary = nil)
|
36
|
+
summary ? super : @summary || "#{full_name} deployment provider"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Summary of the provider's functionality.
|
40
|
+
def description(str = nil)
|
41
|
+
str = str.strip if str
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
# Set or read the provider's maturity status with an optional message
|
46
|
+
def status(status = nil, msg = nil)
|
47
|
+
status ? @status = Status.new(self, status, msg) : @status
|
48
|
+
end
|
49
|
+
|
50
|
+
# Declare additional variables available for interpolation.
|
51
|
+
#
|
52
|
+
# Interpolating strings, when these exposed to the user, should safelist
|
53
|
+
# which variables are available. Options declared on a provider are
|
54
|
+
# always available, except if they are flags, arrays, internal, or
|
55
|
+
# secrets. This method can be used to allow additional variables, e.g.
|
56
|
+
# from the git context.
|
57
|
+
def vars(*vars)
|
58
|
+
return self.vars.concat(vars) if vars.any?
|
59
|
+
return @vars if instance_variable_defined?(:@vars)
|
60
|
+
|
61
|
+
vars = superclass.respond_to?(:vars) ? superclass.vars : []
|
62
|
+
reject = %i[flag array internal interpolate secret]
|
63
|
+
opts = reject.inject(self.opts) { |options, attr| options.reject(&:"#{attr}?") }
|
64
|
+
@vars = vars.dup.concat(opts.map(&:name)).uniq.sort - [:strategy]
|
65
|
+
end
|
66
|
+
|
67
|
+
# @!method env
|
68
|
+
# Declare an environment variable prefix to accept env vars as options
|
69
|
+
#
|
70
|
+
# This method is defined in `Env::ClassMethods`.
|
71
|
+
#
|
72
|
+
# Declares an environment variable prefix that imports environment
|
73
|
+
# variables into `opts` if they match declared options.
|
74
|
+
#
|
75
|
+
# For example, with the following declaration on the class body:
|
76
|
+
#
|
77
|
+
# ```ruby
|
78
|
+
# env :aws
|
79
|
+
# opt '--access_key_id ID'
|
80
|
+
# ```
|
81
|
+
#
|
82
|
+
# if the environment variable `AWS_ACCESS_KEY_ID` is set then the option
|
83
|
+
# `opts[:access_key_id]` will default to the value given on that
|
84
|
+
# variable (i.e. it could still be overwritten by the user by passing
|
85
|
+
# the `--access_key_id` option).
|
86
|
+
|
87
|
+
# @!method opt
|
88
|
+
# Declare command line options that the provider supports.
|
89
|
+
#
|
90
|
+
# This method is inherited from the base class `Cl::Cmd` which is defined
|
91
|
+
# in the Rubygem `Cl`. See the gem's documentation for details on how
|
92
|
+
# to declare command line options.
|
93
|
+
#
|
94
|
+
# @see https://github.com/svenfuchs/cl
|
95
|
+
|
96
|
+
def path(path)
|
97
|
+
ENV['PATH'] = "#{File.expand_path(path)}:#{ENV['PATH']}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def move(*paths)
|
101
|
+
paths.any? ? @move = paths : @move ||= []
|
102
|
+
end
|
103
|
+
|
104
|
+
def node_js(*requirements)
|
105
|
+
runtimes(:node_js, requirements)
|
106
|
+
end
|
107
|
+
|
108
|
+
def python(*requirements)
|
109
|
+
runtimes(:python, requirements)
|
110
|
+
end
|
111
|
+
|
112
|
+
def runtimes(name = nil, requirements = nil)
|
113
|
+
return @runtimes ||= [] unless name
|
114
|
+
|
115
|
+
runtimes << [name, requirements]
|
116
|
+
end
|
117
|
+
|
118
|
+
# Declare APT packages the provider depends on. These will be installed
|
119
|
+
# during the `before_install` stage using `apt-get install`, unless the
|
120
|
+
# given cmd is already available according to `which [cmd]`.
|
121
|
+
#
|
122
|
+
# @param package [String] Package name (required).
|
123
|
+
# @param cmd [String] Executable command installed by that package (optional, defaults to the package name).
|
124
|
+
#
|
125
|
+
# @return Previously declared apt packages if no arguments were given.
|
126
|
+
def apt(package = nil, cmd = nil)
|
127
|
+
return apt << [package, cmd].compact if package
|
128
|
+
|
129
|
+
@apt ||= self == Provider ? [] : superclass.apt.dup
|
130
|
+
end
|
131
|
+
|
132
|
+
# Whether or not the provider depends on any apt packages.
|
133
|
+
def apt?
|
134
|
+
apt.any?
|
135
|
+
end
|
136
|
+
|
137
|
+
# Declare additional paths to Ruby gem source code that this provider
|
138
|
+
# requires.
|
139
|
+
#
|
140
|
+
# These gems will be installed, and files required at runtime, during the
|
141
|
+
# `before_init` stage (not at install time, and/or load time), unless they
|
142
|
+
# are already installed.
|
143
|
+
#
|
144
|
+
# @param name [String] Ruby gem name (required)
|
145
|
+
# @param version [String] Ruby gem version (required)
|
146
|
+
# @param opts [Hash] options
|
147
|
+
# @option opts [Array<String>, String] :require A single path or a list of paths to source files to require from this Ruby gem. If not given the name of the gem will be assumed to be the path to be required.
|
148
|
+
#
|
149
|
+
# @return Previously declared gems if no arguments were given
|
150
|
+
def gem(name = nil, version = nil, opts = {})
|
151
|
+
return gem << [name, version, opts] if name
|
152
|
+
|
153
|
+
@gem ||= self == Provider ? [] : superclass.gem.dup
|
154
|
+
end
|
155
|
+
|
156
|
+
def gem?
|
157
|
+
gem.any?
|
158
|
+
end
|
159
|
+
|
160
|
+
# Declare NPM packages the provider depends on. These will be installed
|
161
|
+
# during the `before_install` stage using `npm install -g`, unless the
|
162
|
+
# given cmd is already available according to `which [cmd]`.
|
163
|
+
#
|
164
|
+
# @param package [String] Package name (required).
|
165
|
+
# @param cmd [String] Executable command installed by that package (optional, defaults to the package name).
|
166
|
+
#
|
167
|
+
# @return Previously declared NPM packages if no arguments are given.
|
168
|
+
def npm(package = nil, cmd = nil)
|
169
|
+
return npm << [package, cmd].compact if package
|
170
|
+
|
171
|
+
@npm ||= self == Provider ? [] : superclass.npm.dup
|
172
|
+
end
|
173
|
+
|
174
|
+
# Whether or not the provider depends on any NPM packages.
|
175
|
+
def npm?
|
176
|
+
npm.any?
|
177
|
+
end
|
178
|
+
|
179
|
+
# Declare Python packages the provider depends on. These will be installed
|
180
|
+
# during the `before_install` stage using `pip install --user`. A previously
|
181
|
+
# installed package is uninstalled before that, but only if `version` was
|
182
|
+
# given.
|
183
|
+
#
|
184
|
+
# @param package [String] Package name (required).
|
185
|
+
# @param cmd [String] Executable command installed by that package (optional, defaults to the package name).
|
186
|
+
# @param version [String] Package version (optional).
|
187
|
+
#
|
188
|
+
# @return Previously declared Python packages if no arguments are given.
|
189
|
+
def pip(package = nil, cmd = nil, version = nil)
|
190
|
+
return pip << [package, cmd, version].compact if package
|
191
|
+
|
192
|
+
@pip ||= self == Provider ? [] : superclass.pip.dup
|
193
|
+
end
|
194
|
+
|
195
|
+
# Whether or not the provider depends on any Python packages.
|
196
|
+
def pip?
|
197
|
+
pip.any?
|
198
|
+
end
|
199
|
+
|
200
|
+
# Declare shell commands used by the provider.
|
201
|
+
#
|
202
|
+
# This exists so shell commands used can be separated from the
|
203
|
+
# implementation that runs them. This is useful in order to easily get an
|
204
|
+
# overview of all shell commands used by a provider on one hand, and in
|
205
|
+
# order to keep the implementation code focussed on the logic and
|
206
|
+
# functionality it provides, rather than the details of (potentially long
|
207
|
+
# winded) shell commands.
|
208
|
+
#
|
209
|
+
# For example, a shell command declared on the class body like so:
|
210
|
+
#
|
211
|
+
# ```ruby
|
212
|
+
# cmds git_push: 'git push -f %{target}'
|
213
|
+
# ```
|
214
|
+
#
|
215
|
+
# can be used in the deploy stage like so:
|
216
|
+
#
|
217
|
+
# ```ruby
|
218
|
+
# def deploy
|
219
|
+
# shell :git_push
|
220
|
+
# end
|
221
|
+
# ```
|
222
|
+
#
|
223
|
+
# The variable `%{target}` will be interpolated by calling the method
|
224
|
+
# `target` on the provider instance, so it will expect that method to
|
225
|
+
# exist.
|
226
|
+
#
|
227
|
+
# @param cmds [Hash] Commands to declare.
|
228
|
+
# @return Previously declared cmds if no argument is given.
|
229
|
+
#
|
230
|
+
# @see Dpl::Ctx::Bash#shell Ctx::Bash#shell for more details on how to call shell
|
231
|
+
# commands.
|
232
|
+
def cmds(cmds = nil)
|
233
|
+
return self.cmds.update(cmds) if cmds
|
234
|
+
|
235
|
+
@cmds ||= self == Provider ? {} : superclass.cmds.dup
|
236
|
+
end
|
237
|
+
|
238
|
+
# Declare error messages that are raised if a shell command fails.
|
239
|
+
#
|
240
|
+
# This exists so error messages can be separated from the implementation
|
241
|
+
# that uses them. This is useful in order to easily get an overview of
|
242
|
+
# all error messages used by a provider on one hand, and in order to keep
|
243
|
+
# the implementation code focussed on the logic and functionality it
|
244
|
+
# provides, rather than the details of (potentially long winded) error
|
245
|
+
# message strings.
|
246
|
+
#
|
247
|
+
# The method `shell` will raise an error if the given shell command fails
|
248
|
+
# (returns a non-zero exit code) unless it is called with the option
|
249
|
+
# `assert: false`. The error message declared using `errs` will be used
|
250
|
+
# to raise with the eror.
|
251
|
+
#
|
252
|
+
# For example, an error message declared on the class body like so:
|
253
|
+
#
|
254
|
+
# ```ruby
|
255
|
+
# errs git_push: 'Failed to push to %{target}'
|
256
|
+
# ```
|
257
|
+
#
|
258
|
+
# will be included to the raised error if the given command has failed:
|
259
|
+
#
|
260
|
+
# ```ruby
|
261
|
+
# def deploy
|
262
|
+
# shell :git_push
|
263
|
+
# end
|
264
|
+
# ```
|
265
|
+
#
|
266
|
+
# The variable `%{target}` will be interpolated by calling the method
|
267
|
+
# `target` on the provider instance, so it will expect that method to
|
268
|
+
# exist.
|
269
|
+
#
|
270
|
+
# @param errs [Hash] Error messages to declare.
|
271
|
+
# @return Previously declared errs if no argument is given.
|
272
|
+
#
|
273
|
+
# See Dpl::Ctx::Bash#shell for more details on how to call shell
|
274
|
+
# commands.
|
275
|
+
def errs(errs = nil)
|
276
|
+
return self.errs.update(errs) if errs
|
277
|
+
|
278
|
+
@errs ||= self == Provider ? {} : superclass.errs.dup
|
279
|
+
end
|
280
|
+
|
281
|
+
# Declare other messages, such as info level log output, warnings, or
|
282
|
+
# custom strings, such as commit messages or descriptions.
|
283
|
+
#
|
284
|
+
# This exists so various messages can be separated from the
|
285
|
+
# implementation that uses them. This is useful in order to easily get an
|
286
|
+
# overview of all error messages used by a provider on one hand, and in
|
287
|
+
# order to keep the implementation code focussed on the logic and
|
288
|
+
# functionality it provides, rather than the details of (potentially long
|
289
|
+
# winded) message strings.
|
290
|
+
#
|
291
|
+
# For example, a message declared on the class body like so:
|
292
|
+
#
|
293
|
+
# ```ruby
|
294
|
+
# msgs login: 'Logging in to the service %{full_name}'
|
295
|
+
# ```
|
296
|
+
#
|
297
|
+
# could be used by the implementation like so:
|
298
|
+
#
|
299
|
+
# ```ruby
|
300
|
+
# def login
|
301
|
+
# info :login
|
302
|
+
# end
|
303
|
+
# ```
|
304
|
+
#
|
305
|
+
# The variable `%{full_name}` will be interpolated by calling the method
|
306
|
+
# `full_name` on the provider instance, so it will expect that method to
|
307
|
+
# exist.
|
308
|
+
#
|
309
|
+
# It is possible to use msgs in order to declare and use custom messages,
|
310
|
+
# e.g. for the commit message on a commit a provider needs to create, or
|
311
|
+
# a description that needs to be included to an API call.
|
312
|
+
#
|
313
|
+
# For example, a message declared on the class body like so:
|
314
|
+
#
|
315
|
+
# ```ruby
|
316
|
+
# cmds git_commit: 'git commit -am "%{commit_msg}"'
|
317
|
+
# msgs commit_msg: 'Commit build artifacts on build %{build_number}'
|
318
|
+
# ```
|
319
|
+
#
|
320
|
+
# could be used by the implementation like so:
|
321
|
+
#
|
322
|
+
# ```ruby
|
323
|
+
# def create_commit
|
324
|
+
# shell :git_commit
|
325
|
+
# end
|
326
|
+
#
|
327
|
+
# def commit_msg
|
328
|
+
# interpolate(msg(:commit_msg))
|
329
|
+
# end
|
330
|
+
# ```
|
331
|
+
#
|
332
|
+
# Note that in cases where builtin methods such as `shell`, `info`,
|
333
|
+
# `warn` etc. are not used the method `interpolate` needs to be used in
|
334
|
+
# order to interpolate variables used in a message (if any).
|
335
|
+
#
|
336
|
+
# @param msgs [Hash] Messages to declare.
|
337
|
+
# @return Previously declared msgs if no argument is given.
|
338
|
+
def msgs(msgs = nil)
|
339
|
+
return self.msgs.update(msgs) if msgs
|
340
|
+
|
341
|
+
@msgs ||= self == Provider ? {} : superclass.msgs.dup
|
342
|
+
end
|
343
|
+
|
344
|
+
def strs(strs = nil)
|
345
|
+
return self.strs.update(strs) if strs
|
346
|
+
|
347
|
+
@strs ||= self == Provider ? {} : superclass.strs.dup
|
348
|
+
end
|
349
|
+
|
350
|
+
# Declare artifacts, such as executables during the `install` stage that
|
351
|
+
# need to be kept during `cleanup`.
|
352
|
+
#
|
353
|
+
# @param paths [String] Paths to artifacts to keep during `cleanup`
|
354
|
+
# @return Previously declared artifacts to keep if no argument is given.
|
355
|
+
def keep(*paths)
|
356
|
+
return keep.concat(paths) if paths.any?
|
357
|
+
|
358
|
+
@keep ||= self == Provider ? [] : superclass.keep.dup
|
359
|
+
end
|
360
|
+
|
361
|
+
# Declare features that the provider needs.
|
362
|
+
#
|
363
|
+
# Known features currently are:
|
364
|
+
#
|
365
|
+
# * `ssh_key`: Generates a temporary, per-build SSH key, and calls the
|
366
|
+
# methods `add_key` and `remove_key` if the provider defines them.
|
367
|
+
# This gives providers the opportunity to install this key on their
|
368
|
+
# service, and remove it after the deployment has finished.
|
369
|
+
# * `git`: Populates the git config.user and config.email attributes,
|
370
|
+
# unless present.
|
371
|
+
# * `git_http_user_agent`: Changes the environment variable
|
372
|
+
# `GIT_HTTP_USER_AGENT` to the one generated by `user_agent`. This
|
373
|
+
# gives providers the opportunity to identify and track coming from
|
374
|
+
# Travis CI and/or dpl.
|
375
|
+
#
|
376
|
+
# @param features [Symbol] Features to activate for this provider
|
377
|
+
# @return Previously declared features needed if no argument is given.
|
378
|
+
def needs(*features)
|
379
|
+
return needs.concat(features) if features.any?
|
380
|
+
|
381
|
+
@needs ||= self == Provider ? [] : superclass.needs.dup
|
382
|
+
end
|
383
|
+
|
384
|
+
# Whether or not the provider has declared any features it needs.
|
385
|
+
def needs?(feature)
|
386
|
+
needs.include?(feature)
|
387
|
+
end
|
388
|
+
|
389
|
+
# Generates a useragent string that identifies the current dpl version,
|
390
|
+
# and whether it runs int he context of Travis CI. Can include arbitrary
|
391
|
+
# extra strings or key value pairs (passed as String or Hash arguments).
|
392
|
+
# @param strs [String(s) or Hash(es)] Additional strings or key value pairs to include to the useragent string.
|
393
|
+
# @return [String] The useragent string
|
394
|
+
def user_agent(*strs)
|
395
|
+
strs.unshift "dpl/#{Dpl::VERSION}"
|
396
|
+
strs.unshift 'travis/0.1.0' if ENV['TRAVIS']
|
397
|
+
strs = strs.flat_map { |e| e.is_a?(Hash) ? e.map { |k, v| "#{k}/#{v}" } : e }
|
398
|
+
strs.join(' ').gsub(/\s+/, ' ').strip
|
399
|
+
end
|
400
|
+
|
401
|
+
def ruby_version
|
402
|
+
Gem::Version.new(RUBY_VERSION)
|
403
|
+
end
|
404
|
+
|
405
|
+
def ruby_pre?(version)
|
406
|
+
ruby_version < Gem::Version.new(version)
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
class Examples < Struct.new(:const)
|
5
|
+
def cmds
|
6
|
+
examples.map(&:cmd).join("\n")
|
7
|
+
end
|
8
|
+
|
9
|
+
def full_config
|
10
|
+
full.config
|
11
|
+
end
|
12
|
+
|
13
|
+
def configs
|
14
|
+
examples.map(&:config)
|
15
|
+
end
|
16
|
+
|
17
|
+
def examples
|
18
|
+
[requireds, required, many].flatten.compact.uniq
|
19
|
+
end
|
20
|
+
|
21
|
+
def requireds
|
22
|
+
requireds_opts.map { |opts| example(opts) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def required
|
26
|
+
opts = required_opts
|
27
|
+
example(opts)
|
28
|
+
end
|
29
|
+
|
30
|
+
def many
|
31
|
+
opts = const.opts.opts
|
32
|
+
opts = order(opts)
|
33
|
+
opts = without_required(opts)
|
34
|
+
opts = with_required(opts)
|
35
|
+
opts = filter(opts)
|
36
|
+
opts = opts[0, 5]
|
37
|
+
example(opts)
|
38
|
+
end
|
39
|
+
|
40
|
+
def full
|
41
|
+
opts = const.opts.opts
|
42
|
+
opts = filter(opts)
|
43
|
+
example(opts)
|
44
|
+
end
|
45
|
+
|
46
|
+
def filter(opts)
|
47
|
+
opts = opts.reject(&:internal?)
|
48
|
+
opts.reject { |opt| opt.name == :help }
|
49
|
+
end
|
50
|
+
|
51
|
+
def order(opts)
|
52
|
+
cmmn = const.superclass.opts.opts
|
53
|
+
opts - cmmn + cmmn
|
54
|
+
end
|
55
|
+
|
56
|
+
def with_required(opts)
|
57
|
+
requireds = requireds_opts.first || []
|
58
|
+
opts = requireds + required_opts + opts
|
59
|
+
opts.uniq
|
60
|
+
end
|
61
|
+
|
62
|
+
def without_required(opts)
|
63
|
+
opts -= const.required.flatten.map { |key| const.opts[key] }
|
64
|
+
opts - required_opts.map(&:opts)
|
65
|
+
end
|
66
|
+
|
67
|
+
def example(opts)
|
68
|
+
return unless opts.any?
|
69
|
+
|
70
|
+
opts = required_opts.concat(opts).uniq.compact
|
71
|
+
Example.new(const, opts)
|
72
|
+
end
|
73
|
+
|
74
|
+
def requireds_opts
|
75
|
+
opts = const.required.flatten(1)
|
76
|
+
opts.map { |keys| Array(keys).map { |key| const.opts[key] } }
|
77
|
+
end
|
78
|
+
|
79
|
+
def required_opts
|
80
|
+
const.opts.select(&:required?)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class Example < Struct.new(:const, :opts)
|
85
|
+
def config
|
86
|
+
config = opts_for(opts)
|
87
|
+
config = config.merge(strategy: strategy) # hmm.
|
88
|
+
compact(config)
|
89
|
+
end
|
90
|
+
|
91
|
+
def strategy
|
92
|
+
const.registry_key.to_s.split(':').last if const.registry_key.to_s.include?(':')
|
93
|
+
end
|
94
|
+
|
95
|
+
def cmd
|
96
|
+
"dpl #{name} #{strs_for(opts)}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def ==(other)
|
100
|
+
const == other.const && opts == other.opts
|
101
|
+
end
|
102
|
+
|
103
|
+
def name
|
104
|
+
const.registry_key.to_s.split(':').join(' ')
|
105
|
+
end
|
106
|
+
|
107
|
+
def opts_for(opts)
|
108
|
+
opts.map { |opt| [opt.name, value_for(opt)] }.to_h
|
109
|
+
end
|
110
|
+
|
111
|
+
def strs_for(opts)
|
112
|
+
opts.map { |opt| str_for(opt) }.join(' ')
|
113
|
+
end
|
114
|
+
|
115
|
+
def str_for(opt)
|
116
|
+
"--#{opt.name} #{value_for(opt)}".strip
|
117
|
+
end
|
118
|
+
|
119
|
+
def value_for(opt)
|
120
|
+
return if opt.type == :flag
|
121
|
+
return 1 if opt.type == :integer
|
122
|
+
return opt.enum.first if opt.enum?
|
123
|
+
|
124
|
+
str = opt.strs.detect { |str| str =~ /^--#{opt.name} (.*)$/ } && ::Regexp.last_match(1)
|
125
|
+
str ? str.downcase : 'str'
|
126
|
+
end
|
127
|
+
|
128
|
+
def compact(hash)
|
129
|
+
hash.reject { |_, value| value.nil? }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
class Provider < Cl::Cmd
|
5
|
+
class Status < Struct.new(:provider, :status, :info)
|
6
|
+
STATUS = %i[dev alpha beta stable deprecated].freeze
|
7
|
+
|
8
|
+
MSG = {
|
9
|
+
dev: 'Support for deployments to %s is in **development**',
|
10
|
+
alpha: 'Support for deployments to %s is in **alpha**',
|
11
|
+
beta: 'Support for deployments to %s is in **beta**',
|
12
|
+
deprecated: 'Support for deployments to %s is *deprecated**',
|
13
|
+
pre_stable: 'Please see [Maturity Levels](%s) for details.'
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
URL = 'https://github.com/travis-ci/dpl/#maturity-levels'
|
17
|
+
|
18
|
+
def initialize(provider, status, info)
|
19
|
+
unknown!(status) unless known?(status)
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def announce?
|
24
|
+
!stable?
|
25
|
+
end
|
26
|
+
|
27
|
+
def msg
|
28
|
+
msg = (MSG[status] % name).to_s
|
29
|
+
msg << "(#{info})" if info
|
30
|
+
msg << ". #{MSG[:pre_stable] % URL}" if pre_stable?
|
31
|
+
msg
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def name
|
37
|
+
provider.full_name
|
38
|
+
end
|
39
|
+
|
40
|
+
def pre_stable?
|
41
|
+
STATUS.index(status) < STATUS.index(:stable)
|
42
|
+
end
|
43
|
+
|
44
|
+
def stable?
|
45
|
+
status == :stable
|
46
|
+
end
|
47
|
+
|
48
|
+
def deprecated?
|
49
|
+
status == :deprecated
|
50
|
+
end
|
51
|
+
|
52
|
+
def known?(status)
|
53
|
+
STATUS.include?(status)
|
54
|
+
end
|
55
|
+
|
56
|
+
def unknown!(status)
|
57
|
+
raise "Unknown status: #{status.inspect}. Known statuses are: #{STATUS.map(&:inspect).join(', ')}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|