google-cloud-storage 1.31.1 → 1.32.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: 690d38d7f8cccf7a8ad6433b829c02b0e9f9fbaa48198f68ff4c7a661820d93a
4
- data.tar.gz: 6a8b0782c6ab6cfdf194f0be0b51993e817b182a8a599d67e4c52cab11d98203
3
+ metadata.gz: 10f1fa9dd485d8891fa159b09b463fcf20d5320fd759f2dc92164c0a6f4647af
4
+ data.tar.gz: 1734495bde125925f45fdaf9a2c2a9da421d9cb38c5b7ac1e5785a869594c09f
5
5
  SHA512:
6
- metadata.gz: d8b94e1a9426345a436902611e74eb627eff7867eec1546084aaef1dd16e8a8e9af0dea24493572c8142f7dc7b530ed1cb84abf94e6dbb8acc00ef8a04ab9d65
7
- data.tar.gz: 65162ab2d788531d21efaa23d87e7bdbafcdc8f6c3fd62f556be07f35d440f3055f830ee45cb903443aa695db56cd08b18afa02f3aa6b247b3ba761c1adfe4be
6
+ metadata.gz: 614c067fa9c914e07acf1473e36a78cb04fa6070ddd2d1d96fee3693a2b6cc650a9005af515cdcbb9e6db9c1816985656977934fb5f3fe75248730673dbda675
7
+ data.tar.gz: b3f43b0193147e89de327734384e3a3b3581abfe921e0efcfdfd094e0373a76fb719f079fde3c3e6351216d2b9150af3b1a7a46249d35f7e170168a41e28175f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Release History
2
2
 
3
+ ### 1.32.0 / 2021-06-22
4
+
5
+ #### Features
6
+
7
+ * Add sources_if_generation_match to Bucket#compose
8
+ * Add support for (meta)generation preconditions to File operations
9
+ * Add if_(meta)generation_match options to Bucket#compose
10
+ * Add if_(meta)generation_(not_)match options to Bucket#create_file
11
+ * Add if_(meta)generation_(not_)match options to Bucket#file
12
+ * Add if_(meta)generation_(not_)match options to File#delete.
13
+ * Add if_(meta)generation_(not_)match options to File#rewrite
14
+ * Add generation and if_(meta)generation_(not_)match options to File#update
15
+ * Add generation and if_(meta)generation_(not_)match options to File::Acl predefined_acl methods
16
+
17
+ #### Bug Fixes
18
+
19
+ * Expand googleauth dependency to support future 1.x versions
20
+ * Update File::Verifier to test for File#to_path
21
+
3
22
  ### 1.31.1 / 2021-05-19
4
23
 
5
24
  #### Documentation
@@ -315,6 +315,9 @@ module Google
315
315
  ##
316
316
  # Updates the destination bucket for the bucket's logs.
317
317
  #
318
+ # To pass metageneration preconditions, call this method within a
319
+ # block passed to {#update}.
320
+ #
318
321
  # @see https://cloud.google.com/storage/docs/access-logs Access Logs
319
322
  #
320
323
  # @param [String] logging_bucket The bucket to hold the logging output
@@ -344,6 +347,9 @@ module Google
344
347
  # By default, the object prefix is the name of the bucket for which the
345
348
  # logs are enabled.
346
349
  #
350
+ # To pass metageneration preconditions, call this method within a
351
+ # block passed to {#update}.
352
+ #
347
353
  # @see https://cloud.google.com/storage/docs/access-logs Access Logs
348
354
  #
349
355
  # @param [String] logging_prefix The logging object prefix.
@@ -377,6 +383,9 @@ module Google
377
383
  # For more information, see [Storage
378
384
  # Classes](https://cloud.google.com/storage/docs/storage-classes).
379
385
  #
386
+ # To pass metageneration preconditions, call this method within a
387
+ # block passed to {#update}.
388
+ #
380
389
  # @param [Symbol, String] new_storage_class Storage class of the bucket.
381
390
  #
382
391
  def storage_class= new_storage_class
@@ -400,6 +409,9 @@ module Google
400
409
  # Versioning](https://cloud.google.com/storage/docs/object-versioning)
401
410
  # is enabled for the bucket.
402
411
  #
412
+ # To pass metageneration preconditions, call this method within a
413
+ # block passed to {#update}.
414
+ #
403
415
  # @param [Boolean] new_versioning true if versioning is to be enabled
404
416
  # for the bucket.
405
417
  #
@@ -428,6 +440,9 @@ module Google
428
440
  ##
429
441
  # Updates the main page suffix for a static website.
430
442
  #
443
+ # To pass metageneration preconditions, call this method within a
444
+ # block passed to {#update}.
445
+ #
431
446
  # @see https://cloud.google.com/storage/docs/website-configuration#step4
432
447
  # How to Host a Static Website
433
448
  #
@@ -467,6 +482,9 @@ module Google
467
482
  ##
468
483
  # Updates the hash of user-provided labels.
469
484
  #
