Allow creating casks with brew create --cask.

This commit is contained in:
Markus Reiter 2020-11-20 12:13:53 +01:00
parent fb1f12d601
commit b6492094d0
4 changed files with 95 additions and 31 deletions

View File

@ -111,7 +111,7 @@ module Cask
sig { returns(String) } sig { returns(String) }
def to_s def to_s
%Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew cask edit #{token}")} to edit it.) %Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew edit --cask #{token}")} to edit it.)
end end
end end

View File

@ -6,6 +6,7 @@ require "formula_creator"
require "missing_formula" require "missing_formula"
require "cli/parser" require "cli/parser"
require "utils/pypi" require "utils/pypi"
require "cask/cask_loader"
module Homebrew module Homebrew
extend T::Sig extend T::Sig
@ -18,14 +19,16 @@ module Homebrew
usage_banner <<~EOS usage_banner <<~EOS
`create` [<options>] <URL> `create` [<options>] <URL>
Generate a formula for the downloadable file at <URL> and open it in the editor. Generate a formula or, with `--cask`, a cask for the downloadable file at <URL>
Homebrew will attempt to automatically derive the formula name and version, but and open it in the editor. Homebrew will attempt to automatically derive the
if it fails, you'll have to make your own template. The `wget` formula serves as formula name and version, but if it fails, you'll have to make your own template.
a simple example. For the complete API, see: The `wget` formula serves as a simple example. For the complete API, see:
<https://rubydoc.brew.sh/Formula> <https://rubydoc.brew.sh/Formula>
EOS EOS
switch "--autotools", switch "--autotools",
description: "Create a basic template for an Autotools-style build." description: "Create a basic template for an Autotools-style build."
switch "--cask",
description: "Create a basic template for a cask."
switch "--cmake", switch "--cmake",
description: "Create a basic template for a CMake-style build." description: "Create a basic template for a CMake-style build."
switch "--crystal", switch "--crystal",
@ -51,9 +54,10 @@ module Homebrew
switch "--HEAD", switch "--HEAD",
description: "Indicate that <URL> points to the package's repository rather than a file." description: "Indicate that <URL> points to the package's repository rather than a file."
flag "--set-name=", flag "--set-name=",
description: "Explicitly set the <name> of the new formula." description: "Explicitly set the <name> of the new formula or cask.",
required_for: "--cask"
flag "--set-version=", flag "--set-version=",
description: "Explicitly set the <version> of the new formula." description: "Explicitly set the <version> of the new formula or cask."
flag "--set-license=", flag "--set-license=",
description: "Explicitly set the <license> of the new formula." description: "Explicitly set the <license> of the new formula."
flag "--tap=", flag "--tap=",
@ -61,7 +65,12 @@ module Homebrew
switch "-f", "--force", switch "-f", "--force",
description: "Ignore errors for disallowed formula names and names that shadow aliases." description: "Ignore errors for disallowed formula names and names that shadow aliases."
conflicts "--autotools", "--cmake", "--crystal", "--go", "--meson", "--node", "--perl", "--python", "--rust" conflicts "--autotools", "--cmake", "--crystal", "--go", "--meson", "--node",
"--perl", "--python", "--ruby", "--rust", "--cask"
conflicts "--cask", "--HEAD"
conflicts "--cask", "--set-license"
conflicts "--cask", "--tap"
named 1 named 1
end end
end end
@ -70,24 +79,73 @@ module Homebrew
def create def create
args = create_args.parse args = create_args.parse
# Ensure that the cache exists so we can fetch the tarball path = if args.cask?
HOMEBREW_CACHE.mkpath create_cask(args: args)
else
create_formula(args: args)
end
url = args.named.first # Pull the first (and only) url from ARGV exec_editor path
end
version = args.set_version def create_cask(args:)
name = args.set_name url = args.named.first
license = args.set_license
tap = args.tap
if (token = args.set_name).nil?
raise UsageError, "The `--set-name` flag is required for creating casks."
end
cask_path = Cask::CaskLoader.path(token)
raise Cask::CaskAlreadyCreatedError, token if cask_path.exist?
version = if args.set_version
Version.create(args.set_version)
else
Version.detect(url.gsub(token, ""))
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
cask_path.atomic_write <<~RUBY
cask "#{token}" do
version "#{version}"
sha256 "#{sha256}"
url "#{interpolated_url}"
name ""
desc ""
homepage ""
app ""
end
RUBY
puts "Please run `brew audit --cask --new #{token}` before submitting, thanks."
cask_path
end
def create_formula(args:)
fc = FormulaCreator.new(args) fc = FormulaCreator.new(args)
fc.name = name fc.name = args.name
fc.version = version fc.version = args.version
fc.license = license fc.license = args.license
fc.tap = Tap.fetch(tap || "homebrew/core") fc.tap = Tap.fetch(args.tap || "homebrew/core")
raise TapUnavailableError, tap unless fc.tap.installed? raise TapUnavailableError, tap unless fc.tap.installed?
fc.url = url fc.url = args.named.first # Pull the first (and only) url from ARGV
fc.mode = if args.cmake? fc.mode = if args.cmake?
:cmake :cmake
@ -143,8 +201,8 @@ module Homebrew
PyPI.update_python_resources! Formula[fc.name], ignore_non_pypi_packages: true if args.python? PyPI.update_python_resources! Formula[fc.name], ignore_non_pypi_packages: true if args.python?
puts "Please run `brew audit --new-formula #{fc.name}` before submitting, thanks." puts "Please run `brew audit --new #{fc.name}` before submitting, thanks."
exec_editor fc.path fc.path
end end
def __gets def __gets

