google-cloud-core 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e44ada22e203f330c8b70e746ce7b7fe79ff7a40587f993126f18438e18bebf1
4
- data.tar.gz: a3eba190acf8259d8c9dd8c14ce8db08fa7f133a1c38c81958dac03cb74c3eeb
3
+ metadata.gz: dd3cf2a2e538cb37ffd2daae810180a7cf19dcad051f1fdce8d6b6c6dd13a566
4
+ data.tar.gz: e197ffcd7a014052eaeabba0f744ce0c3c86da7be88639bd9e91338eb122b7e4
5
5
  SHA512:
6
- metadata.gz: e230827b88d66edb003623e9955e522f5695ffd7a5d7b095bf678ae886a049014917511bfc4d79a23dfa5d16a6b64f445c985a8e57dae0298354b243a9cf3e36
7
- data.tar.gz: 4248b6744703cae1c167d6fcfc59c69a0ca99d155a17b5a7deef3137c197b7e625382d7935dab26383a64649ef692f713a933528e3a79f46406dfb94b2d6d2e4
6
+ metadata.gz: 27e11063ff53977170fa53a5559d272ac324225ee0ee9bc85f2b696b5b6f31f0719b605283eae7b73d12808a8326a97f9dd5308d89fab5b89df22dac5fdca8b3
7
+ data.tar.gz: 4ba78b2ef42de56f09660dd30c40eee1fcd7c74a6ba5c57fc126dcd05cb9af59e9087caa8f9745a44f8e332c67a6e8b16252ef8f600655ff811c74314635011b
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  Apache License
2
2
  Version 2.0, January 2004
3
- http://www.apache.org/licenses/
3
+ https://www.apache.org/licenses/
4
4
 
5
5
  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
6
 
@@ -192,7 +192,7 @@
192
192
  you may not use this file except in compliance with the License.
193
193
  You may obtain a copy of the License at
194
194
 
195
- http://www.apache.org/licenses/LICENSE-2.0
195
+ https://www.apache.org/licenses/LICENSE-2.0
196
196
 
197
197
  Unless required by applicable law or agreed to in writing, software
198
198
  distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,10 +1,10 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
1
+ # Copyright 2015 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
+ require "google/cloud/config"
16
17
  require "google/cloud/core/version"
17
18
 
18
19
  ##
@@ -23,10 +24,14 @@ require "google/cloud/core/version"
23
24
  # that allow you to create anything from simple websites to complex
24
25
  # applications.
25
26
  #
26
- # The goal of google-cloud is to provide a API that is familiar and comfortable
27
- # to Rubyists. Authentication is handled by providing project and credential
28
- # information, or if you are running on Google Compute Engine this configuration
29
- # is taken care of for you.
27
+ # The goal of google-cloud is to provide an API that is comfortable to
28
+ # Rubyists. Your authentication credentials are detected automatically in
29
+ # Google Cloud Platform environments such as Google Compute Engine, Google
30
+ # App Engine and Google Kubernetes Engine. In other environments you can
31
+ # configure authentication easily, either directly in your code or via
32
+ # environment variables. Read more about the options for connecting in the
33
+ # [Authentication
34
+ # Guide](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/guides/authentication).
30
35
  #
31
36
  # You can learn more about various options for connection on the [Authentication
32
37
  # Guide](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/guides/authentication).
@@ -67,9 +72,51 @@ module Google
67
72
  gcloud.extend Google::Cloud
68
73
  gcloud
69
74
  end
75
+
76
+ ##
77
+ # Configure the default parameter for Google::Cloud. The values defined on
78
+ # this top level will be shared across all Google::Cloud libraries, which
79
+ # may also add fields to this object or add sub configuration options under
80
+ # this object.
81
+ #
82
+ # Possible configuration parameters:
83
+ #
84
+ # * `project_id`: The Google Cloud Project ID. Automatically discovered
85
+ # when running from GCP environments.
86
+ # * `credentials`: The service account JSON file path. Automatically
87
+ # discovered when running from GCP environments.
88
+ #
89
+ # @return [Google::Cloud::Config] The top-level configuration object for
90
+ # Google::Cloud libraries.
91
+ #
92
+ def self.configure
93
+ @config ||= Config.create
94
+
95
+ yield @config if block_given?
96
+
97
+ @config
98
+ end
70
99
  end
