import { Task , TaskGroup , WorkspaceFolder , ShellExecution , Uri , workspace } from "vscode" ; import * as path from "path" ; import * as util from "../common/utils" ; import * as log from "../common/log" ; import { filesCache } from "../cache" ; import { TaskExplorerProvider } from "./provider" ; import { TaskExplorerDefinition } from "../taskDefinition" ; export class GruntTaskProvider extends TaskExplorerProvider implements TaskExplorerProvider { constructor ( ) { super ( "grunt" ) ; } public createTask ( target , cmd , folder , uri ) { const def = this . getDefaultDefinition ( target , folder , uri ) , cwd = path . dirname ( uri . fsPath ) , args = [ "grunt" , target ] , options = { cwd } , execution = new ShellExecution ( "npx" , args , options ) ; return new Task ( def , folder , target , "grunt" , execution , "$msCompile" ) ; } public async readTasks ( logPad = "" ) { log . methodStart ( "detect grunt files" , 1 , logPad , true ) ; const allTasks = [ ] ; const visitedFiles = new Set ( ) ; const paths = filesCache . get ( "grunt" ) ; if ( workspace . workspaceFolders && paths ) { for ( const fobj of paths ) { if ( ! util . isExcluded ( fobj . uri . path ) && ! visitedFiles . has ( fobj . uri . fsPath ) ) { visitedFiles . add ( fobj . uri . fsPath ) ; const tasks = await this . readUriTasks ( fobj . uri , undefined , logPad + "   " ) ; log . write ( "   processed grunt file" , 3 , logPad ) ; log . value ( "      file" , fobj . uri . fsPath , 3 , logPad ) ; log . value ( "      targets in file" , tasks . length , 3 , logPad ) ; allTasks . push ( ... tasks ) ; } } } log . value ( "   # of tasks" , allTasks . length , 2 , logPad ) ; log . methodDone ( "detect grunt files" , 1 , logPad , true ) ; return allTasks ; } private findTargets ( fsPath , logPad = "" ) { const scripts = [ ] ; log . methodStart ( "find grunt targets" , 1 , logPad , true ) ; const contents = util . readFileSync ( fsPath ) ; let idx = 0 ; let eol = contents . indexOf ( "\n" , 0 ) ; while ( eol !== - 1 ) { let line = contents . substring ( idx , eol ) . trim ( ) ; if ( line . length > 0 && line . toLowerCase ( ) . trimLeft ( ) . startsWith ( "grunt.registertask" ) ) { let idx1 = line . indexOf ( "'" ) ; if ( idx1 === - 1 ) { idx1 = line . indexOf ( '"' ) ; } if ( idx1 === - 1 ) { let eol2 = eol + 1 ; eol2 = contents . indexOf ( "\n" , eol2 ) ; line = contents . substring ( eol + 1 , eol2 ) . trim ( ) ; if ( line . startsWith ( "'" ) || line . startsWith ( '"' ) ) { idx1 = line . indexOf ( "'" ) ; if ( idx1 === - 1 ) { idx1 = line . indexOf ( '"' ) ; } if ( idx1 !== - 1 ) { eol = eol2 ; } } } if ( idx1 !== - 1 ) { idx1 ++ ; let idx2 = line . indexOf ( "'" , idx1 ) ; if ( idx2 === - 1 ) { idx2 = line . indexOf ( '"' , idx1 ) ; } if ( idx2 !== - 1 ) { const tgtName = line . substring ( idx1 , idx2 ) . trim ( ) ; if ( tgtName ) { scripts . push ( tgtName ) ; log . write ( "   found grunt target" , 3 , logPad ) ; log . value ( "      name" , tgtName , 3 , logPad ) ; } } } } idx = eol + 1 ; eol = contents . indexOf ( "\n" , idx ) ; } log . methodDone ( "find grunt targets" , 1 , logPad , true ) ; return scripts ; } public getDefaultDefinition ( target , folder , uri ) { const def = { type : "grunt" , script : target , target , path : util . getRelativePath ( folder , uri ) , fileName : path . basename ( uri . path ) , uri } ; return def ; } public getDocumentPosition ( taskName , documentText ) { return this . getDocumentPositionLine ( "grunt.registerTask(" , taskName , documentText ) ; } public async readUriTasks ( uri , wsFolder ? , logPad = "" ) { const result = [ ] ; const folder = wsFolder || workspace . getWorkspaceFolder ( uri ) ; log . methodStart ( "read grunt file uri task" , 1 , logPad , true , [ [ "path" , uri ?. fsPath ] , [ "project folder" , folder ?. name ] ] ) ; if ( folder ) { const scripts = this . findTargets ( uri . fsPath , logPad + "   " ) ; if ( scripts ) { for ( const s of scripts ) { const task = this . createTask ( s , s , folder , uri ) ; task . group = TaskGroup . Build ; result . push ( task ) ; } } } log . methodDone ( "read grunt file uri tasks" , 1 , logPad , true ) ; return result ; } }