View File

@ -946,14 +946,16 @@ Display the path to the file being used when invoking `brew` *`cmd`*.
### `create` [*`options`*] *`URL`* ### `create` [*`options`*] *`URL`*
Generate a formula for the downloadable file at *`URL`* and open it in the editor. Generate a formula or, with `--cask`, a cask for the downloadable file at *`URL`*
Homebrew will attempt to automatically derive the formula name and version, but and open it in the editor. Homebrew will attempt to automatically derive the
if it fails, you'll have to make your own template. The `wget` formula serves as formula name and version, but if it fails, you'll have to make your own template.
a simple example. For the complete API, see: The `wget` formula serves as a simple example. For the complete API, see:
<https://rubydoc.brew.sh/Formula> <https://rubydoc.brew.sh/Formula>
* `--autotools`: * `--autotools`:
Create a basic template for an Autotools-style build. Create a basic template for an Autotools-style build.
* `--cask`:
Create a basic template for a cask.
* `--cmake`: * `--cmake`:
Create a basic template for a CMake-style build. Create a basic template for a CMake-style build.
* `--crystal`: * `--crystal`:
@ -977,9 +979,9 @@ a simple example. For the complete API, see:
* `--HEAD`: * `--HEAD`:
Indicate that *`URL`* points to the package's repository rather than a file. Indicate that *`URL`* points to the package's repository rather than a file.
* `--set-name`: * `--set-name`:
Explicitly set the *`name`* of the new formula. Explicitly set the *`name`* of the new formula or cask.
* `--set-version`: * `--set-version`:
Explicitly set the *`version`* of the new formula. Explicitly set the *`version`* of the new formula or cask.
* `--set-license`: * `--set-license`:
Explicitly set the *`license`* of the new formula. Explicitly set the *`license`* of the new formula.
* `--tap`: * `--tap`:

View File

@ -1316,13 +1316,17 @@ Treat all named arguments as casks\.
Display the path to the file being used when invoking \fBbrew\fR \fIcmd\fR\. Display the path to the file being used when invoking \fBbrew\fR \fIcmd\fR\.
. .
.SS "\fBcreate\fR [\fIoptions\fR] \fIURL\fR" .SS "\fBcreate\fR [\fIoptions\fR] \fIURL\fR"
Generate a formula for the downloadable file at \fIURL\fR 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 \fBwget\fR formula serves as a simple example\. For the complete API, see: \fIhttps://rubydoc\.brew\.sh/Formula\fR Generate a formula or, with \fB\-\-cask\fR, a cask for the downloadable file at \fIURL\fR 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 \fBwget\fR formula serves as a simple example\. For the complete API, see: \fIhttps://rubydoc\.brew\.sh/Formula\fR
. .
.TP .TP
\fB\-\-autotools\fR \fB\-\-autotools\fR
Create a basic template for an Autotools\-style build\. Create a basic template for an Autotools\-style build\.
. .
.TP .TP
\fB\-\-cask\fR
Create a basic template for a cask\.
.
.TP
\fB\-\-cmake\fR \fB\-\-cmake\fR
Create a basic template for a CMake\-style build\. Create a basic template for a CMake\-style build\.
. .
@ -1368,11 +1372,11 @@ Indicate that \fIURL\fR points to the package\'s repository rather than a file\.
. .
.TP .TP
\fB\-\-set\-name\fR \fB\-\-set\-name\fR
Explicitly set the \fIname\fR of the new formula\. Explicitly set the \fIname\fR of the new formula or cask\.
. .
.TP .TP
\fB\-\-set\-version\fR \fB\-\-set\-version\fR
Explicitly set the \fIversion\fR of the new formula\. Explicitly set the \fIversion\fR of the new formula or cask\.
. .
.TP .TP
\fB\-\-set\-license\fR \fB\-\-set\-license\fR