code_ownership 1.29.3 → 1.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ea243e473ae151a2775f8e1e47d0eb9dacb27f3d2d594db63d3004f5c611109
4
- data.tar.gz: eb77703d34e6c40ee734d3e487fd58ba0f124555a681ff267326a4a3f4aeb03e
3
+ metadata.gz: 292664613750d5a5413984bac92ade17caa9a7f1796123455d16dd6f76ae6410
4
+ data.tar.gz: 306f65f710f7462acc3b001232e73e3561a63faa260153b7f759adc3dbf0a28e
5
5
  SHA512:
6
- metadata.gz: 8464d15022cc9a5f9e6019c0633b8941a3a5f1984f5d55f676c6377b94c335efb0b5722c4289f40b32da5f01453e806911c829c7fa0f11643f2d90c3327db3f3
7
- data.tar.gz: 84c95502b0457b848d705b71b675c0d9b8654ed940cd3ba37bc1503c0d8c3cfe7b53dfa28340610ccfde17527e69facc14e7abb106843b21456b3fb17b3bc41d
6
+ metadata.gz: 196be6927310bda4e577f94ea9553d832abf85f2dbc65e2d2efc0c55016001a9d8b6d6c64674aeb846ae41f1500bd0f5254c6e486017653cb03c620be9be0865
7
+ data.tar.gz: bdf65c513ab30773eed96cb934d1212d4599e0f54f0f0fcc1729b54bd6a007aefc6edc7dd647c2348c3020c2afe04d79017b84013d51cb1b6fb3284577653a5f
@@ -31,6 +31,58 @@ module CodeOwnership
31
31
  end
32
32
  end
33
33
 
34
+ class MappingContext < T::Struct
35
+ const :glob, String
36
+ const :team, CodeTeams::Team
37
+ end
38
+
39
+ class GlobOverlap < T::Struct
40
+ extend T::Sig
41
+
42
+ const :mapping_contexts, T::Array[MappingContext]
43
+
44
+ sig { returns(String) }
45
+ def description
46
+ # These are sorted only to prevent non-determinism in output between local and CI environments.
47
+ sorted_contexts = mapping_contexts.sort_by{|context| context.team.config_yml.to_s }
48
+ description_args = sorted_contexts.map do |context|
49
+ "`#{context.glob}` (from `#{context.team.config_yml}`)"
50
+ end
51
+
52
+ description_args.join(', ')
53
+ end
54
+ end
55
+
56
+ sig do
57
+ returns(T::Array[GlobOverlap])
58
+ end
59
+ def find_overlapping_globs
60
+ mapped_files = T.let({}, T::Hash[String, T::Array[MappingContext]])
61
+ CodeTeams.all.each_with_object({}) do |team, map| # rubocop:disable Style/ClassVars
62
+ TeamPlugins::Ownership.for(team).owned_globs.each do |glob|
63
+ Dir.glob(glob).each do |filename|
64
+ mapped_files[filename] ||= []
65
+ T.must(mapped_files[filename]) << MappingContext.new(glob: glob, team: team)
66
+ end
67
+ end
68
+ end
69
+
70
+ overlaps = T.let([], T::Array[GlobOverlap])
71
+ mapped_files.each do |filename, mapping_contexts|
72
+ if mapping_contexts.count > 1
73
+ overlaps << GlobOverlap.new(mapping_contexts: mapping_contexts)
74
+ end
75
+ end
76
+
77
+ deduplicated_overlaps = overlaps.uniq do |glob_overlap|
78
+ glob_overlap.mapping_contexts.map do |context|
79
+ [context.glob, context.team.name]
80
+ end
81
+ end
82
+
83
+ deduplicated_overlaps
84
+ end
85
+
34
86
  sig do
35
87
  override.params(file: String).
