| 
									
										
										
										
											2021-09-11 01:00:23 +01:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  | require "formula" | 
					
						
							| 
									
										
										
										
											2018-06-03 15:28:48 +05:30
										 |  |  | require "formula_creator" | 
					
						
							| 
									
										
										
										
											2017-03-18 17:02:08 +02:00
										 |  |  | require "missing_formula" | 
					
						
							| 
									
										
										
										
											2019-04-17 18:25:08 +09:00
										 |  |  | require "cli/parser" | 
					
						
							| 
									
										
										
										
											2020-07-27 10:38:50 -04:00
										 |  |  | require "utils/pypi" | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  | require "cask/cask_loader" | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-18 22:41:47 -05:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   extend T::Sig | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-26 01:44:51 +02:00
										 |  |  |   module_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |   sig { returns(CLI::Parser) } | 
					
						
							| 
									
										
										
										
											2018-07-30 18:25:38 +05:30
										 |  |  |   def create_args | 
					
						
							|  |  |  |     Homebrew::CLI::Parser.new do | 
					
						
							| 
									
										
										
										
											2021-01-15 15:04:02 -05:00
										 |  |  |       description <<~EOS | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |         Generate a formula or, with `--cask`, a cask for the downloadable file at <URL> | 
					
						
							|  |  |  |         and open it in the editor. Homebrew will attempt to automatically derive the | 
					
						
							|  |  |  |         formula name and version, but if it fails, you'll have to make your own template. | 
					
						
							|  |  |  |         The `wget` formula serves as a simple example. For the complete API, see: | 
					
						
							| 
									
										
										
										
											2020-07-23 16:00:03 -04:00
										 |  |  |         <https://rubydoc.brew.sh/Formula> | 
					
						
							| 
									
										
										
										
											2018-09-28 21:39:52 +05:30
										 |  |  |       EOS | 
					
						
							|  |  |  |       switch "--autotools", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Create a basic template for an Autotools-style build." | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |       switch "--cask", | 
					
						
							|  |  |  |              description: "Create a basic template for a cask." | 
					
						
							| 
									
										
										
										
											2018-09-28 21:39:52 +05:30
										 |  |  |       switch "--cmake", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Create a basic template for a CMake-style build." | 
					
						
							| 
									
										
										
										
											2020-06-25 17:17:42 +02:00
										 |  |  |       switch "--crystal", | 
					
						
							|  |  |  |              description: "Create a basic template for a Crystal build." | 
					
						
							| 
									
										
										
										
											2019-09-24 16:49:27 +02:00
										 |  |  |       switch "--go", | 
					
						
							|  |  |  |              description: "Create a basic template for a Go build." | 
					
						
							| 
									
										
										
										
											2018-09-28 21:39:52 +05:30
										 |  |  |       switch "--meson", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Create a basic template for a Meson-style build." | 
					
						
							| 
									
										
										
										
											2020-07-12 21:25:01 -07:00
										 |  |  |       switch "--node", | 
					
						
							|  |  |  |              description: "Create a basic template for a Node build." | 
					
						
							| 
									
										
										
										
											2019-09-25 21:52:16 +02:00
										 |  |  |       switch "--perl", | 
					
						
							|  |  |  |              description: "Create a basic template for a Perl build." | 
					
						
							| 
									
										
										
										
											2019-09-24 19:34:34 +02:00
										 |  |  |       switch "--python", | 
					
						
							|  |  |  |              description: "Create a basic template for a Python build." | 
					
						
							| 
									
										
										
										
											2020-03-21 15:32:52 +01:00
										 |  |  |       switch "--ruby", | 
					
						
							|  |  |  |              description: "Create a basic template for a Ruby build." | 
					
						
							| 
									
										
										
										
											2019-09-25 14:29:09 +02:00
										 |  |  |       switch "--rust", | 
					
						
							|  |  |  |              description: "Create a basic template for a Rust build." | 
					
						
							| 
									
										
										
										
											2018-09-28 21:39:52 +05:30
										 |  |  |       switch "--no-fetch", | 
					
						
							| 
									
										
										
										
											2022-06-28 10:09:59 +01:00
										 |  |  |              description: "Homebrew will not download <URL> to the cache and will thus not add its SHA-256 " \ | 
					
						
							|  |  |  |                           "to the formula for you, nor will it check the GitHub API for GitHub projects " \ | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |                           "(to fill out its description and homepage)." | 
					
						
							| 
									
										
										
										
											2018-10-08 22:49:03 -04:00
										 |  |  |       switch "--HEAD", | 
					
						
							| 
									
										
										
										
											2019-04-30 08:44:35 +01:00
										 |  |  |              description: "Indicate that <URL> points to the package's repository rather than a file." | 
					
						
							| 
									
										
										
										
											2018-09-28 21:39:52 +05:30
										 |  |  |       flag   "--set-name=", | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |              description: "Explicitly set the <name> of the new formula or cask." | 
					
						
							| 
									
										
										
										
											2018-09-28 21:39:52 +05:30
										 |  |  |       flag   "--set-version=", | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |              description: "Explicitly set the <version> of the new formula or cask." | 
					
						
							| 
									
										
										
										
											2020-06-17 22:52:25 +08:00
										 |  |  |       flag   "--set-license=", | 
					
						
							|  |  |  |              description: "Explicitly set the <license> of the new formula." | 
					
						
							| 
									
										
										
										
											2018-09-28 21:39:52 +05:30
										 |  |  |       flag   "--tap=", | 
					
						
							| 
									
										
										
										
											2019-08-20 00:04:14 -04:00
										 |  |  |              description: "Generate the new formula within the given tap, specified as <user>`/`<repo>." | 
					
						
							| 
									
										
										
										
											2020-07-27 03:59:52 +02:00
										 |  |  |       switch "-f", "--force", | 
					
						
							| 
									
										
										
										
											2020-11-12 10:40:48 -05:00
										 |  |  |              description: "Ignore errors for disallowed formula names and names that shadow aliases." | 
					
						
							| 
									
										
										
										
											2020-07-30 18:40:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |       conflicts "--autotools", "--cmake", "--crystal", "--go", "--meson", "--node", | 
					
						
							|  |  |  |                 "--perl", "--python", "--ruby", "--rust", "--cask" | 
					
						
							|  |  |  |       conflicts "--cask", "--HEAD" | 
					
						
							|  |  |  |       conflicts "--cask", "--set-license" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 15:04:02 -05:00
										 |  |  |       named_args :url, number: 1
 | 
					
						
							| 
									
										
										
										
											2018-06-03 01:15:28 +05:30
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-07-30 18:25:38 +05:30
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |   # Create a formula from a tarball URL. | 
					
						
							| 
									
										
										
										
											2018-07-30 18:25:38 +05:30
										 |  |  |   def create | 
					
						
							| 
									
										
										
										
											2020-07-23 03:08:19 +02:00
										 |  |  |     args = create_args.parse | 
					
						
							| 
									
										
										
										
											2018-07-30 18:25:38 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |     path = if args.cask? | 
					
						
							|  |  |  |       create_cask(args: args) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       create_formula(args: args) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     exec_editor path | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def create_cask(args:) | 
					
						
							| 
									
										
										
										
											2021-04-12 16:06:38 -04:00
										 |  |  |     raise UsageError, "The `--set-name` flag is required for creating casks." if args.set_name.blank? | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-12 16:06:38 -04:00
										 |  |  |     url = args.named.first | 
					
						
							|  |  |  |     name = args.set_name | 
					
						
							|  |  |  |     token = Cask::Utils.token_from(args.set_name) | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 12:55:07 -05:00
										 |  |  |     cask_tap = Tap.fetch(args.tap || "homebrew/cask") | 
					
						
							|  |  |  |     raise TapUnavailableError, args.tap unless cask_tap.installed? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cask_path = Cask::CaskLoader.path("#{cask_tap}/#{token}") | 
					
						
							|  |  |  |     cask_path.dirname.mkpath unless cask_path.dirname.exist? | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |     raise Cask::CaskAlreadyCreatedError, token if cask_path.exist? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     version = if args.set_version | 
					
						
							|  |  |  |       Version.create(args.set_version) | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2021-04-12 16:06:38 -04:00
										 |  |  |       Version.detect(url.gsub(token, "").gsub(/x86(_64)?/, "")) | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     interpolated_url, sha256 = if version.null? | 
					
						
							|  |  |  |       [url, ""] | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       sha256 = if args.no_fetch? | 
					
						
							|  |  |  |         "" | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         strategy = DownloadStrategyDetector.detect(url) | 
					
						
							|  |  |  |         downloader = strategy.new(url, token, version.to_s, cache: Cask::Cache.path) | 
					
						
							|  |  |  |         downloader.fetch | 
					
						
							|  |  |  |         downloader.cached_location.sha256 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       [url.gsub(version.to_s, "\#{version}"), sha256] | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |     cask_path.atomic_write <<~RUBY | 
					
						
							|  |  |  |       cask "#{token}" do | 
					
						
							|  |  |  |         version "#{version}" | 
					
						
							|  |  |  |         sha256 "#{sha256}" | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |         url "#{interpolated_url}" | 
					
						
							| 
									
										
										
										
											2021-04-12 16:06:38 -04:00
										 |  |  |         name "#{name}" | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |         desc "" | 
					
						
							|  |  |  |         homepage "" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app "" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     RUBY | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     puts "Please run `brew audit --cask --new #{token}` before submitting, thanks." | 
					
						
							|  |  |  |     cask_path | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |   def create_formula(args:) | 
					
						
							| 
									
										
										
										
											2020-07-23 03:08:19 +02:00
										 |  |  |     fc = FormulaCreator.new(args) | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |     fc.name = args.set_name | 
					
						
							|  |  |  |     fc.version = args.set_version | 
					
						
							|  |  |  |     fc.license = args.set_license | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |     fc.tap = Tap.fetch(args.tap || "homebrew/core") | 
					
						
							| 
									
										
										
										
											2020-12-15 12:55:07 -05:00
										 |  |  |     raise TapUnavailableError, args.tap unless fc.tap.installed? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-29 17:31:11 -04:00
										 |  |  |     fc.url = args.named.first # Pull the first (and only) URL from ARGV | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |     fc.mode = if args.autotools? | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |       :autotools | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |     elsif args.cmake? | 
					
						
							|  |  |  |       :cmake | 
					
						
							| 
									
										
										
										
											2020-06-25 17:17:42 +02:00
										 |  |  |     elsif args.crystal? | 
					
						
							|  |  |  |       :crystal | 
					
						
							| 
									
										
										
										
											2019-09-24 16:49:27 +02:00
										 |  |  |     elsif args.go? | 
					
						
							|  |  |  |       :go | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |     elsif args.meson? | 
					
						
							|  |  |  |       :meson | 
					
						
							| 
									
										
										
										
											2020-07-12 21:25:01 -07:00
										 |  |  |     elsif args.node? | 
					
						
							|  |  |  |       :node | 
					
						
							| 
									
										
										
										
											2019-09-25 21:52:16 +02:00
										 |  |  |     elsif args.perl? | 
					
						
							|  |  |  |       :perl | 
					
						
							| 
									
										
										
										
											2019-09-24 19:34:34 +02:00
										 |  |  |     elsif args.python? | 
					
						
							|  |  |  |       :python | 
					
						
							| 
									
										
										
										
											2020-03-21 15:32:52 +01:00
										 |  |  |     elsif args.ruby? | 
					
						
							|  |  |  |       :ruby | 
					
						
							| 
									
										
										
										
											2019-09-25 14:29:09 +02:00
										 |  |  |     elsif args.rust? | 
					
						
							|  |  |  |       :rust | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-17 19:40:44 -05:00
										 |  |  |     if fc.name.nil? || fc.name.strip.empty? | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |       stem = Pathname.new(fc.url).stem.rpartition("=").last | 
					
						
							| 
									
										
										
										
											2014-07-17 19:40:44 -05:00
										 |  |  |       print "Formula name [#{stem}]: " | 
					
						
							|  |  |  |       fc.name = __gets || stem | 
					
						
							| 
									
										
										
										
											2016-06-23 23:23:41 -07:00
										 |  |  |       fc.update_path | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-06 21:10:16 +01:00
										 |  |  |     # Check for disallowed formula, or names that shadow aliases, | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     # unless --force is specified. | 
					
						
							| 
									
										
										
										
											2018-06-03 01:15:28 +05:30
										 |  |  |     unless args.force? | 
					
						
							| 
									
										
										
										
											2021-02-12 18:33:37 +05:30
										 |  |  |       if (reason = MissingFormula.disallowed_reason(fc.name)) | 
					
						
							| 
									
										
										
										
											2020-12-03 00:02:22 -05:00
										 |  |  |         odie <<~EOS | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |           The formula '#{fc.name}' is not allowed to be created. | 
					
						
							| 
									
										
										
										
											2018-09-02 16:15:09 +01:00
										 |  |  |           #{reason} | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |           If you really want to create this formula use `--force`. | 
					
						
							| 
									
										
										
										
											2018-09-02 16:15:09 +01:00
										 |  |  |         EOS | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if Formula.aliases.include? fc.name | 
					
						
							| 
									
										
										
										
											2014-06-22 15:00:15 -05:00
										 |  |  |         realname = Formulary.canonical_name(fc.name) | 
					
						
							| 
									
										
										
										
											2020-12-03 00:02:22 -05:00
										 |  |  |         odie <<~EOS | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |           The formula '#{realname}' is already aliased to '#{fc.name}'. | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |           Please check that you are not creating a duplicate. | 
					
						
							| 
									
										
										
										
											2020-12-07 23:37:54 -05:00
										 |  |  |           To force creation use `--force`. | 
					
						
							| 
									
										
										
										
											2018-06-06 23:34:19 -04:00
										 |  |  |         EOS | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     fc.generate! | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 10:38:50 -04:00
										 |  |  |     PyPI.update_python_resources! Formula[fc.name], ignore_non_pypi_packages: true if args.python? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 12:13:53 +01:00
										 |  |  |     puts "Please run `brew audit --new #{fc.name}` before submitting, thanks." | 
					
						
							|  |  |  |     fc.path | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def __gets | 
					
						
							|  |  |  |     gots = $stdin.gets.chomp | 
					
						
							| 
									
										
										
										
											2016-09-11 17:41:51 +01:00
										 |  |  |     gots.empty? ? nil : gots | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | end |