import { Task , TaskGroup , 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 { filesCache } from "../cache" ; import { TaskExplorerProvider } from "./provider" ; import { TaskExplorerDefinition } from "../taskDefinition" ; import { configuration } from "../common/configuration" ; import * as bombadil from "@sgarciac/bombadil" ; /**
 * Parses [scripts] from the pipenv Python package manager's Pipfile.
 */ export class PipenvTaskProvider extends TaskExplorerProvider implements TaskExplorerProvider { constructor ( ) { super ( "pipenv" ) ; } public createTask ( target , cmd , folder , uri ) { const pipenv = configuration . get < string > ( "pathToPipenv" ) ; let pythonPath = null ; if ( pipenv === "pipenv" ) { pythonPath = workspace . getConfiguration ( "python" ) . get ( "pythonPath" ) ?? "python" ; } const def = this . getDefaultDefinition ( target , folder , uri ) ; const cwd = path . dirname ( uri . fsPath ) ; const args = [ "run" , target ] ; if ( pythonPath ) { args . unshift ( ... [ "-m" , "pipenv" ] ) ; } const options = { cwd } ; const execution = new ShellExecution ( pythonPath ?? pipenv , args , options ) ; return new Task ( def , folder , target , "pipenv" , execution , "$msCompile" ) ; } public async readTasks ( logPad = "" ) { log . methodStart ( "detect pipenv Pipfile files" , 1 , logPad , true ) ; const allTasks = [ ] ; const visitedFiles = new Set ( ) ; const paths = filesCache . get ( "pipenv" ) ; if ( workspace . workspaceFolders && paths ) { for ( const obj of paths ) { if ( ! util . isExcluded ( obj . uri . path ) && ! visitedFiles . has ( obj . uri . fsPath ) ) { visitedFiles . add ( obj . uri . fsPath ) ; const tasks = await this . readUriTasks ( obj . uri , undefined , logPad + "   " ) ; log . write ( "   processed pipenv Pipfile file" , 3 , logPad ) ; log . value ( "      file" , obj . 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 pipenv Pipfile files" , 1 , logPad , true ) ; return allTasks ; } private findTargets ( fsPath , logPad = "" ) { const scripts = [ ] ; log . methodStart ( "find pipenv Pipfile targets" , 1 , logPad , true ) ; const contents = util . readFileSync ( fsPath ) ; const pipfile = new bombadil . TomlReader ( ) ; pipfile . readToml ( contents ) ; Object . entries ( pipfile . result ?. scripts ?? { } ) . forEach ( ( [ scriptName , _scriptCmd ] ) => { scripts . push ( scriptName ) ; log . write ( "   found pipenv Pipfile target" , 3 , logPad ) ; log . value ( "      name" , scriptName , 3 , logPad ) ; } ) ; log . methodDone ( "find pipenv Pipfile targets" , 1 , logPad , true ) ; return scripts ; } public getDefaultDefinition ( target , folder , uri ) { const def = { type : "pipenv" , script : target , target , path : util . getRelativePath ( folder , uri ) , fileName : path . basename ( uri . path ) , uri } ; return def ; } public getDocumentPosition ( taskName , documentText ) { return this . getDocumentPositionLine ( "" , taskName , documentText , 0 , 0 , true ) ; } public async readUriTasks ( uri , wsFolder ? , logPad = "" ) { const result = [ ] ; const folder = wsFolder || workspace . getWorkspaceFolder ( uri ) ; log . methodStart ( "read pipenv Pipfile 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 pipenv Pipfile file uri tasks" , 1 , logPad , true ) ; return result ; } }