36
88
  returns(T.nilable(::CodeTeams::Team))
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ # typed: true
4
+
5
+ module CodeOwnership
6
+ module Private
7
+ module OwnershipMappers
8
+ class TeamYmlOwnership
9
+ extend T::Sig
10
+ include Interface
11
+
12
+ @@map_files_to_owners = T.let(@map_files_to_owners, T.nilable(T::Hash[String, T.nilable(::CodeTeams::Team)])) # rubocop:disable Style/ClassVars
13
+ @@map_files_to_owners = {} # rubocop:disable Style/ClassVars
14
+ @@codeowners_lines_to_owners = T.let(@codeowners_lines_to_owners, T.nilable(T::Hash[String, T.nilable(::CodeTeams::Team)])) # rubocop:disable Style/ClassVars
15
+ @@codeowners_lines_to_owners = {} # rubocop:disable Style/ClassVars
16
+
17
+ sig do
18
+ override.
19
+ params(files: T::Array[String]).
20
+ returns(T::Hash[String, T.nilable(::CodeTeams::Team)])
21
+ end
22
+ def map_files_to_owners(files) # rubocop:disable Lint/UnusedMethodArgument
23
+ return @@map_files_to_owners if @@map_files_to_owners&.keys && @@map_files_to_owners.keys.count > 0
24
+
25
+ @@map_files_to_owners = CodeTeams.all.each_with_object({}) do |team, map| # rubocop:disable Style/ClassVars
26
+ map[team.config_yml] = team
27
+ end
28
+ end
29
+
30
+ sig do
31
+ override.params(file: String).
32
+ returns(T.nilable(::CodeTeams::Team))
33
+ end
34
+ def map_file_to_owner(file)
35
+ map_files_to_owners([file])[file]
36
+ end
37
+
38
+ sig do
39
+ override.returns(T::Hash[String, T.nilable(::CodeTeams::Team)])
40
+ end
41
+ def codeowners_lines_to_owners
42
+ return @@codeowners_lines_to_owners if @@codeowners_lines_to_owners&.keys && @@codeowners_lines_to_owners.keys.count > 0
43
+
44
+ @@codeowners_lines_to_owners = CodeTeams.all.each_with_object({}) do |team, map| # rubocop:disable Style/ClassVars
45
+ map[team.config_yml] = team
46
+ end
47
+ end
48
+
49
+ sig { override.void }
50
+ def bust_caches!
51
+ @@codeowners_lines_to_owners = {} # rubocop:disable Style/ClassVars
52
+ @@map_files_to_owners = {} # rubocop:disable Style/ClassVars
53
+ end
54
+
55
+ sig { override.returns(String) }
56
+ def description
57
+ 'Team YML ownership'
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,30 @@
1
+ # typed: strict
2
+
3
+ module CodeOwnership
4
+ module Private
5
+ module Validations
6
+ class NoOverlappingGlobs
7
+ extend T::Sig
8
+ extend T::Helpers
9
+ include Interface
10
+
11
+ sig { override.params(files: T::Array[String], autocorrect: T::Boolean, stage_changes: T::Boolean).returns(T::Array[String]) }
12
+ def validation_errors(files:, autocorrect: true, stage_changes: true)
13
+ overlapping_globs = OwnershipMappers::TeamGlobs.new.find_overlapping_globs
14
+
15
+ errors = T.let([], T::Array[String])
16
+
17
+ if overlapping_globs.any?
18
+ errors << <<~MSG
19
+ `owned_globs` cannot overlap between teams. The following globs overlap:
20
+
21
+ #{overlapping_globs.map { |overlap| "- #{overlap.description}"}.join("\n")}
22
+ MSG
23
+ end
24
+
25
+ errors
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -10,11 +10,13 @@ require 'code_ownership/private/validations/interface'
10
10
  require 'code_ownership/private/validations/files_have_owners'
11
11
  require 'code_ownership/private/validations/github_codeowners_up_to_date'
12
12
  require 'code_ownership/private/validations/files_have_unique_owners'
13
+ require 'code_ownership/private/validations/no_overlapping_globs'
13
14
  require 'code_ownership/private/ownership_mappers/interface'
14
15
  require 'code_ownership/private/ownership_mappers/file_annotations'
15
16
  require 'code_ownership/private/ownership_mappers/team_globs'
16
17
  require 'code_ownership/private/ownership_mappers/package_ownership'
17
18
  require 'code_ownership/private/ownership_mappers/js_package_ownership'
19
+ require 'code_ownership/private/ownership_mappers/team_yml_ownership'
18
20
 
19
21
  module CodeOwnership
20
22
  module Private
@@ -39,6 +41,7 @@ module CodeOwnership
39
41
  Validations::FilesHaveOwners.new,
40
42
  Validations::FilesHaveUniqueOwners.new,
41
43
  Validations::GithubCodeownersUpToDate.new,
44
+ Validations::NoOverlappingGlobs.new,
42
45
  ]
43
46
 
44
47
  errors = validators.flat_map do |validator|
@@ -62,6 +65,7 @@ module CodeOwnership
62
65
  Private::OwnershipMappers::TeamGlobs.new,
63
66
  Private::OwnershipMappers::PackageOwnership.new,
64
67
  Private::OwnershipMappers::JsPackageOwnership.new,
68
+ Private::OwnershipMappers::TeamYmlOwnership.new,
65
69
  ]
66
70
  end
67
71
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_ownership
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.29.3
4
+ version: 1.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-02 00:00:00.000000000 Z
11
+ date: 2023-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: code_teams
@@ -141,6 +141,7 @@ files:
141
141
  - lib/code_ownership/private/ownership_mappers/js_package_ownership.rb
142
142
  - lib/code_ownership/private/ownership_mappers/package_ownership.rb
143
143
  - lib/code_ownership/private/ownership_mappers/team_globs.rb
144
+ - lib/code_ownership/private/ownership_mappers/team_yml_ownership.rb
144
145
  - lib/code_ownership/private/parse_js_packages.rb
145
146
  - lib/code_ownership/private/team_plugins/github.rb
146
147
  - lib/code_ownership/private/team_plugins/ownership.rb
@@ -148,6 +149,7 @@ files:
148
149
  - lib/code_ownership/private/validations/files_have_unique_owners.rb
149
150
  - lib/code_ownership/private/validations/github_codeowners_up_to_date.rb
150
151
  - lib/code_ownership/private/validations/interface.rb
152
+ - lib/code_ownership/private/validations/no_overlapping_globs.rb
151
153
  - sorbet/config
152
154
  - sorbet/rbi/gems/code_teams@1.0.0.rbi
153
155
  - sorbet/rbi/gems/packs@0.0.2.rbi