71
100
  end
72
101
 
102
+ # Set the default top-level configuration
103
+ Google::Cloud.configure do |config|
104
+ default_project = Google::Cloud::Config.deferred do
105
+ ENV["GOOGLE_CLOUD_PROJECT"] || ENV["GCLOUD_PROJECT"]
106
+ end
107
+ default_creds = Google::Cloud::Config.deferred do
108
+ Google::Cloud::Config.credentials_from_env \
109
+ "GOOGLE_CLOUD_CREDENTIALS", "GOOGLE_CLOUD_CREDENTIALS_JSON",
110
+ "GOOGLE_CLOUD_KEYFILE", "GOOGLE_CLOUD_KEYFILE_JSON",
111
+ "GCLOUD_KEYFILE", "GCLOUD_KEYFILE_JSON"
112
+ end
113
+
114
+ config.add_field! :project_id, default_project, match: String, allow_nil: true
115
+ config.add_alias! :project, :project_id
116
+ config.add_field! :credentials, default_creds, match: Object
117
+ config.add_alias! :keyfile, :credentials
118
+ end
119
+
73
120
  # Auto-load all Google Cloud service gems.
74
121
  Gem.find_files("google-cloud-*.rb").each do |google_cloud_service|
75
122
  require google_cloud_service
@@ -0,0 +1,607 @@
1
+ # Copyright 2018 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Google
17
+ module Cloud
18
+ ##
19
+ # Configuration mechanism for Google Cloud libraries. A Config object
20
+ # contains a list of predefined keys, some of which are values and others
21
+ # of which are subconfigurations, i.e. categories. Field access is
22
+ # generally validated to ensure that the field is defined, and when a
23
+ # a value is set, it is validated for the correct type. Warnings are
24
+ # printed when a validation fails.
25
+ #
26
+ # You generally access fields and subconfigs by calling accessor methods.
27
+ # Methods meant for "administration" such as adding options, are named
28
+ # with a trailing "!" or "?" so they don't pollute the method namespace.
29
+ # It is also possible to access a field using the `[]` operator.
30
+ #
31
+ # Note that config objects inherit from `BasicObject`. This means it does
32
+ # not define many methods you might expect to find in most Ruby objects.
33
+ # For example, `to_s`, `inspect`, `is_a?`, `instance_variable_get`, and so
34
+ # forth.
35
+ #
36
+ # @example
37
+ # require "google/cloud/config"
38
+ #
39
+ # config = Google::Cloud::Config.create do |c|
40
+ # c.add_field! :opt1, 10
41
+ # c.add_field! :opt2, :one, enum: [:one, :two, :three]
42
+ # c.add_field! :opt3, "hi", match: [String, Symbol]
43
+ # c.add_field! :opt4, "hi", match: /^[a-z]+$/, allow_nil: true
44
+ # c.add_config! :sub do |c2|
45
+ # c2.add_field! :opt5, false
46
+ # end
47
+ # end
48
+ #
49
+ # config.opt1 #=> 10
50
+ # config.opt1 = 20 #=> 20
51
+ # config.opt1 #=> 20
52
+ # config.opt1 = "hi" #=> "hi" (but prints a warning)
53
+ # config.opt1 = nil #=> nil (but prints a warning)
54
+ #
55
+ # config.opt2 #=> :one
56
+ # config.opt2 = :two #=> :two
57
+ # config.opt2 #=> :two
58
+ # config.opt2 = :four #=> :four (but prints a warning)
59
+ #
60
+ # config.opt3 #=> "hi"
61
+ # config.opt3 = "hiho" #=> "hiho"
62
+ # config.opt3 #=> "hiho"
63
+ # config.opt3 = "HI" #=> "HI" (but prints a warning)
64
+ #
65
+ # config.opt4 #=> "yo"
66
+ # config.opt4 = :yo #=> :yo (Strings and Symbols allowed)
67
+ # config.opt4 #=> :yo
68
+ # config.opt4 = 3.14 #=> 3.14 (but prints a warning)
69
+ # config.opt4 = nil #=> nil (no warning: nil allowed)
70
+ #
71
+ # config.sub #=> <Google::Cloud::Config>
72
+ #
73
+ # config.sub.opt5 #=> false
74
+ # config.sub.opt5 = true #=> true (true and false allowed)
75
+ # config.sub.opt5 #=> true
76
+ # config.sub.opt5 = nil #=> nil (but prints a warning)
77
+ #
78
+ # config.opt9 = "hi" #=> "hi" (warning about unknown key)
79
+ # config.opt9 #=> "hi" (no warning: key now known)
80
+ # config.sub.opt9 #=> nil (warning about unknown key)
81
+ #
82
+ class Config < BasicObject
83
+ ##
84
+ # Constructs a Config object. If a block is given, yields `self` to the
85
+ # block, which makes it convenient to initialize the structure by making
86
+ # calls to `add_field!` and `add_config!`.
87
+ #
88
+ # @param [boolean] show_warnings Whether to print warnings when a
89
+ # validation fails. Defaults to `true`.
90
+ # @return [Config] The constructed Config object.
91
+ #
92
+ def self.create show_warnings: true
93
+ config = new [], show_warnings: show_warnings
94
+ yield config if block_given?
95
+ config
96
+ end
97
+
98
+ ##
99
+ # Determines if the given object is a config. Useful because Config
100
+ # does not define the `is_a?` method.
101
+ #
102
+ # @return [boolean]
103
+ #
104
+ def self.config? obj
105
+ Config.send :===, obj
106
+ end
107
+
108
+ ##
109
+ # Internal constructor. Generally you should not call `new` directly,
110
+ # but instead use the `Config.create` method. The initializer is used
111
+ # directly by a few older clients that expect a legacy interface.
112
+ #
113
+ # @private
114
+ #
115
+ def initialize legacy_categories = {}, opts = {}
116
+ @show_warnings = opts.fetch :show_warnings, false
117
+ @values = {}
118
+ @defaults = {}
119
+ @validators = {}
120
+ add_options legacy_categories
121
+ end
122
+
123
+ ##
124
+ # Legacy method of adding subconfigs. This is used by older versions of
125
+ # the stackdriver client libraries but should not be used in new code.
126
+ #
127
+ # @deprecated
128
+ # @private
129
+ #
130
+ def add_options legacy_categories
131
+ [legacy_categories].flatten(1).each do |sub_key|
132
+ case sub_key
133
+ when ::Symbol
134
+ add_config! sub_key, Config.new
135
+ when ::Hash
136
+ sub_key.each do |k, v|
137
+ add_config! k, Config.new(v)
138
+ end
139
+ else
140
+ raise ArgumentError "Category must be a Symbol or Hash"
141
+ end
142
+ end
143
+ end
144
+
145
+ ##
146
+ # Add a value field to this configuration.
147
+ #
148
+ # You must provide a key, which becomes the field name in this config.
149
+ # Field names may comprise only letters, numerals, and underscores, and
150
+ # must begin with a letter. This will create accessor methods for the
151
+ # new configuration key.
152
+ #
153
+ # You may pass an initial value (which defaults to nil if not provided).
154
+ #
155
+ # You may also specify how values are validated. Validation is defined
156
+ # as follows:
157
+ #
158
+ # * If you provide a block or a `:validator` option, it is used as the
159
+ # validator. A proposed value is passed to the proc, which should
160
+ # return `true` or `false` to indicate whether the value is valid.
161
+ # * If you provide a `:match` option, it is compared to the proposed
162
+ # value using the `===` operator. You may, for example, provide a
163
+ # class, a regular expression, or a range. If you pass an array,
164
+ # the value is accepted if _any_ of the elements match.
165
+ # * If you provide an `:enum` option, it should be an `Enumerable`.
166
+ # A proposed value is valid if it is included.
167
+ # * Otherwise if you do not provide any of the above options, then a
168
+ # default validation strategy is inferred from the initial value:
169
+ # * If the initial is `true` or `false`, then either boolean value
170
+ # is considered valid. This is the same as `enum: [true, false]`.
171
+ # * If the initial is `nil`, then any object is considered valid.
172
+ # * Otherwise, any object of the same class as the initial value is
173
+ # considered valid. This is effectively the same as
174
+ # `match: initial.class`.
175
+ # * You may also provide the `:allow_nil` option, which, if set to
176
+ # true, alters any of the above validators to allow `nil` values.
177
+ #
178
+ # In many cases, you may find that the default validation behavior
179
+ # (interpreted from the initial value) is sufficient. If you want to
180
+ # accept any value, use `match: Object`.
181
+ #
182
+ # @param [String, Symbol] key The name of the option
183
+ # @param [Object] initial Initial value (defaults to nil)
184
+ # @param [Hash] opts Validation options
185
+ #
186
+ # @return [Config] self for chaining
187
+ #
188
+ def add_field! key, initial = nil, opts = {}, &block
189
+ key = validate_new_key! key
190
+ opts[:validator] = block if block
191
+ validator = resolve_validator! initial, opts
192
+ validate_value! key, validator, initial
193
+ @values[key] = initial
194
+ @defaults[key] = initial
195
+ @validators[key] = validator
196
+ self
197
+ end
198
+
199
+ ##
200
+ # Add a subconfiguration field to this configuration.
201
+ #
202
+ # You must provide a key, which becomes the method name that you use to
203
+ # navigate to the subconfig. Names may comprise only letters, numerals,
204
+ # and underscores, and must begin with a letter.
205
+ #
206
+ # If you provide a block, the subconfig object is passed to the block,
207
+ # so you can easily add fields to the subconfig.
208
+ #
209
+ # You may also pass in a config object that already exists. This will
210
+ # "attach" that configuration in this location.
211
+ #
212
+ # @param [String, Symbol] key The name of the subconfig
213
+ # @param [Config] config A config object to attach here. If not provided,
214
+ # creates a new config.
215
+ #
216
+ # @return [Config] self for chaining
217
+ #
218
+ def add_config! key, config = nil, &block
219
+ key = validate_new_key! key
220
+ if config.nil?
221
+ config = Config.create(&block)
222
+ elsif block
223
+ yield config
224
+ end
225
+ @values[key] = config
226
+ @defaults[key] = config
227
+ @validators[key] = SUBCONFIG
228
+ self
229
+ end
230
+
231
+ ##
232
+ # Cause a key to be an alias of another key. The two keys will refer to
233
+ # the same field.
234
+ #
235
+ def add_alias! key, to_key
236
+ key = validate_new_key! key
237
+ @values.delete key
238
+ @defaults.delete key
239
+ @validators[key] = to_key.to_sym
240
+ self
241
+ end
242
+
243
+ ##
244
+ # Restore the original default value of the given key.
245
+ # If the key is omitted, restore the original defaults for all keys,
246
+ # and all keys of subconfigs, recursively.
247
+ #
248
+ # @param [Symbol, nil] key The key to reset. If omitted or `nil`,
249
+ # recursively reset all fields and subconfigs.
250
+ #
251
+ def reset! key = nil
252
+ if key.nil?
253
+ @values.each_key { |k| reset! k }
254
+ else
255
+ key = key.to_sym
256
+ if @defaults.key? key
257
+ @values[key] = @defaults[key]
258
+ @values[key].reset! if @validators[key] == SUBCONFIG
259
+ elsif @values.key? key
260
+ warn! "Key #{key.inspect} has not been added, but has a value." \
261
+ " Removing the value."
262
+ @values.delete key
263
+ else
264
+ warn! "Key #{key.inspect} does not exist. Nothing to reset."
265
+ end
266
+ end
267
+ self
268
+ end
269
+
270
+ ##
271
+ # Remove the given key from the configuration, deleting any validation
272
+ # and value. If the key is omitted, delete all keys. If the key is an
273
+ # alias, deletes the alias but leaves the original.
274
+ #
275
+ # @param [Symbol, nil] key The key to delete. If omitted or `nil`,
276
+ # delete all fields and subconfigs.
277
+ #
278
+ def delete! key = nil
279
+ if key.nil?
280
+ @values.clear
281
+ @defaults.clear
282
+ @validators.clear
283
+ else
284
+ @values.delete key
285
+ @defaults.delete key
286
+ @validators.delete key
287
+ end
288
+ self
289
+ end
290
+
291
+ ##
292
+ # Assign an option with the given name to the given value.
293
+ #
294
+ # @param [Symbol, String] key The option name
295
+ # @param [Object] value The new option value
296
+ #
297
+ def []= key, value
298
+ key = resolve_key! key
299
+ validate_value! key, @validators[key], value
300
+ @values[key] = value
301
+ end
302
+
303
+ ##
304
+ # Get the option or subconfig with the given name.
305
+ #
306
+ # @param [Symbol, String] key The option or subconfig name
307
+ # @return [Object] The option value or subconfig object
308
+ #
309
+ def [] key
310
+ key = resolve_key! key
311
+ unless @validators.key? key
312
+ warn! "Key #{key.inspect} does not exist. Returning nil."
313
+ end
314
+ value = @values[key]
315
+ value = value.call if Config::DeferredValue === value
316
+ value
317
+ end
318
+
319
+ ##
320
+ # Check if the given key has been set in this object. Returns true if the
321
+ # key has been added as a normal field, subconfig, or alias, or if it has
322
+ # not been added explicitly but still has a value.
323
+ #
324
+ # @param [Symbol] key The key to check for.
325
+ # @return [boolean]
326
+ #
327
+ def value_set? key
328
+ @values.key? resolve_key! key
329
+ end
330
+ alias option? value_set?
331
+
332
+ ##
333
+ # Check if the given key has been explicitly added as a field name.
334
+ #
335
+ # @param [Symbol] key The key to check for.
336
+ # @return [boolean]
337
+ #
338
+ def field? key
339
+ @validators[key.to_sym].is_a? ::Proc
340
+ end
341
+
342
+ ##
343
+ # Check if the given key has been explicitly added as a subconfig name.
344
+ #
345
+ # @param [Symbol] key The key to check for.
346
+ # @return [boolean]
347
+ #
348
+ def subconfig? key
349
+ @validators[key.to_sym] == SUBCONFIG
350
+ end
351
+
352
+ ##
353
+ # Check if the given key has been explicitly added as an alias.
354
+ # If so, return the target, otherwise return nil.
355
+ #
356
+ # @param [Symbol] key The key to check for.
357
+ # @return [Symbol,nil] The alias target, or nil if not an alias.
358
+ #
359
+ def alias? key
360
+ target = @validators[key.to_sym]
361
+ target.is_a?(::Symbol) ? target : nil
362
+ end
363
+
364
+ ##
365
+ # Return a list of explicitly added field names.
366
+ #
367
+ # @return [Array<Symbol>] a list of field names as symbols.
368
+ #
369
+ def fields!
370
+ @validators.keys.find_all { |key| @validators[key].is_a? ::Proc }
371
+ end
372
+
373
+ ##
374
+ # Return a list of explicitly added subconfig names.
375
+ #
376
+ # @return [Array<Symbol>] a list of subconfig names as symbols.
377
+ #
378
+ def subconfigs!
379
+ @validators.keys.find_all { |key| @validators[key] == SUBCONFIG }
380
+ end
381
+
382
+ ##
383
+ # Return a list of alias names.
384
+ #
385
+ # @return [Array<Symbol>] a list of alias names as symbols.
386
+ #
387
+ def aliases!
388
+ @validators.keys.find_all { |key| @validators[key].is_a? ::Symbol }
389
+ end
390
+
391
+ ##
392
+ # Returns a string representation of this configuration state, including
393
+ # subconfigs. Only explicitly added fields and subconfigs are included.
394
+ #
395
+ # @return [String]
396
+ #
397
+ def to_s!
398
+ elems = @validators.keys.map do |k|
399
+ v = @values[k]
400
+ vstr = Config.config?(v) ? v.to_s! : value.inspect
401
+ " #{k}=#{vstr}"
402
+ end
403
+ "<Config:#{elems.join}>"
404
+ end
405
+
406
+ ##
407
+ # Returns a nested hash representation of this configuration state,
408
+ # including subconfigs. Only explicitly added fields and subconfigs are
409
+ # included.
410
+ #
411
+ # @return [Hash]
412
+ #
413
+ def to_h!
414
+ h = {}
415
+ @validators.each_key do |k|
416
+ v = @values[k]
417
+ h[k] = Config.config?(v) ? v.to_h! : v.inspect
418
+ end
419
+ h
420
+ end
421
+
422
+ ##
423
+ # Search the given environment variable names for valid credential data
424
+ # that can be passed to `Google::Auth::Credentials.new`.
425
+ # If a variable contains a valid file path, returns that path as a string.
426
+ # If a variable contains valid JSON, returns the parsed JSON as a hash.
427
+ # If no variables contain valid data, returns nil.
428
+ # @private
429
+ #
430
+ def self.credentials_from_env *vars
431
+ vars.each do |var|
432
+ data = ::ENV[var]
433
+ next unless data
434
+ str = data.strip
435
+ return str if ::File.file? str
436
+ json = begin
437
+ ::JSON.parse str
438
+ rescue ::StandardError
439
+ nil
440
+ end
441
+ return json if json.is_a? ::Hash
442
+ end
443
+ nil
444
+ end
445
+
446
+ ##
447
+ # @private
448
+ # Create a configuration value that will be invoked when retrieved.
449
+ #
450
+ def self.deferred &block
451
+ DeferredValue.new(&block)
452
+ end
453
+
454
+ ##
455
+ # @private
456
+ # Dynamic methods accessed as keys.
457
+ #
458
+ def method_missing name, *args
459
+ name_str = name.to_s
460
+ super unless name_str =~ /^[a-zA-Z]\w*=?$/
461
+ if name_str.chomp! "="
462
+ self[name_str] = args.first
463
+ else
464
+ self[name]
465
+ end
466
+ end
467
+
468
+ ##
469
+ # @private
470
+ # Dynamic methods accessed as keys.
471
+ #
472
+ def respond_to_missing? name, include_private
473
+ return true if value_set? name.to_s.chomp("=")
474
+ super
475
+ end
476
+
477
+ ##
478
+ # @private
479
+ # Implement standard nil check
480
+ #
481
+ # @return [false]
482
+ #
483
+ def nil?
484
+ false
485
+ end
486
+
487
+ private
488
+
489
+ ##
490
+ # @private A validator that allows all values
491
+ #
492
+ OPEN_VALIDATOR = ::Proc.new { true }
493
+
494
+ ##
495
+ # @private a list of key names that are technically illegal because
496
+ # they clash with method names.
497
+ #
498
+ ILLEGAL_KEYS = %i[
499
+ add_options
500
+ initialize
501
+ instance_eval
502
+ instance_exec
503
+ method_missing
504
+ singleton_method_added
505
+ singleton_method_removed
506
+ singleton_method_undefined
507
+ ].freeze
508
+
509
+ ##
510
+ # @private sentinel indicating a subconfig in the validators hash
511
+ #
512
+ SUBCONFIG = ::Object.new
513
+
514
+ def resolve_key! key
515
+ key = key.to_sym
516
+ alias_target = @validators[key]
517
+ alias_target.is_a?(::Symbol) ? alias_target : key
518
+ end
519
+
520
+ def validate_new_key! key
521
+ key_str = key.to_s
522
+ key = key.to_sym
523
+ if key_str !~ /^[a-zA-Z]\w*$/ || ILLEGAL_KEYS.include?(key)
524
+ warn! "Illegal key name: #{key_str.inspect}. Method dispatch will" \
525
+ " not work for this key."
526
+ end
527
+ if @validators.key? key
528
+ warn! "Key #{key.inspect} already exists. It will be replaced."
529
+ end
530
+ key
531
+ end
532
+
533
+ def resolve_validator! initial, opts
534
+ allow_nil = initial.nil? || opts[:allow_nil]
535
+ if opts.key? :validator
536
+ build_proc_validator! opts[:validator], allow_nil
537
+ elsif opts.key? :match
538
+ build_match_validator! opts[:match], allow_nil
539
+ elsif opts.key? :enum
540
+ build_enum_validator! opts[:enum], allow_nil
541
+ elsif [true, false].include? initial
542
+ build_enum_validator! [true, false], allow_nil
543
+ elsif initial.nil?
544
+ OPEN_VALIDATOR
545
+ else
546
+ klass = Config.config?(initial) ? Config : initial.class
547
+ build_match_validator! klass, allow_nil
548
+ end
549
+ end
550
+
551
+ def build_match_validator! matches, allow_nil
552
+ matches = ::Kernel.Array(matches)
553
+ matches += [nil] if allow_nil && !matches.include?(nil)
554
+ ->(val) { matches.any? { |m| m.send :===, val } }
555
+ end
556
+
557
+ def build_enum_validator! allowed, allow_nil
558
+ allowed = ::Kernel.Array(allowed)
559
+ allowed += [nil] if allow_nil && !allowed.include?(nil)
560
+ ->(val) { allowed.include? val }
561
+ end
562
+
563
+ def build_proc_validator! proc, allow_nil
564
+ ->(val) { proc.call(val) || (allow_nil && val.nil?) }
565
+ end
566
+
567
+ def validate_value! key, validator, value
568
+ value = value.call if Config::DeferredValue === value
569
+ case validator
570
+ when ::Proc
571
+ unless validator.call value
572
+ warn! "Invalid value #{value.inspect} for key #{key.inspect}." \
573
+ " Setting anyway."
574
+ end
575
+ when Config
576
+ if value != validator
577
+ warn! "Key #{key.inspect} refers to a subconfig and shouldn't" \
578
+ " be changed. Setting anyway."
579
+ end
580
+ else
581
+ warn! "Key #{key.inspect} has not been added. Setting anyway."
582
+ end
583
+ end
584
+
585
+ def warn! msg
586
+ return unless @show_warnings
587
+ location = ::Kernel.caller_locations.find do |s|
588
+ !s.to_s.include? "/google/cloud/config.rb:"
589
+ end
590
+ ::Kernel.warn "#{msg} at #{location}"
591
+ end
592
+
593
+ ##
594
+ # @private
595
+ #
596
+ class DeferredValue
597
+ def initialize &block
598
+ @callback = block
599
+ end
600
+
601
+ def call
602
+ @callback.call
603
+ end
604
+ end
605
+ end
606
+ end
607
+ end
@@ -1,10 +1,10 @@
1
- # Copyright 2016 Google Inc. All rights reserved.
1
+ # Copyright 2016 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Core
19
- VERSION = "1.1.0"
19
+ VERSION = "1.2.0".freeze
20
20
  end
