Merge pull request #16518 from issyl0/rubocop-md

rubocop: Try out `rubocop-md` for linting the code in our docs
This commit is contained in:
Issy Long 2024-02-02 15:49:46 +00:00 committed by GitHub
commit 06028c204a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 185 additions and 141 deletions

View File

@ -40,6 +40,10 @@ jobs:
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs
run: bundle exec rake lint run: bundle exec rake lint
- name: Check code blocks conform to our Ruby style guide
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs
run: brew style .
- name: Build the site and check for broken links - name: Build the site and check for broken links
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs
run: | run: |

View File

@ -1,6 +1,7 @@
--- ---
require: require:
- ./Homebrew/rubocops.rb - ./Homebrew/rubocops.rb
- rubocop-md
- rubocop-performance - rubocop-performance
- rubocop-rspec - rubocop-rspec
- rubocop-sorbet - rubocop-sorbet

View File

@ -42,6 +42,7 @@ group :pry, optional: true do
end end
group :style, optional: true do group :style, optional: true do
gem "rubocop", require: false gem "rubocop", require: false
gem "rubocop-md", require: false
gem "rubocop-performance", require: false gem "rubocop-performance", require: false
gem "rubocop-rspec", require: false gem "rubocop-rspec", require: false
gem "rubocop-sorbet", require: false gem "rubocop-sorbet", require: false

View File

@ -103,6 +103,8 @@ GEM
rubocop (~> 1.41) rubocop (~> 1.41)
rubocop-factory_bot (2.25.1) rubocop-factory_bot (2.25.1)
rubocop (~> 1.41) rubocop (~> 1.41)
rubocop-md (1.2.2)
rubocop (>= 1.0)
rubocop-performance (1.20.2) rubocop-performance (1.20.2)
rubocop (>= 1.48.1, < 2.0) rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0) rubocop-ast (>= 1.30.0, < 2.0)
@ -190,6 +192,7 @@ DEPENDENCIES
rspec_junit_formatter rspec_junit_formatter
rubocop rubocop
rubocop-ast rubocop-ast
rubocop-md
rubocop-performance rubocop-performance
rubocop-rspec rubocop-rspec
rubocop-sorbet rubocop-sorbet

View File

@ -129,6 +129,8 @@ module Homebrew
files&.map!(&:expand_path) files&.map!(&:expand_path)
if files.blank? || files == [HOMEBREW_REPOSITORY] if files.blank? || files == [HOMEBREW_REPOSITORY]
files = [HOMEBREW_LIBRARY_PATH] files = [HOMEBREW_LIBRARY_PATH]
elsif files.any? { |f| f.to_s.start_with? HOMEBREW_REPOSITORY/"docs" }
args << "--config" << (HOMEBREW_REPOSITORY/"docs/.rubocop.yml")
elsif files.none? { |f| f.to_s.start_with? HOMEBREW_LIBRARY_PATH } elsif files.none? { |f| f.to_s.start_with? HOMEBREW_LIBRARY_PATH }
args << "--config" << (HOMEBREW_LIBRARY/".rubocop.yml") args << "--config" << (HOMEBREW_LIBRARY/".rubocop.yml")
end end

View File

@ -95,6 +95,7 @@ $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-1.60.2/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-1.60.2/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-capybara-2.20.0/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-capybara-2.20.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-factory_bot-2.25.1/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-factory_bot-2.25.1/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-md-1.2.2/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-performance-1.20.2/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-performance-1.20.2/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rspec-2.26.1/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rspec-2.26.1/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-sorbet-0.7.6/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-sorbet-0.7.6/lib")

32
docs/.rubocop.yml Normal file
View File

@ -0,0 +1,32 @@
inherit_from: ../Library/.rubocop.yml
AllCops:
Exclude:
- Gemfile
- ".mdl*.rb"
- Rakefile
- "_site/**/*"
- Manpage.md
# These are included in docs deliberately to show what
# `brew create` does and what the user should replace.
FormulaAudit/Comments:
Enabled: false
# This forces us to use dummy descriptions/homepages in example formulae which we don't need to clutter the docs with.
FormulaAudit/Desc:
Enabled: false
FormulaAudit/Homepage:
Enabled: false
Layout/LineLength:
Exclude:
- Bottles.md # The bottle block line length is long in its full form.
# Apparently Casks are allowed to have constant definitions in blocks and we document this.
Lint/ConstantDefinitionInBlock:
Enabled: false
# A fake regexp is deliberately documented for `inreplace` in the Formula Cookbook.
Style/RedundantRegexpArgument:
Enabled: false

