| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  | require "formula" | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  | require "fetch" | 
					
						
							| 
									
										
										
										
											2019-04-17 18:25:08 +09:00
										 |  |  | require "cli/parser" | 
					
						
							| 
									
										
										
										
											2011-03-12 09:40:10 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-18 22:41:47 -05:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2016-09-26 01:44:51 +02:00
										 |  |  |   module_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |   def fetch_args | 
					
						
							|  |  |  |     Homebrew::CLI::Parser.new do | 
					
						
							|  |  |  |       usage_banner <<~EOS | 
					
						
							| 
									
										
										
										
											2019-01-30 21:32:35 +00:00
										 |  |  |         `fetch` [<options>] <formula> | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-19 22:44:50 -04:00
										 |  |  |         Download a bottle (if available) or source packages for <formula>. | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |         For tarballs, also print SHA-256 checksums. | 
					
						
							|  |  |  |       EOS | 
					
						
							|  |  |  |       switch "--HEAD", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Fetch HEAD version instead of stable version." | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |       switch "--devel", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Fetch development version instead of stable version." | 
					
						
							| 
									
										
										
										
											2019-08-09 14:23:04 -04:00
										 |  |  |       switch :force, | 
					
						
							|  |  |  |              description: "Remove a previously cached version and re-fetch." | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |       switch :verbose, | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Do a verbose VCS checkout, if the URL represents a VCS. This is useful for "\ | 
					
						
							|  |  |  |                           "seeing if an existing VCS cache has been updated." | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |       switch "--retry", | 
					
						
							| 
									
										
										
										
											2019-08-20 00:04:14 -04:00
										 |  |  |              description: "Retry if downloading fails or re-download if the checksum of a previously cached "\ | 
					
						
							| 
									
										
										
										
											2019-08-06 13:23:19 -04:00
										 |  |  |                           "version no longer matches." | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |       switch "--deps", | 
					
						
							| 
									
										
										
										
											2019-08-20 00:04:14 -04:00
										 |  |  |              description: "Also download dependencies for any listed <formula>." | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |       switch "-s", "--build-from-source", | 
					
						
							| 
									
										
										
										
											2019-08-19 22:44:50 -04:00
										 |  |  |              description: "Download source packages rather than a bottle." | 
					
						
							| 
									
										
										
										
											2019-01-29 11:35:04 +00:00
										 |  |  |       switch "--build-bottle", | 
					
						
							| 
									
										
										
										
											2019-08-19 22:44:50 -04:00
										 |  |  |              description: "Download source packages (for eventual bottling) rather than a bottle." | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |       switch "--force-bottle", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Download a bottle if it exists for the current or newest version of macOS, "\ | 
					
						
							|  |  |  |                           "even if it would not be used during installation." | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |       switch :debug | 
					
						
							| 
									
										
										
										
											2019-01-29 19:39:41 +00:00
										 |  |  |       conflicts "--devel", "--HEAD" | 
					
						
							|  |  |  |       conflicts "--build-from-source", "--build-bottle", "--force-bottle" | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-12 09:40:10 -08:00
										 |  |  |   def fetch | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |     fetch_args.parse | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-04 00:01:29 -06:00
										 |  |  |     raise FormulaUnspecifiedError if ARGV.named.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |     if args.deps? | 
					
						
							| 
									
										
										
										
											2011-04-14 14:57:21 -07:00
										 |  |  |       bucket = [] | 
					
						
							|  |  |  |       ARGV.formulae.each do |f| | 
					
						
							|  |  |  |         bucket << f | 
					
						
							| 
									
										
										
										
											2013-05-16 14:06:25 -05:00
										 |  |  |         bucket.concat f.recursive_dependencies.map(&:to_formula) | 
					
						
							| 
									
										
										
										
											2011-04-14 14:57:21 -07:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-05-16 14:06:25 -05:00
										 |  |  |       bucket.uniq! | 
					
						
							| 
									
										
										
										
											2011-04-14 14:57:21 -07:00
										 |  |  |     else | 
					
						
							|  |  |  |       bucket = ARGV.formulae | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     puts "Fetching: #{bucket * ", "}" if bucket.size > 1
 | 
					
						
							| 
									
										
										
										
											2013-08-06 19:53:43 -07:00
										 |  |  |     bucket.each do |f| | 
					
						
							| 
									
										
										
										
											2016-09-17 15:32:44 +01:00
										 |  |  |       f.print_tap_action verb: "Fetching" | 
					
						
							| 
									
										
										
										
											2014-10-19 13:54:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-03 11:00:39 +02:00
										 |  |  |       fetched_bottle = false | 
					
						
							| 
									
										
										
										
											2018-06-05 23:19:18 -04:00
										 |  |  |       if Fetch.fetch_bottle?(f) | 
					
						
							| 
									
										
										
										
											2015-12-03 11:00:39 +02:00
										 |  |  |         begin | 
					
						
							|  |  |  |           fetch_formula(f.bottle) | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |         rescue Interrupt | 
					
						
							|  |  |  |           raise | 
					
						
							|  |  |  |         rescue => e | 
					
						
							|  |  |  |           raise if ARGV.homebrew_developer? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-03 11:00:39 +02:00
										 |  |  |           fetched_bottle = false | 
					
						
							|  |  |  |           onoe e.message | 
					
						
							|  |  |  |           opoo "Bottle fetch failed: fetching the source." | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           fetched_bottle = true | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-10 10:24:56 +01:00
										 |  |  |       next if fetched_bottle | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-10 10:24:56 +01:00
										 |  |  |       fetch_formula(f) | 
					
						
							| 
									
										
										
										
											2018-01-21 23:41:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       f.resources.each do |r| | 
					
						
							|  |  |  |         fetch_resource(r) | 
					
						
							|  |  |  |         r.patches.each { |p| fetch_patch(p) if p.external? } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-10 10:24:56 +01:00
										 |  |  |       f.patchlist.each { |p| fetch_patch(p) if p.external? } | 
					
						
							| 
									
										
										
										
											2013-08-06 19:53:43 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-01-11 18:03:51 -06:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2011-04-14 14:57:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def fetch_resource(r) | 
					
						
							| 
									
										
										
										
											2013-08-06 19:53:43 -07:00
										 |  |  |     puts "Resource: #{r.name}" | 
					
						
							|  |  |  |     fetch_fetchable r | 
					
						
							|  |  |  |   rescue ChecksumMismatchError => e | 
					
						
							| 
									
										
										
										
											2014-03-08 17:21:37 +00:00
										 |  |  |     retry if retry_fetch? r | 
					
						
							| 
									
										
										
										
											2013-08-06 19:53:43 -07:00
										 |  |  |     opoo "Resource #{r.name} reports different #{e.hash_type}: #{e.expected}" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def fetch_formula(f) | 
					
						
							| 
									
										
										
										
											2013-08-06 19:53:43 -07:00
										 |  |  |     fetch_fetchable f | 
					
						
							|  |  |  |   rescue ChecksumMismatchError => e | 
					
						
							| 
									
										
										
										
											2014-03-01 12:28:45 +00:00
										 |  |  |     retry if retry_fetch? f | 
					
						
							| 
									
										
										
										
											2013-08-06 19:53:43 -07:00
										 |  |  |     opoo "Formula reports different #{e.hash_type}: #{e.expected}" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def fetch_patch(p) | 
					
						
							| 
									
										
										
										
											2014-03-13 19:51:23 -05:00
										 |  |  |     fetch_fetchable p | 
					
						
							|  |  |  |   rescue ChecksumMismatchError => e | 
					
						
							|  |  |  |     Homebrew.failed = true | 
					
						
							|  |  |  |     opoo "Patch reports different #{e.hash_type}: #{e.expected}" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def retry_fetch?(f) | 
					
						
							| 
									
										
										
										
											2014-08-22 22:55:10 -05:00
										 |  |  |     @fetch_failed ||= Set.new | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |     if args.retry? && @fetch_failed.add?(f) | 
					
						
							| 
									
										
										
										
											2014-08-22 22:55:10 -05:00
										 |  |  |       ohai "Retrying download" | 
					
						
							|  |  |  |       f.clear_cache | 
					
						
							|  |  |  |       true | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2014-03-01 12:28:45 +00:00
										 |  |  |       Homebrew.failed = true | 
					
						
							| 
									
										
										
										
											2014-08-22 22:55:10 -05:00
										 |  |  |       false | 
					
						
							| 
									
										
										
										
											2014-03-01 12:28:45 +00:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def fetch_fetchable(f) | 
					
						
							| 
									
										
										
										
											2018-10-27 23:44:32 +05:30
										 |  |  |     f.clear_cache if args.force? | 
					
						
							| 
									
										
										
										
											2013-10-31 14:28:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     already_fetched = f.cached_download.exist? | 
					
						
							| 
									
										
										
										
											2014-08-16 08:48:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							| 
									
										
										
										
											2019-06-15 17:22:45 +01:00
										 |  |  |       download = f.fetch(verify_download_integrity: false) | 
					
						
							| 
									
										
										
										
											2014-08-22 22:55:10 -05:00
										 |  |  |     rescue DownloadError | 
					
						
							| 
									
										
										
										
											2014-08-16 08:48:28 +01:00
										 |  |  |       retry if retry_fetch? f | 
					
						
							| 
									
										
										
										
											2014-08-22 22:55:10 -05:00
										 |  |  |       raise | 
					
						
							| 
									
										
										
										
											2014-08-16 08:48:28 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2011-03-12 09:40:10 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-16 14:06:26 -05:00
										 |  |  |     return unless download.file? | 
					
						
							| 
									
										
										
										
											2011-03-12 09:40:10 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-31 14:28:49 -05:00
										 |  |  |     puts "Downloaded to: #{download}" unless already_fetched | 
					
						
							| 
									
										
										
										
											2016-03-20 13:53:48 +08:00
										 |  |  |     puts Checksum::TYPES.map { |t| "#{t.to_s.upcase}: #{download.send(t)}" } | 
					
						
							| 
									
										
										
										
											2013-01-11 18:03:51 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-16 14:06:26 -05:00
										 |  |  |     f.verify_download_integrity(download) | 
					
						
							| 
									
										
										
										
											2011-03-12 09:40:10 -08:00
										 |  |  |   end | 
					
						
							|  |  |  | end |