2016-06-23 23:23:41 -07:00
|
|
|
#: * `create` <URL> [`--autotools`|`--cmake`] [`--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
|
|
|
|
#:
|
|
|
|
#: <http://www.rubydoc.info/github/Homebrew/brew/master/Formula>
|
|
|
|
#:
|
|
|
|
#: 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.
|
|
|
|
#:
|
|
|
|
#: If `--no-fetch` is passed, Homebrew will not download <URL> to the cache and
|
|
|
|
#: will thus not add the SHA256 to the formula for you.
|
|
|
|
#:
|
|
|
|
#: 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"
|
|
|
|
require "blacklist"
|
|
|
|
require "digest"
|
|
|
|
require "erb"
|
2010-09-11 20:22:54 +01:00
|
|
|
|
2014-06-18 22:41:47 -05:00
|
|
|
module Homebrew
|
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
|
|
|
# Allow searching MacPorts or Fink.
|
2015-08-03 13:09:07 +01:00
|
|
|
if ARGV.include? "--macports"
|
2015-10-29 16:22:48 +01:00
|
|
|
opoo "`brew create --macports` is deprecated; use `brew search --macports` instead"
|
2015-01-04 05:02:27 +01:00
|
|
|
exec_browser "https://www.macports.org/ports.php?by=name&substr=#{ARGV.next}"
|
2015-08-03 13:09:07 +01:00
|
|
|
elsif ARGV.include? "--fink"
|
2015-10-29 16:22:48 +01:00
|
|
|
opoo "`brew create --fink` is deprecated; use `brew search --fink` instead"
|
2012-12-27 23:34:29 -06:00
|
|
|
exec_browser "http://pdb.finkproject.org/pdb/browse.php?summary=#{ARGV.next}"
|
2012-08-22 19:42:01 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
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
|
|
|
|
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?
|
|
|
|
if msg = blacklisted?(fc.name)
|
|
|
|
raise "#{fc.name} is blacklisted for creation.\n#{msg}\nIf you really want to create this formula use --force."
|
|
|
|
end
|
|
|
|
|
|
|
|
if Formula.aliases.include? fc.name
|
2014-06-22 15:00:15 -05:00
|
|
|
realname = Formulary.canonical_name(fc.name)
|
2012-08-22 19:42:01 -07:00
|
|
|
raise <<-EOS.undent
|
|
|
|
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!
|
|
|
|
|
2014-12-27 16:51:53 +00:00
|
|
|
puts "Please `brew audit --strict #{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
|
|
|
|
if gots.empty? then nil else gots end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class FormulaCreator
|
2015-02-24 23:25:57 +00:00
|
|
|
attr_reader :url, :sha256
|
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
|
|
|
|
when %r{github\.com/\S+/(\S+)\.git}
|
|
|
|
@name = $1
|
|
|
|
@head = true
|
|
|
|
when %r{github\.com/\S+/(\S+)/archive/}
|
|
|
|
@name = $1
|
|
|
|
else
|
|
|
|
/(.*?)[-_.]?#{path.version}/.match path.basename
|
|
|
|
@name = $1
|
|
|
|
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
|
|
|
|
@version = Version.new(@version)
|
|
|
|
else
|
2012-08-22 19:42:01 -07:00
|
|
|
@version = Pathname.new(url).version
|
|
|
|
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?
|
2015-10-26 16:01:16 +01:00
|
|
|
!head? && !ARGV.include?("--no-fetch")
|
|
|
|
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?
|
|
|
|
|
|
|
|
if version.nil?
|
|
|
|
opoo "Version cannot be determined from URL."
|
|
|
|
puts "You'll need to add an explicit 'version' to the formula."
|
|
|
|
end
|
|
|
|
|
2014-02-22 20:17:04 -05:00
|
|
|
if fetch? && version
|
2013-09-23 21:39:19 -05:00
|
|
|
r = Resource.new
|
2015-01-08 14:28:43 -05:00
|
|
|
r.url(url)
|
|
|
|
r.version(version)
|
|
|
|
r.owner = self
|
2015-02-24 23:25:57 +00:00
|
|
|
@sha256 = r.fetch.sha256 if r.download_strategy == CurlDownloadStrategy
|
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
|
|
|
|
|
|
|
|
def template; <<-EOS.undent
|
2016-04-03 14:03:33 +01:00
|
|
|
# Documentation: https://github.com/Homebrew/brew/blob/master/share/doc/homebrew/Formula-Cookbook.md
|
|
|
|
# http://www.rubydoc.info/github/Homebrew/brew/master/Formula
|
2012-03-01 13:25:10 +00:00
|
|
|
# PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST!
|
2012-02-29 02:00:33 +00:00
|
|
|
|
2014-02-22 20:17:04 -05:00
|
|
|
class #{Formulary.class_s(name)} < Formula
|
2015-05-20 11:08:48 -04:00
|
|
|
desc ""
|
2014-01-07 08:10:31 +00:00
|
|
|
homepage ""
|
2015-10-26 16:01:16 +01:00
|
|
|
<% if head? %>
|
|
|
|
head "#{url}"
|
|
|
|
<% else %>
|
2014-01-07 08:10:31 +00:00
|
|
|
url "#{url}"
|
2013-09-16 16:12:25 -05:00
|
|
|
<% unless version.nil? or version.detected_from_url? %>
|
2014-01-07 08:10:31 +00:00
|
|
|
version "#{version}"
|
2012-08-22 19:42:01 -07:00
|
|
|
<% end %>
|
2015-02-24 23:25:57 +00:00
|
|
|
sha256 "#{sha256}"
|
2015-10-26 16:01:16 +01:00
|
|
|
<% end %>
|
2010-09-11 20:22:54 +01:00
|
|
|
|
|
|
|
<% if mode == :cmake %>
|
2014-01-07 08:10:31 +00:00
|
|
|
depends_on "cmake" => :build
|
2013-06-26 18:47:00 -05:00
|
|
|
<% elsif mode.nil? %>
|
2014-01-07 08:10:31 +00:00
|
|
|
# depends_on "cmake" => :build
|
2010-09-11 20:22:54 +01:00
|
|
|
<% end %>
|
2012-08-09 11:00:35 -05:00
|
|
|
depends_on :x11 # if your formula requires any X11/XQuartz components
|
2010-09-11 20:22:54 +01:00
|
|
|
|
|
|
|
def install
|
2013-12-24 15:37:59 -05:00
|
|
|
# ENV.deparallelize # if your formula fails when building in parallel
|
2012-03-01 13:25:10 +00:00
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
<% if mode == :cmake %>
|
2012-05-22 22:32:16 -05:00
|
|
|
system "cmake", ".", *std_cmake_args
|
2010-09-11 20:22:54 +01:00
|
|
|
<% elsif mode == :autotools %>
|
2013-09-05 22:54:32 -07:00
|
|
|
# Remove unrecognized options if warned by configure
|
|
|
|
system "./configure", "--disable-debug",
|
|
|
|
"--disable-dependency-tracking",
|
|
|
|
"--disable-silent-rules",
|
2010-09-11 20:22:54 +01:00
|
|
|
"--prefix=\#{prefix}"
|
|
|
|
<% else %>
|
2013-09-05 22:54:32 -07:00
|
|
|
# Remove unrecognized options if warned by configure
|
|
|
|
system "./configure", "--disable-debug",
|
|
|
|
"--disable-dependency-tracking",
|
|
|
|
"--disable-silent-rules",
|
2010-09-11 20:22:54 +01:00
|
|
|
"--prefix=\#{prefix}"
|
2012-05-22 22:32:16 -05:00
|
|
|
# system "cmake", ".", *std_cmake_args
|
2010-09-11 20:22:54 +01:00
|
|
|
<% end %>
|
2013-04-03 11:24:45 -07:00
|
|
|
system "make", "install" # if this fails, try separate make/make install steps
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
2011-08-25 00:52:12 +01:00
|
|
|
|
2013-02-23 08:42:34 +00:00
|
|
|
test do
|
|
|
|
# `test do` will create, run in and delete a temporary directory.
|
|
|
|
#
|
2014-01-07 12:53:09 +01:00
|
|
|
# This test will fail and we won't accept that! It's enough to just replace
|
|
|
|
# "false" with the main program this formula installs, but it'd be nice if you
|
2014-06-02 22:30:22 +02:00
|
|
|
# were more thorough. Run the test with `brew test #{name}`. Options passed
|
|
|
|
# to `brew install` such as `--HEAD` also need to be provided to `brew test`.
|
2013-10-26 15:39:39 -07:00
|
|
|
#
|
|
|
|
# The installed folder is not in the path, so use the entire path to any
|
2014-01-07 08:10:31 +00:00
|
|
|
# executables being tested: `system "\#{bin}/program", "do", "something"`.
|
2011-09-20 03:38:30 +01:00
|
|
|
system "false"
|
2011-08-25 00:52:12 +01:00
|
|
|
end
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
end
|