485
+ # To pass metageneration preconditions, call this method within a
486
+ # block passed to {#update}.
487
+ #
470
488
  # @param [Hash(String => String)] labels The user-provided labels.
471
489
  #
472
490
  def labels= labels
@@ -478,6 +496,9 @@ module Google
478
496
  # Updates the page returned from a static website served from the bucket
479
497
  # when a site visitor requests a resource that does not exist.
480
498
  #
499
+ # To pass metageneration preconditions, call this method within a
500
+ # block passed to {#update}.
501
+ #
481
502
  # @see https://cloud.google.com/storage/docs/website-configuration#step4
482
503
  # How to Host a Static Website
483
504
  #
@@ -509,6 +530,9 @@ module Google
509
530
  # {Project#bucket} and {Project#buckets} to indicate the project to
510
531
  # which the access costs should be billed.
511
532
  #
533
+ # To pass metageneration preconditions, call this method within a
534
+ # block passed to {#update}.
535
+ #
512
536
  # @param [Boolean] new_requester_pays When set to `true`, requester pays
513
537
  # is enabled for the bucket.
514
538
  #
@@ -557,6 +581,9 @@ module Google
557
581
  # Set the Cloud KMS encryption key that will be used to protect files.
558
582
  # For example: `projects/a/locations/b/keyRings/c/cryptoKeys/d`
559
583
  #
584
+ # To pass metageneration preconditions, call this method within a
585
+ # block passed to {#update}.
586
+ #
560
587
  # @param [String, nil] new_default_kms_key New Cloud KMS key name, or
561
588
  # `nil` to delete the Cloud KMS encryption key.
562
589
  #
@@ -617,6 +644,9 @@ module Google
617
644
  # See also: {#lock_retention_policy!}, {#retention_period},
618
645
  # {#retention_effective_at}, and {#retention_policy_locked?}.
619
646
  #
647
+ # To pass metageneration preconditions, call this method within a
648
+ # block passed to {#update}.
649
+ #
620
650
  # @param [Integer, nil] new_retention_period The retention period
621
651
  # defined in seconds. The value must be between 0 and 100 years (in
622
652
  # seconds), or `nil`.
@@ -715,6 +745,9 @@ module Google
715
745
  #
716
746
  # See {File#event_based_hold?} and {File#set_event_based_hold!}.
717
747
  #
748
+ # To pass metageneration preconditions, call this method within a
749
+ # block passed to {#update}.
750
+ #
718
751
  # @param [Boolean] new_default_event_based_hold The default event-based
719
752
  # hold field for the bucket.
720
753
  #
@@ -823,6 +856,9 @@ module Google
823
856
  # Before enabling uniform bucket-level access please review [uniform bucket-level
824
857
  # access](https://cloud.google.com/storage/docs/uniform-bucket-level-access).
825
858
  #
859
+ # To pass metageneration preconditions, call this method within a
860
+ # block passed to {#update}.
861
+ #
826
862
  # @param [Boolean] new_uniform_bucket_level_access When set to `true`, uniform bucket-level access is enabled in
827
863
  # the bucket's IAM configuration.
828
864
  #
@@ -905,6 +941,12 @@ module Google
905
941
  # completely mutable and will be included in the request. (See
906
942
  # {Bucket::Cors})
907
943
  #
944
+ # @param [Integer] if_metageneration_match Makes the operation conditional
945
+ # on whether the bucket's current metageneration matches the given value.
946
+ # @param [Integer] if_metageneration_not_match Makes the operation
947
+ # conditional on whether the bucket's current metageneration does not
948
+ # match the given value.
949
+ #
908
950
  # @yield [bucket] a block yielding a delegate object for updating the
909
951
  # file
910
952
  #
@@ -936,14 +978,27 @@ module Google
936
978
  # end
937
979
  # end
938
980
  #
939
- def update
981
+ # @example With a `if_metageneration_match` precondition:
982
+ # require "google/cloud/storage"
983
+ #
984
+ # storage = Google::Cloud::Storage.new
985
+ #
986
+ # bucket = storage.bucket "my-todo-app"
987
+ # bucket.update if_metageneration_match: 6 do |b|
988
+ # b.website_main = "index.html"
989
+ # end
990
+ #
991
+ def update if_metageneration_match: nil, if_metageneration_not_match: nil
940
992
  updater = Updater.new @gapi
941
993
  yield updater
942
994
  # Add check for mutable cors
943
995
  updater.check_for_changed_labels!
944
996
  updater.check_for_mutable_cors!
945
997
  updater.check_for_mutable_lifecycle!
946
- patch_gapi! updater.updates unless updater.updates.empty?
998
+ return if updater.updates.empty?
999
+ patch_gapi! updater.updates,
1000
+ if_metageneration_match: if_metageneration_match,
1001
+ if_metageneration_not_match: if_metageneration_not_match
947
1002
  end
948
1003
 
949
1004
  ##
@@ -953,6 +1008,12 @@ module Google
953
1008
  # The API call to delete the bucket may be retried under certain
954
1009
  # conditions. See {Google::Cloud#storage} to control this behavior.
955
1010
  #
