Skip to content

Commit 3c21626

Browse files
audit: ensure that official formula and cask names don't conflict.
Co-authored-by: Eric Knibbe <[email protected]>
1 parent c19f08b commit 3c21626

File tree

7 files changed

+47
-73
lines changed

7 files changed

+47
-73
lines changed

Library/Homebrew/cask/audit.rb

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,21 @@ class Audit
2727

2828
sig {
2929
params(
30-
cask: ::Cask::Cask, download: T::Boolean, quarantine: T::Boolean, token_conflicts: T.nilable(T::Boolean),
30+
cask: ::Cask::Cask, download: T::Boolean, quarantine: T::Boolean,
3131
online: T.nilable(T::Boolean), strict: T.nilable(T::Boolean), signing: T.nilable(T::Boolean),
3232
new_cask: T.nilable(T::Boolean), only: T::Array[String], except: T::Array[String]
3333
).void
3434
}
3535
def initialize(
3636
cask,
3737
download: false, quarantine: false,
38-
token_conflicts: nil, online: nil, strict: nil, signing: nil,
38+
online: nil, strict: nil, signing: nil,
3939
new_cask: nil, only: [], except: []
4040
)
41-
# `new_cask` implies `online`, `token_conflicts`, `strict` and `signing`
41+
# `new_cask` implies `online`, `strict` and `signing`
4242
online = new_cask if online.nil?
4343
strict = new_cask if strict.nil?
4444
signing = new_cask if signing.nil?
45-
token_conflicts = new_cask if token_conflicts.nil?
4645

4746
# `online` and `signing` imply `download`
4847
download ||= online || signing
@@ -53,7 +52,6 @@ def initialize(
5352
@strict = strict
5453
@signing = signing
5554
@new_cask = new_cask
56-
@token_conflicts = token_conflicts
5755
@only = only
5856
@except = except
5957
end
@@ -70,9 +68,6 @@ def signing? = !!@signing
7068
sig { returns(T::Boolean) }
7169
def strict? = !!@strict
7270

73-
sig { returns(T::Boolean) }
74-
def token_conflicts? = !!@token_conflicts
75-
7671
sig { returns(::Cask::Audit) }
7772
def run!
7873
only_audits = @only
@@ -430,15 +425,10 @@ def audit_token
430425

431426
sig { void }
432427
def audit_token_conflicts
433-
return unless token_conflicts?
434-
435428
Homebrew.with_no_api_env do
436429
return unless core_formula_names.include?(cask.token)
437430

438-
add_error(
439-
"possible duplicate, cask token conflicts with Homebrew core formula: #{Formatter.url(core_formula_url)}",
440-
strict_only: true,
441-
)
431+
add_error("cask token conflicts with an existing homebrew/core formula: #{Formatter.url(core_formula_url)}")
442432
end
443433
end
444434

Library/Homebrew/cask/auditor.rb

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ class Auditor
1111
params(
1212
cask: ::Cask::Cask, audit_download: T::Boolean, audit_online: T.nilable(T::Boolean),
1313
audit_strict: T.nilable(T::Boolean), audit_signing: T.nilable(T::Boolean),
14-
audit_token_conflicts: T.nilable(T::Boolean), audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
14+
audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
1515
any_named_args: T::Boolean, language: T.nilable(String), only: T::Array[String], except: T::Array[String]
1616
).returns(T::Set[String])
1717
}
1818
def self.audit(
1919
cask, audit_download: false, audit_online: nil, audit_strict: nil, audit_signing: nil,
20-
audit_token_conflicts: nil, audit_new_cask: nil, quarantine: false, any_named_args: false, language: nil,
20+
audit_new_cask: nil, quarantine: false, any_named_args: false, language: nil,
2121
only: [], except: []
2222
)
2323
new(
24-
cask, audit_download:, audit_online:, audit_strict:, audit_signing:, audit_token_conflicts:,
24+
cask, audit_download:, audit_online:, audit_strict:, audit_signing:,
2525
audit_new_cask:, quarantine:, any_named_args:, language:, only:, except:
2626
).audit
2727
end
@@ -36,7 +36,7 @@ def self.audit(
3636
params(
3737
cask: ::Cask::Cask, audit_download: T::Boolean, audit_online: T.nilable(T::Boolean),
3838
audit_strict: T.nilable(T::Boolean), audit_signing: T.nilable(T::Boolean),
39-
audit_token_conflicts: T.nilable(T::Boolean), audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
39+
audit_new_cask: T.nilable(T::Boolean), quarantine: T::Boolean,
4040
any_named_args: T::Boolean, language: T.nilable(String), only: T::Array[String], except: T::Array[String]
4141
).void
4242
}
@@ -46,7 +46,6 @@ def initialize(
4646
audit_online: nil,
4747
audit_strict: nil,
4848
audit_signing: nil,
49-
audit_token_conflicts: nil,
5049
audit_new_cask: nil,
5150
quarantine: false,
5251
any_named_args: false,
@@ -61,7 +60,6 @@ def initialize(
6160
@audit_strict = audit_strict
6261
@audit_signing = audit_signing
6362
@quarantine = quarantine
64-
@audit_token_conflicts = audit_token_conflicts
6563
@any_named_args = any_named_args
6664
@language = language
6765
@only = only
@@ -127,15 +125,14 @@ def audit_languages(languages)
127125
def audit_cask_instance(cask)
128126
audit = Audit.new(
129127
cask,
130-
online: @audit_online,
131-
strict: @audit_strict,
132-
signing: @audit_signing,
133-
new_cask: @audit_new_cask,
134-
token_conflicts: @audit_token_conflicts,
135-
download: @audit_download,
136-
quarantine: @quarantine,
137-
only: @only,
138-
except: @except,
128+
online: @audit_online,
129+
strict: @audit_strict,
130+
signing: @audit_signing,
131+
new_cask: @audit_new_cask,
132+
download: @audit_download,
133+
quarantine: @quarantine,
134+
only: @only,
135+
except: @except,
139136
)
140137
audit.run!
141138
end

Library/Homebrew/dev-cmd/audit.rb

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ class Audit < AbstractCommand
5858
hidden: true
5959
switch "--[no-]signing",
6060
description: "Audit for app signatures, which are required by macOS on ARM."
61+
# should be odeprecated in future
6162
switch "--token-conflicts",
62-
description: "Audit for token conflicts."
63+
description: "Audit for token conflicts.",
64+
hidden: true
6365
flag "--tap=",
6466
description: "Check formulae and casks within the given tap, specified as <user>`/`<repo>."
6567
switch "--fix",
@@ -251,18 +253,17 @@ def run
251253
# For switches, we add `|| nil` so that `nil` will be passed
252254
# instead of `false` if they aren't set.
253255
# This way, we can distinguish between "not set" and "set to false".
254-
audit_online: args.online? || nil,
255-
audit_strict: args.strict? || nil,
256+
audit_online: args.online? || nil,
257+
audit_strict: args.strict? || nil,
256258

257259
# No need for `|| nil` for `--[no-]signing`
258260
# because boolean switches are already `nil` if not passed
259-
audit_signing: args.signing?,
260-
audit_new_cask: args.new? || nil,
261-
audit_token_conflicts: args.token_conflicts? || nil,
262-
quarantine: true,
263-
any_named_args: !no_named_args,
264-
only: args.only || [],
265-
except: args.except || [],
261+
audit_signing: args.signing?,
262+
audit_new_cask: args.new? || nil,
263+
quarantine: true,
264+
any_named_args: !no_named_args,
265+
only: args.only || [],
266+
except: args.except || [],
266267
).to_a
267268
end
268269
end.uniq

Library/Homebrew/dev-cmd/generate-cask-ci-matrix.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,7 @@ def generate_matrix(tap, labels: [], cask_names: [], skip_install: false, new_ca
274274
bitbucket_repository]
275275
end
276276

277-
if labels.include?("ci-skip-token")
278-
audit_exceptions << %w[token_conflicts token_valid
279-
token_bad_words]
280-
end
277+
audit_exceptions << %w[token_valid token_bad_words] if labels.include?("ci-skip-token")
281278

282279
audit_args << "--except" << audit_exceptions.join(",") if audit_exceptions.any?
283280

Library/Homebrew/formula_auditor.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,15 @@ def audit_name
170170
last_word_connector: " or ")}."
171171
end
172172

173-
return unless @strict
174173
return unless @core_tap
175174

175+
if CoreCaskTap.instance.cask_tokens.include?(name)
176+
problem "Formula name conflicts with an existing Homebrew/cask cask's token."
177+
return
178+
end
179+
180+
return unless @strict
181+
176182
problem "'#{name}' is not allowed in homebrew/core." if MissingFormula.disallowed_reason(name)
177183

