11import { EOL } from 'os' ;
22import { join , relative , resolve , sep } from 'path' ;
33import * as cp from 'child_process' ;
4+ import { readFile } from 'fs/promises' ;
45
56import * as minimatch from 'minimatch' ; // Only needed for githubValiator
7+ import * as yaml from 'js-yaml' ;
68import * as vscode from 'vscode' ;
79
810let statusBarItem : vscode . StatusBarItem ;
911let channel : vscode . OutputChannel ;
1012let owner : Owner | undefined = undefined ;
1113
1214function updateStatus ( active : vscode . TextEditor | undefined ) {
13- console . log ( active ) ;
1415 if ( active ) {
1516 statusBarItem . text = '$(loading~spin) Owner: running...' ;
1617 statusBarItem . show ( ) ;
1718 setTimeout ( ( ) => {
1819 try {
1920 codeownershipValidator ( active . document . uri . fsPath ) . then ( ( result ) => {
2021 owner = result ;
22+ log ( 'debug' , JSON . stringify ( owner ) ) ;
2123 if (
2224 active . document . uri . fsPath ===
2325 vscode . window . activeTextEditor ?. document . uri . fsPath
@@ -57,18 +59,34 @@ export function activate(context: vscode.ExtensionContext) {
5759 ( ) => {
5860 if ( owner ) {
5961 const filename = owner . filepath . split ( sep ) . slice ( - 1 ) [ 0 ] ;
60- const { teamConfig } = owner ;
62+ const { teamConfig, slack } = owner ;
63+
64+ const items : { title : string ; action : ( ) => void } [ ] = [ ] ;
65+
66+ if ( slack ) {
67+ items . push ( {
68+ title : `Slack: #${ slack } ` ,
69+ action ( ) {
70+ const uri = vscode . Uri . parse (
71+ `https://slack.com/app_redirect?channel=${ slack } ` ,
72+ ) ;
73+ vscode . commands . executeCommand ( 'vscode.open' , uri ) ;
74+ } ,
75+ } ) ;
76+ }
77+
78+ items . push ( {
79+ title : 'View team config' ,
80+ action ( ) {
81+ const uri = vscode . Uri . parse ( teamConfig ) ;
82+ vscode . commands . executeCommand ( 'vscode.open' , uri ) ;
83+ } ,
84+ } ) ;
6185
6286 vscode . window
6387 . showInformationMessage (
6488 `${ filename } is owned by ${ owner . teamName } ` ,
65- {
66- title : 'View team config' ,
67- action ( ) {
68- const uri = vscode . Uri . parse ( teamConfig ) ;
69- vscode . commands . executeCommand ( 'vscode.open' , uri ) ;
70- } ,
71- } ,
89+ ...items ,
7290 )
7391 . then ( ( x ) => x ?. action ( ) ) ;
7492 }
@@ -103,6 +121,7 @@ type Owner = {
103121 filepath : string ;
104122 teamName : string ;
105123 teamConfig : string ;
124+ slack ?: string ;
106125} ;
107126
108127type Validator = ( filepath : string ) => Promise < Owner | undefined > ;
@@ -194,13 +213,16 @@ const codeownershipValidator: Validator = async (filepath) => {
194213 typeof obj . team_yml === 'string' &&
195214 obj . team_name !== 'Unowned'
196215 ) {
216+ const teamConfig = resolve (
217+ vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath || '' ,
218+ obj . team_yml ,
219+ ) ;
220+
197221 return {
198222 filepath,
199223 teamName : obj . team_name ,
200- teamConfig : resolve (
201- vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath || '' ,
202- obj . team_yml ,
203- ) ,
224+ teamConfig,
225+ slack : await getSlackHandle ( teamConfig ) ,
204226 } ;
205227 }
206228 } catch {
@@ -209,6 +231,22 @@ const codeownershipValidator: Validator = async (filepath) => {
209231 return undefined ;
210232} ;
211233
234+ async function getSlackHandle ( teamConfig : string ) : Promise < string | undefined > {
235+ try {
236+ const text = ( await readFile ( teamConfig ) ) . toString ( ) ;
237+ const config = yaml . load ( text ) as any ;
238+
239+ if ( typeof config ?. slack ?. room_for_humans === 'string' ) {
240+ const slack = config ?. slack ?. room_for_humans ;
241+ return slack . startsWith ( '#' ) ? slack . slice ( 1 ) : slack ;
242+ }
243+
244+ return undefined ;
245+ } catch {
246+ return undefined ;
247+ }
248+ }
249+
212250function runCommand ( cwd : string , command : string , stdin ?: string ) : string {
213251 let stdout : string = '' ;
214252 log ( 'info' , `command: ${ command } ` ) ;
0 commit comments