@@ -39,7 +39,8 @@ def globs_to_owner(files)
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 @@ def update_cache(cache, files)
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 @@ def description
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
0 commit comments