1
- # typed: true # rubocop:todo Sorbet/StrictSigil
1
+ # typed: strict
2
2
# frozen_string_literal: true
3
3
4
4
require "cask/denylist"
@@ -19,6 +19,14 @@ class Audit
19
19
include SystemCommand ::Mixin
20
20
include ::Utils ::Curl
21
21
22
+ Error = T . type_alias do
23
+ {
24
+ message : T . nilable ( String ) ,
25
+ location : T . nilable ( Homebrew ::SourceLocation ) ,
26
+ corrected : T ::Boolean ,
27
+ }
28
+ end
29
+
22
30
sig { returns ( Cask ) }
23
31
attr_reader :cask
24
32
@@ -47,6 +55,7 @@ def initialize(
47
55
download ||= online || signing
48
56
49
57
@cask = cask
58
+ @download = T . let ( nil , T . nilable ( Download ) )
50
59
@download = Download . new ( cask , quarantine :) if download
51
60
@online = online
52
61
@strict = strict
@@ -88,8 +97,9 @@ def run!
88
97
self
89
98
end
90
99
100
+ sig { returns ( T ::Array [ Error ] ) }
91
101
def errors
92
- @errors ||= [ ]
102
+ @errors ||= T . let ( [ ] , T . nilable ( T :: Array [ Error ] ) )
93
103
end
94
104
95
105
sig { returns ( T ::Boolean ) }
@@ -113,9 +123,10 @@ def add_error(message, location: nil, strict_only: false)
113
123
# Only raise non-critical audits if the user specified `--strict`.
114
124
return if strict_only && !@strict
115
125
116
- errors << ( { message :, location :, corrected : false } )
126
+ errors << { message :, location :, corrected : false }
117
127
end
118
128
129
+ sig { returns ( T . nilable ( String ) ) }
119
130
def result
120
131
Formatter . error ( "failed" ) if errors?
121
132
end
@@ -346,6 +357,7 @@ def audit_download_url_format
346
357
location : url . location
347
358
end
348
359
360
+ sig { void }
349
361
def audit_download_url_is_osdn
350
362
return if ( url = cask . url ) . nil?
351
363
return if block_url_offline?
@@ -541,8 +553,15 @@ def audit_signing
541
553
end
542
554
end
543
555
544
- sig { void }
545
- def extract_artifacts
556
+ sig {
557
+ params (
558
+ _block : T . nilable ( T . proc . params (
559
+ arg0 : T ::Array [ T . any ( Artifact ::Pkg , Artifact ::Relocated ) ] ,
560
+ arg1 : Pathname ,
561
+ ) . void ) ,
562
+ ) . void
563
+ }
564
+ def extract_artifacts ( &_block )
546
565
return unless online?
547
566
return if ( download = self . download ) . nil?
548
567
@@ -557,7 +576,7 @@ def extract_artifacts
557
576
558
577
return if artifacts . empty?
559
578
560
- @tmpdir ||= Pathname ( Dir . mktmpdir ( "cask-audit" , HOMEBREW_TEMP ) )
579
+ @tmpdir ||= T . let ( Pathname ( Dir . mktmpdir ( "cask-audit" , HOMEBREW_TEMP ) ) , T . nilable ( Pathname ) )
561
580
562
581
# Clean up tmp dir when @tmpdir object is destroyed
563
582
ObjectSpace . define_finalizer (
@@ -606,7 +625,8 @@ def extract_artifacts
606
625
. extract_nestedly ( to : @tmpdir , verbose : false )
607
626
end
608
627
609
- @artifacts_extracted = true # Set the flag to indicate that extraction has occurred.
628
+ # Set the flag to indicate that extraction has occurred.
629
+ @artifacts_extracted = T . let ( true , T . nilable ( TrueClass ) )
610
630
611
631
# Yield the artifacts and temp directory to the block if provided.
612
632
yield artifacts , @tmpdir if block_given?
@@ -626,8 +646,8 @@ def audit_rosetta
626
646
extract_artifacts do |artifacts , tmpdir |
627
647
is_container = artifacts . any? { |a | a . is_a? ( Artifact ::App ) || a . is_a? ( Artifact ::Pkg ) }
628
648
629
- artifacts . filter { | a | a . is_a? ( Artifact :: App ) || a . is_a? ( Artifact :: Binary ) }
630
- . each do | artifact |
649
+ artifacts . each do | artifact |
650
+ next if ! artifact . is_a? ( Artifact :: App ) && ! artifact . is_a? ( Artifact :: Binary )
631
651
next if artifact . is_a? ( Artifact ::Binary ) && is_container
632
652
633
653
path = tmpdir /artifact . source . relative_path_from ( cask . staged_path )
@@ -644,10 +664,10 @@ def audit_rosetta
644
664
645
665
system_command ( "lipo" , args : [ "-archs" , main_binary ] , print_stderr : false )
646
666
when Artifact ::Binary
647
- binary_path = path . to_s . gsub ( cask . appdir , tmpdir )
667
+ binary_path = path . to_s . gsub ( cask . appdir , tmpdir . to_s )
648
668
system_command ( "lipo" , args : [ "-archs" , binary_path ] , print_stderr : true )
649
669
else
650
- add_error "Unknown artifact type: #{ artifact . class } " , location : url . location
670
+ T . absurd ( artifact )
651
671
end
652
672
653
673
# binary stanza can contain shell scripts, so we just continue if lipo fails.
@@ -795,7 +815,7 @@ def cask_bundle_min_os
795
815
return unless online?
796
816
797
817
min_os = T . let ( nil , T . untyped )
798
- @staged_path ||= cask . staged_path
818
+ @staged_path ||= T . let ( cask . staged_path , T . nilable ( Pathname ) )
799
819
800
820
extract_artifacts do |artifacts , tmpdir |
801
821
artifacts . each do |artifact |
@@ -1104,15 +1124,15 @@ def bad_sourceforge_url?
1104
1124
1105
1125
sig { returns ( T ::Boolean ) }
1106
1126
def bad_osdn_url?
1107
- domain . match? ( %r{^(?:\w +\. )*osdn\. jp(?=/|$)} )
1127
+ T . must ( domain ) . match? ( %r{^(?:\w +\. )*osdn\. jp(?=/|$)} )
1108
1128
end
1109
1129
1110
- # sig { returns(String) }
1130
+ sig { returns ( T . nilable ( String ) ) }
1111
1131
def homepage
1112
1132
URI ( cask . homepage . to_s ) . host
1113
1133
end
1114
1134
1115
- # sig { returns(String) }
1135
+ sig { returns ( T . nilable ( String ) ) }
1116
1136
def domain
1117
1137
URI ( cask . url . to_s ) . host
1118
1138
end
@@ -1127,24 +1147,25 @@ def url_match_homepage?
1127
1147
host_uri . host
1128
1148
end
1129
1149
1130
- return false if homepage . blank?
1150
+ home = homepage
1151
+ return false if home . blank?
1131
1152
1132
- home = homepage . downcase
1153
+ home . downcase!
1133
1154
if ( split_host = T . must ( host ) . split ( "." ) ) . length >= 3
1134
1155
host = T . must ( split_host [ -2 ..] ) . join ( "." )
1135
1156
end
1136
- if ( split_home = homepage . split ( "." ) ) . length >= 3
1137
- home = split_home [ -2 ..] . join ( "." )
1157
+ if ( split_home = home . split ( "." ) ) . length >= 3
1158
+ home = T . must ( split_home [ -2 ..] ) . join ( "." )
1138
1159
end
1139
1160
host == home
1140
1161
end
1141
1162
1142
- # sig { params(url: String).returns(String) }
1163
+ sig { params ( url : String ) . returns ( String ) }
1143
1164
def strip_url_scheme ( url )
1144
1165
url . sub ( %r{^[^:/]+://(www\. )?} , "" )
1145
1166
end
1146
1167
1147
- # sig { returns(String) }
1168
+ sig { returns ( String ) }
1148
1169
def url_from_verified
1149
1170
strip_url_scheme ( T . must ( cask . url ) . verified )
1150
1171
end
@@ -1154,8 +1175,10 @@ def verified_matches_url?
1154
1175
url_domain , url_path = strip_url_scheme ( cask . url . to_s ) . split ( "/" , 2 )
1155
1176
verified_domain , verified_path = url_from_verified . split ( "/" , 2 )
1156
1177
1157
- ( url_domain == verified_domain || ( verified_domain && url_domain &.end_with? ( ".#{ verified_domain } " ) ) ) &&
1158
- ( !verified_path || url_path &.start_with? ( verified_path ) )
1178
+ domains_match = ( url_domain == verified_domain ) ||
1179
+ ( verified_domain && url_domain &.end_with? ( ".#{ verified_domain } " ) )
1180
+ paths_match = !verified_path || url_path &.start_with? ( verified_path )
1181
+ ( domains_match && paths_match ) || false
1159
1182
end
1160
1183
1161
1184
sig { returns ( T ::Boolean ) }
@@ -1177,10 +1200,10 @@ def block_url_offline?
1177
1200
1178
1201
sig { returns ( Tap ) }
1179
1202
def core_tap
1180
- @core_tap ||= CoreTap . instance
1203
+ @core_tap ||= T . let ( CoreTap . instance , T . nilable ( Tap ) )
1181
1204
end
1182
1205
1183
- # sig { returns(T::Array[String]) }
1206
+ sig { returns ( T ::Array [ String ] ) }
1184
1207
def core_formula_names
1185
1208
core_tap . formula_names
1186
1209
end
0 commit comments