@@ -284,13 +284,16 @@ final class ExportedPackage {
284284 ///
285285 /// This method will copy GCS objects, when necessary, relying on
286286 /// [SourceObjectInfo.md5Hash] to avoid copying objects that haven't changed.
287+ /// If [forceWrite] is given all files will be rewritten ignoring their
288+ /// previous state.
287289 ///
288290 /// [versions] **must** have an entry for each version that exists.
289291 /// This will **delete** tarballs for versions that do not exist in
290292 /// [versions] .
291293 Future <void > synchronizeTarballs (
292- Map <String , SourceObjectInfo > versions,
293- ) async {
294+ Map <String , SourceObjectInfo > versions, {
295+ bool forceWrite = false ,
296+ }) async {
294297 await Future .wait ([
295298 ..._owner._prefixes.map ((prefix) async {
296299 final pfx = '$prefix /api/archives/$_package -' ;
@@ -314,7 +317,7 @@ final class ExportedPackage {
314317 );
315318
316319 final info = versions[version];
317- if (info != null ) {
320+ if (info != null && ! forceWrite ) {
318321 await tarball (version)._copyToPrefixFromIfNotContentEquals (
319322 prefix,
320323 info,
@@ -342,6 +345,7 @@ final class ExportedPackage {
342345 prefix,
343346 versions[v]! ,
344347 null ,
348+ forceWrite: forceWrite,
345349 );
346350 });
347351 }));
@@ -495,7 +499,10 @@ final class ExportedJsonFile<T> extends ExportedObject {
495499 }
496500
497501 /// Write [data] as gzipped JSON in UTF-8 format.
498- Future <void > write (T data) async {
502+ ///
503+ /// This will only write of `Content-Length` and `md5Hash` doesn't match the
504+ /// existing file, or if [forceWrite] is given.
505+ Future <void > write (T data, {bool forceWrite = false }) async {
499506 final gzipped = _jsonGzip.encode (data);
500507 final metadata = _metadata ();
501508
@@ -505,6 +512,7 @@ final class ExportedJsonFile<T> extends ExportedObject {
505512 prefix + _objectName,
506513 gzipped,
507514 metadata,
515+ forceWrite: forceWrite,
508516 );
509517 });
510518 }));
@@ -542,14 +550,18 @@ final class ExportedBlob extends ExportedObject {
542550 }
543551
544552 /// Write binary blob to this file.
545- Future <void > write (List <int > data) async {
553+ ///
554+ /// This will only write of `Content-Length` and `md5Hash` doesn't match the
555+ /// existing file, or if [forceWrite] is given.
556+ Future <void > write (List <int > data, {bool forceWrite = false }) async {
546557 final metadata = _metadata ();
547558 await Future .wait (_owner._prefixes.map ((prefix) async {
548559 await _owner._pool.withResource (() async {
549560 await _owner._bucket.writeBytesIfDifferent (
550561 prefix + _objectName,
551562 data,
552563 metadata,
564+ forceWrite: forceWrite,
553565 );
554566 });
555567 }));
@@ -563,7 +575,11 @@ final class ExportedBlob extends ExportedObject {
563575 /// [source] is required to be [SourceObjectInfo] for the source object.
564576 /// This method will use [ObjectInfo.length] and [ObjectInfo.md5Hash] to
565577 /// determine if it's necessary to copy the object.
566- Future <void > copyFrom (SourceObjectInfo source) async {
578+ /// If [forceWrite] is given, this method will always copy the object.
579+ Future <void > copyFrom (
580+ SourceObjectInfo source, {
581+ bool forceWrite = false ,
582+ }) async {
567583 await Future .wait (_owner._prefixes.map ((prefix) async {
568584 await _owner._pool.withResource (() async {
569585 final dst = prefix + _objectName;
@@ -572,6 +588,7 @@ final class ExportedBlob extends ExportedObject {
572588 prefix,
573589 source,
574590 await _owner._bucket.tryInfo (dst),
591+ forceWrite: forceWrite,
575592 );
576593 });
577594 }));
@@ -592,12 +609,13 @@ final class ExportedBlob extends ExportedObject {
592609 Future <void > _copyToPrefixFromIfNotContentEquals (
593610 String prefix,
594611 SourceObjectInfo source,
595- ObjectInfo ? destinationInfo,
596- ) async {
612+ ObjectInfo ? destinationInfo, {
613+ bool forceWrite = false ,
614+ }) async {
597615 final dst = prefix + _objectName;
598616
599617 // Check if the dst already exists
600- if (destinationInfo != null ) {
618+ if (destinationInfo != null && ! forceWrite ) {
601619 if (destinationInfo.name != dst) {
602620 throw ArgumentError .value (
603621 destinationInfo,
@@ -633,15 +651,18 @@ extension on Bucket {
633651 Future <void > writeBytesIfDifferent (
634652 String name,
635653 List <int > bytes,
636- ObjectMetadata metadata,
637- ) async {
638- if (await tryInfo (name) case final info? ) {
639- if (info.isSameContent (bytes)) {
640- if (info.metadata.validated
641- .isBefore (clock.agoBy (_updateValidatedAfter))) {
642- await updateMetadata (name, metadata);
654+ ObjectMetadata metadata, {
655+ bool forceWrite = false ,
656+ }) async {
657+ if (! forceWrite) {
658+ if (await tryInfo (name) case final info? ) {
659+ if (info.isSameContent (bytes)) {
660+ if (info.metadata.validated
661+ .isBefore (clock.agoBy (_updateValidatedAfter))) {
662+ await updateMetadata (name, metadata);
663+ }
664+ return ;
643665 }
644- return ;
645666 }
646667 }
647668
0 commit comments