| 
									
										
										
										
											2024-08-10 23:58:53 +01:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  | require "abstract_command" | 
					
						
							| 
									
										
										
										
											2018-07-26 10:49:55 +01:00
										 |  |  | require "caveats" | 
					
						
							| 
									
										
										
										
											2020-11-02 11:20:09 +00:00
										 |  |  | require "unlink" | 
					
						
							| 
									
										
										
										
											2012-10-20 20:54:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-18 22:41:47 -05:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |   module Cmd | 
					
						
							|  |  |  |     class Link < AbstractCommand | 
					
						
							|  |  |  |       cmd_args do | 
					
						
							|  |  |  |         description <<~EOS | 
					
						
							|  |  |  |           Symlink all of <formula>'s installed files into Homebrew's prefix. | 
					
						
							|  |  |  |           This is done automatically when you install formulae but can be useful | 
					
						
							|  |  |  |           for manual installations. | 
					
						
							| 
									
										
										
										
											2019-12-13 15:39:55 -05:00
										 |  |  |         EOS | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |         switch "--overwrite", | 
					
						
							|  |  |  |                description: "Delete files that already exist in the prefix while linking." | 
					
						
							|  |  |  |         switch "-n", "--dry-run", | 
					
						
							|  |  |  |                description: "List files which would be linked or deleted by " \ | 
					
						
							|  |  |  |                             "`brew link --overwrite` without actually linking or deleting any files." | 
					
						
							|  |  |  |         switch "-f", "--force", | 
					
						
							|  |  |  |                description: "Allow keg-only formulae to be linked." | 
					
						
							|  |  |  |         switch "--HEAD", | 
					
						
							|  |  |  |                description: "Link the HEAD version of the formula if it is installed." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         named_args :installed_formula, min: 1
 | 
					
						
							| 
									
										
										
										
											2018-07-10 09:32:42 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-06-17 16:54:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |       sig { override.void } | 
					
						
							|  |  |  |       def run | 
					
						
							|  |  |  |         options = { | 
					
						
							|  |  |  |           overwrite: args.overwrite?, | 
					
						
							|  |  |  |           dry_run:   args.dry_run?, | 
					
						
							|  |  |  |           verbose:   args.verbose?, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         kegs = if args.HEAD? | 
					
						
							|  |  |  |           args.named.to_kegs.group_by(&:name).filter_map do |name, resolved_kegs| | 
					
						
							|  |  |  |             head_keg = resolved_kegs.find { |keg| keg.version.head? } | 
					
						
							|  |  |  |             next head_keg if head_keg.present? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             opoo <<~EOS | 
					
						
							|  |  |  |               No HEAD keg installed for #{name} | 
					
						
							|  |  |  |               To install, run: | 
					
						
							|  |  |  |                 brew install --HEAD #{name} | 
					
						
							|  |  |  |             EOS | 
					
						
							| 
									
										
										
										
											2024-05-10 14:12:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             nil | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2018-07-10 09:32:42 +01:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |           args.named.to_latest_kegs | 
					
						
							| 
									
										
										
										
											2018-07-10 09:32:42 +01:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-11-02 11:20:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |         kegs.freeze.each do |keg| | 
					
						
							|  |  |  |           keg_only = Formulary.keg_only?(keg.rack) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if keg.linked? | 
					
						
							|  |  |  |             opoo "Already linked: #{keg}" | 
					
						
							|  |  |  |             name_and_flag = "#{"--HEAD " if args.HEAD?}#{"--force " if keg_only}#{keg.name}" | 
					
						
							|  |  |  |             puts <<~EOS | 
					
						
							|  |  |  |               To relink, run: | 
					
						
							|  |  |  |                 brew unlink #{keg.name} && brew link #{name_and_flag} | 
					
						
							|  |  |  |             EOS | 
					
						
							|  |  |  |             next | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if args.dry_run? | 
					
						
							|  |  |  |             if args.overwrite? | 
					
						
							|  |  |  |               puts "Would remove:" | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |               puts "Would link:" | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             keg.link(**options) | 
					
						
							|  |  |  |             puts_keg_only_path_message(keg) if keg_only | 
					
						
							|  |  |  |             next | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           formula = begin | 
					
						
							|  |  |  |             keg.to_formula | 
					
						
							|  |  |  |           rescue FormulaUnavailableError | 
					
						
							|  |  |  |             # Not all kegs may belong to formulae | 
					
						
							|  |  |  |             nil | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if keg_only | 
					
						
							|  |  |  |             if HOMEBREW_PREFIX.to_s == HOMEBREW_DEFAULT_PREFIX && formula.present? && | 
					
						
							|  |  |  |                formula.keg_only_reason.by_macos? | 
					
						
							|  |  |  |               caveats = Caveats.new(formula) | 
					
						
							|  |  |  |               opoo <<~EOS | 
					
						
							|  |  |  |                 Refusing to link macOS provided/shadowed software: #{keg.name} | 
					
						
							| 
									
										
										
										
											2024-09-26 10:30:21 -04:00
										 |  |  |                 #{T.must(caveats.keg_only_text(skip_reason: true)).strip} | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |               EOS | 
					
						
							|  |  |  |               next | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if !args.force? && (formula.blank? || !formula.keg_only_reason.versioned_formula?) | 
					
						
							|  |  |  |               opoo "#{keg.name} is keg-only and must be linked with `--force`." | 
					
						
							|  |  |  |               puts_keg_only_path_message(keg) | 
					
						
							|  |  |  |               next | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           Unlink.unlink_versioned_formulae(formula, verbose: args.verbose?) if formula | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           keg.lock do | 
					
						
							|  |  |  |             print "Linking #{keg}... " | 
					
						
							|  |  |  |             puts if args.verbose? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             begin | 
					
						
							|  |  |  |               n = keg.link(**options) | 
					
						
							|  |  |  |             rescue Keg::LinkError | 
					
						
							|  |  |  |               puts | 
					
						
							|  |  |  |               raise | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |               puts "#{n} symlinks created." | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             puts_keg_only_path_message(keg) if keg_only && !Homebrew::EnvConfig.developer? | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2018-07-10 09:32:42 +01:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |       private | 
					
						
							| 
									
										
										
										
											2020-11-02 11:20:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 23:58:53 +01:00
										 |  |  |       sig { params(keg: Keg).void } | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |       def puts_keg_only_path_message(keg) | 
					
						
							|  |  |  |         bin = keg/"bin" | 
					
						
							|  |  |  |         sbin = keg/"sbin" | 
					
						
							|  |  |  |         return if !bin.directory? && !sbin.directory? | 
					
						
							| 
									
										
										
										
											2014-04-21 09:40:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 16:24:11 -07:00
										 |  |  |         opt = HOMEBREW_PREFIX/"opt/#{keg.name}" | 
					
						
							|  |  |  |         puts "\nIf you need to have this software first in your PATH instead consider running:" | 
					
						
							|  |  |  |         puts "  #{Utils::Shell.prepend_path_in_profile(opt/"bin")}"  if bin.directory? | 
					
						
							|  |  |  |         puts "  #{Utils::Shell.prepend_path_in_profile(opt/"sbin")}" if sbin.directory? | 
					
						
							| 
									
										
										
										
											2012-03-19 00:15:40 +00:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | end |