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:
commit
06028c204a
4
.github/workflows/docs.yml
vendored
4
.github/workflows/docs.yml
vendored
@ -40,6 +40,10 @@ jobs:
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs
|
||||
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
|
||||
working-directory: ${{ steps.set-up-homebrew.outputs.repository-path }}/docs
|
||||
run: |
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
require:
|
||||
- ./Homebrew/rubocops.rb
|
||||
- rubocop-md
|
||||
- rubocop-performance
|
||||
- rubocop-rspec
|
||||
- rubocop-sorbet
|
||||
|
@ -42,6 +42,7 @@ group :pry, optional: true do
|
||||
end
|
||||
group :style, optional: true do
|
||||
gem "rubocop", require: false
|
||||
gem "rubocop-md", require: false
|
||||
gem "rubocop-performance", require: false
|
||||
gem "rubocop-rspec", require: false
|
||||
gem "rubocop-sorbet", require: false
|
||||
|
@ -103,6 +103,8 @@ GEM
|
||||
rubocop (~> 1.41)
|
||||
rubocop-factory_bot (2.25.1)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-md (1.2.2)
|
||||
rubocop (>= 1.0)
|
||||
rubocop-performance (1.20.2)
|
||||
rubocop (>= 1.48.1, < 2.0)
|
||||
rubocop-ast (>= 1.30.0, < 2.0)
|
||||
@ -190,6 +192,7 @@ DEPENDENCIES
|
||||
rspec_junit_formatter
|
||||
rubocop
|
||||
rubocop-ast
|
||||
rubocop-md
|
||||
rubocop-performance
|
||||
rubocop-rspec
|
||||
rubocop-sorbet
|
||||
|
@ -129,6 +129,8 @@ module Homebrew
|
||||
files&.map!(&:expand_path)
|
||||
if files.blank? || files == [HOMEBREW_REPOSITORY]
|
||||
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 }
|
||||
args << "--config" << (HOMEBREW_LIBRARY/".rubocop.yml")
|
||||
end
|
||||
|
@ -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-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-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-rspec-2.26.1/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
32
docs/.rubocop.yml
Normal 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
|
@ -165,36 +165,13 @@ If the `generate_cask_token` script does not work for you, see [Cask Token Detai
|
||||
|
||||
#### 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
|
||||
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:
|
||||
|
||||
```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
|
||||
```
|
||||
This will open `EDITOR` with a template for your new cask, to be stored in the file `my-new-cask.rb`.
|
||||
|
||||
#### Cask stanzas
|
||||
|
||||
|
@ -29,13 +29,7 @@ Exception: `do` blocks such as `postflight` may enclose a block of pure Ruby cod
|
||||
|
||||
## Header line details
|
||||
|
||||
The first non-comment line in a cask follows the form:
|
||||
|
||||
```ruby
|
||||
cask "<cask-token>" do
|
||||
```
|
||||
|
||||
[`<cask-token>`](#token-reference) should match the cask filename, without the `.rb` extension, enclosed in double quotes.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@ -1082,7 +1076,7 @@ we can use:
|
||||
|
||||
```ruby
|
||||
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:
|
||||
@ -1096,7 +1090,7 @@ we can use:
|
||||
|
||||
```ruby
|
||||
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
|
||||
@ -1197,6 +1191,7 @@ cask "libreoffice" do
|
||||
|
||||
url "https://download.documentfoundation.org/libreoffice/stable/#{version}/mac/#{folder}/LibreOffice_#{version}_MacOS_#{arch}.dmg",
|
||||
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)):
|
||||
@ -1215,6 +1210,7 @@ cask "inkscape" do
|
||||
end
|
||||
|
||||
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)):
|
||||
@ -1244,6 +1240,7 @@ cask "calibre" do
|
||||
strategy :github_latest
|
||||
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)
|
||||
@ -1260,17 +1257,17 @@ In the exceptional case that the cask DSL is insufficient, it is possible to def
|
||||
cask "myapp" do
|
||||
module Utils
|
||||
def self.arbitrary_method
|
||||
...
|
||||
# ...
|
||||
end
|
||||
end
|
||||
|
||||
name "MyApp"
|
||||
version "1.0"
|
||||
sha256 "a32565cdb1673f4071593d4cc9e1c26bc884218b62fef8abc450daa47ba8fa92"
|
||||
|
||||
url "https://#{Utils.arbitrary_method}"
|
||||
name "MyApp"
|
||||
homepage "https://www.example.com/"
|
||||
...
|
||||
# ...
|
||||
end
|
||||
```
|
||||
|
||||
|
@ -60,33 +60,10 @@ Run `brew create` with a URL to the source tarball:
|
||||
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.
|
||||
|
||||
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, you’ll 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 formula’s 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
|
||||
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 arch: :x86_64
|
||||
depends_on macos: :high_sierra
|
||||
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
|
||||
```
|
||||
|
||||
@ -271,7 +252,7 @@ And install any bins, and munge their shebang lines, with:
|
||||
|
||||
```ruby
|
||||
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
|
||||
@ -284,6 +265,9 @@ If all else fails, you'll want to use [`resource`](https://rubydoc.brew.sh/Formu
|
||||
|
||||
```ruby
|
||||
class Foo < Formula
|
||||
# ...
|
||||
url "https://example.com/foo-1.0.tar.gz"
|
||||
|
||||
resource "pycrypto" do
|
||||
url "https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz"
|
||||
sha256 "f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c"
|
||||
@ -546,7 +530,7 @@ end
|
||||
|
||||
```ruby
|
||||
stable do
|
||||
# some other things...
|
||||
# ...
|
||||
|
||||
patch do
|
||||
url "https://example.com/example_patch.diff"
|
||||
@ -662,6 +646,7 @@ Formulae can specify an alternate download for the upstream project’s developm
|
||||
|
||||
```ruby
|
||||
class Foo < Formula
|
||||
# ...
|
||||
head "https://github.com/some/package.git", branch: "main" # the default is "master"
|
||||
end
|
||||
```
|
||||
@ -670,6 +655,8 @@ You can also bundle the URL and any `head`-specific dependencies and resources i
|
||||
|
||||
```ruby
|
||||
class Foo < Formula
|
||||
# ...
|
||||
|
||||
head do
|
||||
url "https://svn.code.sf.net/p/project/code/trunk"
|
||||
depends_on "pkg-config" => :build
|
||||
@ -685,7 +672,7 @@ When parsing a download URL, Homebrew auto-detects the resource type it points t
|
||||
|
||||
```ruby
|
||||
class Foo < Formula
|
||||
homepage "https://github.com/some/package"
|
||||
# ...
|
||||
url "https://github.com/some/package.git",
|
||||
tag: "v1.6.2",
|
||||
revision: "344cd2ee3463abab4c16ac0f9529a846314932a2"
|
||||
@ -696,10 +683,12 @@ If not inferable, specify which of Homebrew’s built-in download strategies to
|
||||
|
||||
```ruby
|
||||
class Nginx < Formula
|
||||
desc "HTTP(S) server and reverse proxy, and IMAP/POP3 proxy server"
|
||||
homepage "https://nginx.org/"
|
||||
url "https://nginx.org/download/nginx-1.23.2.tar.gz", using: :homebrew_curl
|
||||
sha256 "a80cc272d3d72aaee70aa8b517b4862a635c0256790434dbfc4d618a999b0b46"
|
||||
head "https://hg.nginx.org/nginx/", using: :hg
|
||||
end
|
||||
```
|
||||
|
||||
Homebrew offers these anonymous download strategies.
|
||||
@ -729,7 +718,7 @@ class MyDownloadStrategy < SomeHomebrewDownloadStrategy
|
||||
end
|
||||
|
||||
class Foo < Formula
|
||||
url "something", :using => MyDownloadStrategy
|
||||
url "something", using: MyDownloadStrategy
|
||||
end
|
||||
```
|
||||
|
||||
@ -873,7 +862,7 @@ Several other utilities for Ruby's [`Pathname`](https://rubydoc.brew.sh/Pathname
|
||||
|
||||
```ruby
|
||||
(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
|
||||
@ -890,13 +879,17 @@ If you want to add an [`option`](https://rubydoc.brew.sh/Formula#option-class_me
|
||||
|
||||
```ruby
|
||||
class Yourformula < Formula
|
||||
...
|
||||
# ...
|
||||
url "https://example.com/yourformula-1.0.tar.gz"
|
||||
sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
|
||||
# ...
|
||||
option "with-ham", "Description of the option"
|
||||
option "without-spam", "Another description"
|
||||
|
||||
depends_on "foo" => :optional # automatically adds a with-foo option
|
||||
depends_on "bar" => :recommended # automatically adds a without-bar option
|
||||
...
|
||||
depends_on "bar" => :recommended
|
||||
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:
|
||||
@ -920,10 +913,16 @@ 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>`.
|
||||
|
||||
```ruby
|
||||
class Foo < Formula
|
||||
# ...
|
||||
url "https://example.com/foo-1.0.tar.gz"
|
||||
|
||||
def post_install
|
||||
rm_f pkgetc/"cert.pem"
|
||||
pkgetc.install_symlink Formula["ca-certificates"].pkgetc/"cert.pem"
|
||||
end
|
||||
# ...
|
||||
end
|
||||
```
|
||||
|
||||
In the above example, the [`libressl`](https://github.com/Homebrew/homebrew-core/blob/442f9cc511ce6dfe75b96b2c83749d90dde914d2/Formula/lib/libressl.rb#L53-L56) formula replaces its stock list of certificates with a symlink to that of the `ca-certificates` formula.
|
||||
|
@ -68,8 +68,8 @@ These expressions can be nested as needed:
|
||||
license any_of: [
|
||||
"MIT",
|
||||
:public_domain,
|
||||
all_of: ["0BSD", "Zlib", "Artistic-1.0+"],
|
||||
"Apache-2.0" => { with: "LLVM-exception" },
|
||||
{ all_of: ["0BSD", "Zlib", "Artistic-1.0+"],
|
||||
"Apache-2.0" => { with: "LLVM-exception" } },
|
||||
]
|
||||
```
|
||||
|
||||
|
@ -91,10 +91,10 @@ Installing a standard Node module based formula would look like this:
|
||||
require "language/node"
|
||||
|
||||
class Foo < Formula
|
||||
desc "..."
|
||||
homepage "..."
|
||||
desc "An example formula"
|
||||
homepage "https://example.com"
|
||||
url "https://registry.npmjs.org/foo/-/foo-1.4.2.tgz"
|
||||
sha256 "..."
|
||||
sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
|
||||
|
||||
depends_on "node"
|
||||
# uncomment if there is a native addon inside the dependency tree
|
||||
@ -106,7 +106,8 @@ class Foo < Formula
|
||||
end
|
||||
|
||||
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
|
||||
```
|
||||
|
@ -50,14 +50,31 @@ Homebrew provides helper methods for instantiating and populating virtualenvs. Y
|
||||
For most applications, all you will need to write is:
|
||||
|
||||
```ruby
|
||||
class Foo < Formula
|
||||
include Language::Python::Virtualenv
|
||||
|
||||
name "foo"
|
||||
# ...
|
||||
url "..."
|
||||
sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
|
||||
|
||||
def install
|
||||
virtualenv_install_with_resources
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
This is exactly the same as writing:
|
||||
|
||||
```ruby
|
||||
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
|
||||
# `depends_on "python"` is declared, and use `virtualenv_create(libexec, "python3")`.
|
||||
@ -71,6 +88,7 @@ def install
|
||||
# formula's tarball was unpacked.
|
||||
venv.pip_install_and_link buildpath
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Example formula
|
||||
@ -81,6 +99,8 @@ Installing a formula with dependencies will look like this:
|
||||
class Foo < Formula
|
||||
include Language::Python::Virtualenv
|
||||
|
||||
desc "Description"
|
||||
homepage "https://example.com"
|
||||
url "..."
|
||||
|
||||
resource "six" do
|
||||
@ -102,6 +122,13 @@ end
|
||||
You can also use the more verbose form and request that specific resources be installed:
|
||||
|
||||
```ruby
|
||||
class Foo < Formula
|
||||
include Language::Python::Virtualenv
|
||||
|
||||
desc "Description"
|
||||
homepage "https://example.com"
|
||||
url "..."
|
||||
|
||||
def install
|
||||
venv = virtualenv_create(libexec)
|
||||
%w[six parsedatetime].each do |r|
|
||||
@ -109,6 +136,7 @@ def install
|
||||
end
|
||||
venv.pip_install_and_link buildpath
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
in case you need to do different things for different resources.
|
||||
|
@ -12,8 +12,6 @@ The `sig` method is used to annotate method signatures. Here's a simple example:
|
||||
|
||||
```ruby
|
||||
class MyClass
|
||||
extend T::Sig
|
||||
|
||||
sig { params(name: String).returns(String) }
|
||||
def my_method(name)
|
||||
"Hello, #{name}!"
|
||||
|
Loading…
x
Reference in New Issue
Block a user