@@ -72,29 +72,10 @@ struct ImageMetadata {
7272struct ImageInfo {
7373 path : std:: path:: PathBuf ,
7474 relative_path : String ,
75- hash : String ,
7675 width : u32 ,
7776 height : u32 ,
7877}
7978
80- impl ImageInfo {
81- fn into_manifest_entry ( self ) -> ( String , ImageMetadata ) {
82- let image_file_name = Path :: new ( & self . relative_path )
83- . file_name ( )
84- . unwrap_or_default ( )
85- . to_string_lossy ( )
86- . into_owned ( ) ;
87- (
88- self . hash ,
89- ImageMetadata {
90- image_file_name,
91- width : self . width ,
92- height : self . height ,
93- } ,
94- )
95- }
96- }
97-
9879pub fn execute ( matches : & ArgMatches ) -> Result < ( ) > {
9980 eprintln ! ( "{EXPERIMENTAL_WARNING}" ) ;
10081
@@ -138,15 +119,12 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
138119 style( images. len( ) ) . yellow( ) ,
139120 if images. len( ) == 1 { "file" } else { "files" }
140121 ) ;
141- upload_images ( & images, & org, & project) ?;
122+ let manifest_entries = upload_images ( images, & org, & project) ?;
142123
143124 // Build manifest from discovered images
144125 let manifest = SnapshotsManifest {
145126 app_id : app_id. clone ( ) ,
146- images : images
147- . into_iter ( )
148- . map ( ImageInfo :: into_manifest_entry)
149- . collect ( ) ,
127+ images : manifest_entries,
150128 } ;
151129
152130 // POST manifest to API
@@ -192,12 +170,10 @@ fn collect_images(dir: &Path) -> Result<Vec<ImageInfo>> {
192170}
193171/// Builds [`ImageInfo`] for a discovered image path during snapshot collection.
194172///
195- /// Returns `Ok(Some(ImageInfo))` when the file is readable and its dimensions can
196- /// be parsed, `Ok(None)` when the file should be skipped (currently when image
197- /// dimensions cannot be determined), and `Err` for hard failures such as I/O
198- /// errors reading the file.
173+ /// Returns `Ok(Some(ImageInfo))` when the image dimensions can be parsed,
174+ /// `Ok(None)` when the file should be skipped (e.g. when dimensions cannot be
175+ /// determined), and `Err` for hard failures.
199176fn collect_image_info ( dir : & Path , path : & Path ) -> Result < Option < ImageInfo > > {
200- let contents = fs:: read ( path) . with_context ( || format ! ( "Failed to read: {}" , path. display( ) ) ) ?;
201177 let ( width, height) = match imagesize:: size ( path) {
202178 Ok ( dims) => ( dims. width as u32 , dims. height as u32 ) ,
203179 Err ( err) => {
@@ -211,11 +187,9 @@ fn collect_image_info(dir: &Path, path: &Path) -> Result<Option<ImageInfo>> {
211187 . to_string_lossy ( )
212188 . to_string ( ) ;
213189
214- let hash = compute_sha256_hash ( & contents) ;
215190 Ok ( Some ( ImageInfo {
216191 path : path. to_path_buf ( ) ,
217192 relative_path : relative,
218- hash,
219193 width,
220194 height,
221195 } ) )
@@ -242,7 +216,11 @@ fn is_image_file(path: &Path) -> bool {
242216 . unwrap_or ( false )
243217}
244218
245- fn upload_images ( images : & [ ImageInfo ] , org : & str , project : & str ) -> Result < ( ) > {
219+ fn upload_images (
220+ images : Vec < ImageInfo > ,
221+ org : & str ,
222+ project : & str ,
223+ ) -> Result < HashMap < String , ImageMetadata > > {
246224 let api = Api :: current ( ) ;
247225 let authenticated_api = api. authenticated ( ) ?;
248226 let options = authenticated_api. fetch_snapshots_upload_options ( org, project) ?;
@@ -270,21 +248,35 @@ fn upload_images(images: &[ImageInfo], org: &str, project: &str) -> Result<()> {
270248 . context ( "Failed to create tokio runtime" ) ?;
271249
272250 let mut many_builder = session. many ( ) ;
251+ let mut manifest_entries = HashMap :: new ( ) ;
252+ let image_count = images. len ( ) ;
273253
274254 for image in images {
275255 debug ! ( "Processing image: {}" , image. path. display( ) ) ;
276256
277257 let contents = fs:: read ( & image. path )
278258 . with_context ( || format ! ( "Failed to read image: {}" , image. path. display( ) ) ) ?;
259+ let hash = compute_sha256_hash ( & contents) ;
279260
280- info ! ( "Queueing {} as {}" , image. path . display ( ) , image . hash) ;
261+ info ! ( "Queueing {} as {}" , image. relative_path , hash) ;
281262
282263 many_builder = many_builder. push (
283264 session
284265 . put ( contents)
285- . key ( & image . hash )
266+ . key ( & hash)
286267 . expiration_policy ( expiration) ,
287268 ) ;
269+
270+ let image_file_name = Path :: new ( & image. relative_path )
271+ . file_name ( )
272+ . unwrap_or_default ( )
273+ . to_string_lossy ( )
274+ . into_owned ( ) ;
275+ manifest_entries. insert ( hash, ImageMetadata {
276+ image_file_name,
277+ width : image. width ,
278+ height : image. height ,
279+ } ) ;
288280 }
289281
290282 let upload = runtime
@@ -296,10 +288,10 @@ fn upload_images(images: &[ImageInfo], org: &str, project: &str) -> Result<()> {
296288 println ! (
297289 "{} Uploaded {} image {}" ,
298290 style( ">" ) . dim( ) ,
299- style( images . len ( ) ) . yellow( ) ,
300- if images . len ( ) == 1 { "file" } else { "files" }
291+ style( image_count ) . yellow( ) ,
292+ if image_count == 1 { "file" } else { "files" }
301293 ) ;
302- Ok ( ( ) )
294+ Ok ( manifest_entries )
303295 }
304296 Err ( errors) => {
305297 eprintln ! ( "There were errors uploading images:" ) ;
@@ -309,7 +301,7 @@ fn upload_images(images: &[ImageInfo], org: &str, project: &str) -> Result<()> {
309301 anyhow:: bail!(
310302 "Failed to upload {} out of {} images" ,
311303 errors. len( ) ,
312- images . len ( )
304+ image_count
313305 )
314306 }
315307 }
0 commit comments