1011
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1012
+ # on whether the bucket's current metageneration matches the given value.
1013
+ # @param [Integer] if_metageneration_not_match Makes the operation
1014
+ # conditional on whether the bucket's current metageneration does not
1015
+ # match the given value.
1016
+ #
956
1017
  # @return [Boolean] Returns `true` if the bucket was deleted.
957
1018
  #
958
1019
  # @example
@@ -963,10 +1024,12 @@ module Google
963
1024
  # bucket = storage.bucket "my-bucket"
964
1025
  # bucket.delete
965
1026
  #
966
- def delete
1027
+ def delete if_metageneration_match: nil, if_metageneration_not_match: nil
967
1028
  ensure_service!
968
- service.delete_bucket name, user_project: user_project
969
- true
1029
+ service.delete_bucket name,
1030
+ if_metageneration_match: if_metageneration_match,
1031
+ if_metageneration_not_match: if_metageneration_not_match,
1032
+ user_project: user_project
970
1033
  end
971
1034
 
972
1035
  ##
@@ -1040,6 +1103,19 @@ module Google
1040
1103
  # @param [String] path Name (path) of the file.
1041
1104
  # @param [Integer] generation When present, selects a specific revision
1042
1105
  # of this object. Default is the latest version.
1106
+ # @param [Integer] if_generation_match Makes the operation conditional
1107
+ # on whether the file's current generation matches the given value.
1108
+ # Setting to 0 makes the operation succeed only if there are no live
1109
+ # versions of the file.
1110
+ # @param [Integer] if_generation_not_match Makes the operation conditional
1111
+ # on whether the file's current generation does not match the given
1112
+ # value. If no live file exists, the precondition fails. Setting to 0
1113
+ # makes the operation succeed only if there is a live version of the file.
1114
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1115
+ # on whether the file's current metageneration matches the given value.
1116
+ # @param [Integer] if_metageneration_not_match Makes the operation
1117
+ # conditional on whether the file's current metageneration does not
1118
+ # match the given value.
1043
1119
  # @param [Boolean] skip_lookup Optionally create a Bucket object
1044
1120
  # without verifying the bucket resource exists on the Storage service.
1045
1121
  # Calls made on this object will raise errors if the bucket resource
@@ -1061,7 +1137,14 @@ module Google
1061
1137
  # file = bucket.file "path/to/my-file.ext"
1062
1138
  # puts file.name
1063
1139
  #
1064
- def file path, generation: nil, skip_lookup: nil, encryption_key: nil
1140
+ def file path,
1141
+ generation: nil,
1142
+ if_generation_match: nil,
1143
+ if_generation_not_match: nil,
1144
+ if_metageneration_match: nil,
1145
+ if_metageneration_not_match: nil,
1146
+ skip_lookup: nil,
1147
+ encryption_key: nil
1065
1148
  ensure_service!
1066
1149
  if skip_lookup
1067
1150
  return File.new_lazy name, path, service,
@@ -1069,6 +1152,10 @@ module Google
1069
1152
  user_project: user_project
1070
1153
  end
1071
1154
  gapi = service.get_file name, path, generation: generation,
1155
+ if_generation_match: if_generation_match,
1156
+ if_generation_not_match: if_generation_not_match,
1157
+ if_metageneration_match: if_metageneration_match,
1158
+ if_metageneration_not_match: if_metageneration_not_match,
1072
1159
  key: encryption_key,
1073
1160
  user_project: user_project
1074
1161
  File.from_gapi gapi, service, user_project: user_project
@@ -1179,6 +1266,19 @@ module Google
1179
1266
  # the same location as the bucket.The Service Account associated with
1180
1267
  # your project requires access to this encryption key. Do not provide
1181
1268
  # if `encryption_key` is used.
1269
+ # @param [Integer] if_generation_match Makes the operation conditional
1270
+ # on whether the file's current generation matches the given value.
1271
+ # Setting to 0 makes the operation succeed only if there are no live
1272
+ # versions of the file.
1273
+ # @param [Integer] if_generation_not_match Makes the operation conditional
1274
+ # on whether the file's current generation does not match the given
1275
+ # value. If no live file exists, the precondition fails. Setting to 0
1276
+ # makes the operation succeed only if there is a live version of the file.
1277
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1278
+ # on whether the file's current metageneration matches the given value.
1279
+ # @param [Integer] if_metageneration_not_match Makes the operation
1280
+ # conditional on whether the file's current metageneration does not
1281
+ # match the given value.
1182
1282
  #
1183
1283
  # @return [Google::Cloud::Storage::File]
1184
1284
  #
@@ -1262,12 +1362,27 @@ module Google
1262
1362
  # file.download "path/to/downloaded/gzipped.txt",
1263
1363
  # skip_decompress: true
1264
1364
  #
