| 
									
										
										
										
											2020-10-10 14:16:11 +02:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-03 07:24:35 -07:00
										 |  |  | # Cleans a newly installed keg. | 
					
						
							|  |  |  | # By default: | 
					
						
							| 
									
										
										
										
											2018-10-18 21:42:43 -04:00
										 |  |  | # | 
					
						
							|  |  |  | # * removes `.la` files | 
					
						
							|  |  |  | # * removes `perllocal.pod` files | 
					
						
							|  |  |  | # * removes `.packlist` files | 
					
						
							| 
									
										
										
										
											2012-07-03 07:24:35 -07:00
										 |  |  | # * removes empty directories | 
					
						
							|  |  |  | # * sets permissions on executables | 
					
						
							| 
									
										
										
										
											2014-02-23 21:18:09 -08:00
										 |  |  | # * removes unresolved symlinks | 
					
						
							| 
									
										
										
										
											2010-08-21 11:06:02 -07:00
										 |  |  | class Cleaner | 
					
						
							| 
									
										
										
										
											2020-08-02 14:32:31 +02:00
										 |  |  |   include Context | 
					
						
							| 
									
										
										
										
											2020-08-02 03:01:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Create a cleaner for the given formula. | 
					
						
							| 
									
										
										
										
											2020-08-02 14:32:31 +02:00
										 |  |  |   def initialize(f) | 
					
						
							| 
									
										
										
										
											2013-06-23 12:48:45 -07:00
										 |  |  |     @f = f | 
					
						
							| 
									
										
										
										
											2014-02-23 11:07:37 -08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Clean the keg of the formula. | 
					
						
							| 
									
										
										
										
											2014-02-23 11:07:37 -08:00
										 |  |  |   def clean | 
					
						
							|  |  |  |     ObserverPathnameExtension.reset_counts! | 
					
						
							| 
									
										
										
										
											2014-02-23 17:39:01 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Many formulae include 'lib/charset.alias', but it is not strictly needed | 
					
						
							|  |  |  |     # and will conflict if more than one formula provides it | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     observe_file_removal @f.lib/"charset.alias" | 
					
						
							| 
									
										
										
										
											2014-02-23 17:39:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 17:08:23 +02:00
										 |  |  |     [@f.bin, @f.sbin, @f.lib].each { |d| clean_dir(d) if d.exist? } | 
					
						
							| 
									
										
										
										
											2010-08-21 11:23:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-23 11:07:37 -08:00
										 |  |  |     # Get rid of any info 'dir' files, so they don't conflict at the link stage | 
					
						
							| 
									
										
										
										
											2020-08-19 17:12:32 +01:00
										 |  |  |     info_dir_file = @f.info/"dir" | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     observe_file_removal info_dir_file if info_dir_file.file? && !@f.skip_clean?(info_dir_file) | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-21 23:28:04 -06:00
										 |  |  |     prune | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def observe_file_removal(path) | 
					
						
							| 
									
										
										
										
											2014-07-20 09:54:51 -07:00
										 |  |  |     path.extend(ObserverPathnameExtension).unlink if path.exist? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-23 21:18:09 -08:00
										 |  |  |   # Removes any empty directories in the formula's prefix subtree | 
					
						
							| 
									
										
										
										
											2019-04-08 10:33:49 -07:00
										 |  |  |   # Keeps any empty directories protected by skip_clean | 
					
						
							| 
									
										
										
										
											2014-07-20 09:57:33 -07:00
										 |  |  |   # Removes any unresolved symlinks | 
					
						
							| 
									
										
										
										
											2013-12-21 23:28:04 -06:00
										 |  |  |   def prune | 
					
						
							|  |  |  |     dirs = [] | 
					
						
							|  |  |  |     symlinks = [] | 
					
						
							|  |  |  |     @f.prefix.find do |path| | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |       if path == @f.libexec || @f.skip_clean?(path) | 
					
						
							| 
									
										
										
										
											2013-12-21 23:28:04 -06:00
										 |  |  |         Find.prune | 
					
						
							|  |  |  |       elsif path.symlink? | 
					
						
							|  |  |  |         symlinks << path | 
					
						
							|  |  |  |       elsif path.directory? | 
					
						
							|  |  |  |         dirs << path | 
					
						
							| 
									
										
										
										
											2013-01-08 21:27:18 -08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-23 21:18:09 -08:00
										 |  |  |     # Remove directories opposite from traversal, so that a subtree with no | 
					
						
							|  |  |  |     # actual files gets removed correctly. | 
					
						
							| 
									
										
										
										
											2013-12-21 23:28:04 -06:00
										 |  |  |     dirs.reverse_each do |d| | 
					
						
							|  |  |  |       if d.children.empty? | 
					
						
							| 
									
										
										
										
											2020-08-02 03:01:42 +02:00
										 |  |  |         puts "rmdir: #{d} (empty)" if verbose? | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |         d.rmdir | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2010-08-21 11:06:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-23 21:18:09 -08:00
										 |  |  |     # Remove unresolved symlinks | 
					
						
							| 
									
										
										
										
											2013-12-21 23:28:04 -06:00
										 |  |  |     symlinks.reverse_each do |s| | 
					
						
							|  |  |  |       s.unlink unless s.resolved_path_exists? | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2010-11-09 13:00:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-04 16:10:24 +01:00
										 |  |  |   def executable_path?(path) | 
					
						
							| 
									
										
										
										
											2016-07-12 19:47:27 +01:00
										 |  |  |     path.text_executable? || path.executable? | 
					
						
							| 
									
										
										
										
											2016-07-04 16:10:24 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 17:21:51 +01:00
										 |  |  |   # Both these files are completely unnecessary to package and cause | 
					
						
							|  |  |  |   # pointless conflicts with other formulae. They are removed by Debian, | 
					
						
							|  |  |  |   # Arch & MacPorts amongst other packagers as well. The files are | 
					
						
							|  |  |  |   # created as part of installing any Perl module. | 
					
						
							|  |  |  |   PERL_BASENAMES = Set.new(%w[perllocal.pod .packlist]).freeze | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-19 23:27:58 -07:00
										 |  |  |   # Clean a top-level (bin, sbin, lib) directory, recursively, by fixing file | 
					
						
							|  |  |  |   # permissions and removing .la files, unless the files (or parent | 
					
						
							|  |  |  |   # directories) are protected by skip_clean. | 
					
						
							| 
									
										
										
										
											2014-07-20 09:51:11 -07:00
										 |  |  |   # | 
					
						
							|  |  |  |   # bin and sbin should not have any subdirectories; if either do that is | 
					
						
							|  |  |  |   # caught as an audit warning | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # lib may have a large directory tree (see Erlang for instance), and | 
					
						
							|  |  |  |   # clean_dir applies cleaning rules to the entire tree | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def clean_dir(d) | 
					
						
							| 
									
										
										
										
											2010-08-21 11:06:02 -07:00
										 |  |  |     d.find do |path| | 
					
						
							| 
									
										
										
										
											2013-12-22 13:43:51 -06:00
										 |  |  |       path.extend(ObserverPathnameExtension) | 
					
						
							| 
									
										
										
										
											2012-09-18 16:25:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-22 13:43:50 -06:00
										 |  |  |       Find.prune if @f.skip_clean? path | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-27 18:49:25 -05:00
										 |  |  |       next if path.directory? | 
					
						
							| 
									
										
										
										
											2016-09-22 20:12:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 17:21:51 +01:00
										 |  |  |       if path.extname == ".la" || PERL_BASENAMES.include?(path.basename.to_s) | 
					
						
							| 
									
										
										
										
											2016-07-31 02:00:33 +01:00
										 |  |  |         path.unlink | 
					
						
							| 
									
										
										
										
											2020-11-13 10:07:02 -05:00
										 |  |  |       elsif path.symlink? | 
					
						
							|  |  |  |         # Skip it. | 
					
						
							| 
									
										
										
										
											2013-12-22 13:43:50 -06:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2014-02-23 16:46:44 -08:00
										 |  |  |         # Set permissions for executables and non-executables | 
					
						
							| 
									
										
										
										
											2016-07-04 16:10:24 +01:00
										 |  |  |         perms = if executable_path?(path) | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |           0555
 | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           0444
 | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-08-02 03:01:42 +02:00
										 |  |  |         if debug? | 
					
						
							| 
									
										
										
										
											2014-02-23 16:46:44 -08:00
										 |  |  |           old_perms = path.stat.mode & 0777
 | 
					
						
							| 
									
										
										
										
											2019-11-29 14:54:41 -05:00
										 |  |  |           odebug "Fixing #{path} permissions from #{old_perms.to_s(8)} to #{perms.to_s(8)}" if perms != old_perms | 
					
						
							| 
									
										
										
										
											2014-02-23 16:46:44 -08:00
										 |  |  |         end | 
					
						
							|  |  |  |         path.chmod perms | 
					
						
							| 
									
										
										
										
											2010-08-21 11:06:02 -07:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							| 
									
										
										
										
											2016-07-04 16:10:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | require "extend/os/cleaner" |