import { Task , WorkspaceFolder , ShellExecution , Uri , workspace , ShellExecutionOptions } from "vscode" ; import * as path from "path" ; import * as util from "../common/utils" ; import * as log from "../common/log" ; import { configuration } from "../common/configuration" ; import { filesCache } from "../cache" ; import { TaskExplorerProvider } from "./provider" ; import { TaskExplorerDefinition } from "../taskDefinition" ; export class ScriptTaskProvider extends TaskExplorerProvider implements TaskExplorerProvider { constructor ( ) { super ( "script" ) ; } private scriptTable : any = { sh : { exec : "" , type : "bash" , args : [ ] , enabled : configuration . get ( "enableBash" ) } , py : { exec : configuration . get ( "pathToPython" ) , type : "python" , args : [ ] , enabled : configuration . get ( "enablePython" ) } , rb : { exec : configuration . get ( "pathToRuby" ) , type : "ruby" , args : [ ] , enabled : configuration . get ( "enableRuby" ) } , ps1 : { exec : configuration . get ( "pathToPowershell" ) , type : "powershell" , args : [ ] , enabled : configuration . get ( "enablePowershell" ) } , pl : { exec : configuration . get ( "pathToPerl" ) , type : "perl" , args : [ ] , enabled : configuration . get ( "enablePerl" ) } , bat : { exec : "cmd" , type : "batch" , args : [ "/c" ] , enabled : configuration . get ( "enableBatch" ) } , cmd : { exec : "cmd" , type : "batch" , args : [ "/c" ] , enabled : configuration . get ( "enableBatch" ) } , nsi : { exec : configuration . get ( "pathToNsis" ) , type : "nsis" , args : [ ] , enabled : configuration . get ( "enableNsis" ) } } ; public createTask ( target , cmd , folder , uri , xArgs ? ) { let sep = ( process . platform === "win32" ? "\\" : "/" ) ; const scriptDef = this . scriptTable [ target ?. toLowerCase ( ) ] , cwd = path . dirname ( uri . fsPath ) , fileName = path . basename ( uri . fsPath ) , def = this . getDefaultDefinition ( target , folder , uri ) , options = { cwd } , args = [ ] ; let isWinShell = false , exec = scriptDef . exec ; if ( ! scriptDef ) { return ; } if ( process . platform === "win32" ) { isWinShell = true ; const winShell = workspace . getConfiguration ( ) . get ( "terminal.integrated.shell.windows" ) ; if ( winShell ?. includes ( "bash.exe" ) ) { sep = "/" ; isWinShell = false ; } } if ( isWinShell ) { if ( scriptDef . type === "bash" ) { let bash = configuration . get < string > ( "pathToBash" ) ; if ( ! bash ) { bash = "C:\\Program Files\\Git\\bin\\bash.exe" ; } if ( ! util . pathExists ( bash ) ) { bash = "bash.exe" ; } options . executable = bash ; sep = "/" ; } } const fileNamePathPre = "." + sep + fileName ; if ( scriptDef . type === "bash" ) { exec = fileNamePathPre ; } else { if ( scriptDef . args ) { args . push ( ... scriptDef . args ) ; } args . push ( scriptDef . type !== "powershell" ? fileName : fileNamePathPre ) ; } if ( scriptDef . type === "python" ) { args . push ( "bdist_egg" ) ; } if ( xArgs ) { args . push ( ... xArgs ) ; } if ( ! isWinShell ) { exec = exec . replace ( /\\/g , "/" ) ; } const execution = new ShellExecution ( exec , args , options ) ; return new Task ( def , folder , scriptDef . type !== "python" ? fileName : "build egg" , scriptDef . type , execution , "$msCompile" ) ; } public getDefaultDefinition ( target , folder , uri ) { const tgt = target ?. toLowerCase ( ) , scriptDef = this . scriptTable [ tgt ] , fileName = path . basename ( uri . fsPath ) ; const def = { type : "script" , script : target ?. toLowerCase ( ) , target : tgt , scriptType : scriptDef ?. type || "unknown" , fileName , scriptFile : true , path : util . getRelativePath ( folder , uri ) , takesArgs : false , uri } ; if ( scriptDef . type === "batch" ) { const contents = util . readFileSync ( uri . fsPath ) ; def . takesArgs = ( new RegExp ( "%[1-9]" ) ) . test ( contents ) ; } return def ; } public getDocumentPosition ( taskName , documentText ) { return 0 ; } public async readTasks ( logPad = "" ) { log . methodStart ( "detect script files" , 1 , logPad , true ) ; const allTasks = [ ] ; const visitedFiles = new Set ( ) ; const paths = filesCache . get ( "script" ) ; 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 task = this . createTask ( path . extname ( fobj . uri . fsPath ) . substring ( 1 ) , undefined , fobj . folder , fobj . uri ) ; if ( task ) { allTasks . push ( task ) ; log . write ( "   found script target/file" , 3 , logPad ) ; log . value ( "      script file" , fobj . uri . fsPath , 3 , logPad ) ; } } } } log . value ( "   # of tasks" , allTasks . length , 2 , logPad ) ; log . methodDone ( "detect script files" , 1 , logPad , true ) ; return allTasks ; } public async readUriTasks ( uri , wsFolder ? , logPad = "" ) { const folder = wsFolder || workspace . getWorkspaceFolder ( uri ) ; log . methodStart ( "read script file uri task" , 1 , logPad , true , [ [ "path" , uri ?. fsPath ] , [ "project folder" , folder ?. name ] ] ) ; let task ; if ( folder ) { task = this . createTask ( path . extname ( uri . fsPath ) . substring ( 1 ) , undefined , folder , uri ) ; } log . methodDone ( "read script file uri task" , 1 , logPad , true ) ; return task ? [ task ] : [ ] ; } }