@@ -116,43 +116,75 @@ def local_catalogue(self):
116116
117117 @functools .lru_cache (maxsize = 8 )
118118 def get_remote_catalogue (self ):
119- _ , b = self ._boto_bucket ()
120- rmt_cat_fp = self .file_prepper_wrapped ('.s3sup.catalogue.csv' )
121- f = b .Object (rmt_cat_fp .s3_path ())
122119 remote_cat = s3sup .catalogue .Catalogue (
123120 preserve_deleted_files = self ._preserve_deleted_files )
124121
122+ _ , b = self ._boto_bucket ()
123+ old_cat_fp = self .file_prepper_wrapped ('.s3sup.catalogue.csv' )
124+ old_f = b .Object (old_cat_fp .s3_path ())
125+
126+ new_cat_fp = self .file_prepper_wrapped ('.s3sup.cat' )
127+ new_f = b .Object (new_cat_fp .s3_path ())
128+
125129 hndl , tmpp = tempfile .mkstemp ()
126130 os .close (hndl )
127131 try :
128- f .download_file (tmpp )
129- remote_cat .from_csv (tmpp )
132+ new_f .download_file (tmpp )
133+ remote_cat .from_sqlite (tmpp )
130134 except botocore .exceptions .NoCredentialsError :
131135 raise click .UsageError (
132136 'Cannot find AWS credentials.\n -> Configure AWS credentials '
133- ' using any mthod that the underlying boto3 library supports:'
137+ ' using any method that the underlying boto3 library supports:'
134138 '\n -> https://boto3.amazonaws.com/v1/documentation/'
135139 'api/latest/guide/configuration.html' )
136140 except botocore .exceptions .ClientError :
137141 if self .verbose :
138142 click .echo (
139- 'Project not uploaded before (no {0} on S3).' .format (
140- rmt_cat_fp .s3_path ()))
143+ ('Could not find SQLite based remote catalogue on S3 '
144+ '(expected at {0}).' ).format (new_cat_fp .s3_path ()))
145+ try :
146+ old_f .download_file (tmpp )
147+ remote_cat .from_csv (tmpp )
148+ click .echo (click .style ((
149+ 'WARNING: After the next s3sup push, do not attempt to '
150+ 'use older versions of s3sup (0.3.0 or below) with this '
151+ 'project, as they will no longer be able to read the '
152+ 'remote catalogue.' ), fg = 'blue' ))
153+ except botocore .exceptions .ClientError :
154+ if self .verbose :
155+ click .echo (
156+ ('Could not find older CSV based remote catalogue on '
157+ 'S3 either (expected at {0}). This indicates the '
158+ 'project has never been pushed to S3 before.' ).format (
159+ old_cat_fp .s3_path ()))
160+ pass
141161 pass
142162 os .remove (tmpp )
143163 return remote_cat
144164
145165 def write_remote_catalogue (self , catalogue ):
146166 hndl , tmpp = tempfile .mkstemp ()
147167 os .close (hndl )
148- catalogue .to_csv (tmpp )
149- rmt_cat_fp = self .file_prepper_wrapped ('.s3sup.catalogue.csv ' )
168+ catalogue .to_sqlite (tmpp )
169+ rmt_cat_fp = self .file_prepper_wrapped ('.s3sup.cat ' )
150170 _ , b = self ._boto_bucket ()
151171 o = b .Object (rmt_cat_fp .s3_path ())
152172 with open (tmpp , 'rb' ) as lf :
153173 o .put (Body = lf , ACL = 'private' )
154174 os .remove (tmpp )
155175
176+ # Deliberately break older s3sup clients <= 0.3.0.
177+ # This file even needs uploading even for projects that have never used
178+ # the old format, just in-case an old version of s3sup is used on it
179+ # in the future (perhaps if part of a CI/CD system is used).
180+ old_rmt_cat_fp = self .file_prepper_wrapped ('.s3sup.catalogue.csv' )
181+ the_breaker = (
182+ b'\xF9 \xF9 This is a deliberately corrupt old version of the s3sup '
183+ b'catalogue format It is not used any more and this file is only '
184+ b'here to cause s3sup clients <= 0.3.0 to fail, rather than have '
185+ b'them try to upload everything again.' )
186+ b .Object (old_rmt_cat_fp .s3_path ()).put (Body = the_breaker , ACL = 'private' )
187+
156188 def calculate_diff (self ):
157189 local_cat = self .local_catalogue ()
158190 remote_cat = self .get_remote_catalogue ()
@@ -171,7 +203,7 @@ def sync(self):
171203
172204 if self .dryrun :
173205 click .echo (click .style (
174- 'Not making any changes as this is a dryrun .' , fg = 'blue' ))
206+ 'Not making any changes as this is a dry run .' , fg = 'blue' ))
175207 return changes
176208
177209 _ , b = self ._boto_bucket ()
0 commit comments