| 
									
										
										
										
											2016-12-19 21:51:57 +01:00
										 |  |  | #:  * `create` <URL> [`--autotools`|`--cmake`|`--meson`] [`--no-fetch`] [`--set-name` <name>] [`--set-version` <version>] [`--tap` <user>`/`<repo>]: | 
					
						
							| 
									
										
										
										
											2016-04-08 16:28:43 +02:00
										 |  |  | #:    Generate a formula 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 have a look at | 
					
						
							| 
									
										
										
										
											2017-02-25 17:37:57 -05:00
										 |  |  | #:    <http://www.rubydoc.info/github/Homebrew/brew/master/Formula>. | 
					
						
							| 
									
										
										
										
											2016-04-08 16:28:43 +02:00
										 |  |  | #: | 
					
						
							|  |  |  | #:    If `--autotools` is passed, create a basic template for an Autotools-style build. | 
					
						
							|  |  |  | #:    If `--cmake` is passed, create a basic template for a CMake-style build. | 
					
						
							| 
									
										
										
										
											2016-12-19 21:51:57 +01:00
										 |  |  | #:    If `--meson` is passed, create a basic template for a Meson-style build. | 
					
						
							| 
									
										
										
										
											2016-04-08 16:28:43 +02:00
										 |  |  | #: | 
					
						
							|  |  |  | #:    If `--no-fetch` is passed, Homebrew will not download <URL> to the cache and | 
					
						
							| 
									
										
										
										
											2017-04-18 08:22:37 +01:00
										 |  |  | #:    will thus not add the SHA256 to the formula for you. It will also not check | 
					
						
							|  |  |  | #:    the GitHub API for GitHub projects (to fill out the description and homepage). | 
					
						
							| 
									
										
										
										
											2016-04-08 16:28:43 +02:00
										 |  |  | #: | 
					
						
							|  |  |  | #:    The options `--set-name` and `--set-version` each take an argument and allow | 
					
						
							|  |  |  | #:    you to explicitly set the name and version of the package you are creating. | 
					
						
							| 
									
										
										
										
											2016-06-23 23:23:41 -07:00
										 |  |  | #: | 
					
						
							|  |  |  | #:    The option `--tap` takes a tap as its argument and generates the formula in | 
					
						
							|  |  |  | #:    the specified tap. | 
					
						
							| 
									
										
										
										
											2016-04-08 16:28:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  | require "formula" | 
					
						
							| 
									
										
										
										
											2017-03-18 17:02:08 +02:00
										 |  |  | require "missing_formula" | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  | require "digest" | 
					
						
							|  |  |  | require "erb" | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-18 22:41:47 -05:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2016-09-26 01:44:51 +02:00
										 |  |  |   module_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |   # Create a formula from a tarball URL | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |   def create | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     raise UsageError if ARGV.named.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Ensure that the cache exists so we can fetch the tarball | 
					
						
							|  |  |  |     HOMEBREW_CACHE.mkpath | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     url = ARGV.named.first # Pull the first (and only) url from ARGV | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     version = ARGV.next if ARGV.include? "--set-version" | 
					
						
							|  |  |  |     name = ARGV.next if ARGV.include? "--set-name" | 
					
						
							| 
									
										
										
										
											2016-06-23 23:23:41 -07:00
										 |  |  |     tap = ARGV.next if ARGV.include? "--tap" | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     fc = FormulaCreator.new | 
					
						
							|  |  |  |     fc.name = name | 
					
						
							|  |  |  |     fc.version = version | 
					
						
							| 
									
										
										
										
											2016-06-23 23:23:41 -07:00
										 |  |  |     fc.tap = Tap.fetch(tap || "homebrew/core") | 
					
						
							|  |  |  |     raise TapUnavailableError, tap unless fc.tap.installed? | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     fc.url = url | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     fc.mode = if ARGV.include? "--cmake" | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |       :cmake | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     elsif ARGV.include? "--autotools" | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |       :autotools | 
					
						
							| 
									
										
										
										
											2016-12-19 21:51:57 +01:00
										 |  |  |     elsif ARGV.include? "--meson" | 
					
						
							|  |  |  |       :meson | 
					
						
							| 
									
										
										
										
											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? | 
					
						
							|  |  |  |       stem = Pathname.new(url).stem | 
					
						
							|  |  |  |       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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Don't allow blacklisted formula, or names that shadow aliases, | 
					
						
							|  |  |  |     # unless --force is specified. | 
					
						
							|  |  |  |     unless ARGV.force? | 
					
						
							| 
									
										
										
										
											2017-03-18 17:02:08 +02:00
										 |  |  |       if reason = Homebrew::MissingFormula.blacklisted_reason(fc.name) | 
					
						
							|  |  |  |         raise "#{fc.name} is blacklisted for creation.\n#{reason}\nIf you really want to create this formula use --force." | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |         raise <<~EOS | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |           The formula #{realname} is already aliased to #{fc.name} | 
					
						
							|  |  |  |           Please check that you are not creating a duplicate. | 
					
						
							|  |  |  |           To force creation use --force. | 
					
						
							|  |  |  |           EOS | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     fc.generate! | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 10:59:39 +01:00
										 |  |  |     puts "Please `brew audit --new-formula #{fc.name}` before submitting, thanks." | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     exec_editor 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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FormulaCreator | 
					
						
							| 
									
										
										
										
											2017-04-18 08:22:37 +01:00
										 |  |  |   attr_reader :url, :sha256, :desc, :homepage | 
					
						
							| 
									
										
										
										
											2016-06-23 23:23:41 -07:00
										 |  |  |   attr_accessor :name, :version, :tap, :path, :mode | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def url=(url) | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     @url = url | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     path = Pathname.new(url) | 
					
						
							|  |  |  |     if @name.nil? | 
					
						
							| 
									
										
										
										
											2015-10-26 16:01:16 +01:00
										 |  |  |       case url | 
					
						
							| 
									
										
										
										
											2017-04-18 08:22:37 +01:00
										 |  |  |       when %r{github\.com/(\S+)/(\S+)\.git} | 
					
						
							| 
									
										
										
										
											2017-06-10 20:23:20 +03:00
										 |  |  |         @user = Regexp.last_match(1) | 
					
						
							|  |  |  |         @name = Regexp.last_match(2) | 
					
						
							| 
									
										
										
										
											2015-10-26 16:01:16 +01:00
										 |  |  |         @head = true | 
					
						
							| 
									
										
										
										
											2017-04-18 08:22:37 +01:00
										 |  |  |         @github = true | 
					
						
							|  |  |  |       when %r{github\.com/(\S+)/(\S+)/(archive|releases)/} | 
					
						
							| 
									
										
										
										
											2017-06-10 20:23:20 +03:00
										 |  |  |         @user = Regexp.last_match(1) | 
					
						
							|  |  |  |         @name = Regexp.last_match(2) | 
					
						
							| 
									
										
										
										
											2017-04-18 08:22:37 +01:00
										 |  |  |         @github = true | 
					
						
							| 
									
										
										
										
											2015-10-26 16:01:16 +01:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2016-07-18 00:03:56 +08:00
										 |  |  |         @name = path.basename.to_s[/(.*?)[-_.]?#{Regexp.escape(path.version.to_s)}/, 1] | 
					
						
							| 
									
										
										
										
											2015-10-26 16:01:16 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-06-23 23:23:41 -07:00
										 |  |  |     update_path | 
					
						
							| 
									
										
										
										
											2013-08-02 04:44:14 +07:00
										 |  |  |     if @version | 
					
						
							| 
									
										
										
										
											2016-07-11 16:09:35 +03:00
										 |  |  |       @version = Version.create(@version) | 
					
						
							| 
									
										
										
										
											2013-08-02 04:44:14 +07:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2016-12-18 13:32:29 -08:00
										 |  |  |       @version = Version.detect(url, {}) | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-23 23:23:41 -07:00
										 |  |  |   def update_path | 
					
						
							|  |  |  |     return if @name.nil? || @tap.nil? | 
					
						
							|  |  |  |     @path = Formulary.path "#{@tap}/#{@name}" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-22 20:17:04 -05:00
										 |  |  |   def fetch? | 
					
						
							| 
									
										
										
										
											2017-04-18 08:22:37 +01:00
										 |  |  |     !ARGV.include?("--no-fetch") | 
					
						
							| 
									
										
										
										
											2015-10-26 16:01:16 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def head? | 
					
						
							|  |  |  |     @head || ARGV.build_head? | 
					
						
							| 
									
										
										
										
											2014-02-22 20:17:04 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-22 19:42:01 -07:00
										 |  |  |   def generate! | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     raise "#{path} already exists" if path.exist? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-16 20:15:20 +00:00
										 |  |  |     if version.nil? || version.null? | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |       opoo "Version cannot be determined from URL." | 
					
						
							|  |  |  |       puts "You'll need to add an explicit 'version' to the formula." | 
					
						
							| 
									
										
										
										
											2017-01-16 20:15:20 +00:00
										 |  |  |     elsif fetch? | 
					
						
							| 
									
										
										
										
											2017-04-18 08:22:37 +01:00
										 |  |  |       unless head? | 
					
						
							|  |  |  |         r = Resource.new | 
					
						
							|  |  |  |         r.url(url) | 
					
						
							|  |  |  |         r.version(version) | 
					
						
							|  |  |  |         r.owner = self | 
					
						
							|  |  |  |         @sha256 = r.fetch.sha256 if r.download_strategy == CurlDownloadStrategy | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if @user && @name | 
					
						
							|  |  |  |         begin | 
					
						
							|  |  |  |           metadata = GitHub.repository(@user, @name) | 
					
						
							|  |  |  |           @desc = metadata["description"] | 
					
						
							|  |  |  |           @homepage = metadata["homepage"] | 
					
						
							|  |  |  |         rescue GitHub::HTTPNotFoundError | 
					
						
							|  |  |  |           # If there was no repository found assume the network connection is at | 
					
						
							|  |  |  |           # fault rather than the input URL. | 
					
						
							|  |  |  |           nil | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     path.write ERB.new(template, nil, ">").result(binding) | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |   def template | 
					
						
							|  |  |  |     <<~EOS | 
					
						
							| 
									
										
										
										
											2018-02-22 19:46:58 +00:00
										 |  |  |       # Documentation: https://docs.brew.sh/Formula-Cookbook | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |       #                http://www.rubydoc.info/github/Homebrew/brew/master/Formula | 
					
						
							|  |  |  |       # PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST! | 
					
						
							| 
									
										
										
										
											2018-03-12 09:04:07 +00:00
										 |  |  |       class #{Formulary.class_s(name)} < Formula | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |         desc "#{desc}" | 
					
						
							|  |  |  |         homepage "#{homepage}" | 
					
						
							|  |  |  |       <% if  head? %> | 
					
						
							|  |  |  |         head "#{url}" | 
					
						
							|  |  |  |       <% else  %> | 
					
						
							|  |  |  |         url "#{url}" | 
					
						
							|  |  |  |       <% unless  version.nil? or version.detected_from_url? %> | 
					
						
							|  |  |  |         version "#{version}" | 
					
						
							|  |  |  |       <% end  %> | 
					
						
							|  |  |  |         sha256 "#{sha256}" | 
					
						
							|  |  |  |       <% end  %> | 
					
						
							| 
									
										
										
										
											2018-03-12 09:04:07 +00:00
										 |  |  |       <% if  mode == :cmake %> | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |         depends_on "cmake" => :build | 
					
						
							|  |  |  |       <% elsif  mode == :meson %> | 
					
						
							| 
									
										
										
										
											2018-04-01 11:16:08 +02:00
										 |  |  |         depends_on "meson-internal" => :build | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |         depends_on "ninja" => :build | 
					
						
							| 
									
										
										
										
											2018-04-01 11:16:08 +02:00
										 |  |  |         depends_on "python" => :build | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |       <% elsif  mode.nil? %> | 
					
						
							|  |  |  |         # depends_on "cmake" => :build | 
					
						
							|  |  |  |       <% end  %> | 
					
						
							| 
									
										
										
										
											2018-03-12 09:04:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def install | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |           # ENV.deparallelize  # if your formula fails when building in parallel | 
					
						
							| 
									
										
										
										
											2018-03-12 09:04:07 +00:00
										 |  |  |       <% if  mode == :cmake %> | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |           system "cmake", ".", *std_cmake_args | 
					
						
							|  |  |  |       <% elsif  mode == :autotools %> | 
					
						
							|  |  |  |           # Remove unrecognized options if warned by configure | 
					
						
							|  |  |  |           system "./configure", "--disable-debug", | 
					
						
							|  |  |  |                                 "--disable-dependency-tracking", | 
					
						
							|  |  |  |                                 "--disable-silent-rules", | 
					
						
							|  |  |  |                                 "--prefix=\#{prefix}" | 
					
						
							|  |  |  |       <% elsif  mode == :meson %> | 
					
						
							| 
									
										
										
										
											2018-04-01 11:16:08 +02:00
										 |  |  |           ENV.refurbish_args | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |           mkdir "build" do | 
					
						
							|  |  |  |             system "meson", "--prefix=\#{prefix}", ".." | 
					
						
							|  |  |  |             system "ninja" | 
					
						
							|  |  |  |             system "ninja", "install" | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |       <% else  %> | 
					
						
							|  |  |  |           # Remove unrecognized options if warned by configure | 
					
						
							|  |  |  |           system "./configure", "--disable-debug", | 
					
						
							|  |  |  |                                 "--disable-dependency-tracking", | 
					
						
							|  |  |  |                                 "--disable-silent-rules", | 
					
						
							|  |  |  |                                 "--prefix=\#{prefix}" | 
					
						
							|  |  |  |           # system "cmake", ".", *std_cmake_args | 
					
						
							|  |  |  |       <% end  %> | 
					
						
							|  |  |  |       <% if  mode != :meson %> | 
					
						
							|  |  |  |           system "make", "install" # if this fails, try separate make/make install steps | 
					
						
							|  |  |  |       <% end  %> | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2018-03-12 09:04:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         test do | 
					
						
							| 
									
										
										
										
											2018-01-17 10:42:43 +00:00
										 |  |  |           # `test do` will create, run in and delete a temporary directory. | 
					
						
							|  |  |  |           # | 
					
						
							|  |  |  |           # This test will fail and we won't accept that! For Homebrew/homebrew-core | 
					
						
							|  |  |  |           # this will need to be a test that verifies the functionality of the | 
					
						
							|  |  |  |           # software. Run the test with `brew test #{name}`. Options passed | 
					
						
							|  |  |  |           # to `brew install` such as `--HEAD` also need to be provided to `brew test`. | 
					
						
							|  |  |  |           # | 
					
						
							|  |  |  |           # The installed folder is not in the path, so use the entire path to any | 
					
						
							|  |  |  |           # executables being tested: `system "\#{bin}/program", "do", "something"`. | 
					
						
							|  |  |  |           system "false" | 
					
						
							| 
									
										
										
										
											2016-12-19 21:51:57 +01:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2011-08-25 00:52:12 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     EOS | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |