128 lines
4.0 KiB
Ruby
Raw Normal View History

2020-10-10 14:16:11 +02:00
# typed: false
# frozen_string_literal: true
require "utils/github/actions"
2018-09-06 08:29:14 +02:00
module Cask
2018-09-04 08:45:48 +01:00
class Cmd
2020-08-19 10:34:07 +02:00
# Implementation of the `brew cask audit` command.
#
# @api private
2017-05-20 19:08:03 +02:00
class Audit < AbstractCommand
2020-10-20 12:03:48 +02:00
extend T::Sig
sig { returns(String) }
2020-08-01 02:30:46 +02:00
def self.description
2020-04-23 21:16:17 +02:00
<<~EOS
Check <cask> for Homebrew coding style violations. This should be run before
2020-08-01 02:30:46 +02:00
submitting a new cask. If no <cask> is provided, checks all locally
2020-04-23 21:16:17 +02:00
available casks. Will exit with a non-zero status if any errors are
found, which can be useful for implementing pre-commit hooks.
EOS
end
2017-05-21 00:15:56 +02:00
2020-08-01 02:30:46 +02:00
def self.parser
super do
switch "--download",
description: "Audit the downloaded file"
switch "--[no-]appcast",
2020-08-01 02:30:46 +02:00
description: "Audit the appcast"
switch "--token-conflicts",
description: "Audit for token conflicts"
switch "--strict",
description: "Run additional, stricter style checks"
switch "--online",
description: "Run additional, slower style checks that require a network connection"
switch "--new-cask",
2020-08-18 16:14:30 +01:00
description: "Run various additional style checks to determine if a new cask is eligible " \
"for Homebrew. This should be used when creating new casks and implies " \
"`--strict` and `--online`"
2020-08-01 02:30:46 +02:00
end
2016-09-24 13:52:43 +02:00
end
2020-10-20 12:03:48 +02:00
sig { void }
2016-09-24 13:52:43 +02:00
def run
casks = args.named.flat_map do |name|
2020-11-13 17:21:51 +01:00
next name if File.exist?(name)
next Tap.fetch(name).cask_files if name.count("/") == 1
name
2020-09-29 23:46:30 +02:00
end
casks = casks.map { |c| CaskLoader.load(c, config: Config.from_args(args)) }
any_named_args = casks.any?
casks = Cask.to_a if casks.empty?
2020-11-18 12:41:18 +01:00
results = self.class.audit_casks(
*casks,
download: args.download?,
appcast: args.appcast?,
online: args.online?,
strict: args.strict?,
new_cask: args.new_cask?,
token_conflicts: args.token_conflicts?,
quarantine: args.quarantine?,
any_named_args: any_named_args,
language: args.language,
)
2020-11-18 12:41:18 +01:00
self.class.print_annotations(results)
failed_casks = results.reject { |_, result| result[:errors].empty? }.map(&:first)
return if failed_casks.empty?
raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}"
end
def self.audit_casks(
*casks,
download: nil,
appcast: nil,
online: nil,
strict: nil,
new_cask: nil,
token_conflicts: nil,
quarantine: nil,
any_named_args: nil,
language: nil
)
options = {
audit_download: download,
audit_appcast: appcast,
audit_online: online,
audit_strict: strict,
audit_new_cask: new_cask,
audit_token_conflicts: token_conflicts,
quarantine: quarantine,
language: language,
any_named_args: any_named_args,
}.compact
options[:quarantine] = true if options[:quarantine].nil?
Homebrew.auditing = true
require "cask/auditor"
2020-11-18 12:41:18 +01:00
casks.map do |cask|
2020-04-23 21:16:17 +02:00
odebug "Auditing Cask #{cask}"
2020-11-18 12:41:18 +01:00
[cask, Auditor.audit(cask, **options)]
end.to_h
end
2020-11-18 12:41:18 +01:00
def self.print_annotations(results)
return unless ENV["GITHUB_ACTIONS"]
2020-11-18 12:41:18 +01:00
results.each do |cask, result|
cask_path = cask.sourcefile_path
annotations = (result[:warnings].map { |w| [:warning, w] } + result[:errors].map { |e| [:error, e] })
.map { |type, message| GitHub::Actions::Annotation.new(type, message, file: cask_path) }
2020-11-18 12:41:18 +01:00
annotations.each do |annotation|
puts annotation if annotation.relevant?
end
2020-04-23 21:16:17 +02:00
end
2016-09-24 13:52:43 +02:00
end
2016-08-18 22:11:42 +03:00
end
end
end