code_ownership 1.37.0 → 1.38.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c854c774447149078df69925e183be064e8ac92ea464da9eea83cec2cfb10931
4
- data.tar.gz: 5a42650db0cdc8f14fd8878a0c70587b21a722a284a45104051062464f73a4a7
3
+ metadata.gz: 8319ea8a2a73ecec20a28193627b25b877ae9983b206dae6ff9422d5be157625
4
+ data.tar.gz: 13228207fa0b9042fe5f87e53c80234e862a476ef4a3888bce7f4bbdfb64e970
5
5
  SHA512:
6
- metadata.gz: 25025e91fa585614f864ab1f84d829037b5769cd491dcca93bf822e25ecb3222388d8d9315bf7dd3fe5a645645855c391028a9df01592199ce0857d47276656e
7
- data.tar.gz: 8f8035f102b184ac7ea866df6bff7cee92f0bd2fe5337b49956c85e2ead483a5868c0969030392c63dda1575f9bf33ae085058c0114ef027140b3bf629a60895
6
+ metadata.gz: a80e615b1d6e7cc8ec795a7b2ffdb20f0ffb8b0e8027cd70e8361542ff5650f195fca4fdf4ece8e0f1331e987dcef9e2d1106c7125925a43d16403e6e9ed0a78
7
+ data.tar.gz: 8fabc79d074c2491c49a3cdc1b0caf24f009dbab3e81b7cdcb84ac4b6d563d6ac7e32c83ec6494a3df81d8293afa01c7674e87b0b05878515177e757a4df0fe3
@@ -73,7 +73,26 @@ module CodeOwnership
73
73
 
74
74
  next if ownership_entries.none?
75
75
 
76
- codeowners_file_lines += ['', "# #{mapper_description}", *ownership_entries.sort]
76
+ # When we have a special character at the beginning of a folder name, then this character
77
+ # may be prioritized over *. However, we want the most specific folder to be listed last
78
+ # in the CODEOWNERS file, so we should prioritize any character above an asterisk in the
79
+ # same position.
80
+ if mapper_description == OwnershipMappers::FileAnnotations::DESCRIPTION
81
+ # individually owned files definitely won't have globs so we don't need to do special sorting
82
+ sorted_ownership_entries = ownership_entries.sort
83
+ else
84
+ sorted_ownership_entries = ownership_entries.sort do |entry1, entry2|
85
+ if entry2.start_with?(entry1.split('**').first)
86
+ -1
87
+ elsif entry1.start_with?(entry2.split('**').first)
88
+ 1
89
+ else
90
+ entry1 <=> entry2
91
+ end
92
+ end
93
+ end
94
+
95
+ codeowners_file_lines += ['', "# #{mapper_description}", *sorted_ownership_entries]
77
96
  end
78
97
 
79
98
  [
@@ -39,7 +39,8 @@ module CodeOwnership
39
39
  owner = file_annotation_based_owner(filename_relative_to_root)
40
40
  next unless owner
41
41
 
42
- mapping[filename_relative_to_root] = owner
42
+ escaped_filename = escaped_path_for_codeowners_file(filename_relative_to_root)
43
+ mapping[escaped_filename] = owner
43
44
  end
44
45
  end
45
46
 
@@ -55,7 +56,8 @@ module CodeOwnership
55
56
 
56
57
  invalid_files = cache.keys.select do |file|
57
58
  # If a file is not tracked, it should be removed from the cache
58
- !Private.file_tracked?(file) ||
59
+ unescaped_file = unescaped_path_for_codeowners_file(file)
60
+ !Private.file_tracked?(unescaped_file) ||
59
61
  # If a file no longer has a file annotation (i.e. `globs_to_owner` doesn't map it)
60
62
  # it should be removed from the cache
61
63
  # We make sure to only apply this to the input files since otherwise `updated_cache_for_files.key?(file)` would always return `false` when files == []
@@ -126,6 +128,32 @@ module CodeOwnership
126
128
 
127
129
  sig { override.void }
128
130
  def bust_caches!; end
131
+
132
+ sig { params(filename: String).returns(String) }
133
+ def escaped_path_for_codeowners_file(filename)
134
+ # Globs can contain certain regex characters, like "[" and "]".
135
+ # However, when we are generating a glob from a file annotation, we
136
+ # need to escape bracket characters and interpret them literally.
137
+ # Otherwise the resulting glob will not actually match the directory
138
+ # containing the file.
139
+ #
140
+ # Example
141
+ # filename: "/some/[xId]/myfile.tsx"
142
+ # matches: "/some/1/file"
143
+ # matches: "/some/2/file"
144
+ # matches: "/some/3/file"
145
+ # does not match!: "/some/[xId]/myfile.tsx"
146
+ filename.gsub(/[\[\]]/) { |x| "\\#{x}" }
147
+ end
148
+
149
+ sig { params(filename: String).returns(String) }
150
+ def unescaped_path_for_codeowners_file(filename)
151
+ # Globs can contain certain regex characters, like "[" and "]".
152
+ # We escape bracket characters and interpret them literally for
153
+ # the CODEOWNERS file. However, we want to compare the unescaped
154
+ # glob to the actual file path when we check if the file was deleted.
155
+ filename.gsub(/\\([\[\]])/, '\1')
156
+ end
129
157
  end
130
158
  end
131
159
  end
@@ -99,6 +99,7 @@ module CodeOwnership
99
99
  in_unowned_globs = configuration.unowned_globs.any? do |unowned_glob|
100
100
  File.fnmatch?(unowned_glob, file, File::FNM_PATHNAME | File::FNM_EXTGLOB)
101
101
  end
102
+
102
103
  in_owned_globs && !in_unowned_globs && File.exist?(file)
103
104
  end
104
105
 
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.37.0
4
+ version: 1.38.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-13 00:00:00.000000000 Z
11
+ date: 2024-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: code_teams
@@ -220,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
220
  - !ruby/object:Gem::Version
221
221
  version: '0'
222
222
  requirements: []
223
- rubygems_version: 3.5.11
223
+ rubygems_version: 3.5.22
224
224
  signing_key:
225
225
  specification_version: 4
226
226
  summary: A gem to help engineering teams declare ownership of code