1265
- def create_file file, path = nil, acl: nil, cache_control: nil,
1266
- content_disposition: nil, content_encoding: nil,
1267
- content_language: nil, content_type: nil, custom_time: nil,
1268
- crc32c: nil, md5: nil, metadata: nil,
1269
- storage_class: nil, encryption_key: nil, kms_key: nil,
1270
- temporary_hold: nil, event_based_hold: nil
1365
+ def create_file file,
1366
+ path = nil,
1367
+ acl: nil,
1368
+ cache_control: nil,
1369
+ content_disposition: nil,
1370
+ content_encoding: nil,
1371
+ content_language: nil,
1372
+ content_type: nil,
1373
+ custom_time: nil,
1374
+ crc32c: nil,
1375
+ md5: nil,
1376
+ metadata: nil,
1377
+ storage_class: nil,
1378
+ encryption_key: nil,
1379
+ kms_key: nil,
1380
+ temporary_hold: nil,
1381
+ event_based_hold: nil,
1382
+ if_generation_match: nil,
1383
+ if_generation_not_match: nil,
1384
+ if_metageneration_match: nil,
1385
+ if_metageneration_not_match: nil
1271
1386
  ensure_service!
1272
1387
  ensure_io_or_file_exists! file
1273
1388
  path ||= file.path if file.respond_to? :path
@@ -1275,22 +1390,29 @@ module Google
1275
1390
  raise ArgumentError, "must provide path" if path.nil?
1276
1391
 
1277
1392
 
1278
- gapi = service.insert_file name, file, path, acl: File::Acl.predefined_rule_for(acl),
1279
- md5: md5,
1280
- cache_control: cache_control,
1281
- content_type: content_type,
1282
- custom_time: custom_time,
1283
- content_disposition: content_disposition,
1284
- crc32c: crc32c,
1285
- content_encoding: content_encoding,
1286
- metadata: metadata,
1287
- content_language: content_language,
1288
- key: encryption_key,
1289
- kms_key: kms_key,
1290
- storage_class: storage_class_for(storage_class),
1291
- temporary_hold: temporary_hold,
1292
- event_based_hold: event_based_hold,
1293
- user_project: user_project
1393
+ gapi = service.insert_file name,
1394
+ file,
1395
+ path,
1396
+ acl: File::Acl.predefined_rule_for(acl),
1397
+ md5: md5,
1398
+ cache_control: cache_control,
1399
+ content_type: content_type,
1400
+ custom_time: custom_time,
1401
+ content_disposition: content_disposition,
1402
+ crc32c: crc32c,
1403
+ content_encoding: content_encoding,
1404
+ metadata: metadata,
1405
+ content_language: content_language,
1406
+ key: encryption_key,
1407
+ kms_key: kms_key,
1408
+ storage_class: storage_class_for(storage_class),
1409
+ temporary_hold: temporary_hold,
1410
+ event_based_hold: event_based_hold,
1411
+ if_generation_match: if_generation_match,
1412
+ if_generation_not_match: if_generation_not_match,
1413
+ if_metageneration_match: if_metageneration_match,
1414
+ if_metageneration_not_match: if_metageneration_not_match,
1415
+ user_project: user_project
1294
1416
  File.from_gapi gapi, service, user_project: user_project
1295
1417
  end
1296
1418
  alias upload_file create_file
@@ -1334,6 +1456,16 @@ module Google
1334
1456
  # used. All source files must have been encrypted with the same key,
1335
1457
  # and the resulting destination file will also be encrypted with the
1336
1458
  # key.
1459
+ # @param [Array<Integer>] if_source_generation_match Makes the operation
1460
+ # conditional on whether the source files' current generations match the
1461
+ # given values. The list must match `sources` item-to-item.
1462
+ # @param [Integer] if_generation_match Makes the operation conditional
1463
+ # on whether the destination file's current generation matches the
1464
+ # given value. Setting to 0 makes the operation succeed only if there
1465
+ # are no live versions of the file.
1466
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1467
+ # on whether the destination file's current metageneration matches the
1468
+ # given value.
1337
1469
  #
1338
1470
  # @yield [file] A block yielding a delegate file object for setting the
1339
1471
  # properties of the destination file.
@@ -1382,7 +1514,13 @@ module Google
1382
1514
  #
1383
1515
  # new_file = bucket.compose [file_1, file_2], "path/to/new-file.ext"
1384
1516
  #
1385
- def compose sources, destination, acl: nil, encryption_key: nil
1517
+ def compose sources,
1518
+ destination,
1519
+ acl: nil,
1520
+ encryption_key: nil,
1521
+ if_source_generation_match: nil,
1522
+ if_generation_match: nil,
1523
+ if_metageneration_match: nil
1386
1524
  ensure_service!
1387
1525
  sources = Array sources
1388
1526
  if sources.size < 2
@@ -1398,9 +1536,16 @@ module Google
1398
1536
  end
1399
1537
 
1400
1538
  acl_rule = File::Acl.predefined_rule_for acl