21
21
  end
22
22
  end
@@ -1,10 +1,10 @@
1
- # Copyright 2014 Google Inc. All rights reserved.
1
+ # Copyright 2014 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -33,8 +33,8 @@ module Google
33
33
  TOKEN_CREDENTIAL_URI = "https://accounts.google.com/o/oauth2/token"
34
34
  AUDIENCE = "https://accounts.google.com/o/oauth2/token"
35
35
  SCOPE = []
36
- PATH_ENV_VARS = %w(GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE)
37
- JSON_ENV_VARS = %w(GOOGLE_CLOUD_KEYFILE_JSON GCLOUD_KEYFILE_JSON)
36
+ PATH_ENV_VARS = %w[GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE]
37
+ JSON_ENV_VARS = %w[GOOGLE_CLOUD_KEYFILE_JSON GCLOUD_KEYFILE_JSON]
38
38
  DEFAULT_PATHS = ["~/.config/gcloud/application_default_credentials.json"]
39
39
 
40
40
  attr_accessor :client
@@ -72,10 +72,9 @@ module Google
72
72
  path = ->(p) { ::File.file? p }
73
73
 
74
74
  # First try to find keyfile file from environment variables.
75
- self::PATH_ENV_VARS.map(&env).compact.select(&path)
76
- .each do |file|
77
- return new file, scope: scope
78
- end
75
+ self::PATH_ENV_VARS.map(&env).compact.select(&path).each do |file|
76
+ return new file, scope: scope
77
+ end
79
78
  # Second try to find keyfile json from environment variables.
