@@ -90,6 +90,58 @@ def self.write!
9090 def self . path
9191 Pathname . pwd . join ( '.github/CODEOWNERS' )
9292 end
93+
94+ sig { params ( files : T ::Array [ String ] ) . void }
95+ def self . update_cache! ( files )
96+ cache = Private . glob_cache
97+ # Each mapper returns a new copy of the cache subset related to that mapper,
98+ # which is then stored back into the cache.
99+ Mapper . all . each do |mapper |
100+ existing_cache = cache . raw_cache_contents . fetch ( mapper . description , { } )
101+ updated_cache = mapper . update_cache ( existing_cache , files )
102+ cache . raw_cache_contents [ mapper . description ] = updated_cache
103+ end
104+ end
105+
106+ sig { returns ( T ::Boolean ) }
107+ def self . use_codeowners_cache?
108+ CodeownersFile . path . exist? && !Private . configuration . skip_codeowners_validation
109+ end
110+
111+ sig { returns ( GlobCache ) }
112+ def self . to_glob_cache
113+ github_team_to_code_team_map = T . let ( { } , T ::Hash [ String , CodeTeams ::Team ] )
114+ CodeTeams . all . each do |team |
115+ github_team = TeamPlugins ::Github . for ( team ) . github . team
116+ github_team_to_code_team_map [ github_team ] = team
117+ end
118+ raw_cache_contents = T . let ( { } , GlobCache ::CacheShape )
119+ current_mapper = T . let ( nil , T . nilable ( String ) )
120+ mapper_descriptions = Set . new ( Mapper . all . map ( &:description ) )
121+
122+ path . readlines . each do |line |
123+ line_with_no_comment = line . chomp . gsub ( "# " , "" )
124+ if mapper_descriptions . include? ( line_with_no_comment )
125+ current_mapper = line_with_no_comment
126+ else
127+ next if current_mapper . nil?
128+ next if line . chomp == ""
129+ # The codeowners file stores paths relative to the root of directory
130+ # Since a `/` means root of the file system from the perspective of ruby,
131+ # we remove that beginning slash so we can correctly glob the files out.
132+ normalized_line = line . gsub ( /^# / , '' ) . gsub ( /^\/ / , '' )
133+ split_line = normalized_line . split
134+ # Most lines will be in the format: /path/to/file my-github-team
135+ # This will skip over lines that are not of the correct form
136+ next if split_line . count > 2
137+ entry , github_team = split_line
138+ raw_cache_contents [ current_mapper ] ||= { }
139+ raw_cache_contents . fetch ( current_mapper ) [ T . must ( entry ) ] = github_team_to_code_team_map . fetch ( T . must ( github_team ) )
140+ end
141+ end
142+
143+ GlobCache . new ( raw_cache_contents )
144+ end
93145 end
94146 end
95147end
0 commit comments