1401
- gapi = service.compose_file name, sources, destination, destination_gapi, acl: acl_rule,
1402
- key: encryption_key,
1403
- user_project: user_project
1539
+ gapi = service.compose_file name,
1540
+ sources,
1541
+ destination,
1542
+ destination_gapi,
1543
+ acl: acl_rule,
1544
+ key: encryption_key,
1545
+ if_source_generation_match: if_source_generation_match,
1546
+ if_generation_match: if_generation_match,
1547
+ if_metageneration_match: if_metageneration_match,
1548
+ user_project: user_project
1404
1549
  File.from_gapi gapi, service, user_project: user_project
1405
1550
  end
1406
1551
  alias compose_file compose
@@ -2546,7 +2691,10 @@ module Google
2546
2691
  reload!
2547
2692
  end
2548
2693
 
2549
- def patch_gapi! *attributes
2694
+ def patch_gapi! attributes,
2695
+ if_metageneration_match: nil,
2696
+ if_metageneration_not_match: nil
2697
+ attributes = Array(attributes)
2550
2698
  attributes.flatten!
2551
2699
  return if attributes.empty?
2552
2700
  ensure_service!
@@ -2554,7 +2702,10 @@ module Google
2554
2702
  [attr, @gapi.send(attr)]
2555
2703
  end]
2556
2704
  patch_gapi = API::Bucket.new(**patch_args)
2557
- @gapi = service.patch_bucket name, patch_gapi,
2705
+ @gapi = service.patch_bucket name,
2706
+ patch_gapi,
2707
+ if_metageneration_match: if_metageneration_match,
2708
+ if_metageneration_not_match: if_metageneration_not_match,
2558
2709
  user_project: user_project
2559
2710
  @lazy = nil
2560
2711
  self
@@ -260,6 +260,9 @@ module Google
260
260
  # directive for the file data. If omitted, and the file is accessible
261
261
  # to all anonymous users, the default will be `public, max-age=3600`.
262
262
  #
263
+ # To pass generation and/or metageneration preconditions, call this
264
+ # method within a block passed to {#update}.
265
+ #
263
266
  # @param [String] cache_control The Cache-Control directive.
264
267
  #
265
268
  def cache_control= cache_control
@@ -281,6 +284,9 @@ module Google
281
284
  # Updates the [Content-Disposition](https://tools.ietf.org/html/rfc6266)
282
285
  # of the file data.
283
286
  #
287
+ # To pass generation and/or metageneration preconditions, call this
288
+ # method within a block passed to {#update}.
289
+ #
284
290
  # @param [String] content_disposition The Content-Disposition of the
285
291
  # file.
286
292
  #
@@ -305,6 +311,9 @@ module Google
305
311
  # ](https://tools.ietf.org/html/rfc7231#section-3.1.2.2) of the file
306
312
  # data.
307
313
  #
314
+ # To pass generation and/or metageneration preconditions, call this
315
+ # method within a block passed to {#update}.
316
+ #
308
317
  # @param [String] content_encoding The Content-Encoding of the file.
309
318
  #
310
319
  def content_encoding= content_encoding
@@ -326,6 +335,9 @@ module Google
326
335
  # Updates the [Content-Language](http://tools.ietf.org/html/bcp47) of
327
336
  # the file data.
328
337
  #
338
+ # To pass generation and/or metageneration preconditions, call this
339
+ # method within a block passed to {#update}.
340
+ #
329
341
  # @param [String] content_language The Content-Language of the file.
330
342
  #
331
343
  def content_language= content_language
@@ -348,6 +360,9 @@ module Google
348
360
  # [Content-Type](https://tools.ietf.org/html/rfc2616#section-14.17) of
349
361
  # the file data.
350
362
  #
363
+ # To pass generation and/or metageneration preconditions, call this
364
+ # method within a block passed to {#update}.
365
+ #
351
366
  # @param [String] content_type The Content-Type of the file.
352
367
  #
353
368
  def content_type= content_type
@@ -370,6 +385,9 @@ module Google
370
385
  # future. If custom_time must be unset, you must either perform a rewrite
371
386
  # operation, or upload the data again and create a new file.
372
387
  #
388
+ # To pass generation and/or metageneration preconditions, call this
389
+ # method within a block passed to {#update}.
390
+ #
373
391
  # @param [DateTime] custom_time A custom time specified by the user
374
392
  # for the file.
375
393
  #
@@ -396,6 +414,9 @@ module Google
396
414
  # string values that will returned with requests for the file as
397
415
  # "x-goog-meta-" response headers.
398
416
  #
417
+ # To pass generation and/or metageneration preconditions, call this
418
+ # method within a block passed to {#update}.
419
+ #
399
420
  # @param [Hash(String => String)] metadata The user-provided metadata,
400
421
  # in key/value pairs.
401
422
  #
@@ -465,6 +486,9 @@ module Google
465
486
  # The default value is the default storage class for the bucket. See
466
487
  # {Bucket#storage_class}.
467
488
  #
489
+ # To pass generation and/or metageneration preconditions, call this
490
+ # method within a block passed to {#update}.
491
+ #
468
492
  # @param [Symbol, String] storage_class Storage class of the file.
469
493
  #
470
494
  def storage_class= storage_class
@@ -505,6 +529,9 @@ module Google
505
529
  # removed, the file's `retention_expires_at` date is not changed. The
