-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9149c01
commit 616c35e
Showing
8 changed files
with
193 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { EventEmitter, Event } from 'vscode' | ||
import { Args, Command, Flag, QueueSubCommand } from './constants' | ||
import { getOptions } from './options' | ||
import { CliResult, CliStarted, ICli, typeCheckCommands } from '..' | ||
import { Config } from '../../config' | ||
import { Disposable } from '../../class/dispose' | ||
import { ViewableCliProcess } from '../viewable' | ||
|
||
export const autoRegisteredCommands = { | ||
QUEUE_LOGS: 'queueLogs' | ||
} as const | ||
|
||
export class DvcViewer extends Disposable implements ICli { | ||
public readonly autoRegisteredCommands = typeCheckCommands( | ||
autoRegisteredCommands, | ||
this | ||
) | ||
|
||
public readonly processCompleted: EventEmitter<CliResult> | ||
public readonly onDidCompleteProcess: Event<CliResult> | ||
|
||
public readonly processStarted: EventEmitter<CliStarted> | ||
public readonly onDidStartProcess: Event<CliStarted> | ||
|
||
private processes: { | ||
[id: string]: ViewableCliProcess | ||
} | ||
|
||
private readonly config: Config | ||
|
||
constructor(config: Config) { | ||
super() | ||
|
||
this.config = config | ||
|
||
this.processes = {} | ||
|
||
this.processCompleted = this.dispose.track(new EventEmitter<CliResult>()) | ||
this.onDidCompleteProcess = this.processCompleted.event | ||
|
||
this.processStarted = this.dispose.track(new EventEmitter<CliStarted>()) | ||
this.onDidStartProcess = this.processStarted.event | ||
} | ||
|
||
public run(name: string, cwd: string, ...args: Args) { | ||
const viewableProcess = this.getRunningProcess(cwd, ...args) | ||
if (viewableProcess) { | ||
return viewableProcess.show() | ||
} | ||
|
||
return this.createProcess(name, cwd, args) | ||
} | ||
|
||
public queueLogs(cwd: string, expName: string) { | ||
return this.run( | ||
expName, | ||
cwd, | ||
Command.QUEUE, | ||
QueueSubCommand.LOGS, | ||
expName, | ||
Flag.FOLLOW | ||
) | ||
} | ||
|
||
private createProcess(name: string, cwd: string, args: Args) { | ||
const viewableProcess = this.viewProcess(name, cwd, args) | ||
|
||
this.setRunningProcess(viewableProcess, cwd, ...args) | ||
|
||
const listener = this.dispose.track( | ||
viewableProcess.onDidDispose(() => { | ||
delete this.processes[this.getId(cwd, ...args)] | ||
this.dispose.untrack(listener) | ||
listener.dispose() | ||
}) | ||
) | ||
} | ||
|
||
private viewProcess(name: string, cwd: string, args: Args) { | ||
return this.dispose.track( | ||
new ViewableCliProcess( | ||
`DVC: ${name}`, | ||
this.getOptions(cwd, args), | ||
this.processStarted, | ||
this.processCompleted | ||
) | ||
) | ||
} | ||
|
||
private getOptions(cwd: string, args: Args) { | ||
return getOptions( | ||
this.config.getPythonBinPath(), | ||
this.config.getCliPath(), | ||
cwd, | ||
...args | ||
) | ||
} | ||
|
||
private getRunningProcess(cwd: string, ...args: Args) { | ||
return this.processes[this.getId(cwd, ...args)] | ||
} | ||
|
||
private setRunningProcess( | ||
viewableProcess: ViewableCliProcess, | ||
cwd: string, | ||
...args: Args | ||
) { | ||
this.processes[this.getId(cwd, ...args)] = viewableProcess | ||
} | ||
|
||
private getId(cwd: string, ...args: Args) { | ||
return [cwd, ...args].join(':') | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { afterEach, beforeEach, describe, it, suite } from 'mocha' | ||
import { expect } from 'chai' | ||
import { restore, spy } from 'sinon' | ||
import { Disposable } from '../../../../extension' | ||
import { Config } from '../../../../config' | ||
import { DvcViewer } from '../../../../cli/dvc/viewer' | ||
import { dvcDemoPath } from '../../../util' | ||
import { ViewableCliProcess } from '../../../../cli/viewable' | ||
|
||
suite('DVC Viewer Test Suite', () => { | ||
const disposable = Disposable.fn() | ||
|
||
beforeEach(() => { | ||
restore() | ||
}) | ||
|
||
afterEach(() => { | ||
disposable.dispose() | ||
}) | ||
|
||
describe('DvcViewer', () => { | ||
it('should only be able to run a command once', async () => { | ||
const mockConfig = { | ||
getCliPath: () => 'sleep', | ||
getPythonBinPath: () => undefined | ||
} as Config | ||
const dvcViewer = disposable.track(new DvcViewer(mockConfig)) | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const getProcess = (dvcViewer: any, id: string): ViewableCliProcess => | ||
dvcViewer.processes[id] | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const createProcessSpy = spy(dvcViewer as any, 'createProcess') | ||
|
||
await dvcViewer.run('command', dvcDemoPath, '10000') | ||
|
||
expect(createProcessSpy).to.be.called | ||
const viewableProcess = getProcess( | ||
dvcViewer, | ||
[dvcDemoPath, '10000'].join(':') | ||
) | ||
const showProcessSpy = spy(viewableProcess, 'show') | ||
|
||
createProcessSpy.resetHistory() | ||
|
||
await dvcViewer.run('command', dvcDemoPath, '10000') | ||
|
||
expect(createProcessSpy).not.to.be.called | ||
expect(showProcessSpy).to.be.calledOnce | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters