Module: CodeOwnership

Extended by:
T::Helpers, T::Sig
Defined in:
lib/code_ownership/mapper.rb,
lib/code_ownership.rb,
lib/code_ownership/cli.rb,
lib/code_ownership/private.rb,
lib/code_ownership/validator.rb,
lib/code_ownership/configuration.rb,
lib/code_ownership/private/glob_cache.rb,
lib/code_ownership/private/owner_assigner.rb,
lib/code_ownership/private/codeowners_file.rb,
lib/code_ownership/private/extension_loader.rb,
lib/code_ownership/private/parse_js_packages.rb,
lib/code_ownership/private/team_plugins/github.rb,
lib/code_ownership/private/team_plugins/ownership.rb,
lib/code_ownership/private/ownership_mappers/team_globs.rb,
lib/code_ownership/private/validations/files_have_owners.rb,
lib/code_ownership/private/permit_pack_owner_top_level_key.rb,
lib/code_ownership/private/ownership_mappers/file_annotations.rb,
lib/code_ownership/private/ownership_mappers/package_ownership.rb,
lib/code_ownership/private/ownership_mappers/team_yml_ownership.rb,
lib/code_ownership/private/validations/files_have_unique_owners.rb,
lib/code_ownership/private/ownership_mappers/directory_ownership.rb,
lib/code_ownership/private/ownership_mappers/js_package_ownership.rb,
lib/code_ownership/private/validations/github_codeowners_up_to_date.rb

Overview

typed: strict

Defined Under Namespace

Modules: Mapper, Validator Classes: Cli, Configuration, InvalidCodeOwnershipConfigurationError

Constant Summary collapse

GlobsToOwningTeamMap =
T.type_alias { T::Hash[String, CodeTeams::Team] }

Class Method Summary collapse

Class Method Details

.bust_caches!Object



188
189
190
191
192
193
# File 'lib/code_ownership.rb', line 188

def self.bust_caches!
  @for_file = nil
  @memoized_values = nil
  Private.bust_caches!
  Mapper.all.each(&:bust_caches!)
end

.configurationObject



196
197
198
# File 'lib/code_ownership.rb', line 196

def self.configuration
  Private.configuration
end

.first_owned_file_for_backtrace(backtrace, excluded_teams: []) ⇒ Object



118
119
120
121
122
123
124
125
126
# File 'lib/code_ownership.rb', line 118

def first_owned_file_for_backtrace(backtrace, excluded_teams: [])
  backtrace_with_ownership(backtrace).each do |(team, file)|
    if team && !excluded_teams.include?(team)
      return [team, file]
    end
  end

  nil
end

.for_backtrace(backtrace, excluded_teams: []) ⇒ Object



111
112
113
# File 'lib/code_ownership.rb', line 111

def for_backtrace(backtrace, excluded_teams: [])
  first_owned_file_for_backtrace(backtrace, excluded_teams: excluded_teams)&.first
end

.for_class(klass) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/code_ownership.rb', line 162

def for_class(klass)
  @memoized_values ||= T.let(@memoized_values, T.nilable(T::Hash[String, T.nilable(::CodeTeams::Team)]))
  @memoized_values ||= {}
  # We use key because the memoized value could be `nil`
  if @memoized_values.key?(klass.to_s)
    @memoized_values[klass.to_s]
  else
    path = Private.path_from_klass(klass)
    return nil if path.nil?

    value_to_memoize = for_file(path)
    @memoized_values[klass.to_s] = value_to_memoize
    value_to_memoize
  end
end

.for_file(file) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/code_ownership.rb', line 30

def for_file(file)
  @for_file ||= T.let(@for_file, T.nilable(T::Hash[String, T.nilable(CodeTeams::Team)]))
  @for_file ||= {}

  return nil if file.start_with?('./')
  return @for_file[file] if @for_file.key?(file)

  Private.load_configuration!

  owner = T.let(nil, T.nilable(CodeTeams::Team))

  Mapper.all.each do |mapper|
    owner = mapper.map_file_to_owner(file)
    break if owner # TODO: what if there are multiple owners? Should we respond with an error instead of the first match?
  end

  @for_file[file] = owner
end

.for_package(package) ⇒ Object



179
180
181
# File 'lib/code_ownership.rb', line 179

def for_package(package)
  Private::OwnershipMappers::PackageOwnership.new.owner_for_package(package)
end

.for_team(team) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/code_ownership.rb', line 50

def for_team(team)
  team = T.must(CodeTeams.find(team)) if team.is_a?(String)
  ownership_information = T.let([], T::Array[String])

  ownership_information << "# Code Ownership Report for `#{team.name}` Team"

  Private.glob_cache.raw_cache_contents.each do |mapper_description, glob_to_owning_team_map|
    ownership_information << "## #{mapper_description}"
    ownership_for_mapper = []
    glob_to_owning_team_map.each do |glob, owning_team|
      next if owning_team != team

      ownership_for_mapper << "- #{glob}"
    end

    if ownership_for_mapper.empty?
      ownership_information << 'This team owns nothing in this category.'
    else
      ownership_information += ownership_for_mapper.sort
    end

    ownership_information << ''
  end

  ownership_information.join("\n")
end

.remove_file_annotation!(filename) ⇒ Object



81
82
83
# File 'lib/code_ownership.rb', line 81

def self.remove_file_annotation!(filename)
  Private::OwnershipMappers::FileAnnotations.new.remove_file_annotation!(filename)
end

.validate!(autocorrect: true, stage_changes: true, files: nil) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/code_ownership.rb', line 92

def validate!(
  autocorrect: true,
  stage_changes: true,
  files: nil
)
  Private.load_configuration!

  tracked_file_subset = if files
                          files.select { |f| Private.file_tracked?(f) }
                        else
                          Private.tracked_files
                        end

  Private.validate!(files: tracked_file_subset, autocorrect: autocorrect, stage_changes: stage_changes)
end