506
530
  # default value is `false`.
507
531
  #
532
+ # To pass generation and/or metageneration preconditions, call this
533
+ # method within a block passed to {#update}.
534
+ #
508
535
  # See {#retention_expires_at}.
509
536
  #
510
537
  # @example
@@ -533,6 +560,9 @@ module Google
533
560
  #
534
561
  # See {#retention_expires_at}.
535
562
  #
563
+ # To pass generation and/or metageneration preconditions, call this
564
+ # method within a block passed to {#update}.
565
+ #
536
566
  # @example
537
567
  # require "google/cloud/storage"
538
568
  #
@@ -643,6 +673,9 @@ module Google
643
673
  # holds released prior to the effective date of the new policy may
644
674
  # have already been deleted by the user.
645
675
  #
676
+ # To pass generation and/or metageneration preconditions, call this
677
+ # method within a block passed to {#update}.
678
+ #
646
679
  # @example
647
680
  # require "google/cloud/storage"
648
681
  #
@@ -681,6 +714,9 @@ module Google
681
714
  # {Bucket#default_event_based_hold?} and
682
715
  # {Bucket#default_event_based_hold=}.
683
716
  #
717
+ # To pass generation and/or metageneration preconditions, call this
718
+ # method within a block passed to {#update}.
719
+ #
684
720
  # @example
685
721
  # require "google/cloud/storage"
686
722
  #
@@ -774,6 +810,22 @@ module Google
774
810
  # accessible in the block is completely mutable and will be included in the
775
811
  # request.
776
812
  #
813
+ # @param [Integer] generation Select a specific revision of the file to
814
+ # update. The default is the latest version.
815
+ # @param [Integer] if_generation_match Makes the operation conditional
816
+ # on whether the file's current generation matches the given value.
817
+ # Setting to 0 makes the operation succeed only if there are no live
818
+ # versions of the file.
819
+ # @param [Integer] if_generation_not_match Makes the operation conditional
820
+ # on whether the file's current generation does not match the given
821
+ # value. If no live file exists, the precondition fails. Setting to 0
822
+ # makes the operation succeed only if there is a live version of the file.
823
+ # @param [Integer] if_metageneration_match Makes the operation conditional
824
+ # on whether the file's current metageneration matches the given value.
825
+ # @param [Integer] if_metageneration_not_match Makes the operation
826
+ # conditional on whether the file's current metageneration does not
827
+ # match the given value.
828
+ #
777
829
  # @yield [file] a block yielding a delegate object for updating the file
778
830
  #
779
831
  # @example
@@ -796,11 +848,34 @@ module Google
796
848
  # f.metadata["score"] = "10"
797
849
  # end
798
850
  #
799
- def update
851
+ # @example With a `if_generation_match` precondition:
852
+ # require "google/cloud/storage"
853
+ #
854
+ # storage = Google::Cloud::Storage.new
855
+ #
856
+ # bucket = storage.bucket "my-bucket"
857
+ #
858
+ # file = bucket.file "path/to/my-file.ext"
859
+ #
860
+ # file.update if_generation_match: 1602263125261858 do |f|
861
+ # f.cache_control = "private, max-age=0, no-cache"
862
+ # end
863
+ #
864
+ def update generation: nil,
865
+ if_generation_match: nil,
866
+ if_generation_not_match: nil,
867
+ if_metageneration_match: nil,
868
+ if_metageneration_not_match: nil
800
869
  updater = Updater.new gapi
801
870
  yield updater
802
871
  updater.check_for_changed_metadata!
803
- update_gapi! updater.updates unless updater.updates.empty?
872
+ return if updater.updates.empty?
873
+ update_gapi! updater.updates,
874
+ generation: generation,
875
+ if_generation_match: if_generation_match,
876
+ if_generation_not_match: if_generation_not_match,
877
+ if_metageneration_match: if_metageneration_match,
878
+ if_metageneration_not_match: if_metageneration_not_match
804
879
  end
805
880
 
806
881
  ##
@@ -1138,6 +1213,27 @@ module Google
1138
1213
  # access, and allUsers get READER access.
1139
1214
  # @param [Integer] generation Select a specific revision of the file to
1140
1215
  # rewrite. The default is the latest version.
1216
+ # @param [Integer] if_generation_match Makes the operation conditional
1217
+ # on whether the destination file's current generation matches the given value.
1218
+ # Setting to 0 makes the operation succeed only if there are no live
1219
+ # versions of the file.
1220
+ # @param [Integer] if_generation_not_match Makes the operation conditional
1221
+ # on whether the destination file's current generation does not match the given
1222
+ # value. If no live file exists, the precondition fails. Setting to 0
1223
+ # makes the operation succeed only if there is a live version of the file.
1224
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1225
+ # on whether the destination file's current metageneration matches the given value.
1226
+ # @param [Integer] if_metageneration_not_match Makes the operation
1227
+ # conditional on whether the destination file's current metageneration does not
1228
+ # match the given value.
1229
+ # @param [Integer] if_source_generation_match Makes the operation conditional on
1230
+ # whether the source object's current generation matches the given value.
1231
+ # @param [Integer] if_source_generation_not_match Makes the operation conditional
1232
+ # on whether the source object's current generation does not match the given value.
1233
+ # @param [Integer] if_source_metageneration_match Makes the operation conditional
1234
+ # on whether the source object's current metageneration matches the given value.
1235
+ # @param [Integer] if_source_metageneration_not_match Makes the operation conditional
1236
+ # on whether the source object's current metageneration does not match the given value.
1141
1237
  # @param [String] encryption_key Optional. The customer-supplied,
