@@ -3,6 +3,7 @@ use super::Tarballer;
33use crate :: compression:: CompressionFormats ;
44use crate :: util:: * ;
55use anyhow:: { bail, format_err, Context , Result } ;
6+ use std:: collections:: BTreeSet ;
67use std:: io:: Write ;
78use std:: path:: Path ;
89
@@ -121,13 +122,14 @@ impl Generator {
121122
122123/// Copies the `src` directory recursively to `dst`, writing `manifest.in` too.
123124fn copy_and_manifest ( src : & Path , dst : & Path , bulk_dirs : & str ) -> Result < ( ) > {
124- let manifest = create_new_file ( dst. join ( "manifest.in" ) ) ?;
125+ let mut manifest = create_new_file ( dst. join ( "manifest.in" ) ) ?;
125126 let bulk_dirs: Vec < _ > = bulk_dirs
126127 . split ( ',' )
127128 . filter ( |s| !s. is_empty ( ) )
128129 . map ( Path :: new)
129130 . collect ( ) ;
130131
132+ let mut paths = BTreeSet :: new ( ) ;
131133 copy_with_callback ( src, dst, |path, file_type| {
132134 // We need paths to be compatible with both Unix and Windows.
133135 if path
@@ -157,14 +159,20 @@ fn copy_and_manifest(src: &Path, dst: &Path, bulk_dirs: &str) -> Result<()> {
157159 if file_type. is_dir ( ) {
158160 // Only manifest directories that are explicitly bulk.
159161 if bulk_dirs. contains ( & path) {
160- writeln ! ( & manifest , "dir:{}" , string) ? ;
162+ paths . insert ( format ! ( "dir:{}\n " , string) ) ;
161163 }
162164 } else {
163165 // Only manifest files that aren't under bulk directories.
164166 if !bulk_dirs. iter ( ) . any ( |d| path. starts_with ( d) ) {
165- writeln ! ( & manifest , "file:{}" , string) ? ;
167+ paths . insert ( format ! ( "file:{}\n " , string) ) ;
166168 }
167169 }
168170 Ok ( ( ) )
169- } )
171+ } ) ?;
172+
173+ for path in paths {
174+ manifest. write_all ( path. as_bytes ( ) ) ?;
175+ }
176+
177+ Ok ( ( ) )
170178}
0 commit comments