(userEnvProbe: UserEnvProbe, params: { allowSystemConfigChange: boolean; output: Log }, containerProperties: { shell: string; remoteExec: ExecFunction; installFolder?: string; env?: NodeJS.ProcessEnv; shellServer?: ShellServer; launchRootShellServer?: (() => Promise<ShellServer>); user?: string }, cmd: string, sep: string)
| 836 | } |
| 837 | |
| 838 | async function runUserEnvProbe(userEnvProbe: UserEnvProbe, params: { allowSystemConfigChange: boolean; output: Log }, containerProperties: { shell: string; remoteExec: ExecFunction; installFolder?: string; env?: NodeJS.ProcessEnv; shellServer?: ShellServer; launchRootShellServer?: (() => Promise<ShellServer>); user?: string }, cmd: string, sep: string) { |
| 839 | if (userEnvProbe === 'none') { |
| 840 | return {}; |
| 841 | } |
| 842 | try { |
| 843 | // From VS Code's shellEnv.ts |
| 844 | |
| 845 | const mark = crypto.randomUUID(); |
| 846 | const regex = new RegExp(mark + '([^]*)' + mark); |
| 847 | const systemShellUnix = containerProperties.shell; |
| 848 | params.output.write(`userEnvProbe shell: ${systemShellUnix}`); |
| 849 | |
| 850 | // handle popular non-POSIX shells |
| 851 | const name = path.posix.basename(systemShellUnix); |
| 852 | const command = `echo -n ${mark}; ${cmd}; echo -n ${mark}`; |
| 853 | let shellArgs: string[]; |
| 854 | if (/^pwsh(-preview)?$/.test(name)) { |
| 855 | shellArgs = userEnvProbe === 'loginInteractiveShell' || userEnvProbe === 'loginShell' ? |
| 856 | ['-Login', '-Command'] : // -Login must be the first option. |
| 857 | ['-Command']; |
| 858 | } else { |
| 859 | shellArgs = [ |
| 860 | userEnvProbe === 'loginInteractiveShell' ? '-lic' : |
| 861 | userEnvProbe === 'loginShell' ? '-lc' : |
| 862 | userEnvProbe === 'interactiveShell' ? '-ic' : |
| 863 | '-c' |
| 864 | ]; |
| 865 | } |
| 866 | |
| 867 | const traceOutput = makeLog(params.output, LogLevel.Trace); |
| 868 | const resultP = runRemoteCommandNoPty({ output: traceOutput }, { remoteExec: containerProperties.remoteExec }, [systemShellUnix, ...shellArgs, command], containerProperties.installFolder); |
| 869 | Promise.race([resultP, delay(2000)]) |
| 870 | .then(async result => { |
| 871 | if (!result) { |
| 872 | let processes: Process[]; |
| 873 | const shellServer = containerProperties.shellServer || await launch(containerProperties.remoteExec, params.output); |
| 874 | try { |
| 875 | ({ processes } = await findProcesses(shellServer)); |
| 876 | } finally { |
| 877 | if (!containerProperties.shellServer) { |
| 878 | await shellServer.process.terminate(); |
| 879 | } |
| 880 | } |
| 881 | const shell = processes.find(p => p.cmd.startsWith(systemShellUnix) && p.cmd.indexOf(mark) !== -1); |
| 882 | if (shell) { |
| 883 | const index = buildProcessTrees(processes); |
| 884 | const tree = index[shell.pid]; |
| 885 | params.output.write(`userEnvProbe is taking longer than 2 seconds. Process tree: |
| 886 | ${processTreeToString(tree)}`); |
| 887 | } else { |
| 888 | params.output.write(`userEnvProbe is taking longer than 2 seconds. Process not found.`); |
| 889 | } |
| 890 | } |
| 891 | }, () => undefined) |
| 892 | .catch(err => params.output.write(toErrorText(err && (err.stack || err.message) || 'Error reading process tree.'))); |
| 893 | const result = await Promise.race([resultP, delay(10000)]); |
| 894 | if (!result) { |
| 895 | params.output.write(toErrorText(`userEnvProbe is taking longer than 10 seconds. Avoid waiting for user input in your shell's startup scripts. Continuing.`)); |
no test coverage detected