1142
1238
  # AES-256 encryption key used to decrypt the file, if the existing
1143
1239
  # file is encrypted.
@@ -1259,11 +1355,24 @@ module Google
1259
1355
  # f.metadata["rewritten_from"] = "#{file.bucket}/#{file.name}"
1260
1356
  # end
1261
1357
  #
1262
- def rewrite dest_bucket_or_path, dest_path = nil, acl: nil, generation: nil, encryption_key: nil,
1263
- new_encryption_key: nil, new_kms_key: nil, force_copy_metadata: nil
1358
+ def rewrite dest_bucket_or_path,
1359
+ dest_path = nil,
1360
+ acl: nil,
1361
+ generation: nil,
1362
+ if_generation_match: nil,
1363
+ if_generation_not_match: nil,
1364
+ if_metageneration_match: nil,
1365
+ if_metageneration_not_match: nil,
1366
+ if_source_generation_match: nil,
1367
+ if_source_generation_not_match: nil,
1368
+ if_source_metageneration_match: nil,
1369
+ if_source_metageneration_not_match: nil,
1370
+ encryption_key: nil,
1371
+ new_encryption_key: nil,
1372
+ new_kms_key: nil,
1373
+ force_copy_metadata: nil
1264
1374
  ensure_service!
1265
- dest_bucket, dest_path = fix_rewrite_args dest_bucket_or_path,
1266
- dest_path
1375
+ dest_bucket, dest_path = fix_rewrite_args dest_bucket_or_path, dest_path
1267
1376
 
1268
1377
  update_gapi = nil
1269
1378
  if block_given?
@@ -1276,9 +1385,21 @@ module Google
1276
1385
  end
1277
1386
  end
1278
1387
 
1279
- new_gapi = rewrite_gapi bucket, name, update_gapi,
1280
- new_bucket: dest_bucket, new_name: dest_path,
1281
- acl: acl, generation: generation,
1388
+ new_gapi = rewrite_gapi bucket,
1389
+ name,
1390
+ update_gapi,
1391
+ new_bucket: dest_bucket,
1392
+ new_name: dest_path,
1393
+ acl: acl,
1394
+ generation: generation,
1395
+ if_generation_match: if_generation_match,
1396
+ if_generation_not_match: if_generation_not_match,
1397
+ if_metageneration_match: if_metageneration_match,
1398
+ if_metageneration_not_match: if_metageneration_not_match,
1399
+ if_source_generation_match: if_source_generation_match,
1400
+ if_source_generation_not_match: if_source_generation_not_match,
1401
+ if_source_metageneration_match: if_source_metageneration_match,
1402
+ if_source_metageneration_not_match: if_source_metageneration_not_match,
1282
1403
  encryption_key: encryption_key,
1283
1404
  new_encryption_key: new_encryption_key,
1284
1405
  new_kms_key: new_kms_key,
@@ -1375,6 +1496,20 @@ module Google
1375
1496
  # {#generation}. The default behavior is to delete the latest version
1376
1497
  # of the file (regardless of the version to which the file is set,
1377
1498
  # which is the version returned by {#generation}.)
1499
+ # @param [Integer] if_generation_match Makes the operation conditional
1500
+ # on whether the file's current generation matches the given value.
1501
+ # Setting to 0 makes the operation succeed only if there are no live
1502
+ # versions of the file.
1503
+ # @param [Integer] if_generation_not_match Makes the operation conditional
1504
+ # on whether the file's current generation does not match the given
1505
+ # value. If no live file exists, the precondition fails. Setting to 0
1506
+ # makes the operation succeed only if there is a live version of the file.
1507
+ # @param [Integer] if_metageneration_match Makes the operation conditional
1508
+ # on whether the file's current metageneration matches the given value.
1509
+ # @param [Integer] if_metageneration_not_match Makes the operation
1510
+ # conditional on whether the file's current metageneration does not
1511
+ # match the given value.
1512
+ #
1378
1513
  # @return [Boolean] Returns `true` if the file was deleted.
1379
1514
  #
1380
1515
  # @example
@@ -1407,11 +1542,21 @@ module Google
1407
1542
  # file = bucket.file "path/to/my-file.ext"
1408
1543
  # file.delete generation: 123456
1409
1544
  #
1410
- def delete generation: nil
1545
+ def delete generation: nil,
1546
+ if_generation_match: nil,
1547
+ if_generation_not_match: nil,
1548
+ if_metageneration_match: nil,
1549
+ if_metageneration_not_match: nil
1411
1550
  generation = self.generation if generation == true
