Skip to content

Commit

Permalink
Merge pull request #16351 from Rylan12/rubocop-for-cask-discontinued
Browse files Browse the repository at this point in the history
Create rubocop requiring `deprecate!` over `discontinued` for casks
  • Loading branch information
Rylan12 authored Dec 20, 2023
2 parents 67598ce + 841a062 commit f61ef4b
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 19 deletions.
42 changes: 42 additions & 0 deletions Library/Homebrew/rubocops/cask/discontinued.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# typed: true
# frozen_string_literal: true

module RuboCop
module Cop
module Cask
# This cop corrects `caveats { discontinued }` to `deprecate!`.
class Discontinued < Base
include CaskHelp
extend AutoCorrector

MESSAGE = "Use `deprecate!` instead of `caveats { discontinued }`."

def on_cask_stanza_block(stanza_block)
stanza_block.stanzas.select(&:caveats?).each do |stanza|
find_discontinued_method_call(stanza.stanza_node) do |node|
if caveats_constains_only_discontinued?(node.parent)
add_offense(node.parent, message: MESSAGE) do |corrector|
corrector.replace(node.parent.source_range,
"deprecate! date: \"#{Date.today}\", because: :discontinued")
end
else
add_offense(node, message: MESSAGE)
end
end
end
end

def_node_matcher :caveats_constains_only_discontinued?, <<~EOS
(block
(send nil? :caveats)
(args)
(send nil? :discontinued))
EOS

def_node_search :find_discontinued_method_call, <<~EOS
$(send nil? :discontinued)
EOS
end
end
end
end
25 changes: 25 additions & 0 deletions Library/Homebrew/rubocops/cask/discontinued.rbi
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# typed: strict

module RuboCop
module Cop
module Cask
class Discontinued < Base
sig {
params(
base_node: RuboCop::AST::BlockNode,
block: T.nilable(T.proc.params(node: RuboCop::AST::SendNode).void),
).returns(T::Boolean)
}
def caveats_constains_only_discontinued?(base_node, &block); end

sig {
params(
base_node: RuboCop::AST::BlockNode,
block: T.proc.params(node: RuboCop::AST::SendNode).void,
).void
}
def find_discontinued_method_call(base_node, &block); end
end
end
end
end
1 change: 1 addition & 0 deletions Library/Homebrew/rubocops/rubocop-cask.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
require_relative "cask/mixin/on_homepage_stanza"
require_relative "cask/mixin/on_url_stanza"
require_relative "cask/desc"
require_relative "cask/discontinued"
require_relative "cask/homepage_url_trailing_slash"
require_relative "cask/no_overrides"
require_relative "cask/on_system_conditionals"
Expand Down
20 changes: 16 additions & 4 deletions Library/Homebrew/test/cask/audit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -529,14 +529,26 @@ def tmp_cask(name, text)
it { is_expected.not_to error_with(message) }
end

context "when the Cask is discontinued" do
let(:cask_token) { "livecheck/livecheck-discontinued" }
context "when the Cask is deprecated" do
let(:cask_token) { "livecheck/livecheck-deprecated" }

it { is_expected.not_to error_with(message) }
end

context "when the Cask has a livecheck block referencing a discontinued Cask" do
let(:cask_token) { "livecheck/livecheck-discontinued-reference" }
context "when the Cask has a livecheck block referencing a deprecated Cask" do
let(:cask_token) { "livecheck/livecheck-deprecated-reference" }

it { is_expected.not_to error_with(message) }
end

context "when the Cask is disabled" do
let(:cask_token) { "livecheck/livecheck-disabled" }

it { is_expected.not_to error_with(message) }
end

context "when the Cask has a livecheck block referencing a disabled Cask" do
let(:cask_token) { "livecheck/livecheck-disabled-reference" }

it { is_expected.not_to error_with(message) }
end
Expand Down
65 changes: 65 additions & 0 deletions Library/Homebrew/test/rubocops/cask/discontinued_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# frozen_string_literal: true

require "rubocops/rubocop-cask"

describe RuboCop::Cop::Cask::Discontinued, :config do
it "reports no offenses when there is no `caveats` stanza" do
expect_no_offenses <<~CASK
cask "foo" do
url "https://example.com/download/foo-v1.2.0.dmg",
verified: "example.com/download/"
end
CASK
end