80
79
  self::JSON_ENV_VARS.map(&json).compact.each do |hash|
81
80
  return new hash, scope: scope
@@ -95,14 +94,14 @@ module Google
95
94
  ##
96
95
  # Verify that the keyfile argument is provided.
97
96
  def verify_keyfile_provided! keyfile
98
- fail "You must provide a keyfile to connect with." if keyfile.nil?
97
+ raise "You must provide a keyfile to connect with." if keyfile.nil?
99
98
  end
100
99
 
101
100
  ##
102
101
  # Verify that the keyfile argument is a file.
103
102
  def verify_keyfile_exists! keyfile
104
103
  exists = ::File.file? keyfile
105
- fail "The keyfile '#{keyfile}' is not a valid file." unless exists
104
+ raise "The keyfile '#{keyfile}' is not a valid file." unless exists
106
105
  end
107
106
 
108
107
  ##
@@ -1,10 +1,10 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
1
+ # Copyright 2015 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -146,18 +146,21 @@ module Google
146
146
  def self.grpc_error_class_for grpc_error_code
147
147
  # The gRPC status code 0 is for a successful response.
148
148
  # So there is no error subclass for a 0 status code, use current class.
149
- [self, CanceledError, UnknownError, InvalidArgumentError,
150
- DeadlineExceededError, NotFoundError, AlreadyExistsError,
151
- PermissionDeniedError, ResourceExhaustedError, FailedPreconditionError,
152
- AbortedError, OutOfRangeError, UnimplementedError, InternalError,
153
- UnavailableError, DataLossError, UnauthenticatedError
149
+ [
150
+ self, CanceledError, UnknownError, InvalidArgumentError,
151
+ DeadlineExceededError, NotFoundError, AlreadyExistsError,
152
+ PermissionDeniedError, ResourceExhaustedError,
153
+ FailedPreconditionError, AbortedError, OutOfRangeError,
154
+ UnimplementedError, InternalError, UnavailableError, DataLossError,
155
+ UnauthenticatedError
154
156
  ][grpc_error_code] || self
155
157
  end
156
158
 
157
159
  # @private Identify the subclass for a Google API Client error
158
160
  def self.gapi_error_class_for http_status_code
159
161
  # The http status codes mapped to their error classes.
160
- { 400 => InvalidArgumentError, # FailedPreconditionError/OutOfRangeError
162
+ {
163
+ 400 => InvalidArgumentError, # FailedPreconditionError/OutOfRangeError
161
164
  401 => UnauthenticatedError,
162
165
  403 => PermissionDeniedError,
163
166
  404 => NotFoundError,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-11-14 00:00:00.000000000 Z
12
+ date: 2018-02-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-env
@@ -99,16 +99,16 @@ dependencies:
99
99
  name: rubocop
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - "<="
102
+ - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: 0.35.1
104
+ version: 0.50.0
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - "<="
109
+ - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: 0.35.1
111
+ version: 0.50.0
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: simplecov
114
114
  requirement: !ruby/object:Gem::Requirement
@@ -163,6 +163,7 @@ files:
163
163
  - LICENSE
164
164
  - README.md
165
165
  - lib/google/cloud.rb
166
+ - lib/google/cloud/config.rb
166
167
  - lib/google/cloud/core/version.rb
167
168
  - lib/google/cloud/credentials.rb
168
169
  - lib/google/cloud/errors.rb
@@ -186,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
187
  version: '0'
187
188
  requirements: []
188
189
  rubyforge_project:
189
- rubygems_version: 2.7.2
190
+ rubygems_version: 2.7.6
190
191
  signing_key:
191
192
  specification_version: 4
192
193
  summary: Internal shared library for google-cloud-ruby