1412
1551
  ensure_service!
1413
- service.delete_file bucket, name, generation: generation,
1414
- user_project: user_project
1552
+ service.delete_file bucket,
1553
+ name,
1554
+ generation: generation,
1555
+ if_generation_match: if_generation_match,
1556
+ if_generation_not_match: if_generation_not_match,
1557
+ if_metageneration_match: if_metageneration_match,
1558
+ if_metageneration_not_match: if_metageneration_not_match,
1559
+ user_project: user_project
1415
1560
  true
1416
1561
  end
1417
1562
 
@@ -1865,7 +2010,13 @@ module Google
1865
2010
  reload! generation: true
1866
2011
  end
1867
2012
 
1868
- def update_gapi! *attributes
2013
+ def update_gapi! attributes,
2014
+ generation: nil,
2015
+ if_generation_match: nil,
2016
+ if_generation_not_match: nil,
2017
+ if_metageneration_match: nil,
2018
+ if_metageneration_not_match: nil
2019
+ attributes = Array(attributes)
1869
2020
  attributes.flatten!
1870
2021
  return if attributes.empty?
1871
2022
  update_gapi = self.class.gapi_from_attrs @gapi, attributes
@@ -1875,26 +2026,65 @@ module Google
1875
2026
 
1876
2027
  rewrite_attrs = [:storage_class, :kms_key_name]
1877
2028
  @gapi = if attributes.any? { |a| rewrite_attrs.include? a }
1878
- rewrite_gapi \
1879
- bucket, name, update_gapi, user_project: user_project
2029
+ rewrite_gapi bucket,
2030
+ name,
2031
+ update_gapi,
2032
+ generation: generation,
2033
+ if_generation_match: if_generation_match,
2034
+ if_generation_not_match: if_generation_not_match,
2035
+ if_metageneration_match: if_metageneration_match,
2036
+ if_metageneration_not_match: if_metageneration_not_match,
2037
+ user_project: user_project
1880
2038
  else
1881
- service.patch_file \
1882
- bucket, name, update_gapi, user_project: user_project
2039
+ service.patch_file bucket,
2040
+ name,
2041
+ update_gapi,
2042
+ generation: generation,
2043
+ if_generation_match: if_generation_match,
2044
+ if_generation_not_match: if_generation_not_match,
2045
+ if_metageneration_match: if_metageneration_match,
2046
+ if_metageneration_not_match: if_metageneration_not_match,
2047
+ user_project: user_project
1883
2048
  end
1884
2049
  end
1885
2050
 
1886
- def rewrite_gapi bucket, name, updated_gapi,
1887
- new_bucket: nil, new_name: nil, acl: nil,
1888
- generation: nil, encryption_key: nil,
1889
- new_encryption_key: nil, new_kms_key: nil,
2051
+ def rewrite_gapi bucket,
2052
+ name,
2053
+ updated_gapi,
2054
+ new_bucket: nil,
2055
+ new_name: nil,
2056
+ acl: nil,
2057
+ generation: nil,
2058
+ if_generation_match: nil,
2059
+ if_generation_not_match: nil,
2060
+ if_metageneration_match: nil,
2061
+ if_metageneration_not_match: nil,
2062
+ if_source_generation_match: nil,
2063
+ if_source_generation_not_match: nil,
2064
+ if_source_metageneration_match: nil,
2065
+ if_source_metageneration_not_match: nil,
2066
+ encryption_key: nil,
2067
+ new_encryption_key: nil,
2068
+ new_kms_key: nil,
1890
2069
  user_project: nil
1891
2070
  new_bucket ||= bucket
1892
2071
  new_name ||= name
1893
- options = { acl: File::Acl.predefined_rule_for(acl),
1894
- generation: generation, source_key: encryption_key,
1895
- destination_key: new_encryption_key,
1896
- destination_kms_key: new_kms_key,
1897
- user_project: user_project }.delete_if { |_k, v| v.nil? }
2072
+ options = {
2073
+ acl: File::Acl.predefined_rule_for(acl),
2074
+ generation: generation,
2075
+ if_generation_match: if_generation_match,
2076
+ if_generation_not_match: if_generation_not_match,
2077
+ if_metageneration_match: if_metageneration_match,
2078
+ if_metageneration_not_match: if_metageneration_not_match,
2079
+ if_source_generation_match: if_source_generation_match,
2080
+ if_source_generation_not_match: if_source_generation_not_match,
2081
+ if_source_metageneration_match: if_source_metageneration_match,
2082
+ if_source_metageneration_not_match: if_source_metageneration_not_match,
2083
+ source_key: encryption_key,
2084
+ destination_key: new_encryption_key,
2085
+ destination_kms_key: new_kms_key,
2086
+ user_project: user_project
2087
+ }.delete_if { |_k, v| v.nil? }
1898
2088
 
1899
2089
  resp = service.rewrite_file \
1900
2090
  bucket, name, new_bucket, new_name, updated_gapi, **options