File size: 2,217 Bytes
09321b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import os
import platform
import shutil

from ..subprocess_code_interpreter import SubprocessCodeInterpreter


class PowerShell(SubprocessCodeInterpreter):
    file_extension = 'ps1'
    proper_name = 'PowerShell'

    def __init__(self):
        super().__init__()

        # Determine the start command based on the platform (use "powershell" for Windows)
        if platform.system() == 'Windows':
            self.start_cmd = 'powershell.exe'
            # self.start_cmd = os.environ.get('SHELL', 'powershell.exe')
        else:
            # On non-Windows platforms, prefer pwsh (PowerShell Core) if available, or fall back to bash
            self.start_cmd = 'pwsh' if shutil.which('pwsh') else 'bash'

    def preprocess_code(self, code):
        return preprocess_powershell(code)

    def line_postprocessor(self, line):
        return line

    def detect_active_line(self, line):
        if '##active_line' in line:
            return int(line.split('##active_line')[1].split('##')[0])
        return None

    def detect_end_of_execution(self, line):
        return '##end_of_execution##' in line


def preprocess_powershell(code):
    """
    Add active line markers
    Wrap in try-catch block
    Add end of execution marker
    """
    # Add commands that tell us what the active line is
    code = add_active_line_prints(code)

    # Wrap in try-catch block for error handling
    code = wrap_in_try_catch(code)

    # Add end marker (we'll be listening for this to know when it ends)
    code += '\nWrite-Output "##end_of_execution##"'

    return code


def add_active_line_prints(code):
    """
    Add Write-Output statements indicating line numbers to a PowerShell script.
    """
    lines = code.split('\n')
    for index, line in enumerate(lines):
        # Insert the Write-Output command before the actual line
        lines[index] = f'Write-Output "##active_line{index + 1}##"\n{line}'
    return '\n'.join(lines)


def wrap_in_try_catch(code):
    """
    Wrap PowerShell code in a try-catch block to catch errors and display them.
    """
    try_catch_code = """
try {
    $ErrorActionPreference = "Stop"
"""
    return try_catch_code + code + '\n} catch {\n    Write-Error $_\n}\n'