| 
									
										
										
										
											2023-04-01 18:56:42 -07:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-04 22:55:00 -07:00
										 |  |  | class Keg | 
					
						
							| 
									
										
										
										
											2019-04-19 21:46:20 +09:00
										 |  |  |   GENERIC_KEG_LINK_DIRECTORIES = (remove_const :KEG_LINK_DIRECTORIES).freeze | 
					
						
							| 
									
										
										
										
											2018-10-04 22:55:00 -07:00
										 |  |  |   KEG_LINK_DIRECTORIES = (GENERIC_KEG_LINK_DIRECTORIES + ["Frameworks"]).freeze | 
					
						
							| 
									
										
										
										
											2019-10-22 17:52:09 -07:00
										 |  |  |   GENERIC_MUST_EXIST_SUBDIRECTORIES = (remove_const :MUST_EXIST_SUBDIRECTORIES).freeze | 
					
						
							|  |  |  |   MUST_EXIST_SUBDIRECTORIES = ( | 
					
						
							|  |  |  |     GENERIC_MUST_EXIST_SUBDIRECTORIES + | 
					
						
							|  |  |  |     [HOMEBREW_PREFIX/"Frameworks"] | 
					
						
							|  |  |  |   ).sort.uniq.freeze | 
					
						
							| 
									
										
										
										
											2019-10-19 17:49:50 -07:00
										 |  |  |   GENERIC_MUST_EXIST_DIRECTORIES = (remove_const :MUST_EXIST_DIRECTORIES).freeze | 
					
						
							| 
									
										
										
										
											2019-10-22 17:52:09 -07:00
										 |  |  |   MUST_EXIST_DIRECTORIES = ( | 
					
						
							|  |  |  |     GENERIC_MUST_EXIST_DIRECTORIES + | 
					
						
							|  |  |  |     [HOMEBREW_PREFIX/"Frameworks"] | 
					
						
							|  |  |  |   ).sort.uniq.freeze | 
					
						
							|  |  |  |   GENERIC_MUST_BE_WRITABLE_DIRECTORIES = (remove_const :MUST_BE_WRITABLE_DIRECTORIES).freeze | 
					
						
							|  |  |  |   MUST_BE_WRITABLE_DIRECTORIES = ( | 
					
						
							|  |  |  |     GENERIC_MUST_BE_WRITABLE_DIRECTORIES + | 
					
						
							|  |  |  |     [HOMEBREW_PREFIX/"Frameworks"] | 
					
						
							|  |  |  |   ).sort.uniq.freeze | 
					
						
							| 
									
										
										
										
											2021-07-03 19:23:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   undef binary_executable_or_library_files | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def binary_executable_or_library_files | 
					
						
							|  |  |  |     mach_o_files | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def codesign_patched_binary(file) | 
					
						
							|  |  |  |     return if MacOS.version < :big_sur | 
					
						
							| 
									
										
										
										
											2023-08-23 11:48:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     unless Hardware::CPU.arm? | 
					
						
							|  |  |  |       result = system_command("codesign", args: ["--verify", file], print_stderr: false) | 
					
						
							|  |  |  |       return unless result.stderr.match?(/invalid signature/i) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     odebug "Codesigning #{file}" | 
					
						
							| 
									
										
										
										
											2022-10-03 22:55:26 -04:00
										 |  |  |     prepare_codesign_writable_files(file) do | 
					
						
							|  |  |  |       # Use quiet_system to squash notifications about resigning binaries | 
					
						
							|  |  |  |       # which already have valid signatures. | 
					
						
							|  |  |  |       return if quiet_system("codesign", "--sign", "-", "--force", | 
					
						
							|  |  |  |                              "--preserve-metadata=entitlements,requirements,flags,runtime", | 
					
						
							|  |  |  |                              file) | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 22:55:26 -04:00
										 |  |  |       # If the codesigning fails, it may be a bug in Apple's codesign utility | 
					
						
							|  |  |  |       # A known workaround is to copy the file to another inode, then move it back | 
					
						
							|  |  |  |       # erasing the previous file. Then sign again. | 
					
						
							|  |  |  |       # | 
					
						
							|  |  |  |       # TODO: remove this once the bug in Apple's codesign utility is fixed | 
					
						
							|  |  |  |       Dir::Tmpname.create("workaround") do |tmppath| | 
					
						
							|  |  |  |         FileUtils.cp file, tmppath | 
					
						
							|  |  |  |         FileUtils.mv tmppath, file, force: true | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Try signing again | 
					
						
							|  |  |  |       odebug "Codesigning (2nd try) #{file}" | 
					
						
							|  |  |  |       result = system_command("codesign", args: [ | 
					
						
							|  |  |  |         "--sign", "-", "--force", | 
					
						
							|  |  |  |         "--preserve-metadata=entitlements,requirements,flags,runtime", | 
					
						
							|  |  |  |         file | 
					
						
							|  |  |  |       ], print_stderr: false) | 
					
						
							|  |  |  |       return if result.success? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # If it fails again, error out | 
					
						
							|  |  |  |       onoe <<~EOS | 
					
						
							|  |  |  |         Failed applying an ad-hoc signature to #{file}: | 
					
						
							|  |  |  |         #{result.stderr} | 
					
						
							|  |  |  |       EOS | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-10-03 22:55:26 -04:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 22:55:26 -04:00
										 |  |  |   def prepare_codesign_writable_files(file) | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  |     result = system_command("codesign", args: [ | 
					
						
							| 
									
										
										
										
											2022-10-03 22:55:26 -04:00
										 |  |  |       "--display", "--file-list", "-", file | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  |     ], print_stderr: false) | 
					
						
							| 
									
										
										
										
											2022-10-03 22:55:26 -04:00
										 |  |  |     return unless result.success? | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 22:55:26 -04:00
										 |  |  |     files = result.stdout.lines.map { |f| Pathname(f.chomp) } | 
					
						
							|  |  |  |     saved_perms = {} | 
					
						
							|  |  |  |     files.each do |f| | 
					
						
							|  |  |  |       unless f.writable_real? | 
					
						
							|  |  |  |         saved_perms[f] = f.stat.mode | 
					
						
							|  |  |  |         FileUtils.chmod "u+rw", f.to_path | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     yield | 
					
						
							|  |  |  |   ensure | 
					
						
							|  |  |  |     saved_perms&.each do |f, p| | 
					
						
							|  |  |  |       f.chmod p if p | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-04-08 18:09:25 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2022-07-26 00:00:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-12 16:47:56 +00:00
										 |  |  |   undef prepare_debug_symbols | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 11:08:52 +01:00
										 |  |  |   def prepare_debug_symbols | 
					
						
							| 
									
										
										
										
											2022-07-26 10:00:05 +01:00
										 |  |  |     binary_executable_or_library_files.each do |file| | 
					
						
							|  |  |  |       odebug "Extracting symbols #{file}" | 
					
						
							| 
									
										
										
										
											2022-07-26 00:00:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 12:15:53 +01:00
										 |  |  |       result = system_command("dsymutil", args: [file], print_stderr: false) | 
					
						
							| 
									
										
										
										
											2022-07-26 10:00:05 +01:00
										 |  |  |       next if result.success? | 
					
						
							| 
									
										
										
										
											2022-07-26 00:00:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 10:00:05 +01:00
										 |  |  |       # If it fails again, error out | 
					
						
							| 
									
										
										
										
											2022-07-30 11:41:05 +01:00
										 |  |  |       ofail <<~EOS | 
					
						
							| 
									
										
										
										
											2022-07-26 10:00:05 +01:00
										 |  |  |         Failed to extract symbols from #{file}: | 
					
						
							|  |  |  |         #{result.stderr} | 
					
						
							|  |  |  |       EOS | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2022-07-26 00:00:45 +01:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2022-12-12 16:47:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   undef consistent_reproducible_symlink_permissions! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Needed to make symlink permissions consistent on macOS and Linux for | 
					
						
							|  |  |  |   # reproducible bottles. | 
					
						
							|  |  |  |   def consistent_reproducible_symlink_permissions! | 
					
						
							| 
									
										
										
										
											2023-04-01 18:56:42 -07:00
										 |  |  |     path.find do |file| | 
					
						
							| 
									
										
										
										
											2022-12-12 16:47:56 +00:00
										 |  |  |       File.lchmod 0777, file if file.symlink? | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-10-04 22:55:00 -07:00
										 |  |  | end |