@@ -71,8 +71,25 @@ impl<'a> ProjectBuilder<'a> {
7171 } )
7272 } ) ;
7373
74- // Process sequentially with &mut self
75- let collected_entries = Arc :: try_unwrap ( collected) . unwrap ( ) . into_inner ( ) . unwrap ( ) ;
74+ // Process sequentially with &mut self without panicking on Arc/Mutex unwraps
75+ let collected_entries = match Arc :: try_unwrap ( collected) {
76+ // We are the sole owner of the Arc
77+ Ok ( mutex) => match mutex. into_inner ( ) {
78+ // Mutex not poisoned
79+ Ok ( entries) => entries,
80+ // Recover entries even if the mutex was poisoned
81+ Err ( poisoned) => poisoned. into_inner ( ) ,
82+ } ,
83+ // There are still other Arc references; lock and take the contents
84+ Err ( arc) => match arc. lock ( ) {
85+ Ok ( mut guard) => std:: mem:: take ( & mut * guard) ,
86+ // Recover guard even if poisoned, then take contents
87+ Err ( poisoned) => {
88+ let mut guard = poisoned. into_inner ( ) ;
89+ std:: mem:: take ( & mut * guard)
90+ }
91+ } ,
92+ } ;
7693 for entry in collected_entries {
7794 entry_types. push ( self . build_entry_type ( entry) ?) ;
7895 }
@@ -89,11 +106,10 @@ impl<'a> ProjectBuilder<'a> {
89106 if is_dir {
90107 return Ok ( EntryType :: Directory ( absolute_path. to_owned ( ) , relative_path. to_owned ( ) ) ) ;
91108 }
92- let file_name = relative_path
93- . file_name ( )
94- . expect ( "expected a file_name" )
95- . to_string_lossy ( )
96- . to_lowercase ( ) ;
109+ let file_name = match relative_path. file_name ( ) {
110+ Some ( name) => name. to_string_lossy ( ) . to_lowercase ( ) ,
111+ None => return Ok ( EntryType :: NullEntry ( ) ) ,
112+ } ;
97113
98114 match file_name. as_str ( ) {
99115 name if name == "package.yml"
@@ -142,11 +158,14 @@ impl<'a> ProjectBuilder<'a> {
142158 }
143159 EntryType :: Directory ( absolute_path, relative_path) => {
144160 if relative_path. parent ( ) == Some ( Path :: new ( & self . config . vendored_gems_path ) ) {
145- let file_name = relative_path. file_name ( ) . expect ( "expected a file_name" ) ;
146- gems. push ( VendoredGem {
147- path : absolute_path,
148- name : file_name. to_string_lossy ( ) . to_string ( ) ,
149- } ) ;
161+ if let Some ( file_name) = relative_path. file_name ( ) {
162+ gems. push ( VendoredGem {
163+ path : absolute_path,
164+ name : file_name. to_string_lossy ( ) . to_string ( ) ,
165+ } ) ;
166+ } else {
167+ warn ! ( "Vendored gem path without file name: {:?}" , relative_path) ;
168+ }
150169 }
151170 }
152171 EntryType :: RubyPackage ( absolute_path, relative_path) => {
0 commit comments