178184
if Formula.aliases.include? name
@@ -185,6 +191,11 @@ def audit_name
185191
return
186192
end
187193

194+
if CoreCaskTap.instance.cask_tokens.include?(name)
195+
problem "Formula name conflicts with an existing Homebrew/cask cask's token."
196+
return
197+
end
198+
188199
return if formula.core_formula?
189200
return unless Formula.core_names.include?(name)
190201

Library/Homebrew/test/cask/audit_spec.rb

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,11 @@ def outcome(audit)
4949
let(:only) { [] }
5050
let(:except) { [] }
5151
let(:strict) { nil }
52-
let(:token_conflicts) { nil }
5352
let(:signing) { nil }
5453
let(:audit) do
5554
described_class.new(cask, online:,
5655
strict:,
5756
new_cask:,
58-
token_conflicts:,
5957
signing:,
6058
only:,
6159
except:)
@@ -72,10 +70,6 @@ def outcome(audit)
7270
it "implies `strict`" do
7371
expect(audit).to be_strict
7472
end
75-
76-
it "implies `token_conflicts`" do
77-
expect(audit.token_conflicts?).to be true
78-
end
7973
end
8074

8175
context "when `online` is specified" do
@@ -949,34 +943,15 @@ def tmp_cask(name, text)
949943
end
950944

951945
describe "token conflicts" do
952-
let(:only) { ["token_conflicts"] }
953946
let(:cask_token) { "with-binary" }
954-
let(:token_conflicts) { true }
955947

956948
context "when cask token conflicts with a core formula" do
957949
let(:formula_names) { %w[with-binary other-formula] }
958950

959-
context "when `--strict` is passed" do
960-
let(:strict) { true }
961-
962-
it "warns about duplicates" do
963-
expect(audit).to receive(:core_formula_names).and_return(formula_names)
964-
expect(run).to error_with(/possible duplicate/)
965-
end
951+
it "warns about conflicts" do
952+
expect(audit).to receive(:core_formula_names).and_return(formula_names)
953+
expect(run).to error_with(/cask token conflicts/)
966954
end
967-
968-
context "when `--strict` is not passed" do
969-
it "does not warn about duplicates" do
970-
expect(audit).to receive(:core_formula_names).and_return(formula_names)
971-
expect(run).not_to error_with(/possible duplicate/)
972-
end
973-
end
974-
end
975-
976-
context "when cask token does not conflict with a core formula" do
977-
let(:formula_names) { %w[other-formula] }
978-
979-
it { is_expected.to pass }
980955
end
981956
end
982957

docs/Cask-Cookbook.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,7 @@ Software vendors are often inconsistent with their naming. By enforcing strict n
13211321
* Prevent duplicate submissions
13221322
* Minimize renaming events
13231323
* Unambiguously boil down the name of the software into a unique identifier
1324+
* Avoid conflicts with Homebrew/homebrew-core formulae
13241325

13251326
Details of software names and brands will inevitably be lost in the conversion to a minimal token. To capture the vendor’s full name for a distribution, use the [`name`](#stanza-name) within a cask, which accepts an unrestricted UTF-8 string.
13261327

@@ -1362,7 +1363,9 @@ Details of software names and brands will inevitably be lost in the conversion t
13621363

13631364
* If the result of this process is a generic term, such as “Macintosh Installer”, try prepending the name of the vendor or developer, followed by a hyphen. If that doesn’t work, then just create the best name you can, based on the vendor’s web page.
13641365

1365-
* If the result conflicts with the name of an existing cask, make yours unique by prepending the name of the vendor or developer, followed by a hyphen. Example: [unison.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/u/unison.rb) and [panic-unison.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/p/panic-unison.rb).
1366+
* If the result conflicts with the name of an existing cask or Homebrew/homebrew-core formula, make yours unique by prepending the name of the vendor or developer, followed by a hyphen. Example: [unison.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/u/unison.rb) and [panic-unison.rb](https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/p/panic-unison.rb).
1367+
1368+
* If the result still conflicts with the name of an existing Homebrew/homebrew-core formula, adjust the name to better describe the difference by e.g. appending `-app`. Example: `appium` formula and `appium-desktop` cask, `angband` formula and `angband-app` cask.
13661369

13671370
* Inevitably, there are a small number of exceptions not covered by the rules. Don’t hesitate to [use the forum](https://github.com/orgs/Homebrew/discussions) if you have a problem.
13681371

0 commit comments

Comments
 (0)