| 
									
										
										
										
											2024-07-11 19:57:12 +01:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-23 20:59:21 +02:00
										 |  |  | module UnpackStrategy | 
					
						
							| 
									
										
										
										
											2020-08-09 06:09:05 +02:00
										 |  |  |   # Strategy for unpacking directories. | 
					
						
							| 
									
										
										
										
											2018-07-23 20:59:21 +02:00
										 |  |  |   class Directory | 
					
						
							|  |  |  |     include UnpackStrategy | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-05 22:29:41 -07:00
										 |  |  |     sig { override.returns(T::Array[String]) } | 
					
						
							| 
									
										
										
										
											2018-07-30 09:49:59 +02:00
										 |  |  |     def self.extensions | 
					
						
							|  |  |  |       [] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-11 19:57:12 +01:00
										 |  |  |     sig { override.params(path: Pathname).returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2018-07-29 10:04:51 +02:00
										 |  |  |     def self.can_extract?(path) | 
					
						
							| 
									
										
										
										
											2018-07-23 20:59:21 +02:00
										 |  |  |       path.directory? | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 17:19:53 -04:00
										 |  |  |     sig { | 
					
						
							|  |  |  |       params( | 
					
						
							|  |  |  |         path:         T.any(String, Pathname), | 
					
						
							|  |  |  |         ref_type:     T.nilable(Symbol), | 
					
						
							|  |  |  |         ref:          T.nilable(String), | 
					
						
							|  |  |  |         merge_xattrs: T::Boolean, | 
					
						
							|  |  |  |         move:         T::Boolean, | 
					
						
							|  |  |  |       ).void | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     def initialize(path, ref_type: nil, ref: nil, merge_xattrs: false, move: false) | 
					
						
							|  |  |  |       super(path, ref_type:, ref:, merge_xattrs:) | 
					
						
							|  |  |  |       @move = move | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-23 20:59:21 +02:00
										 |  |  |     private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-11 11:05:42 +01:00
										 |  |  |     sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).void } | 
					
						
							| 
									
										
										
										
											2018-07-23 20:59:21 +02:00
										 |  |  |     def extract_to_dir(unpack_dir, basename:, verbose:) | 
					
						
							| 
									
										
										
										
											2024-10-05 17:19:53 -04:00
										 |  |  |       move_to_dir(unpack_dir, verbose:) if @move | 
					
						
							| 
									
										
										
										
											2024-10-03 15:50:23 -04:00
										 |  |  |       path_children = path.children | 
					
						
							|  |  |  |       return if path_children.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 17:19:53 -04:00
										 |  |  |       system_command!("cp", args: ["-pR", *path_children, unpack_dir], verbose:) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Move all files from source `path` to target `unpack_dir`. Any existing | 
					
						
							|  |  |  |     # subdirectories are not modified and only the contents are moved. | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     # @raise [RuntimeError] on unsupported `mv` operation, e.g. overwriting a file with a directory | 
					
						
							|  |  |  |     sig { params(unpack_dir: Pathname, verbose: T::Boolean).void } | 
					
						
							|  |  |  |     def move_to_dir(unpack_dir, verbose:) | 
					
						
							|  |  |  |       path.find do |src| | 
					
						
							|  |  |  |         next if src == path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dst = unpack_dir/src.relative_path_from(path) | 
					
						
							|  |  |  |         if dst.exist? | 
					
						
							|  |  |  |           dst_real_dir = dst.directory? && !dst.symlink? | 
					
						
							|  |  |  |           src_real_dir = src.directory? && !src.symlink? | 
					
						
							|  |  |  |           # Avoid moving a directory over an existing non-directory and vice versa. | 
					
						
							|  |  |  |           # This outputs the same error message as GNU mv which is more readable than macOS mv. | 
					
						
							|  |  |  |           raise "mv: cannot overwrite non-directory '#{dst}' with directory '#{src}'" if src_real_dir && !dst_real_dir | 
					
						
							|  |  |  |           raise "mv: cannot overwrite directory '#{dst}' with non-directory '#{src}'" if !src_real_dir && dst_real_dir | 
					
						
							|  |  |  |           # Defer writing over existing directories. Handle this later on to copy attributes | 
					
						
							|  |  |  |           next if dst_real_dir | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           FileUtils.rm(dst, verbose:) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         FileUtils.mv(src, dst, verbose:) | 
					
						
							|  |  |  |         Find.prune | 
					
						
							| 
									
										
										
										
											2018-07-23 20:59:21 +02:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |