diff --git a/extension/package.json b/extension/package.json index c9526d6d88..bf00122735 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1654,8 +1654,8 @@ "@types/vscode": "1.64.0", "@vscode/test-electron": "2.3.0", "@vscode/vsce": "2.18.0", - "@wdio/cli": "8.5.1", - "@wdio/local-runner": "8.5.4", + "@wdio/cli": "8.5.5", + "@wdio/local-runner": "8.5.5", "@wdio/mocha-framework": "8.4.0", "@wdio/spec-reporter": "8.4.0", "chai": "4.3.7", @@ -1665,7 +1665,7 @@ "fork-ts-checker-webpack-plugin": "7.3.0", "jest": "29.4.3", "jest-environment-node": "29.4.3", - "lint-staged": "13.1.2", + "lint-staged": "13.1.3", "mocha": "10.2.0", "mock-require": "3.0.3", "process-exists": "4.1.0", @@ -1675,7 +1675,7 @@ "ts-loader": "9.4.2", "vscode-uri": "3.0.7", "wdio-vscode-service": "5.0.0", - "webdriverio": "8.5.1", + "webdriverio": "8.5.5", "webpack": "5.75.0", "webpack-cli": "5.0.1" }, diff --git a/extension/src/cli/dvc/reader.test.ts b/extension/src/cli/dvc/reader.test.ts index 3780576ad3..b372ba6deb 100644 --- a/extension/src/cli/dvc/reader.test.ts +++ b/extension/src/cli/dvc/reader.test.ts @@ -12,6 +12,7 @@ import { getProcessEnv } from '../../env' import expShowFixture from '../../test/fixtures/expShow/base/output' import plotsDiffFixture from '../../test/fixtures/plotsDiff/output/minimal' import { Config } from '../../config' +import { joinEnvPath } from '../../util/env' jest.mock('vscode') jest.mock('@hediet/std/disposable') @@ -31,6 +32,8 @@ const mockedEnv = { } const JSON_FLAG = '--json' +const mockedGetPythonBinPath = jest.fn() + beforeEach(() => { jest.resetAllMocks() mockedGetProcessEnv.mockReturnValueOnce(mockedEnv) @@ -49,7 +52,7 @@ describe('CliReader', () => { const dvcReader = new DvcReader( { getCliPath: () => undefined, - getPythonBinPath: () => undefined + getPythonBinPath: mockedGetPythonBinPath } as unknown as Config, { processCompleted: { @@ -144,6 +147,33 @@ describe('CliReader', () => { }) }) + describe('globalVersion', () => { + it('should call execute process with the correct parameters (does not respect pythonBinPath)', async () => { + const cwd = __dirname + const stdout = '3.9.11' + mockedCreateProcess.mockReturnValueOnce(getMockedProcess(stdout)) + mockedGetPythonBinPath.mockReturnValueOnce('python') + const output = await dvcReader.globalVersion(cwd) + + expect(output).toStrictEqual(stdout) + expect(mockedCreateProcess).toHaveBeenCalledWith({ + args: ['--version'], + cwd, + env: mockedEnv, + executable: 'dvc' + }) + }) + + it('should not retry if the process fails (cannot find cli - extension should reset)', async () => { + const cwd = __dirname + mockedCreateProcess.mockImplementationOnce(() => { + throw new Error('spawn dvc ENOENT retrying...') + }) + + await expect(dvcReader.globalVersion(cwd)).rejects.toBeTruthy() + }) + }) + describe('plotsDiff', () => { it('should handle empty output being returned', async () => { const cwd = __dirname @@ -229,6 +259,27 @@ describe('CliReader', () => { }) }) + it('should respect the pythonBinPath parameters', async () => { + const cwd = __dirname + const stdout = '2.47.0' + const mockedPythonPath = 'some/python/path' + const mockedPythonBinPath = [mockedPythonPath, 'python'].join('/') + mockedGetPythonBinPath.mockReturnValue(mockedPythonBinPath) + mockedCreateProcess.mockReturnValueOnce(getMockedProcess(stdout)) + const output = await dvcReader.version(cwd) + + expect(output).toStrictEqual(stdout) + expect(mockedCreateProcess).toHaveBeenCalledWith({ + args: ['-m', 'dvc', '--version'], + cwd, + env: { + ...mockedEnv, + PATH: joinEnvPath(mockedPythonPath, mockedEnv.PATH) + }, + executable: mockedPythonBinPath + }) + }) + it('should not retry if the process fails (cannot find cli - extension should reset)', async () => { const cwd = __dirname mockedCreateProcess.mockImplementationOnce(() => { diff --git a/extension/src/cli/dvc/reader.ts b/extension/src/cli/dvc/reader.ts index dc10f92b8a..26fb8a19ca 100644 --- a/extension/src/cli/dvc/reader.ts +++ b/extension/src/cli/dvc/reader.ts @@ -37,8 +37,11 @@ export const isDvcError = < export const autoRegisteredCommands = { DATA_STATUS: 'dataStatus', EXP_SHOW: 'expShow', + GLOBAL_VERSION: 'globalVersion', PLOTS_DIFF: 'plotsDiff', - STAGE_LIST: 'listStages' + ROOT: 'root', + STAGE_LIST: 'listStages', + VERSION: 'version' } as const export class DvcReader extends DvcCli { @@ -104,9 +107,13 @@ export class DvcReader extends DvcCli { } catch {} } - public version(cwd: string, isCliGlobal?: true): Promise { + public version(cwd: string): Promise { + return this.executeDvcProcess(cwd, Flag.VERSION) + } + + public globalVersion(cwd: string): Promise { const options = getOptions( - isCliGlobal ? undefined : this.config.getPythonBinPath(), + undefined, this.config.getCliPath(), cwd, Flag.VERSION diff --git a/extension/src/cli/git/executor.ts b/extension/src/cli/git/executor.ts index 69e4cff63d..008e4b3ea4 100644 --- a/extension/src/cli/git/executor.ts +++ b/extension/src/cli/git/executor.ts @@ -4,6 +4,7 @@ import { getOptions } from './options' import { typeCheckCommands } from '..' export const autoRegisteredCommands = { + GIT_INIT: 'gitInit', GIT_PUSH_BRANCH: 'pushBranch', GIT_RESET_WORKSPACE: 'resetWorkspace', GIT_STAGE_ALL: 'stageAll', @@ -17,7 +18,7 @@ export class GitExecutor extends GitCli { this ) - public init(cwd: string) { + public gitInit(cwd: string) { const options = getOptions(cwd, Command.INITIALIZE) return this.executeProcess(options) diff --git a/extension/src/cli/git/reader.ts b/extension/src/cli/git/reader.ts index 92a958b597..52abb6e15a 100644 --- a/extension/src/cli/git/reader.ts +++ b/extension/src/cli/git/reader.ts @@ -11,6 +11,7 @@ export const autoRegisteredCommands = { GIT_GET_REMOTE_URL: 'getRemoteUrl', GIT_GET_REPOSITORY_ROOT: 'getGitRepositoryRoot', GIT_HAS_CHANGES: 'hasChanges', + GIT_HAS_NO_COMMITS: 'hasNoCommits', GIT_LIST_UNTRACKED: 'listUntracked' } as const diff --git a/extension/src/extension.ts b/extension/src/extension.ts index ad29e06aaa..0e03ec6d01 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -56,7 +56,10 @@ import { LanguageClient } from './languageClient' import { collectRunningExperimentPids } from './experiments/processExecution/collect' import { registerPatchCommand } from './patch' import { DvcViewer } from './cli/dvc/viewer' +import { registerSetupCommands } from './setup/register' +import { Status } from './status' import { registerPersistenceCommands } from './persistence/register' + export class Extension extends Disposable { protected readonly internalCommands: InternalCommands @@ -132,6 +135,8 @@ export class Extension extends Disposable { new InternalCommands(outputChannel, ...clis) ) + const status = this.dispose.track(new Status(config, ...clis)) + this.experiments = this.dispose.track( new WorkspaceExperiments( this.internalCommands, @@ -184,18 +189,14 @@ export class Extension extends Disposable { this.setup = this.dispose.track( new Setup( - stopWatch, config, - this.dvcExecutor, - this.dvcReader, - this.dvcRunner, - this.gitExecutor, - this.gitReader, - () => this.initialize(), - () => this.resetMembers(), - this.experiments, this.internalCommands, + this.experiments, + status, this.resourceLocator.dvcIcon, + stopWatch, + () => this.initialize(), + () => this.resetMembers(), () => collectWorkspaceScale( this.getRoots(), @@ -216,6 +217,7 @@ export class Extension extends Disposable { this.connect ) registerPlotsCommands(this.plots, this.internalCommands, this.setup) + registerSetupCommands(this.setup, this.internalCommands) this.internalCommands.registerExternalCommand( RegisteredCommands.EXPERIMENT_AND_PLOTS_SHOW, async (context: VsCodeContext) => { diff --git a/extension/src/setup/index.ts b/extension/src/setup/index.ts index 84466a7d04..053db1d4de 100644 --- a/extension/src/setup/index.ts +++ b/extension/src/setup/index.ts @@ -1,4 +1,4 @@ -import { Event, EventEmitter, ViewColumn, commands } from 'vscode' +import { Event, EventEmitter, ViewColumn } from 'vscode' import { Disposable, Disposer } from '@hediet/std/disposable' import isEmpty from 'lodash.isempty' import { SetupData as TSetupData } from './webview/contract' @@ -25,16 +25,11 @@ import { getWorkspaceFolderCount, getWorkspaceFolders } from '../vscode/workspaceFolders' -import { DvcReader } from '../cli/dvc/reader' import { ContextKey, setContextValue } from '../vscode/context' -import { DvcExecutor } from '../cli/dvc/executor' -import { GitReader } from '../cli/git/reader' -import { GitExecutor } from '../cli/git/executor' -import { RegisteredCliCommands, RegisteredCommands } from '../commands/external' -import { InternalCommands } from '../commands/internal' +import { RegisteredCommands } from '../commands/external' +import { AvailableCommands, InternalCommands } from '../commands/internal' import { Status } from '../status' import { WorkspaceExperiments } from '../experiments/workspace' -import { DvcRunner } from '../cli/dvc/runner' import { sendTelemetryEvent, sendTelemetryEventAndThrow } from '../telemetry' import { StopWatch } from '../util/time' import { getRelativePattern } from '../fileSystem/relativePattern' @@ -59,11 +54,8 @@ export class Setup private dvcRoots: string[] = [] private readonly config: Config - private readonly dvcReader: DvcReader - private readonly dvcExecutor: DvcExecutor - private readonly gitReader: GitReader - private readonly gitExecutor: GitExecutor private readonly status: Status + private readonly internalCommands: InternalCommands private readonly webviewMessages: WebviewMessages private readonly showExperiments: () => void @@ -83,38 +75,23 @@ export class Setup private dotFolderWatcher?: Disposer constructor( - stopWatch: StopWatch, config: Config, - dvcExecutor: DvcExecutor, - dvcReader: DvcReader, - dvcRunner: DvcRunner, - gitExecutor: GitExecutor, - gitReader: GitReader, - initialize: () => Promise, - resetMembers: () => void, - experiments: WorkspaceExperiments, internalCommands: InternalCommands, + experiments: WorkspaceExperiments, + status: Status, webviewIcon: Resource, + stopWatch: StopWatch, + initialize: () => Promise, + resetMembers: () => void, collectWorkspaceScale: () => Promise ) { super(GLOBAL_WEBVIEW_DVCROOT, webviewIcon) this.config = config - this.dvcExecutor = dvcExecutor - this.dvcReader = dvcReader - this.gitExecutor = gitExecutor - this.gitReader = gitReader - - this.status = this.dispose.track( - new Status( - this.config, - this.dvcExecutor, - this.dvcReader, - dvcRunner, - this.gitExecutor, - this.gitReader - ) - ) + + this.internalCommands = internalCommands + + this.status = status this.initialize = initialize this.resetMembers = resetMembers @@ -134,8 +111,6 @@ export class Setup void experiments.showWebview(this.dvcRoots[0], ViewColumn.Active) } - this.registerCommands(internalCommands) - this.getHasData = () => experiments.getHasData() const onDidChangeHasData = experiments.columnsChanged.event this.dispose.track( @@ -161,7 +136,16 @@ export class Setup public async getCliVersion(cwd: string, tryGlobalCli?: true) { await this.config.isReady() try { - return await this.dvcReader.version(cwd, tryGlobalCli) + if (tryGlobalCli) { + return await this.internalCommands.executeCommand( + AvailableCommands.GLOBAL_VERSION, + cwd + ) + } + return await this.internalCommands.executeCommand( + AvailableCommands.VERSION, + cwd + ) } catch {} } @@ -257,10 +241,50 @@ export class Setup }) } + public async selectFocusedProjects() { + const dvcRoots = await this.findWorkspaceDvcRoots() + const focusedProjects = await pickFocusedProjects(dvcRoots, this.getRoots()) + if (focusedProjects) { + this.config.setFocusedProjectsOption(focusedProjects) + } + } + + public async setupWorkspace() { + const stopWatch = new StopWatch() + try { + const previousCliPath = this.config.getCliPath() + const previousPythonPath = this.config.getPythonBinPath() + + const completed = await this.runWorkspace() + sendTelemetryEvent( + RegisteredCommands.EXTENSION_SETUP_WORKSPACE, + { completed }, + { + duration: stopWatch.getElapsedTime() + } + ) + + const executionDetailsUnchanged = + this.config.getCliPath() === previousPythonPath && + this.config.getPythonBinPath() === previousCliPath + + if (completed && !this.cliAccessible && executionDetailsUnchanged) { + this.workspaceChanged.fire() + } + + return completed + } catch (error: unknown) { + return sendTelemetryEventAndThrow( + RegisteredCommands.EXTENSION_SETUP_WORKSPACE, + error as Error, + stopWatch.getElapsedTime() + ) + } + } + private createWebviewMessageHandler() { const webviewMessages = new WebviewMessages( () => this.getWebview(), - () => this.initializeDvc(), () => this.initializeGit() ) this.dispose.track( @@ -271,7 +295,7 @@ export class Setup return webviewMessages } - private async findWorkspaceDvcRoots(): Promise { + private async findWorkspaceDvcRoots() { let dvcRoots: Set = new Set() for (const workspaceFolder of getWorkspaceFolders()) { @@ -284,7 +308,10 @@ export class Setup await this.config.isReady() const absoluteRoot = await findAbsoluteDvcRootPath( workspaceFolder, - this.dvcReader.root(workspaceFolder) + this.internalCommands.executeCommand( + AvailableCommands.ROOT, + workspaceFolder + ) ) if (absoluteRoot) { dvcRoots.add(absoluteRoot) @@ -310,13 +337,6 @@ export class Setup } } - private async initializeDvc() { - const root = getFirstWorkspaceFolder() - if (root) { - await this.dvcExecutor.init(root) - } - } - private async canGitInitialize(needsGitInit: boolean) { if (!needsGitInit) { return false @@ -341,7 +361,10 @@ export class Setup } try { - return !(await this.gitReader.getGitRepositoryRoot(cwd)) + return !(await this.internalCommands.executeCommand( + AvailableCommands.GIT_GET_REPOSITORY_ROOT, + cwd + )) } catch { return true } @@ -350,7 +373,7 @@ export class Setup private initializeGit() { const cwd = getFirstWorkspaceFolder() if (cwd) { - void this.gitExecutor.init(cwd) + void this.internalCommands.executeCommand(AvailableCommands.GIT_INIT, cwd) } } @@ -363,82 +386,12 @@ export class Setup if (!cwd) { return true } - return this.gitReader.hasNoCommits(cwd) - } - - private registerCommands(internalCommands: InternalCommands) { - internalCommands.registerExternalCliCommand( - RegisteredCliCommands.INIT, - () => this.initializeDvc() - ) - - internalCommands.registerExternalCommand( - RegisteredCommands.EXTENSION_CHECK_CLI_COMPATIBLE, - () => run(this) - ) - - this.dispose.track( - commands.registerCommand( - RegisteredCommands.EXTENSION_SETUP_WORKSPACE, - () => this.setupWorkspace() - ) - ) - - internalCommands.registerExternalCommand( - RegisteredCommands.SETUP_SHOW, - async () => { - await this.showSetup() - } - ) - - internalCommands.registerExternalCommand( - RegisteredCommands.SELECT_FOCUSED_PROJECTS, - async () => { - const dvcRoots = await this.findWorkspaceDvcRoots() - const focusedProjects = await pickFocusedProjects( - dvcRoots, - this.dvcRoots - ) - if (focusedProjects) { - this.config.setFocusedProjectsOption(focusedProjects) - } - } + return this.internalCommands.executeCommand( + AvailableCommands.GIT_HAS_NO_COMMITS, + cwd ) } - private async setupWorkspace() { - const stopWatch = new StopWatch() - try { - const previousCliPath = this.config.getCliPath() - const previousPythonPath = this.config.getPythonBinPath() - - const completed = await this.runWorkspace() - sendTelemetryEvent( - RegisteredCommands.EXTENSION_SETUP_WORKSPACE, - { completed }, - { - duration: stopWatch.getElapsedTime() - } - ) - - const executionDetailsUnchanged = - this.config.getCliPath() === previousPythonPath && - this.config.getPythonBinPath() === previousCliPath - - if (completed && !this.cliAccessible && executionDetailsUnchanged) { - this.workspaceChanged.fire() - } - - return completed - } catch (error: unknown) { - return sendTelemetryEventAndThrow( - RegisteredCommands.EXTENSION_SETUP_WORKSPACE, - error as Error, - stopWatch.getElapsedTime() - ) - } - } - private runWorkspace() { return runWorkspace(() => this.config.setPythonAndNotifyIfChanged()) } diff --git a/extension/src/setup/register.ts b/extension/src/setup/register.ts new file mode 100644 index 0000000000..04ab7474ff --- /dev/null +++ b/extension/src/setup/register.ts @@ -0,0 +1,50 @@ +import { commands } from 'vscode' +import { Setup } from '.' +import { run } from './runner' +import { AvailableCommands, InternalCommands } from '../commands/internal' +import { RegisteredCliCommands, RegisteredCommands } from '../commands/external' +import { getFirstWorkspaceFolder } from '../vscode/workspaceFolders' + +const registerSetupConfigCommands = ( + setup: Setup, + internalCommands: InternalCommands +): void => { + internalCommands.registerExternalCommand( + RegisteredCommands.EXTENSION_CHECK_CLI_COMPATIBLE, + () => run(setup) + ) + + setup.dispose.track( + commands.registerCommand(RegisteredCommands.EXTENSION_SETUP_WORKSPACE, () => + setup.setupWorkspace() + ) + ) + internalCommands.registerExternalCommand( + RegisteredCommands.SELECT_FOCUSED_PROJECTS, + () => setup.selectFocusedProjects() + ) +} + +export const registerSetupCommands = ( + setup: Setup, + internalCommands: InternalCommands +): void => { + internalCommands.registerExternalCliCommand( + RegisteredCliCommands.INIT, + async () => { + const root = getFirstWorkspaceFolder() + if (root) { + await internalCommands.executeCommand(AvailableCommands.INIT, root) + } + } + ) + + internalCommands.registerExternalCommand( + RegisteredCommands.SETUP_SHOW, + async () => { + await setup.showSetup() + } + ) + + registerSetupConfigCommands(setup, internalCommands) +} diff --git a/extension/src/setup/webview/messages.ts b/extension/src/setup/webview/messages.ts index 2d792773c5..2688973751 100644 --- a/extension/src/setup/webview/messages.ts +++ b/extension/src/setup/webview/messages.ts @@ -10,20 +10,20 @@ import { sendTelemetryEvent } from '../../telemetry' import { EventName } from '../../telemetry/constants' import { selectPythonInterpreter } from '../../extensions/python' import { autoInstallDvc } from '../autoInstall' -import { RegisteredCommands } from '../../commands/external' +import { + RegisteredCliCommands, + RegisteredCommands +} from '../../commands/external' export class WebviewMessages { private readonly getWebview: () => BaseWebview | undefined - private readonly initializeDvc: () => Promise private readonly initializeGit: () => void constructor( getWebview: () => BaseWebview | undefined, - initializeDvc: () => Promise, initializeGit: () => void ) { this.getWebview = getWebview - this.initializeDvc = initializeDvc this.initializeGit = initializeGit } @@ -65,7 +65,7 @@ export class WebviewMessages { RegisteredCommands.EXTENSION_CHECK_CLI_COMPATIBLE ) case MessageFromWebviewType.INITIALIZE_DVC: - return this.initializeDvc() + return commands.executeCommand(RegisteredCliCommands.INIT) case MessageFromWebviewType.INITIALIZE_GIT: return this.gitInit() case MessageFromWebviewType.SHOW_SCM_PANEL: diff --git a/extension/src/test/cli/util.ts b/extension/src/test/cli/util.ts index 5944de9030..36af17dc14 100644 --- a/extension/src/test/cli/util.ts +++ b/extension/src/test/cli/util.ts @@ -36,7 +36,7 @@ export const initializeEmptyRepo = async (): Promise => { return '' } - await gitExecutor.init(TEMP_DIR) + await gitExecutor.gitInit(TEMP_DIR) return dvcExecutor.init(TEMP_DIR) } diff --git a/extension/src/test/suite/setup/index.test.ts b/extension/src/test/suite/setup/index.test.ts index 13074a63c0..688e6f9bf0 100644 --- a/extension/src/test/suite/setup/index.test.ts +++ b/extension/src/test/suite/setup/index.test.ts @@ -16,7 +16,10 @@ import { MessageFromWebviewType } from '../../../webview/contract' import { Disposable } from '../../../extension' import { Logger } from '../../../common/logger' import { BaseWebview } from '../../../webview' -import { RegisteredCommands } from '../../../commands/external' +import { + RegisteredCliCommands, + RegisteredCommands +} from '../../../commands/external' import { isDirectory } from '../../../fileSystem' import { gitPath } from '../../../cli/git/constants' import { join } from '../../util/path' @@ -72,7 +75,7 @@ suite('Setup Test Suite', () => { }).timeout(WEBVIEW_TEST_TIMEOUT) it('should handle an initialize project message from the webview', async () => { - const { messageSpy, setup, mockInitializeDvc } = buildSetup(disposable) + const { messageSpy, mockExecuteCommand, setup } = buildSetup(disposable) const webview = await setup.showWebview() await webview.isReady() @@ -84,11 +87,13 @@ suite('Setup Test Suite', () => { type: MessageFromWebviewType.INITIALIZE_DVC }) - expect(mockInitializeDvc).to.be.calledOnce + expect(mockExecuteCommand).to.be.calledWithExactly( + RegisteredCliCommands.INIT + ) }).timeout(WEBVIEW_TEST_TIMEOUT) it('should handle a check cli compatible message from the webview', async () => { - const { messageSpy, setup, mockExecuteCommand } = buildSetup(disposable) + const { messageSpy, mockExecuteCommand, setup } = buildSetup(disposable) const webview = await setup.showWebview() await webview.isReady() @@ -122,7 +127,7 @@ suite('Setup Test Suite', () => { }).timeout(WEBVIEW_TEST_TIMEOUT) it('should handle a select Python interpreter message from the webview', async () => { - const { messageSpy, setup, mockExecuteCommand } = buildSetup(disposable) + const { messageSpy, mockExecuteCommand, setup } = buildSetup(disposable) const setInterpreterCommand = 'python.setInterpreter' const webview = await setup.showWebview() @@ -139,7 +144,7 @@ suite('Setup Test Suite', () => { }).timeout(WEBVIEW_TEST_TIMEOUT) it('should handle a show source control panel message from the webview', async () => { - const { messageSpy, setup, mockExecuteCommand } = buildSetup(disposable) + const { messageSpy, mockExecuteCommand, setup } = buildSetup(disposable) const showScmPanelCommand = 'workbench.view.scm' const webview = await setup.showWebview() @@ -156,7 +161,7 @@ suite('Setup Test Suite', () => { }).timeout(WEBVIEW_TEST_TIMEOUT) it('should handle a setup the workspace message from the webview', async () => { - const { messageSpy, setup, mockExecuteCommand } = buildSetup(disposable) + const { messageSpy, mockExecuteCommand, setup } = buildSetup(disposable) const webview = await setup.showWebview() await webview.isReady() @@ -194,11 +199,7 @@ suite('Setup Test Suite', () => { }).timeout(WEBVIEW_TEST_TIMEOUT) it('should close the webview and open the experiments when the setup is done', async () => { - const { setup, mockOpenExperiments } = buildSetup( - disposable, - undefined, - true - ) + const { setup, mockOpenExperiments } = buildSetup(disposable, true) const closeWebviewSpy = spy(BaseWebview.prototype, 'dispose') @@ -290,7 +291,6 @@ suite('Setup Test Suite', () => { it('should send the expected message to the webview when there is no DVC project in the workspace', async () => { const { config, setup, messageSpy } = buildSetup( disposable, - undefined, false, true, false, @@ -334,7 +334,6 @@ suite('Setup Test Suite', () => { it('should send the expected message to the webview when there is no commits in the git repository', async () => { const { config, setup, messageSpy } = buildSetup( disposable, - undefined, false, false, false, @@ -485,11 +484,10 @@ suite('Setup Test Suite', () => { }) it('should set dvc.pythonPath to the picked value when the user selects to pick a Python interpreter', async () => { - const { config, setup, mockExecuteCommand, mockVersion } = + const { config, mockVersion, mockExecuteCommand, setup } = buildSetup(disposable) mockExecuteCommand.restore() - stub(config, 'isPythonExtensionInstalled').returns(false) mockVersion.rejects('do not initialize') @@ -556,12 +554,13 @@ suite('Setup Test Suite', () => { it('should set the dvc.cli.incompatible context value', async () => { const { config, mockExecuteCommand, mockRunSetup, mockVersion, setup } = - buildSetup(disposable, undefined, true, false, false) + buildSetup(disposable, true, false, false) + + mockExecuteCommand.restore() mockRunSetup.restore() stub(config, 'isPythonExtensionUsed').returns(false) stub(config, 'getPythonBinPath').resolves(join('python')) - mockExecuteCommand.restore() mockVersion.resetBehavior() mockVersion .onFirstCall() @@ -606,5 +605,33 @@ suite('Setup Test Suite', () => { 'should warn the user if the CLI throws an error' ).to.be.calledOnce }) + + it('should call the CLI to see if there is a global version of DVC available if the Python version fails', async () => { + const { + config, + mockExecuteCommand, + mockGlobalVersion, + mockRunSetup, + mockVersion, + setup + } = buildSetup(disposable, true, false, false) + + mockExecuteCommand.restore() + mockRunSetup.restore() + stub(config, 'isPythonExtensionUsed').returns(true) + + mockVersion.resetBehavior() + mockVersion.rejects(new Error('no CLI here')) + + const executeCommandSpy = spy(commands, 'executeCommand') + await run(setup) + + expect(mockVersion).to.be.calledOnce + expect(mockGlobalVersion).to.be.calledOnce + expect( + executeCommandSpy, + 'should set dvc.cli.incompatible to false if the version is compatible' + ).to.be.calledWithExactly('setContext', 'dvc.cli.incompatible', false) + }) }) }) diff --git a/extension/src/test/suite/setup/util.ts b/extension/src/test/suite/setup/util.ts index d39ecb7314..878b901aff 100644 --- a/extension/src/test/suite/setup/util.ts +++ b/extension/src/test/suite/setup/util.ts @@ -1,124 +1,60 @@ import { join } from 'path' import { EventEmitter, commands } from 'vscode' import { Disposer } from '@hediet/std/disposable' -import { fake, SinonSpy, stub } from 'sinon' +import { fake, stub } from 'sinon' import { ensureDirSync } from 'fs-extra' import * as FileSystem from '../../../fileSystem' import { Setup } from '../../../setup' import * as Runner from '../../../setup/runner' import * as WorkspaceFolders from '../../../vscode/workspaceFolders' -import { buildDependencies, mockDisposable } from '../util' +import { buildDependencies } from '../util' import * as AutoInstall from '../../../setup/autoInstall' -import { DvcReader } from '../../../cli/dvc/reader' -import { DvcExecutor } from '../../../cli/dvc/executor' -import { GitReader } from '../../../cli/git/reader' -import { GitExecutor } from '../../../cli/git/executor' import { InternalCommands } from '../../../commands/internal' import { WorkspaceExperiments } from '../../../experiments/workspace' -import { DvcRunner } from '../../../cli/dvc/runner' import { StopWatch } from '../../../util/time' import { WorkspaceScale } from '../../../telemetry/collect' import { dvcDemoPath } from '../../util' import { Config } from '../../../config' -import { Resource, ResourceLocator } from '../../../resourceLocator' +import { Resource } from '../../../resourceLocator' import { MIN_CLI_VERSION } from '../../../cli/dvc/contract' +import { Status } from '../../../status' export const TEMP_DIR = join(dvcDemoPath, 'temp-empty-watcher-dir') -const buildSetupDependencies = ( - disposer: Disposer, - mockDvcRoot: string | undefined, - mockGitRoot: string | undefined, - noGitCommits = true -) => { - const mockEmitter = disposer.track(new EventEmitter()) - const mockEvent = mockEmitter.event - - const mockRoot = stub().resolves(mockDvcRoot) - const mockVersion = stub().resolves(MIN_CLI_VERSION) - const mockGetGitRepositoryRoot = stub().resolves(mockGitRoot) - const mockHasNoCommits = stub().resolves(noGitCommits) - - const mockInitializeDvc = fake() - const mockInitializeGit = fake() - stub(commands, 'registerCommand').returns(mockDisposable) - - return { - mockDvcExecutor: { - init: mockInitializeDvc, - onDidCompleteProcess: mockEvent, - onDidStartProcess: mockEvent - } as unknown as DvcExecutor, - mockDvcReader: { - onDidCompleteProcess: mockEvent, - onDidStartProcess: mockEvent, - root: mockRoot, - version: mockVersion - } as unknown as DvcReader, - mockDvcRunner: { - onDidCompleteProcess: mockEvent, - onDidStartProcess: mockEvent - } as DvcRunner, - mockEmitter, - mockExecuteCommand: stub(commands, 'executeCommand'), - mockGetGitRepositoryRoot, - mockGitExecutor: { - init: mockInitializeGit, - onDidCompleteProcess: mockEvent, - onDidStartProcess: mockEvent - } as unknown as GitExecutor, - mockGitReader: { - getGitRepositoryRoot: mockGetGitRepositoryRoot, - hasNoCommits: mockHasNoCommits, - onDidCompleteProcess: mockEvent, - onDidStartProcess: mockEvent - } as unknown as GitReader, - mockInitializeDvc, - mockInitializeGit, - mockInternalCommands: { - registerExternalCliCommand: stub(), - registerExternalCommand: stub() - } as unknown as InternalCommands, - mockRoot, - mockRunSetup: stub(Runner, 'run').resolves(undefined), - mockRunSetupWithRecheck: stub(Runner, 'runWithRecheck').resolves(undefined), - mockVersion - } -} - export const buildSetup = ( disposer: Disposer, - dependencies?: { - config: Config - messageSpy: SinonSpy<[data: unknown], Promise> - resourceLocator: ResourceLocator - }, hasData = false, noDvcRoot = true, noGitRoot = true, noGitCommits = true ) => { - const { config, messageSpy, resourceLocator } = - dependencies || buildDependencies(disposer) + const { + config, + messageSpy, + resourceLocator, + internalCommands, + dvcReader, + gitExecutor, + gitReader + } = buildDependencies(disposer) const mockDvcRoot = noDvcRoot ? undefined : dvcDemoPath const mockGitRoot = noGitRoot ? undefined : dvcDemoPath - const { - mockDvcExecutor, - mockDvcReader, - mockDvcRunner, - mockExecuteCommand, - mockGitExecutor, - mockGitReader, - mockEmitter, - mockGetGitRepositoryRoot, - mockInitializeDvc, - mockInitializeGit, - mockInternalCommands, - mockRunSetup, - mockVersion - } = buildSetupDependencies(disposer, mockDvcRoot, mockGitRoot, noGitCommits) + const mockEmitter = disposer.track(new EventEmitter()) + stub(dvcReader, 'root').resolves(mockDvcRoot) + const mockVersion = stub(dvcReader, 'version').resolves(MIN_CLI_VERSION) + const mockGlobalVersion = stub(dvcReader, 'globalVersion').resolves( + MIN_CLI_VERSION + ) + const mockGetGitRepositoryRoot = stub( + gitReader, + 'getGitRepositoryRoot' + ).resolves(mockGitRoot) + stub(gitReader, 'hasNoCommits').resolves(noGitCommits) + + const mockInitializeGit = stub(gitExecutor, 'gitInit') + stub(FileSystem, 'findDvcRootPaths').resolves( [mockDvcRoot].filter(Boolean) as string[] ) @@ -128,35 +64,38 @@ export const buildSetup = ( const mockOpenExperiments = fake() + const mockRunSetup = stub(Runner, 'run').resolves(undefined) + + const mockExecuteCommand = stub(commands, 'executeCommand').resolves( + undefined + ) + const setup = disposer.track( new Setup( - new StopWatch(), config, - mockDvcExecutor, - mockDvcReader, - mockDvcRunner, - mockGitExecutor, - mockGitReader, - () => Promise.resolve([undefined]), - () => undefined, + internalCommands, { columnsChanged: mockEmitter, getHasData: () => hasData, showWebview: mockOpenExperiments } as unknown as WorkspaceExperiments, - mockInternalCommands, + { setAvailability: stub() } as unknown as Status, resourceLocator.dvcIcon, + new StopWatch(), + () => Promise.resolve([undefined]), + () => undefined, () => Promise.resolve({} as WorkspaceScale) ) ) return { config, + internalCommands, messageSpy, mockAutoInstallDvc, mockExecuteCommand, mockGetGitRepositoryRoot, - mockInitializeDvc, + mockGlobalVersion, mockInitializeGit, mockOpenExperiments, mockRunSetup, @@ -167,16 +106,12 @@ export const buildSetup = ( } export const buildSetupWithWatchers = async (disposer: Disposer) => { - const { - mockDvcExecutor, - mockDvcReader, - mockDvcRunner, - mockEmitter, - mockGitExecutor, - mockGitReader, - mockInternalCommands, - mockRunSetup - } = buildSetupDependencies(disposer, undefined, undefined) + const mockEmitter = disposer.track(new EventEmitter()) + const mockInternalCommands = { + registerExternalCliCommand: stub(), + registerExternalCommand: stub() + } as unknown as InternalCommands + const mockRunSetup = stub(Runner, 'run').resolves(undefined) const config = disposer.track(new Config()) @@ -188,22 +123,18 @@ export const buildSetupWithWatchers = async (disposer: Disposer) => { const setup = disposer.track( new Setup( - new StopWatch(), config, - mockDvcExecutor, - mockDvcReader, - mockDvcRunner, - mockGitExecutor, - mockGitReader, - () => Promise.resolve([undefined]), - () => undefined, + mockInternalCommands, { columnsChanged: mockEmitter, getHasData: () => false, showWebview: fake() } as unknown as WorkspaceExperiments, - mockInternalCommands, + {} as Status, {} as Resource, + new StopWatch(), + () => Promise.resolve([undefined]), + () => undefined, () => Promise.resolve({} as WorkspaceScale) ) ) diff --git a/extension/src/test/suite/util.ts b/extension/src/test/suite/util.ts index 61741bb9a2..4def77c306 100644 --- a/extension/src/test/suite/util.ts +++ b/extension/src/test/suite/util.ts @@ -37,6 +37,7 @@ import { SetupData } from '../../setup/webview/contract' import { DvcViewer } from '../../cli/dvc/viewer' import { ConnectData } from '../../connect/webview/contract' import { Toast } from '../../vscode/toast' +import { GitExecutor } from '../../cli/git/executor' export const mockDisposable = { dispose: stub() @@ -152,6 +153,7 @@ export const buildInternalCommands = (disposer: Disposer) => { ) const dvcViewer = disposer.track(new DvcViewer(config)) const gitReader = disposer.track(new GitReader()) + const gitExecutor = disposer.track(new GitExecutor()) const outputChannel = disposer.track( new OutputChannel([dvcReader], '1', 'test output') @@ -164,6 +166,7 @@ export const buildInternalCommands = (disposer: Disposer) => { dvcReader, dvcRunner, dvcViewer, + gitExecutor, gitReader ) ) @@ -174,6 +177,7 @@ export const buildInternalCommands = (disposer: Disposer) => { dvcReader, dvcRunner, dvcViewer, + gitExecutor, gitReader, internalCommands } @@ -202,6 +206,7 @@ export const buildDependencies = ( dvcReader, dvcRunner, dvcViewer, + gitExecutor, gitReader, internalCommands } = buildInternalCommands(disposer) @@ -237,6 +242,7 @@ export const buildDependencies = ( dvcReader, dvcRunner, dvcViewer, + gitExecutor, gitReader, internalCommands, messageSpy, diff --git a/languageServer/package.json b/languageServer/package.json index 72dffafc63..eb9562d3fb 100644 --- a/languageServer/package.json +++ b/languageServer/package.json @@ -32,7 +32,7 @@ "copy-webpack-plugin": "11.0.0", "fork-ts-checker-webpack-plugin": "7.3.0", "ts-loader": "9.4.2", - "lint-staged": "13.1.2", + "lint-staged": "13.1.3", "jest": "29.4.3", "webpack": "5.75.0", "webpack-cli": "5.0.1", diff --git a/package.json b/package.json index 79058b8451..473f124bdf 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "eslint-plugin-unicorn": "46.0.0", "husky": "8.0.3", "jest": "29.4.3", - "lint-staged": "13.1.2", + "lint-staged": "13.1.3", "npm-run-all": "4.1.5", "nyc": "15.1.0", "prettier": "2.8.4", diff --git a/webview/package.json b/webview/package.json index 34fde7013a..c84e38760a 100644 --- a/webview/package.json +++ b/webview/package.json @@ -68,7 +68,7 @@ "jest": "29.4.3", "jest-canvas-mock": "2.4.0", "jest-environment-jsdom": "29.4.3", - "lint-staged": "13.1.2", + "lint-staged": "13.1.3", "raw-loader": "4.0.2", "sass": "1.58.3", "sass-loader": "13.2.0", diff --git a/yarn.lock b/yarn.lock index 96cd7bf73d..13a2f1987c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4860,14 +4860,14 @@ "@microsoft/fast-foundation" "^2.38.0" "@microsoft/fast-react-wrapper" "^0.1.18" -"@wdio/cli@8.5.1": - version "8.5.1" - resolved "https://registry.yarnpkg.com/@wdio/cli/-/cli-8.5.1.tgz#6c2ffa4eb763cd54228d6ad5742eecbbd88727cb" - integrity sha512-9eXwbG7G5Y660+2tNFBOUPcbMuOwSPocK/BUtAoAN/X8tYspTKAzSjd0CHOJN2uox9/+4HeuIhby86QaY+V3Ag== +"@wdio/cli@8.5.5": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@wdio/cli/-/cli-8.5.5.tgz#9ff59a48047c132eb2a04d8c82ce8967dda37e2b" + integrity sha512-0SuwktljPdZrky5g1XjC1VWk78FUcEN0cvwLNX/lsEbiTF89I3W3+501Zp6PaUhF/6toQ7MeqZgqigVP+JLpsQ== dependencies: "@types/node" "^18.0.0" - "@wdio/config" "8.5.1" - "@wdio/globals" "8.5.1" + "@wdio/config" "8.5.5" + "@wdio/globals" "8.5.5" "@wdio/logger" "8.1.0" "@wdio/protocols" "8.3.11" "@wdio/types" "8.4.0" @@ -4886,7 +4886,7 @@ mkdirp "^2.0.0" read-pkg-up "9.1.0" recursive-readdir "^2.2.2" - webdriverio "8.5.1" + webdriverio "8.5.5" yargs "^17.5.1" yarn-install "^1.0.0" @@ -4904,10 +4904,10 @@ import-meta-resolve "^2.1.0" read-pkg-up "^9.1.0" -"@wdio/config@8.5.1": - version "8.5.1" - resolved "https://registry.yarnpkg.com/@wdio/config/-/config-8.5.1.tgz#69b734f1ac28a344e1b987d2244a060750805357" - integrity sha512-9elvJNMhKu12B7jfjgTK9ENcaKqwFvR2uLjdBpuMvXCisXKuVX1KL47SnFc5cNfRtUzWx0nouotyHQlw1kCf5Q== +"@wdio/config@8.5.5": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@wdio/config/-/config-8.5.5.tgz#6f1b0e07aaf53674cf70ff500ba89c5976cc5219" + integrity sha512-9qGQWBrqaGJRWBN+n7KUp7poqAuvHrvxhCRoXtmLUQ6GmnU6k0FLnavWhfWu5b0PX9LIDBIzgglBAMPaz4LPkA== dependencies: "@wdio/logger" "8.1.0" "@wdio/types" "8.4.0" @@ -4926,23 +4926,23 @@ expect-webdriverio "^4.0.1" webdriverio "8.0.13" -"@wdio/globals@8.5.1": - version "8.5.1" - resolved "https://registry.yarnpkg.com/@wdio/globals/-/globals-8.5.1.tgz#1cdb5f72a59996718dfb81bdf31e6d7dc0f53faa" - integrity sha512-jZlstdwBy2Bn707E+ABmaIajIZYAsQxBsnuDW7LCsDGO6Gb+89ua4IpMXeznJ/NucYnBdT7etyiMSvW4HfVxLA== +"@wdio/globals@8.5.5": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@wdio/globals/-/globals-8.5.5.tgz#ca5a225a49a639262fa0ead5dd6d753a472516ab" + integrity sha512-eHPvj67jHOOzkNzgVp5UEZVYGN6vdkG9Hyveqd2iOWqLdbMMVsEdSwGQ4EUglXGSsuIrU+aaxIlQMOEbZXCRtg== optionalDependencies: expect-webdriverio "^4.0.1" - webdriverio "8.5.1" + webdriverio "8.5.5" -"@wdio/local-runner@8.5.4": - version "8.5.4" - resolved "https://registry.yarnpkg.com/@wdio/local-runner/-/local-runner-8.5.4.tgz#4e80e1187ce08b40b68c4b5c8434c531f735b78a" - integrity sha512-5K6ZtJlmeLJ5J421jBNUrqKauFh1I5VicvI0Aw2r7ZsC0zIDrRJ8RKXPzu2n0JwybkeUZFuICyqEPmGg3ktokg== +"@wdio/local-runner@8.5.5": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@wdio/local-runner/-/local-runner-8.5.5.tgz#30949a4c804bc45b353d2d739f0cf760472a4b38" + integrity sha512-zNQI2pPBH0jGwwLNlfptvkodahCsFlqDT0fvqJc3kFmIlPtFM4pg1tVeyebFKUj/yCoa9fbJaIA0IQj71FVG4Q== dependencies: "@types/node" "^18.0.0" "@wdio/logger" "8.1.0" "@wdio/repl" "8.1.0" - "@wdio/runner" "8.5.4" + "@wdio/runner" "8.5.5" "@wdio/types" "8.4.0" async-exit-hook "^2.0.1" split2 "^4.1.0" @@ -5014,22 +5014,22 @@ object-inspect "^1.12.0" supports-color "9.3.1" -"@wdio/runner@8.5.4": - version "8.5.4" - resolved "https://registry.yarnpkg.com/@wdio/runner/-/runner-8.5.4.tgz#6c7b5d5db020607dca1821bf417dcd198174bdb4" - integrity sha512-K8D9K3t3JQjTpsr1+qHnHIDBooWrMjd3wmWjcY9jzeKNeolk5UnR5smn5TmmrkBAFSZB5WWnwzRHWtRrHmt6Ww== +"@wdio/runner@8.5.5": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@wdio/runner/-/runner-8.5.5.tgz#37a7a1c38acc0fc14ea400f636e14224dbc8d500" + integrity sha512-KplkYDCEFNRRY1QPcnH6dmr77U/urXNXUQpEiW1l5hjj8Kvge5hbbAy67BBcPfP3ll+xi+AM5LMXyjbLdPAN1g== dependencies: "@types/node" "^18.0.0" - "@wdio/config" "8.5.1" - "@wdio/globals" "8.5.1" + "@wdio/config" "8.5.5" + "@wdio/globals" "8.5.5" "@wdio/logger" "8.1.0" "@wdio/types" "8.4.0" "@wdio/utils" "8.4.0" deepmerge-ts "^4.2.2" expect-webdriverio "^4.0.1" gaze "^1.1.2" - webdriver "8.5.1" - webdriverio "8.5.1" + webdriver "8.5.5" + webdriverio "8.5.5" "@wdio/spec-reporter@8.4.0": version "8.4.0" @@ -7443,6 +7443,11 @@ commander@7, commander@^7.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.0.tgz#71797971162cd3cf65f0b9d24eb28f8d303acdf1" + integrity sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA== + commander@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" @@ -8488,13 +8493,13 @@ devtools@8.0.13: uuid "^9.0.0" which "^3.0.0" -devtools@8.5.1: - version "8.5.1" - resolved "https://registry.yarnpkg.com/devtools/-/devtools-8.5.1.tgz#70f24815e91e6c36a656fcf08a7d81a0f7cedde6" - integrity sha512-wFK3WQs6Sy8H4X/d7jE6iWWgygIksMAvhRsq7M+DiCefaWbUK9Upz2mmcoGqff0bETiOdghgVI4Nzff0bkxOzA== +devtools@8.5.5: + version "8.5.5" + resolved "https://registry.yarnpkg.com/devtools/-/devtools-8.5.5.tgz#09ac16244ab65e8be7f6704f7279f8c66b728ed1" + integrity sha512-NwHRHOiRX0h0ZQjMvVvjldG7JMV6v3dAo9QKOEujKe/3wqqQzhLKBzlckdu4PyIf5FkEw4LXimT599jlsWSpBg== dependencies: "@types/node" "^18.0.0" - "@wdio/config" "8.5.1" + "@wdio/config" "8.5.5" "@wdio/logger" "8.1.0" "@wdio/protocols" "8.3.11" "@wdio/types" "8.4.0" @@ -9593,21 +9598,6 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20" - integrity sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^3.0.1" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - execa@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-7.0.0.tgz#2a44e20e73797f6c2df23889927972386157d7e4" @@ -11345,11 +11335,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -human-signals@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" - integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== - human-signals@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.0.tgz#2095c3cd5afae40049403d4b811235b03879db50" @@ -13181,10 +13166,10 @@ lighthouse-logger@^1.0.0: debug "^2.6.9" marky "^1.2.2" -lilconfig@2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== +lilconfig@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== lines-and-columns@^1.1.6: version "1.2.4" @@ -13198,41 +13183,42 @@ linkify-it@^3.0.1: dependencies: uc.micro "^1.0.1" -lint-staged@13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.1.2.tgz#443636a0cfd834d5518d57d228130dc04c83d6fb" - integrity sha512-K9b4FPbWkpnupvK3WXZLbgu9pchUJ6N7TtVZjbaPsoizkqFUDkUReUL25xdrCljJs7uLUF3tZ7nVPeo/6lp+6w== +lint-staged@13.1.3: + version "13.1.3" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.1.3.tgz#5bf0ff98725e3354fb16dcd252b9a5e66bc8dcc7" + integrity sha512-PLbSCYUvW8lcwJ9koMFerBrJ16GsNivu1eDahMKgYlFa0f2rr2+rGVjj27L+1rg9JAz+DZesB+kXCAWHQJN9VQ== dependencies: cli-truncate "^3.1.0" colorette "^2.0.19" - commander "^9.4.1" + commander "^10.0.0" debug "^4.3.4" - execa "^6.1.0" - lilconfig "2.0.6" - listr2 "^5.0.5" + execa "^7.0.0" + lilconfig "2.1.0" + listr2 "^5.0.7" micromatch "^4.0.5" normalize-path "^3.0.0" - object-inspect "^1.12.2" + object-inspect "^1.12.3" pidtree "^0.6.0" string-argv "^0.3.1" - yaml "^2.1.3" + supports-color "9.3.1" + yaml "^2.2.1" listenercount@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= -listr2@^5.0.5: - version "5.0.6" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.6.tgz#3c61153383869ffaad08a8908d63edfde481dff8" - integrity sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag== +listr2@^5.0.7: + version "5.0.8" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.8.tgz#a9379ffeb4bd83a68931a65fb223a11510d6ba23" + integrity sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA== dependencies: cli-truncate "^2.1.0" colorette "^2.0.19" log-update "^4.0.0" p-map "^4.0.0" rfdc "^1.3.0" - rxjs "^7.5.7" + rxjs "^7.8.0" through "^2.3.8" wrap-ansi "^7.0.0" @@ -14548,6 +14534,11 @@ object-inspect@^1.12.2: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.12.3: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + object-is@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" @@ -16649,20 +16640,13 @@ rw@1: resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== -rxjs@^7.5.6: +rxjs@^7.5.6, rxjs@^7.8.0: version "7.8.0" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== dependencies: tslib "^2.1.0" -rxjs@^7.5.7: - version "7.5.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" - integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== - dependencies: - tslib "^2.1.0" - safe-buffer@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -19430,14 +19414,14 @@ webdriver@8.0.13: ky "^0.32.1" ws "^8.8.0" -webdriver@8.5.1: - version "8.5.1" - resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-8.5.1.tgz#9775eb208f7a14cb79dd01d8b8304dac41792265" - integrity sha512-Qx/7q5pwDGQkbRHf4ZdzCM5FD5L9RGoj17V04GnBkLcjnaccqzF82taC8WaFuUcRB4DxUPUm/c5kYARjEtM8JQ== +webdriver@8.5.5: + version "8.5.5" + resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-8.5.5.tgz#728febd3ab26771da1690e4e72c351daae837b4f" + integrity sha512-uJuhHqQAAXAoFHGEDL9bR3hq6BD0jKu5xecLBbiqHqp0940aN8hzEXw+abCFreu66lFwtZODGZweC8UUUysfhQ== dependencies: "@types/node" "^18.0.0" "@types/ws" "^8.5.3" - "@wdio/config" "8.5.1" + "@wdio/config" "8.5.5" "@wdio/logger" "8.1.0" "@wdio/protocols" "8.3.11" "@wdio/types" "8.4.0" @@ -19480,13 +19464,13 @@ webdriverio@8.0.13, webdriverio@^8.0.0-alpha.505: serialize-error "^8.0.0" webdriver "8.0.13" -webdriverio@8.5.1: - version "8.5.1" - resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-8.5.1.tgz#dd77fdfabb27eb935a6bafcd537461784bfc3ed8" - integrity sha512-knDHey1iWJ95y3dYADtT2T24BL4MY/c1/lzJMc1szDgRYgaKXFgT4NjLOH7gy0ljzVtUdQxnKWntb1MaI3pt8g== +webdriverio@8.5.5: + version "8.5.5" + resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-8.5.5.tgz#2e94a70b1f7ebc9298aea1f3bf6b5e32adf11578" + integrity sha512-wPWf8KZmZHks659wI7Rj6oKjpHrlYjy8ySdYf6c872QqpMkmDrkGjr/8rivGiorMOMXRFCrfTUHEkSbpApvUoQ== dependencies: "@types/node" "^18.0.0" - "@wdio/config" "8.5.1" + "@wdio/config" "8.5.5" "@wdio/logger" "8.1.0" "@wdio/protocols" "8.3.11" "@wdio/repl" "8.1.0" @@ -19496,7 +19480,7 @@ webdriverio@8.5.1: aria-query "^5.0.0" css-shorthand-properties "^1.1.1" css-value "^0.0.1" - devtools "8.5.1" + devtools "8.5.5" devtools-protocol "^0.0.1109433" grapheme-splitter "^1.0.2" import-meta-resolve "^2.1.0" @@ -19509,7 +19493,7 @@ webdriverio@8.5.1: resq "^1.9.1" rgb2hex "0.2.5" serialize-error "^8.0.0" - webdriver "8.5.1" + webdriver "8.5.5" webidl-conversions@^3.0.0: version "3.0.1" @@ -20093,7 +20077,7 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@2.2.1: +yaml@2.2.1, yaml@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.1.tgz#3014bf0482dcd15147aa8e56109ce8632cd60ce4" integrity sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw== @@ -20103,11 +20087,6 @@ yaml@^1.10.0, yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yaml@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.3.tgz#9b3a4c8aff9821b696275c79a8bee8399d945207" - integrity sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg== - yargs-parser@20.2.4: version "20.2.4" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"