it "reports no offenses when there is a `caveats` stanza without `discontinued`" do
expect_no_offenses <<~CASK
cask "foo" do
url "https://example.com/download/foo-v1.2.0.dmg",
verified: "example.com/download/"
caveats do
files_in_usr_local
end
end
CASK
end

it "reports an offense when there is a `caveats` stanza with `discontinued` and other caveats" do
expect_offense <<~CASK
cask "foo" do
url "https://example.com/download/foo-v1.2.0.dmg",
verified: "example.com/download/"
caveats do
discontinued
^^^^^^^^^^^^ Use `deprecate!` instead of `caveats { discontinued }`.
files_in_usr_local
end
end
CASK
end

it "corrects `caveats { discontinued }` to `deprecate!`" do
expect_offense <<~CASK
cask "foo" do
url "https://example.com/download/foo-v1.2.0.dmg",
verified: "example.com/download/"
caveats do
^^^^^^^^^^ Use `deprecate!` instead of `caveats { discontinued }`.
discontinued
end
end
CASK

expect_correction <<~CASK
cask "foo" do
url "https://example.com/download/foo-v1.2.0.dmg",
verified: "example.com/download/"
deprecate! date: "#{Date.today}", because: :discontinued
end
CASK
end
end
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
cask "livecheck-discontinued-reference" do
cask "livecheck-deprecated-reference" do
version "1.2.3"
sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"

# This cask is used in --online tests, so we use fake URLs to avoid impacting
# real servers. The URL paths are specific enough that they'll be
# understandable if they appear in local server logs.
url "http://localhost/homebrew/test/cask/audit/livecheck/discontinued-#{version}.dmg"
name "Discontinued Reference"
desc "Cask for testing a livecheck reference to a discontinued cask"
homepage "http://localhost/homebrew/test/cask/audit/livecheck/discontinued"
url "http://localhost/homebrew/test/cask/audit/livecheck/deprecated-#{version}.dmg"
name "Deprecated Reference"
desc "Cask for testing a livecheck reference to a deprecated cask"
homepage "http://localhost/homebrew/test/cask/audit/livecheck/deprecated"

livecheck do
cask "livecheck/livecheck-discontinued"
cask "livecheck/livecheck-deprecated"
end

app "TestCask.app"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cask "livecheck-deprecated" do
version "1.2.3"
sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"

# This cask is used in --online tests, so we use fake URLs to avoid impacting
# real servers. The URL paths are specific enough that they'll be
# understandable if they appear in local server logs.
url "http://localhost/homebrew/test/cask/audit/livecheck/deprecated-#{version}.dmg"
name "Deprecated"
desc "Cask for testing deprecated in livecheck"
homepage "http://localhost/homebrew/test/cask/audit/livecheck/deprecated"

deprecate! date: "2023-01-01", because: :discontinued

app "TestCask.app"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cask "livecheck-disabled-reference" do
version "1.2.3"
sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"

# This cask is used in --online tests, so we use fake URLs to avoid impacting
# real servers. The URL paths are specific enough that they'll be
# understandable if they appear in local server logs.
url "http://localhost/homebrew/test/cask/audit/livecheck/disabled-#{version}.dmg"
name "Disabled Reference"
desc "Cask for testing a livecheck reference to a disabled cask"
homepage "http://localhost/homebrew/test/cask/audit/livecheck/disabled"

livecheck do
cask "livecheck/livecheck-disabled"
end

app "TestCask.app"
end
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
cask "livecheck-discontinued" do
cask "livecheck-disabled" do
version "1.2.3"
sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"

# This cask is used in --online tests, so we use fake URLs to avoid impacting
# real servers. The URL paths are specific enough that they'll be
# understandable if they appear in local server logs.
url "http://localhost/homebrew/test/cask/audit/livecheck/discontinued-#{version}.dmg"
name "Discontinued"
desc "Cask for testing discontinued in livecheck"
homepage "http://localhost/homebrew/test/cask/audit/livecheck/discontinued"
url "http://localhost/homebrew/test/cask/audit/livecheck/disabled-#{version}.dmg"
name "Disabled"
desc "Cask for testing disabled in livecheck"
homepage "http://localhost/homebrew/test/cask/audit/livecheck/disabled"

app "TestCask.app"
disable! date: "2023-01-01", because: :discontinued

caveats do
discontinued
end
app "TestCask.app"
end

0 comments on commit f61ef4b

Please sign in to comment.