View File

@ -165,36 +165,13 @@ If the `generate_cask_token` script does not work for you, see [Cask Token Detai
#### Creating the cask file #### Creating the cask file
Once you know the token, create your cask with the handy-dandy `brew create --cask` command: Once you know the token, create your cask with the `brew create --cask` command:
```bash ```bash
brew create --cask download-url --set-name my-new-cask brew create --cask download-url --set-name my-new-cask
``` ```
This will open `EDITOR` with a template for your new cask, to be stored in the file `my-new-cask.rb`. Running the `create` command above will get you a template that looks like this: This will open `EDITOR` with a template for your new cask, to be stored in the file `my-new-cask.rb`.
```ruby
cask "my-new-cask" do
version ""
sha256 ""
url "download-url"
name ""
desc ""
homepage ""
livecheck do
url ""
strategy ""
end
depends_on macos: ""
app ""
zap trash: ""
end
```
#### Cask stanzas #### Cask stanzas
@ -242,7 +219,7 @@ Example:
1. So, the `app` stanza should include the subfolder as a relative path: 1. So, the `app` stanza should include the subfolder as a relative path:
```ruby ```ruby
app "Simple Floating Clock/SimpleFloatingClock.app" app "Simple Floating Clock/SimpleFloatingClock.app"
``` ```
### Testing and auditing the cask ### Testing and auditing the cask

View File

@ -29,13 +29,7 @@ Exception: `do` blocks such as `postflight` may enclose a block of pure Ruby cod
## Header line details ## Header line details
The first non-comment line in a cask follows the form: The Cask name ([`<cask-token>`](#token-reference)) on the header line `cask <cask-token> do` should match the cask filename, without the `.rb` extension, enclosed in double quotes.
```ruby
cask "<cask-token>" do
```
[`<cask-token>`](#token-reference) should match the cask filename, without the `.rb` extension, enclosed in double quotes.
There are currently some arbitrary limitations on cask tokens which are in the process of being removed. GitHub Actions will catch any errors during the transition. There are currently some arbitrary limitations on cask tokens which are in the process of being removed. GitHub Actions will catch any errors during the transition.
@ -857,7 +851,7 @@ uninstall signal: [
["INT", "fr.madrau.switchresx.daemon"], ["INT", "fr.madrau.switchresx.daemon"],
["HUP", "fr.madrau.switchresx.daemon"], ["HUP", "fr.madrau.switchresx.daemon"],
["KILL", "fr.madrau.switchresx.daemon"], ["KILL", "fr.madrau.switchresx.daemon"],
] ]
``` ```
Note that when multiple running processes match the given bundle ID, all matching processes will be signaled. Note that when multiple running processes match the given bundle ID, all matching processes will be signaled.
@ -1082,7 +1076,7 @@ we can use:
```ruby ```ruby
version "1.2.3" version "1.2.3"
url "https://example.com/file-version-#{version.delete('.')}.dmg" url "https://example.com/file-version-#{version.delete(".")}.dmg"
``` ```
We can also leverage the power of regular expressions. So instead of: We can also leverage the power of regular expressions. So instead of:
@ -1096,7 +1090,7 @@ we can use:
```ruby ```ruby
version "1.2.3build4" version "1.2.3build4"
url "https://example.com/#{version.sub(%r{build\d+}, '')}/file-version-#{version}.dmg" url "https://example.com/#{version.sub(/build\d+/, "")}/file-version-#{version}.dmg"
``` ```
#### `version` methods #### `version` methods
@ -1197,6 +1191,7 @@ cask "libreoffice" do
url "https://download.documentfoundation.org/libreoffice/stable/#{version}/mac/#{folder}/LibreOffice_#{version}_MacOS_#{arch}.dmg", url "https://download.documentfoundation.org/libreoffice/stable/#{version}/mac/#{folder}/LibreOffice_#{version}_MacOS_#{arch}.dmg",
verified: "download.documentfoundation.org/libreoffice/stable/" verified: "download.documentfoundation.org/libreoffice/stable/"
end
``` ```
If the version number is different for each architecture, locate the unique `version` and (if checked) `sha256` stanzas within `on_arm` and `on_intel` blocks. Example (from [inkscape.rb](https://github.com/Homebrew/homebrew-cask/blob/11f6966bf17628b98895d64a61a4fb0bc1bb31bf/Casks/i/inkscape.rb#L1-L13)): If the version number is different for each architecture, locate the unique `version` and (if checked) `sha256` stanzas within `on_arm` and `on_intel` blocks. Example (from [inkscape.rb](https://github.com/Homebrew/homebrew-cask/blob/11f6966bf17628b98895d64a61a4fb0bc1bb31bf/Casks/i/inkscape.rb#L1-L13)):
@ -1215,6 +1210,7 @@ cask "inkscape" do
end end
url "https://inkscape.org/gallery/item/#{version.csv.second}/Inkscape-#{version.csv.first}_#{arch}.dmg" url "https://inkscape.org/gallery/item/#{version.csv.second}/Inkscape-#{version.csv.first}_#{arch}.dmg"
end
``` ```
To adjust the installed version depending on the current macOS release, use a series of `on_<system>` blocks that cover the range of supported releases. Each block can contain stanzas that set which version to download and customize installation/uninstallation and livecheck behaviour for one or more releases. Example (from [calibre.rb](https://github.com/Homebrew/homebrew-cask/blob/482c34e950da8d649705f4aaea7b760dcb4b5402/Casks/c/calibre.rb#L1-L34)): To adjust the installed version depending on the current macOS release, use a series of `on_<system>` blocks that cover the range of supported releases. Each block can contain stanzas that set which version to download and customize installation/uninstallation and livecheck behaviour for one or more releases. Example (from [calibre.rb](https://github.com/Homebrew/homebrew-cask/blob/482c34e950da8d649705f4aaea7b760dcb4b5402/Casks/c/calibre.rb#L1-L34)):
@ -1244,6 +1240,7 @@ cask "calibre" do
strategy :github_latest strategy :github_latest
end end
end end
end
``` ```
Such `on_<system>` blocks can be nested and contain other stanzas not listed here. Examples: [calhash.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/c/calhash.rb), [openzfs.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/o/openzfs.rb), [r.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/r/r.rb), [wireshark.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/w/wireshark.rb) Such `on_<system>` blocks can be nested and contain other stanzas not listed here. Examples: [calhash.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/c/calhash.rb), [openzfs.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/o/openzfs.rb), [r.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/r/r.rb), [wireshark.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/w/wireshark.rb)
@ -1260,17 +1257,17 @@ In the exceptional case that the cask DSL is insufficient, it is possible to def
cask "myapp" do cask "myapp" do
module Utils module Utils
def self.arbitrary_method def self.arbitrary_method
... # ...
end end
end end
name "MyApp"
version "1.0" version "1.0"
sha256 "a32565cdb1673f4071593d4cc9e1c26bc884218b62fef8abc450daa47ba8fa92" sha256 "a32565cdb1673f4071593d4cc9e1c26bc884218b62fef8abc450daa47ba8fa92"
url "https://#{Utils.arbitrary_method}" url "https://#{Utils.arbitrary_method}"
name "MyApp"
homepage "https://www.example.com/" homepage "https://www.example.com/"
... # ...
end end
``` ```

View File

@ -60,33 +60,10 @@ Run `brew create` with a URL to the source tarball:
brew create https://example.com/foo-0.1.tar.gz brew create https://example.com/foo-0.1.tar.gz
``` ```
This creates `$(brew --repository)/Library/Taps/homebrew/homebrew-core/Formula/f/foo.rb` and opens it in your `EDITOR`.
Passing in `--ruby` or `--python` will populate various defaults commonly useful for projects written in those languages. Passing in `--ruby` or `--python` will populate various defaults commonly useful for projects written in those languages.
This creates `$(brew --repository)/Library/Taps/homebrew/homebrew-core/Formula/f/foo.rb` and opens it in your `EDITOR`. If run without any options to customize the output for specific build systems (check `brew create --help` to see which are available) it'll look something like:
```ruby
class Foo < Formula
desc ""
homepage ""
url "https://example.com/foo-0.1.tar.gz"
sha256 "85cc828a96735bdafcf29eb6291ca91bac846579bcef7308536e0c875d6c81d7"
license ""
# depends_on "cmake" => :build
def install
# ENV.deparallelize
system "./configure", *std_configure_args, "--disable-silent-rules"
# system "cmake", "-S", ".", "-B", "build", *std_cmake_args
system "make", "install"
end
test do
system "false"
end
end
```
If `brew` said `Warning: Version cannot be determined from URL` when doing the `create` step, youll need to explicitly add the correct [`version`](https://rubydoc.brew.sh/Formula#version-class_method) to the formula and then save the formula. If `brew` said `Warning: Version cannot be determined from URL` when doing the `create` step, youll need to explicitly add the correct [`version`](https://rubydoc.brew.sh/Formula#version-class_method) to the formula and then save the formula.
Homebrew will try to guess the formulas name from its URL. If it fails to do so you can override this with `brew create <URL> --set-name <name>`. Homebrew will try to guess the formulas name from its URL. If it fails to do so you can override this with `brew create <URL> --set-name <name>`.
@ -145,14 +122,18 @@ Special exceptions are OpenSSL and LibreSSL. Things that use either *should* be
```ruby ```ruby
class Foo < Formula class Foo < Formula
depends_on "pkg-config" # ...
depends_on "jpeg"
depends_on "gtk+" => :optional
depends_on "readline" => :recommended
depends_on "httpd" => [:build, :test] depends_on "httpd" => [:build, :test]
depends_on arch: :x86_64
depends_on macos: :high_sierra
depends_on xcode: ["9.3", :build] depends_on xcode: ["9.3", :build]
depends_on arch: :x86_64
depends_on "jpeg"
depends_on macos: :high_sierra
depends_on "pkg-config"
depends_on "readline" => :recommended
depends_on "gtk+" => :optional
# ...
end end
``` ```
@ -168,8 +149,8 @@ A `Hash` (e.g. `=>`) adds information to a dependency. Given a string or symbol,
* `:recommended` (not allowed in `Homebrew/homebrew-core`) generates an implicit `without-foo` option, meaning that the dependency is enabled by default and the user must pass `--without-foo` to disable this dependency. The default description can be overridden using the [`option`](https://rubydoc.brew.sh/Formula#option-class_method) syntax (in this case, the [`option` declaration](#adding-optional-steps) must precede the dependency): * `:recommended` (not allowed in `Homebrew/homebrew-core`) generates an implicit `without-foo` option, meaning that the dependency is enabled by default and the user must pass `--without-foo` to disable this dependency. The default description can be overridden using the [`option`](https://rubydoc.brew.sh/Formula#option-class_method) syntax (in this case, the [`option` declaration](#adding-optional-steps) must precede the dependency):
```ruby ```ruby
option "with-foo", "Compile with foo bindings" # This overrides the generated description if you want to option "with-foo", "Compile with foo bindings" # This overrides the generated description if you want to
depends_on "foo" => :optional # Generated description would otherwise be "Build with foo support" depends_on "foo" => :optional # Generated description would otherwise be "Build with foo support"
``` ```
* `"<option-name>"` (not allowed in `Homebrew/homebrew-core`) requires a dependency to have been built with the specified option. * `"<option-name>"` (not allowed in `Homebrew/homebrew-core`) requires a dependency to have been built with the specified option.
@ -271,7 +252,7 @@ And install any bins, and munge their shebang lines, with:
```ruby ```ruby
bin.install libexec/"bin/<bin>" bin.install libexec/"bin/<bin>"
bin.env_script_all_files(libexec/"bin", GEM_HOME: ENV["GEM_HOME"]) bin.env_script_all_files(libexec/"bin", GEM_HOME: ENV.fetch("GEM_HOME", nil))
``` ```
### Python dependencies ### Python dependencies
@ -284,6 +265,9 @@ If all else fails, you'll want to use [`resource`](https://rubydoc.brew.sh/Formu
```ruby ```ruby
class Foo < Formula class Foo < Formula
# ...
url "https://example.com/foo-1.0.tar.gz"
resource "pycrypto" do resource "pycrypto" do
url "https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz" url "https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz"
sha256 "f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c" sha256 "f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c"
@ -546,7 +530,7 @@ end
```ruby ```ruby
stable do stable do
# some other things... # ...
patch do patch do
url "https://example.com/example_patch.diff" url "https://example.com/example_patch.diff"
@ -662,6 +646,7 @@ Formulae can specify an alternate download for the upstream projects developm
```ruby ```ruby
class Foo < Formula class Foo < Formula
# ...
head "https://github.com/some/package.git", branch: "main" # the default is "master" head "https://github.com/some/package.git", branch: "main" # the default is "master"
end end
``` ```
@ -670,6 +655,8 @@ You can also bundle the URL and any `head`-specific dependencies and resources i
```ruby ```ruby
class Foo < Formula class Foo < Formula
# ...
head do head do
url "https://svn.code.sf.net/p/project/code/trunk" url "https://svn.code.sf.net/p/project/code/trunk"
depends_on "pkg-config" => :build depends_on "pkg-config" => :build
@ -685,7 +672,7 @@ When parsing a download URL, Homebrew auto-detects the resource type it points t
```ruby ```ruby
class Foo < Formula class Foo < Formula
homepage "https://github.com/some/package" # ...
url "https://github.com/some/package.git", url "https://github.com/some/package.git",
tag: "v1.6.2", tag: "v1.6.2",
revision: "344cd2ee3463abab4c16ac0f9529a846314932a2" revision: "344cd2ee3463abab4c16ac0f9529a846314932a2"
@ -696,10 +683,12 @@ If not inferable, specify which of Homebrews built-in download strategies to
```ruby ```ruby
class Nginx < Formula class Nginx < Formula
desc "HTTP(S) server and reverse proxy, and IMAP/POP3 proxy server"
homepage "https://nginx.org/" homepage "https://nginx.org/"
url "https://nginx.org/download/nginx-1.23.2.tar.gz", using: :homebrew_curl url "https://nginx.org/download/nginx-1.23.2.tar.gz", using: :homebrew_curl
sha256 "a80cc272d3d72aaee70aa8b517b4862a635c0256790434dbfc4d618a999b0b46" sha256 "a80cc272d3d72aaee70aa8b517b4862a635c0256790434dbfc4d618a999b0b46"
head "https://hg.nginx.org/nginx/", using: :hg head "https://hg.nginx.org/nginx/", using: :hg
end
``` ```
Homebrew offers these anonymous download strategies. Homebrew offers these anonymous download strategies.
@ -729,7 +718,7 @@ class MyDownloadStrategy < SomeHomebrewDownloadStrategy
end end
class Foo < Formula class Foo < Formula
url "something", :using => MyDownloadStrategy url "something", using: MyDownloadStrategy
end end
``` ```
@ -855,25 +844,25 @@ Several other utilities for Ruby's [`Pathname`](https://rubydoc.brew.sh/Pathname
* To perform several operations within a directory, enclose them within a [`cd <path> do`](https://rubydoc.brew.sh/Pathname#cd-instance_method) block: * To perform several operations within a directory, enclose them within a [`cd <path> do`](https://rubydoc.brew.sh/Pathname#cd-instance_method) block:
```ruby ```ruby
cd "src" do cd "src" do
system "./configure", "--disable-debug", "--prefix=#{prefix}" system "./configure", "--disable-debug", "--prefix=#{prefix}"
system "make", "install" system "make", "install"
end end
``` ```
* To surface one or more binaries buried in `libexec` or a macOS `.app` package, use [`write_exec_script`](https://rubydoc.brew.sh/Pathname#write_exec_script-instance_method) or [`write_jar_script`](https://rubydoc.brew.sh/Pathname#write_jar_script-instance_method): * To surface one or more binaries buried in `libexec` or a macOS `.app` package, use [`write_exec_script`](https://rubydoc.brew.sh/Pathname#write_exec_script-instance_method) or [`write_jar_script`](https://rubydoc.brew.sh/Pathname#write_jar_script-instance_method):
```ruby ```ruby
bin.write_exec_script (libexec/"bin").children bin.write_exec_script (libexec/"bin").children
bin.write_exec_script prefix/"Package.app/Contents/MacOS/package" bin.write_exec_script prefix/"Package.app/Contents/MacOS/package"
bin.write_jar_script libexec/jar_file, "jarfile", java_version: "11" bin.write_jar_script libexec/jar_file, "jarfile", java_version: "11"
``` ```
* For binaries that require setting one or more environment variables to function properly, use [`write_env_script`](https://rubydoc.brew.sh/Pathname#write_env_script-instance_method) or [`env_script_all_files`](https://rubydoc.brew.sh/Pathname#env_script_all_files-instance_method): * For binaries that require setting one or more environment variables to function properly, use [`write_env_script`](https://rubydoc.brew.sh/Pathname#write_env_script-instance_method) or [`env_script_all_files`](https://rubydoc.brew.sh/Pathname#env_script_all_files-instance_method):
```ruby ```ruby
(bin/"package").write_env_script libexec/"package", PACKAGE_ROOT: libexec (bin/"package").write_env_script libexec/"package", PACKAGE_ROOT: libexec
bin.env_script_all_files(libexec/"bin", PERL5LIB: ENV["PERL5LIB"]) bin.env_script_all_files(libexec/"bin", PERL5LIB: ENV.fetch("PERL5LIB", nil))
``` ```
### Rewriting a script shebang ### Rewriting a script shebang
@ -890,13 +879,17 @@ If you want to add an [`option`](https://rubydoc.brew.sh/Formula#option-class_me
```ruby ```ruby
class Yourformula < Formula class Yourformula < Formula
... # ...
url "https://example.com/yourformula-1.0.tar.gz"
sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
# ...
option "with-ham", "Description of the option" option "with-ham", "Description of the option"
option "without-spam", "Another description" option "without-spam", "Another description"
depends_on "foo" => :optional # automatically adds a with-foo option depends_on "bar" => :recommended
depends_on "bar" => :recommended # automatically adds a without-bar option depends_on "foo" => :optional # automatically adds a with-foo option # automatically adds a without-bar option
... # ...
end
``` ```
And then to define the effects the [`option`](https://rubydoc.brew.sh/Formula#option-class_method)s have: And then to define the effects the [`option`](https://rubydoc.brew.sh/Formula#option-class_method)s have:
@ -920,9 +913,15 @@ end
Any initialization steps that aren't necessarily part of the install process can be located in a `post_install` block, such as setup commands or data directory creation. This block can be re-run separately with `brew postinstall <formula>`. Any initialization steps that aren't necessarily part of the install process can be located in a `post_install` block, such as setup commands or data directory creation. This block can be re-run separately with `brew postinstall <formula>`.
```ruby ```ruby
def post_install class Foo < Formula
# ...
url "https://example.com/foo-1.0.tar.gz"
def post_install
rm_f pkgetc/"cert.pem" rm_f pkgetc/"cert.pem"
pkgetc.install_symlink Formula["ca-certificates"].pkgetc/"cert.pem" pkgetc.install_symlink Formula["ca-certificates"].pkgetc/"cert.pem"
end
# ...
end end
``` ```
@ -941,10 +940,10 @@ There are two ways to add `launchd` plists and `systemd` services to a formula,
1. If the package already provides a service file the formula can reference it by name: 1. If the package already provides a service file the formula can reference it by name:
```ruby ```ruby
service do service do
name macos: "custom.launchd.name", name macos: "custom.launchd.name",
linux: "custom.systemd.name" linux: "custom.systemd.name"
end end
``` ```
To find the file we append `.plist` to the `launchd` service name and `.service` to the `systemd` service name internally. To find the file we append `.plist` to the `launchd` service name and `.service` to the `systemd` service name internally.
@ -953,20 +952,20 @@ There are two ways to add `launchd` plists and `systemd` services to a formula,
```ruby ```ruby
# 1. An individual command # 1. An individual command
service do service do
run opt_bin/"script" run opt_bin/"script"
end end
# 2. A command with arguments # 2. A command with arguments
service do service do
run [opt_bin/"script", "--config", etc/"dir/config.yml"] run [opt_bin/"script", "--config", etc/"dir/config.yml"]
end end
# 3. OS specific commands (If you omit one, the service file won't get generated for that OS.) # 3. OS specific commands (If you omit one, the service file won't get generated for that OS.)
service do service do
run macos: [opt_bin/"macos_script", "standalone"], run macos: [opt_bin/"macos_script", "standalone"],
linux: var/"special_linux_script" linux: var/"special_linux_script"
end end
``` ```
#### Service block methods #### Service block methods

View File

@ -68,8 +68,8 @@ These expressions can be nested as needed:
license any_of: [ license any_of: [
"MIT", "MIT",
:public_domain, :public_domain,
all_of: ["0BSD", "Zlib", "Artistic-1.0+"], { all_of: ["0BSD", "Zlib", "Artistic-1.0+"],
"Apache-2.0" => { with: "LLVM-exception" }, "Apache-2.0" => { with: "LLVM-exception" } },
] ]
``` ```

View File

@ -91,10 +91,10 @@ Installing a standard Node module based formula would look like this:
require "language/node" require "language/node"
class Foo < Formula class Foo < Formula
desc "..." desc "An example formula"
homepage "..." homepage "https://example.com"
url "https://registry.npmjs.org/foo/-/foo-1.4.2.tgz" url "https://registry.npmjs.org/foo/-/foo-1.4.2.tgz"
sha256 "..." sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
depends_on "node" depends_on "node"
# uncomment if there is a native addon inside the dependency tree # uncomment if there is a native addon inside the dependency tree
@ -106,7 +106,8 @@ class Foo < Formula
end end
test do test do
# add a meaningful test here # add a meaningful test here, version isn't usually meaningful
assert_match version.to_s, shell_output("#{bin}/foo --version")
end end
end end
``` ```

View File

@ -50,15 +50,32 @@ Homebrew provides helper methods for instantiating and populating virtualenvs. Y
For most applications, all you will need to write is: For most applications, all you will need to write is:
```ruby ```ruby
def install class Foo < Formula
include Language::Python::Virtualenv
name "foo"
# ...
url "..."
sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
def install
virtualenv_install_with_resources virtualenv_install_with_resources
end
end end
``` ```
This is exactly the same as writing: This is exactly the same as writing:
```ruby ```ruby
def install class Foo < Formula
include Language::Python::Virtualenv
name "foo"
# ...
url "https://example.com/foo-1.0.tar.gz"
sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
def install
# Create a virtualenv in `libexec`. If your app needs Python 3, make sure that # Create a virtualenv in `libexec`. If your app needs Python 3, make sure that
# `depends_on "python"` is declared, and use `virtualenv_create(libexec, "python3")`. # `depends_on "python"` is declared, and use `virtualenv_create(libexec, "python3")`.
venv = virtualenv_create(libexec) venv = virtualenv_create(libexec)
@ -70,6 +87,7 @@ def install
# that the formula points to, because buildpath is the location where the # that the formula points to, because buildpath is the location where the
# formula's tarball was unpacked. # formula's tarball was unpacked.
venv.pip_install_and_link buildpath venv.pip_install_and_link buildpath
end
end end
``` ```
@ -81,6 +99,8 @@ Installing a formula with dependencies will look like this:
class Foo < Formula class Foo < Formula
include Language::Python::Virtualenv include Language::Python::Virtualenv
desc "Description"
homepage "https://example.com"
url "..." url "..."
resource "six" do resource "six" do
@ -102,12 +122,20 @@ end
You can also use the more verbose form and request that specific resources be installed: You can also use the more verbose form and request that specific resources be installed:
```ruby ```ruby
def install class Foo < Formula
include Language::Python::Virtualenv
desc "Description"
homepage "https://example.com"
url "..."
def install
venv = virtualenv_create(libexec) venv = virtualenv_create(libexec)
%w[six parsedatetime].each do |r| %w[six parsedatetime].each do |r|
venv.pip_install resource(r) venv.pip_install resource(r)
end end
venv.pip_install_and_link buildpath venv.pip_install_and_link buildpath
end
end end
``` ```

View File

@ -12,8 +12,6 @@ The `sig` method is used to annotate method signatures. Here's a simple example:
```ruby ```ruby
class MyClass class MyClass
extend T::Sig
sig { params(name: String).returns(String) } sig { params(name: String).returns(String) }
def my_method(name) def my_method(name)
"Hello, #{name}!" "Hello, #{name}!"