diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index fb4fb0aa07a6..d91d1830697d 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -34,18 +34,6 @@ jobs: vsix_name: ${{ env.VSIX_NAME }} artifact_name: ${{ env.ARTIFACT_NAME_VSIX }} - lint: - name: Lint - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2.3.4 - - - name: Lint - uses: ./.github/actions/lint - with: - node_version: ${{ env.NODE_VERSION }} - ### Non-smoke tests tests: name: Tests @@ -59,10 +47,10 @@ jobs: matrix: # We're not running CI on macOS for now because it's one less matrix entry to lower the number of runners used, # macOS runners are expensive, and we assume that Ubuntu is enough to cover the Unix case. - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest] # Run the tests on the oldest and most recent versions of Python. python: ['2.7', '3.9'] - test-suite: [ts-unit, python-unit, venv, single-workspace, debugger, functional] + test-suite: [venv] exclude: # For fast PR turn-around, skip 2.7 under Windows. - os: windows-latest @@ -225,306 +213,9 @@ jobs: env: TEST_FILES_SUFFIX: testvirtualenvs CI_PYTHON_VERSION: ${{ matrix.python }} + VSC_PYTHON_FORCE_LOGGING: 1 uses: GabrielBB/xvfb-action@v1.5 with: run: npm run testSingleWorkspace working-directory: ${{ env.special-working-directory }} if: matrix.test-suite == 'venv' && matrix.os == 'ubuntu-latest' - - - name: Run single-workspace tests - env: - CI_PYTHON_VERSION: ${{ matrix.python }} - uses: GabrielBB/xvfb-action@v1.5 - with: - run: npm run testSingleWorkspace - working-directory: ${{ env.special-working-directory }} - if: matrix.test-suite == 'single-workspace' - - - name: Run multi-workspace tests - env: - CI_PYTHON_VERSION: ${{ matrix.python }} - uses: GabrielBB/xvfb-action@v1.5 - with: - run: npm run testMultiWorkspace - working-directory: ${{ env.special-working-directory }} - if: matrix.test-suite == 'multi-workspace' - - - name: Run debugger tests - env: - CI_PYTHON_VERSION: ${{ matrix.python }} - uses: GabrielBB/xvfb-action@v1.5 - with: - run: npm run testDebugger - working-directory: ${{ env.special-working-directory }} - if: matrix.test-suite == 'debugger' - - # Run TypeScript functional tests - - name: Run TypeScript functional tests - run: npm run test:functional - if: matrix.test-suite == 'functional' - - smoke-tests: - name: Smoke tests - # The value of runs-on is the OS of the current job (specified in the strategy matrix below) instead of being hardcoded. - runs-on: ${{ matrix.os }} - needs: [build-vsix] - strategy: - fail-fast: false - matrix: - # We're not running CI on macOS for now because it's one less matrix entry to lower the number of runners used, - # macOS runners are expensive, and we assume that Ubuntu is enough to cover the UNIX case. - os: [ubuntu-latest, windows-latest] - steps: - # Need the source to have the tests available. - - name: Checkout - uses: actions/checkout@v2 - - - name: Smoke tests - uses: ./.github/actions/smoke-tests - with: - node_version: ${{ env.NODE_VERSION }} - artifact_name: ${{ env.ARTIFACT_NAME_VSIX }} - - # insider-tests: - # name: Insider tests - # # The value of runs-on is the OS of the current job (specified in the strategy matrix below) instead of being hardcoded. - # runs-on: ${{ matrix.os }} - # strategy: - # fail-fast: false - # matrix: - # # We're not running CI on macOS for now because it's one less matrix entry to lower the number of runners used, - # # macOS runners are expensive, and we assume that Ubuntu is enough to cover the UNIX case. - # os: [ubuntu-latest] - # python: [3.8] - # steps: - # # Need the source to have the tests available. - # - name: Checkout - # uses: actions/checkout@v2 - - # - name: Install Node - # uses: actions/setup-node@v2 - # with: - # node-version: ${{ env.NODE_VERSION }} - # cache: 'npm' - - # - name: Use Python ${{ matrix.python }} - # uses: actions/setup-python@v2 - # with: - # python-version: ${{ matrix.python }} - - # - name: Install dependencies (npm ci) - # run: npm ci --prefer-offline - - # - name: pip install system test requirements - # run: | - # python -m pip install --upgrade -r build/test-requirements.txt - # python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade -r requirements.txt - # python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy - # shell: bash - - # - name: pip install smoke test requirements - # run: | - # python -m pip install --upgrade -r build/smoke-test-requirements.txt - # shell: bash - - # # Compile the test files. - # - name: Prepare for insiders tests - # run: npm run prePublish - # shell: bash - - # - name: Set CI_PYTHON_PATH and CI_DISABLE_AUTO_SELECTION - # run: | - # echo "CI_PYTHON_PATH=python" >> $GITHUB_ENV - # echo "CI_DISABLE_AUTO_SELECTION=1" >> $GITHUB_ENV - # shell: bash - - # - name: Run insider tests - # env: - # DISPLAY: 10 - # INSTALL_JUPYTER_EXTENSION: true - # INSTALL_PYLANCE_EXTENSION: true - # VSC_PYTHON_CI_TEST_VSC_CHANNEL: insiders - # TEST_FILES_SUFFIX: insiders.test - # CODE_TESTS_WORKSPACE: ./src/testMultiRootWkspc/smokeTests - # uses: GabrielBB/xvfb-action@v1.5 - # with: - # run: node --no-force-async-hooks-checks ./out/test/standardTest.js - - ### Coverage run - coverage: - name: Coverage - # The value of runs-on is the OS of the current job (specified in the strategy matrix below) instead of being hardcoded. - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - # Only run coverage on linux for PRs - os: [ubuntu-latest] - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Install Node - uses: actions/setup-node@v2 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'npm' - - - name: Install dependencies (npm ci) - run: npm ci - - - name: Compile - run: npx gulp prePublishNonBundle - - - name: Use Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@v2 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Install Python requirements - run: | - python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade -r requirements.txt --no-user - # We need to have debugpy so that tests relying on it keep passing, but we don't need install_debugpy's logic in the test phase. - python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy - python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/jedilsp --no-cache-dir --implementation py --no-deps --upgrade -r ./jedils_requirements.txt - - - name: Install test requirements - run: python -m pip install --upgrade -r build/test-requirements.txt - - - name: Install functional test requirements - run: python -m pip install --upgrade -r ./build/functional-test-requirements.txt - - - name: Prepare pipenv for venv tests - env: - TEST_FILES_SUFFIX: testvirtualenvs - PYTHON_VIRTUAL_ENVS_LOCATION: './src/tmp/envPaths.json' - shell: pwsh - run: | - python -m pip install pipenv - python -m pipenv run python ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} pipenvPath - - - name: Prepare poetry for venv tests - env: - TEST_FILES_SUFFIX: testvirtualenvs - shell: pwsh - run: | - python -m pip install poetry - Move-Item -Path ".\build\ci\pyproject.toml" -Destination . - poetry env use python - - - name: Prepare virtualenv for venv tests - env: - TEST_FILES_SUFFIX: testvirtualenvs - PYTHON_VIRTUAL_ENVS_LOCATION: './src/tmp/envPaths.json' - shell: pwsh - run: | - python -m pip install virtualenv - python -m virtualenv .virtualenv/ - if ('${{ matrix.os }}' -match 'windows-latest') { - & ".virtualenv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} virtualEnvPath - } else { - & ".virtualenv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} virtualEnvPath - } - - - name: Prepare venv for venv tests - env: - TEST_FILES_SUFFIX: testvirtualenvs - PYTHON_VIRTUAL_ENVS_LOCATION: './src/tmp/envPaths.json' - shell: pwsh - run: | - python -m venv .venv - if ('${{ matrix.os }}' -match 'windows-latest') { - & ".venv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath - } else { - & ".venv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath - } - - - name: Prepare conda for venv tests - env: - TEST_FILES_SUFFIX: testvirtualenvs - PYTHON_VIRTUAL_ENVS_LOCATION: './src/tmp/envPaths.json' - shell: pwsh - run: | - # 1. For `terminalActivation.testvirtualenvs.test.ts` - if ('${{ matrix.os }}' -match 'windows-latest') { - $condaPythonPath = Join-Path -Path $Env:CONDA -ChildPath python.exe - $condaExecPath = Join-Path -Path $Env:CONDA -ChildPath Scripts | Join-Path -ChildPath conda - } else{ - $condaPythonPath = Join-Path -Path $Env:CONDA -ChildPath bin | Join-Path -ChildPath python - $condaExecPath = Join-Path -Path $Env:CONDA -ChildPath bin | Join-Path -ChildPath conda - } - & $condaPythonPath ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} condaExecPath $condaExecPath - & $condaPythonPath ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} condaPath - & $condaExecPath init --all - - # 2. For `interpreterLocatorService.testvirtualenvs.ts` - - & $condaExecPath create -n "test_env1" -y python - & $condaExecPath create -p "./test_env2" -y python - & $condaExecPath create -p "~/test_env3" -y python - - - name: Run TypeScript unit tests - run: npm run test:unittests:cover - - - name: Run Python unit tests - run: | - python pythonFiles/tests/run_all.py - - # The virtual environment based tests use the `testSingleWorkspace` set of tests - # with the environment variable `TEST_FILES_SUFFIX` set to `testvirtualenvs`, - # which is set in the "Prepare environment for venv tests" step. - # We also use a third-party GitHub Action to install xvfb on Linux, - # run tests and then clean up the process once the tests ran. - # See https://github.com/GabrielBB/xvfb-action - - name: Run venv tests - env: - TEST_FILES_SUFFIX: testvirtualenvs - CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }} - CI_DISABLE_AUTO_SELECTION: 1 - uses: GabrielBB/xvfb-action@v1.5 - with: - run: npm run testSingleWorkspace:cover - - - name: Run single-workspace tests - env: - CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }} - CI_DISABLE_AUTO_SELECTION: 1 - uses: GabrielBB/xvfb-action@v1.5 - with: - run: npm run testSingleWorkspace:cover - - # Enable these tests when coverage is setup for multiroot workspace tests - # - name: Run multi-workspace tests - # env: - # CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }} - # CI_DISABLE_AUTO_SELECTION: 1 - # uses: GabrielBB/xvfb-action@v1.5 - # with: - # run: npm run testMultiWorkspace:cover - - # Enable these tests when coverage is setup for debugger tests - # - name: Run debugger tests - # env: - # CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }} - # CI_DISABLE_AUTO_SELECTION: 1 - # uses: GabrielBB/xvfb-action@v1.5 - # with: - # run: npm run testDebugger:cover - - # Run TypeScript functional tests - - name: Run TypeScript functional tests - env: - CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }} - CI_DISABLE_AUTO_SELECTION: 1 - run: npm run test:functional:cover - - - name: Generate coverage reports - run: npm run test:cover:report - - - name: Upload HTML report - uses: actions/upload-artifact@v2 - with: - name: ${{ runner.os }}-coverage-report-html - path: ./coverage - retention-days: 1 diff --git a/src/client/common/configSettings.ts b/src/client/common/configSettings.ts index 73c2ac56a96c..b751f4e47bae 100644 --- a/src/client/common/configSettings.ts +++ b/src/client/common/configSettings.ts @@ -41,7 +41,6 @@ import { ITerminalSettings, Resource, } from './types'; -import { debounceSync } from './utils/decorators'; import { SystemVariables } from './variables/systemVariables'; import { getOSType, OSType } from './utils/platform'; @@ -550,11 +549,16 @@ export class PythonSettings implements IPythonSettings { public initialize(): void { const onDidChange = () => { const currentConfig = this.workspace.getConfiguration('python', this.workspaceRoot); + console.log(`Before update [default]: ${this.defaultInterpreterPath}`); + console.log(`Before update [python]: ${this.pythonPath}`); + console.log(`Changed path [default]: ${currentConfig.get('defaultInterpreterPath')}`); + console.log('Inspect path [default]', JSON.stringify(currentConfig.inspect('defaultInterpreterPath'))); + console.log(`Changed path [python]: ${currentConfig.get('pythonPath')}`); this.update(currentConfig); + console.log(`After update [default]: ${this.defaultInterpreterPath}`); + console.log(`After update [python]: ${this.pythonPath}`); - // If workspace config changes, then we could have a cascading effect of on change events. - // Let's defer the change notification. - this.debounceChangeNotification(); + this.changed.fire(); }; this.disposables.push(this.workspace.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged, this)); this.disposables.push( @@ -577,11 +581,6 @@ export class PythonSettings implements IPythonSettings { } } - @debounceSync(1) - protected debounceChangeNotification(): void { - this.changed.fire(); - } - private getPythonPath( pythonSettings: WorkspaceConfiguration, systemVariables: SystemVariables, @@ -594,6 +593,7 @@ export class PythonSettings implements IPythonSettings { * `pythonPath` setting, and I've checked that `pythonPath` setting is not accessed anywhere in the constructor. */ const inExperiment = this.experimentsManager?.inExperimentSync(DeprecatePythonPath.experiment); + console.log('I should be in experiment', inExperiment); // Use the interpreter path service if in the experiment otherwise use the normal settings this.pythonPath = systemVariables.resolveAny( inExperiment && this.interpreterPathService diff --git a/src/client/common/interpreterPathService.ts b/src/client/common/interpreterPathService.ts index e3607323702f..d0ec3beef722 100644 --- a/src/client/common/interpreterPathService.ts +++ b/src/client/common/interpreterPathService.ts @@ -74,6 +74,7 @@ export class InterpreterPathService implements IInterpreterPathService { const defaultInterpreterPath = this.workspaceService .getConfiguration('python', resource)! .inspect('defaultInterpreterPath')!; + console.log('DEFAULT SETTING', JSON.stringify(defaultInterpreterPath), resource?.fsPath); return { globalValue: defaultInterpreterPath.globalValue, workspaceFolderValue: workspaceFolderSetting?.value || defaultInterpreterPath.workspaceFolderValue, @@ -83,6 +84,7 @@ export class InterpreterPathService implements IInterpreterPathService { public get(resource: Resource): string { const settings = this.inspect(resource); + console.log('SETTING', JSON.stringify(settings)); return ( settings.workspaceFolderValue || settings.workspaceValue || diff --git a/src/client/common/terminal/activator/base.ts b/src/client/common/terminal/activator/base.ts index 93ee13ccaaf0..e7d39d8ccd2f 100644 --- a/src/client/common/terminal/activator/base.ts +++ b/src/client/common/terminal/activator/base.ts @@ -14,6 +14,7 @@ export class BaseTerminalActivator implements ITerminalActivator { terminal: Terminal, options?: TerminalActivationOptions, ): Promise { + console.log('INSIDE: BaseTerminalActivator.activateEnvironmentInTerminal'); if (this.activatedTerminals.has(terminal)) { return this.activatedTerminals.get(terminal)!; } @@ -24,15 +25,17 @@ export class BaseTerminalActivator implements ITerminalActivator { const activationCommands = await this.helper.getEnvironmentActivationCommands( terminalShellType, options?.resource, - options?.interpreter, ); + console.log(`ACTIVATION COMMAND: ${activationCommands?.join(' ')}`); let activated = false; if (activationCommands) { for (const command of activationCommands) { terminal.show(options?.preserveFocus); terminal.sendText(command); + console.log(`ACTIVATION COMMAND (sent): ${command}`); await this.waitForCommandToProcess(terminalShellType); activated = true; + console.log(`ACTIVATED`); } } deferred.resolve(activated); diff --git a/src/client/common/terminal/activator/index.ts b/src/client/common/terminal/activator/index.ts index 5bc76c0cb0f8..76c79dd48486 100644 --- a/src/client/common/terminal/activator/index.ts +++ b/src/client/common/terminal/activator/index.ts @@ -36,9 +36,11 @@ export class TerminalActivator implements ITerminalActivator { terminal: Terminal, options?: TerminalActivationOptions, ): Promise { + console.log('INSIDE: TerminalActivator.activateEnvironmentInTerminalImpl'); const settings = this.configurationService.getSettings(options?.resource); const activateEnvironment = settings.terminal.activateEnvironment; if (!activateEnvironment || options?.hideFromUser) { + console.log('SKIPPED ACTIVATION'); return false; } diff --git a/src/client/common/terminal/helper.ts b/src/client/common/terminal/helper.ts index 283e4bec8ba1..54666c74d239 100644 --- a/src/client/common/terminal/helper.ts +++ b/src/client/common/terminal/helper.ts @@ -130,18 +130,24 @@ export class TerminalHelper implements ITerminalHelper { providers: ITerminalActivationCommandProvider[], ): Promise { const settings = this.configurationService.getSettings(resource); + console.log(`ACTIVATION TYPE: ${interpreter?.envType}`); + const details = await this.serviceContainer + .get(IInterpreterService) + .getInterpreterDetails(interpreter ? interpreter.path : settings.pythonPath); + + console.log(interpreter ? interpreter.path : settings.pythonPath, 'DETAILS:', JSON.stringify(details)); const experimentService = this.serviceContainer.get(IExperimentService); const condaService = (await inDiscoveryExperiment(experimentService)) ? this.serviceContainer.get(IComponentAdapter) : this.serviceContainer.get(ICondaLocatorService); // If we have a conda environment, then use that. - const isCondaEnvironment = interpreter - ? interpreter.envType === EnvironmentType.Conda + const isCondaEnvironment = details + ? details.envType === EnvironmentType.Conda : await condaService.isCondaEnvironment(settings.pythonPath); if (isCondaEnvironment) { - const activationCommands = interpreter - ? await this.conda.getActivationCommandsForInterpreter(interpreter.path, terminalShellType) + const activationCommands = details + ? await this.conda.getActivationCommandsForInterpreter(details.path, terminalShellType) : await this.conda.getActivationCommands(resource, terminalShellType); if (Array.isArray(activationCommands)) { @@ -153,8 +159,8 @@ export class TerminalHelper implements ITerminalHelper { const supportedProviders = providers.filter((provider) => provider.isShellSupported(terminalShellType)); for (const provider of supportedProviders) { - const activationCommands = interpreter - ? await provider.getActivationCommandsForInterpreter(interpreter.path, terminalShellType) + const activationCommands = details + ? await provider.getActivationCommandsForInterpreter(details.path, terminalShellType) : await provider.getActivationCommands(resource, terminalShellType); if (Array.isArray(activationCommands) && activationCommands.length > 0) { diff --git a/src/client/common/terminal/service.ts b/src/client/common/terminal/service.ts index 7128d27802f8..e47af08228c7 100644 --- a/src/client/common/terminal/service.ts +++ b/src/client/common/terminal/service.ts @@ -87,7 +87,6 @@ export class TerminalService implements ITerminalService, Disposable { await this.terminalActivator.activateEnvironmentInTerminal(this.terminal!, { resource: this.options?.resource, preserveFocus, - interpreter: this.options?.interpreter, hideFromUser: this.options?.hideFromUser, }); diff --git a/src/client/common/terminal/types.ts b/src/client/common/terminal/types.ts index e02fa1c03fd7..7726a22dad18 100644 --- a/src/client/common/terminal/types.ts +++ b/src/client/common/terminal/types.ts @@ -121,7 +121,6 @@ export const ITerminalActivator = Symbol('ITerminalActivator'); export type TerminalActivationOptions = { resource?: Resource; preserveFocus?: boolean; - interpreter?: PythonEnvironment; /** * When sending commands to the terminal, do not display the terminal. * diff --git a/src/client/terminals/activation.ts b/src/client/terminals/activation.ts index 4963ef08cd88..97cdf9b4af3f 100644 --- a/src/client/terminals/activation.ts +++ b/src/client/terminals/activation.ts @@ -44,10 +44,13 @@ export class TerminalAutoActivation implements ITerminalAutoActivation { } private async activateTerminal(terminal: Terminal): Promise { + console.log('INSIDE: activateTerminal'); if (this.terminalsNotToAutoActivate.has(terminal)) { + console.log('SKIPPED due to: terminalsNotToAutoActivate'); return; } if ('hideFromUser' in terminal.creationOptions && terminal.creationOptions.hideFromUser) { + console.log('SKIPPED due to: hideFromUser'); return; } // If we have just one workspace, then pass that as the resource. diff --git a/src/test/common.ts b/src/test/common.ts index 4d5ab04d71aa..65b6d05d5157 100644 --- a/src/test/common.ts +++ b/src/test/common.ts @@ -119,14 +119,14 @@ export const resetGlobalInterpreterPathSetting = async () => retryAsync(restoreG async function restoreGlobalInterpreterPathSetting(): Promise { const vscode = require('vscode') as typeof import('vscode'); - const pythonConfig = vscode.workspace.getConfiguration('python', (null as any) as Uri); - await pythonConfig.update('defaultInterpreterPath', undefined, true); + const pythonConfig = vscode.workspace.getConfiguration('python'); + await pythonConfig.update('defaultInterpreterPath', undefined, false); await disposePythonSettings(); } async function setGlobalPathToInterpreter(pythonPath?: string): Promise { const vscode = require('vscode') as typeof import('vscode'); - const pythonConfig = vscode.workspace.getConfiguration('python', (null as any) as Uri); - await pythonConfig.update('defaultInterpreterPath', pythonPath, true); + const pythonConfig = vscode.workspace.getConfiguration('python'); + await pythonConfig.update('defaultInterpreterPath', pythonPath, false); await disposePythonSettings(); } export const resetGlobalPythonPathSetting = async () => retryAsync(restoreGlobalPythonPathSetting)(); @@ -232,10 +232,10 @@ async function setPythonPathInWorkspace( } async function restoreGlobalPythonPathSetting(): Promise { const vscode = require('vscode') as typeof import('vscode'); - const pythonConfig = vscode.workspace.getConfiguration('python', (null as any) as Uri); + const pythonConfig = vscode.workspace.getConfiguration('python'); await Promise.all([ - pythonConfig.update('pythonPath', undefined, true), - pythonConfig.update('defaultInterpreterPath', undefined, true), + pythonConfig.update('pythonPath', undefined, false), + pythonConfig.update('defaultInterpreterPath', undefined, false), ]); await disposePythonSettings(); } diff --git a/src/test/common/terminals/environmentActivationProviders/terminalActivation.testvirtualenvs.ts b/src/test/common/terminals/environmentActivationProviders/terminalActivation.testvirtualenvs.ts index 1fe20c50f337..ca69d2da2ad2 100644 --- a/src/test/common/terminals/environmentActivationProviders/terminalActivation.testvirtualenvs.ts +++ b/src/test/common/terminals/environmentActivationProviders/terminalActivation.testvirtualenvs.ts @@ -11,6 +11,7 @@ import * as vscode from 'vscode'; import { DeprecatePythonPath } from '../../../../client/common/experiments/groups'; import { FileSystem } from '../../../../client/common/platform/fileSystem'; import { IExperimentService } from '../../../../client/common/types'; +import { createDeferred } from '../../../../client/common/utils/async'; import { PYTHON_VIRTUAL_ENVS_LOCATION } from '../../../ciConstants'; import { PYTHON_PATH, @@ -135,11 +136,23 @@ suite('Activation of Environments in Terminal', () => { logFile: string, logFileCreationWaitMs: number, ): Promise { - const terminal = vscode.window.createTerminal(); - await sleep(consoleInitWaitMs); + let terminal: vscode.Terminal; + const waitForTerminal = createDeferred(); + const dispose = vscode.window.onDidWriteTerminalData((e) => { + if (e.terminal.processId === terminal.processId && e.data.toLowerCase().includes('activ')) { + console.log(`TERMINAL WRITE: ${e.data}`); + waitForTerminal.resolve(); + } + }); + terminal = vscode.window.createTerminal(); + await Promise.race([waitForTerminal.promise, sleep(consoleInitWaitMs)]); + terminal.sendText(`python ${pythonFile.toCommandArgument()} ${logFile.toCommandArgument()}`, true); await waitForCondition(() => fs.pathExists(logFile), logFileCreationWaitMs, `${logFile} file not created.`); + if (dispose) { + dispose.dispose(); + } return fs.readFile(logFile, 'utf-8'); } @@ -158,13 +171,16 @@ suite('Activation of Environments in Terminal', () => { vscode.workspace.workspaceFolders![0].uri, vscode.ConfigurationTarget.WorkspaceFolder, ); - if (experiments.inExperimentSync(DeprecatePythonPath.experiment)) { - await setGlobalInterpreterPath(envPath); - } else { - await setPythonPathInWorkspaceRoot(envPath); - } + + await setGlobalInterpreterPath(envPath); + await setPythonPathInWorkspaceRoot(envPath); + const content = await openTerminalAndAwaitCommandContent(waitTimeForActivation, file, outputFile, 5_000); - expect(fileSystem.arePathsSame(content, envPath)).to.equal(true, 'Environment not activated'); + console.log('COMPARING PATHS'); + expect(fileSystem.arePathsSame(content, envPath)).to.equal( + true, + `Environment not activated ${content} != ${envPath}`, + ); } test('Should not activate', async () => { @@ -182,15 +198,22 @@ suite('Activation of Environments in Terminal', () => { if (process.env.CI_PYTHON_VERSION && process.env.CI_PYTHON_VERSION.startsWith('2.')) { this.skip(); } + console.log(`STARTED: venv test`); await testActivation(envPaths.venvPath); + console.log(`DONE: venv test`); }); test('Should activate with pipenv', async () => { + console.log(`STARTED: pipenv test`); await testActivation(envPaths.pipenvPath); + console.log(`DONE: pipenv test`); }); test('Should activate with virtualenv', async () => { + console.log(`STARTED: virtualenv test`); await testActivation(envPaths.virtualEnvPath); + console.log(`DONE: virtualenv test`); }); test('Should activate with conda', async function () { + console.log(`STARTED: conda test`); this.skip(); // Powershell does not work with conda by default, hence use cmd. await terminalSettings.update( @@ -200,5 +223,6 @@ suite('Activation of Environments in Terminal', () => { ); await pythonSettings.update('condaPath', envPaths.condaExecPath, vscode.ConfigurationTarget.Workspace); await testActivation(envPaths.condaPath); + console.log(`DONE: conda test`); }).timeout(TEST_TIMEOUT * 2); }); diff --git a/src/test/common/terminals/service.unit.test.ts b/src/test/common/terminals/service.unit.test.ts index 2f0d86f4000f..6da0eca6aed4 100644 --- a/src/test/common/terminals/service.unit.test.ts +++ b/src/test/common/terminals/service.unit.test.ts @@ -11,7 +11,6 @@ import { ITerminalActivator, ITerminalHelper, TerminalShellType } from '../../.. import { IDisposableRegistry } from '../../../client/common/types'; import { IServiceContainer } from '../../../client/ioc/types'; import { ITerminalAutoActivation } from '../../../client/terminals/types'; -import { createPythonInterpreter } from '../../utils/interpreters'; suite('Terminal Service', () => { let service: TerminalService; @@ -253,22 +252,22 @@ suite('Terminal Service', () => { eventHandler!.bind(service)(terminal.object); expect(eventFired).to.be.equal(true, 'Event not fired'); }); - test('Ensure to disable auto activation and right interpreter is activated', async () => { - const interpreter = createPythonInterpreter({ path: 'abc' }); - service = new TerminalService(mockServiceContainer.object, { interpreter }); - - terminalHelper.setup((h) => h.identifyTerminalShell(TypeMoq.It.isAny())).returns(() => TerminalShellType.bash); - terminalManager.setup((t) => t.createTerminal(TypeMoq.It.isAny())).returns(() => terminal.object); - - // This will create the terminal. - await service.sendText('blah'); - - // Ensure we disable auto activation of the terminal. - terminalAutoActivator.verify((t) => t.disableAutoActivation(terminal.object), TypeMoq.Times.once()); - // Ensure the terminal is activated with the interpreter info. - terminalActivator.verify( - (t) => t.activateEnvironmentInTerminal(terminal.object, TypeMoq.It.isObjectWith({ interpreter })), - TypeMoq.Times.once(), - ); - }); + // test('Ensure to disable auto activation and right interpreter is activated', async () => { + // const interpreter = createPythonInterpreter({ path: 'abc' }); + // service = new TerminalService(mockServiceContainer.object, { interpreter }); + + // terminalHelper.setup((h) => h.identifyTerminalShell(TypeMoq.It.isAny())).returns(() => TerminalShellType.bash); + // terminalManager.setup((t) => t.createTerminal(TypeMoq.It.isAny())).returns(() => terminal.object); + + // // This will create the terminal. + // await service.sendText('blah'); + + // // Ensure we disable auto activation of the terminal. + // terminalAutoActivator.verify((t) => t.disableAutoActivation(terminal.object), TypeMoq.Times.once()); + // // Ensure the terminal is activated with the interpreter info. + // terminalActivator.verify( + // (t) => t.activateEnvironmentInTerminal(terminal.object, TypeMoq.It.isObjectWith({ interpreter })), + // TypeMoq.Times.once(), + // ); + // }); }); diff --git a/src/test/initialize.ts b/src/test/initialize.ts index 559a033e1a3b..9ad7cc0a9157 100644 --- a/src/test/initialize.ts +++ b/src/test/initialize.ts @@ -61,7 +61,7 @@ export async function initializeTest(): Promise { } export async function closeActiveWindows(): Promise { await closeActiveNotebooks(); - await closeWindowsInteral(); + await closeWindowsInternal(); } export async function closeActiveNotebooks(): Promise { if (!vscode.env.appName.toLowerCase().includes('insiders') || !isANotebookOpen()) { @@ -76,11 +76,11 @@ export async function closeActiveNotebooks(): Promise { // Hence keep trying. for (let counter = 0; counter <= 5 && isANotebookOpen(); counter += 1) { await sleep(counter * 100); - await closeWindowsInteral(); + await closeWindowsInternal(); } } -async function closeWindowsInteral() { +async function closeWindowsInternal() { return new Promise((resolve, reject) => { // Attempt to fix #1301. // Lets not waste too much time. diff --git a/types/vscode.proposed.d.ts b/types/vscode.proposed.d.ts index 3550b5c667e9..3c6c38cefd59 100644 --- a/types/vscode.proposed.d.ts +++ b/types/vscode.proposed.d.ts @@ -751,16 +751,16 @@ declare module 'vscode' { } export interface QuickPick extends QuickInput { - /** - * An optional flag to sort the final results by index of first query match in label. Defaults to true. - */ - sortByLabel: boolean; + /** + * An optional flag to sort the final results by index of first query match in label. Defaults to true. + */ + sortByLabel: boolean; - /* - * An optional flag that can be set to true to maintain the scroll position of the quick pick when the quick pick items are updated. Defaults to false. - */ - keepScrollPosition?: boolean; - } + /* + * An optional flag that can be set to true to maintain the scroll position of the quick pick when the quick pick items are updated. Defaults to false. + */ + keepScrollPosition?: boolean; + } export enum NotebookCellExecutionState { Idle = 1, @@ -1603,5 +1603,29 @@ declare module 'vscode' { */ readonly messages: ReadonlyArray; } + + //#region Terminal data write event https://github.com/microsoft/vscode/issues/78502 + + export interface TerminalDataWriteEvent { + /** + * The {@link Terminal} for which the data was written. + */ + readonly terminal: Terminal; + /** + * The data being written. + */ + readonly data: string; + } + + namespace window { + /** + * An event which fires when the terminal's child pseudo-device is written to (the shell). + * In other words, this provides access to the raw data stream from the process running + * within the terminal, including VT sequences. + */ + export const onDidWriteTerminalData: Event; + } + + //#endregion } //#endregion