@@ -11,7 +11,7 @@ const getCodeownersFile = memoizeAsync(
1111 } : {
1212 uri : string
1313 sourcegraph : typeof import ( 'sourcegraph' )
14- } ) : Promise < string | null > => {
14+ } ) : Promise < { path : string ; content : string } | null > => {
1515 const { repo, rev } = resolveURI ( uri )
1616 const { data } = await sourcegraph . commands . executeCommand (
1717 'queryGraphQL' ,
@@ -35,10 +35,10 @@ const getCodeownersFile = memoizeAsync(
3535 throw new Error ( 'repository or commit not found when getting CODEOWNERS file' )
3636 }
3737 if ( data . repository . commit . codeownersBlob && data . repository . commit . codeownersBlob . content ) {
38- return data . repository . commit . codeownersBlob . content
38+ return { path : 'CODEOWNERS' , content : data . repository . commit . codeownersBlob . content }
3939 }
4040 if ( data . repository . commit . githubCodeownersBlob && data . repository . commit . githubCodeownersBlob . content ) {
41- return data . repository . commit . githubCodeownersBlob . content
41+ return { path : '.github/CODEOWNERS' , content : data . repository . commit . githubCodeownersBlob . content }
4242 }
4343 return null
4444 } ,
@@ -48,15 +48,21 @@ const getCodeownersFile = memoizeAsync(
4848 }
4949)
5050
51- export async function getCodeOwners ( uri : string ) : Promise < string [ ] | null > {
51+ export interface ResolvedOwnersLine {
52+ path : string
53+ lineNumber : number
54+ owners : string [ ]
55+ }
56+
57+ export async function getCodeOwners ( uri : string ) : Promise < ResolvedOwnersLine | null > {
5258 const codeownersFile = await getCodeownersFile ( { uri, sourcegraph } )
5359 if ( ! codeownersFile ) {
5460 return null
5561 }
56- const codeownersEntries = parseCodeownersFile ( codeownersFile )
57- const entry = matchCodeownersFile ( resolveURI ( uri ) . path , codeownersEntries )
58- if ( entry ) {
59- return entry . owners
62+ const codeownersEntries = parseCodeownersFile ( codeownersFile . content )
63+ const matching = codeownersEntries . find ( entry => matchPattern ( resolveURI ( uri ) . path , entry . pattern ) )
64+ if ( matching ) {
65+ return { path : codeownersFile . path , lineNumber : matching . lineNumber , owners : matching . owners }
6066 }
6167 return null
6268}
@@ -65,6 +71,7 @@ export async function getCodeOwners(uri: string): Promise<string[] | null> {
6571 * An individual entry from a CODEOWNERS file
6672 */
6773export interface CodeOwnersEntry {
74+ lineNumber : number
6875 pattern : string
6976 owners : string [ ]
7077}
@@ -74,17 +81,17 @@ export interface CodeOwnersEntry {
7481 * of the file).
7582 */
7683export function parseCodeownersFile ( str : string ) : CodeOwnersEntry [ ] {
77- const entries = [ ]
84+ const entries : CodeOwnersEntry [ ] = [ ]
7885 const lines = str . split ( '\n' )
7986
80- for ( const line of lines ) {
81- const [ content ] = line . split ( '#' )
87+ for ( const [ index , lineText ] of lines . entries ( ) ) {
88+ const [ content ] = lineText . split ( '#' )
8289 const trimmed = content . trim ( )
8390 if ( trimmed === '' ) {
8491 continue
8592 }
8693 const [ pattern , ...owners ] = trimmed . split ( / \s + / )
87- entries . push ( { pattern, owners } )
94+ entries . push ( { pattern, owners, lineNumber : index + 1 } )
8895 }
8996
9097 return entries . reverse ( )
@@ -96,16 +103,3 @@ export function parseCodeownersFile(str: string): CodeOwnersEntry[] {
96103export function matchPattern ( filename : string , pattern : string ) : boolean {
97104 return ignore ( ) . add ( pattern ) . ignores ( filename )
98105}
99-
100- /**
101- * Match a filename against CODEOWNERS entries to determine which (if any) it
102- * matches.
103- */
104- export function matchCodeownersFile ( filename : string , entries : CodeOwnersEntry [ ] ) : CodeOwnersEntry | null {
105- for ( const entry of entries ) {
106- if ( matchPattern ( filename , entry . pattern ) ) {
107- return entry
108- }
109- }
110- return null
111- }
0 commit comments