-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: User is prompted to choose a directory for Explain command
- Loading branch information
Showing
5 changed files
with
228 additions
and
52 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import * as vscode from 'vscode'; | ||
import IndexProcessWatcher from '../services/indexProcessWatcher'; | ||
import { NodeProcessService } from '../services/nodeProcessService'; | ||
import { workspaceServices } from '../services/workspaceServices'; | ||
|
||
export type IndexProcess = { | ||
configFolder: string; | ||
rpcPort: number; | ||
}; | ||
|
||
export enum ReasonCode { | ||
NoIndexProcessWatchers = 1, | ||
NoReadyIndexProcessWatchers = 2, | ||
NoSelectionMade = 3, | ||
} | ||
|
||
export function readyProcessWatchers( | ||
workspace?: vscode.WorkspaceFolder | ||
): IndexProcessWatcher[] | undefined { | ||
const nodeProcessService = workspaceServices().getService(NodeProcessService); | ||
if (!nodeProcessService) { | ||
console.warn('No node process service found'); | ||
return; | ||
} | ||
|
||
const nodeProcessServices = workspaceServices().getServiceInstances(nodeProcessService); | ||
if (nodeProcessServices.length === 0) { | ||
console.log('No node process services found'); | ||
return; | ||
} | ||
|
||
const indexProcessWatchers = nodeProcessServices | ||
.filter((service) => workspace === undefined || service.folder === workspace) | ||
.flatMap( | ||
(service) => | ||
service.processes.filter((process) => process.id === 'index') as IndexProcessWatcher[] | ||
); | ||
|
||
return indexProcessWatchers; | ||
} | ||
|
||
export default async function selectIndexProcess( | ||
workspace?: vscode.WorkspaceFolder | ||
): Promise<IndexProcess | ReasonCode | undefined> { | ||
const indexProcessWatchers = readyProcessWatchers(workspace); | ||
if (!indexProcessWatchers) { | ||
console.warn(`No index process watchers found for ${workspace?.name || 'your workspace'}`); | ||
return; | ||
} | ||
|
||
if (indexProcessWatchers.length === 0) { | ||
console.log('No index process watchers found'); | ||
return ReasonCode.NoIndexProcessWatchers; | ||
} | ||
|
||
const readyIndexProcessWatchers = indexProcessWatchers.filter((watcher) => | ||
watcher.isRpcAvailable() | ||
); | ||
if (readyIndexProcessWatchers.length === 0) { | ||
console.log('No ready index process watchers found'); | ||
return ReasonCode.NoReadyIndexProcessWatchers; | ||
} | ||
|
||
let selectedWatcher: IndexProcessWatcher | undefined; | ||
if (readyIndexProcessWatchers.length === 1) { | ||
selectedWatcher = readyIndexProcessWatchers[0]; | ||
} else { | ||
const pickResult = await vscode.window.showQuickPick( | ||
readyIndexProcessWatchers.map((watcher) => ({ | ||
label: watcher.configFolder, | ||
watcher, | ||
})), | ||
{ | ||
placeHolder: 'Select a project directory for your question', | ||
} | ||
); | ||
if (!pickResult) return ReasonCode.NoSelectionMade; | ||
|
||
selectedWatcher = pickResult.watcher; | ||
} | ||
|
||
if (!selectedWatcher.rpcPort) { | ||
console.warn(`No RPC port available on index process watcher ${selectedWatcher.configFolder}`); | ||
return; | ||
} | ||
|
||
return { | ||
configFolder: selectedWatcher.configFolder, | ||
rpcPort: selectedWatcher.rpcPort, | ||
}; | ||
} |
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,106 @@ | ||
import { expect } from 'chai'; | ||
import sinon from 'sinon'; | ||
import '../mock/vscode'; | ||
import * as vscode from 'vscode'; | ||
import * as workspaceServices from '../../../src/services/workspaceServices'; | ||
import selectIndexProcess, { ReasonCode } from '../../../src/lib/selectIndexProcess'; | ||
import { ProcessId } from '../../../src/services/processWatcher'; | ||
import IndexProcessWatcher from '../../../src/services/indexProcessWatcher'; | ||
|
||
describe('selectIndexProcess', () => { | ||
let sandbox: sinon.SinonSandbox; | ||
let processes: IndexProcessWatcher[]; | ||
|
||
beforeEach(() => { | ||
sandbox = sinon.createSandbox(); | ||
processes = []; | ||
const stubService = sandbox.stub(); | ||
sandbox.stub(workspaceServices, 'workspaceServices').returns({ | ||
getService: sandbox.stub().returns(stubService), | ||
getServiceInstances: (service: unknown) => { | ||
expect(service).to.eq(stubService); | ||
return [{ processes }]; | ||
}, | ||
} as unknown as workspaceServices.WorkspaceServices); | ||
}); | ||
|
||
afterEach(() => { | ||
sandbox.restore(); | ||
}); | ||
|
||
describe('when there is no index process', () => { | ||
it('returns undefined', async () => { | ||
const result = await selectIndexProcess(); | ||
expect(result).to.eq(ReasonCode.NoIndexProcessWatchers); | ||
}); | ||
}); | ||
describe('when there is one index process', () => { | ||
describe('but the RPC port is not available', () => { | ||
beforeEach(() => { | ||
processes = [ | ||
{ | ||
id: ProcessId.Index, | ||
isRpcAvailable: sandbox.stub().returns(false), | ||
} as unknown as IndexProcessWatcher, | ||
]; | ||
}); | ||
|
||
it('returns undefined', async () => { | ||
const result = await selectIndexProcess(); | ||
expect(result).to.eq(ReasonCode.NoReadyIndexProcessWatchers); | ||
}); | ||
}); | ||
describe('and the RPC port is available', () => { | ||
beforeEach(() => { | ||
processes = [ | ||
{ | ||
id: ProcessId.Index, | ||
isRpcAvailable: sandbox.stub().returns(true), | ||
configFolder: './the-project', | ||
rpcPort: 1234, | ||
} as unknown as IndexProcessWatcher, | ||
]; | ||
}); | ||
|
||
it('returns the process', async () => { | ||
const result = await selectIndexProcess(); | ||
expect(result).to.deep.equal({ | ||
configFolder: './the-project', | ||
rpcPort: 1234, | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('when there are multiple index processes', () => { | ||
beforeEach(() => { | ||
processes = [ | ||
{ | ||
id: ProcessId.Index, | ||
isRpcAvailable: sandbox.stub().returns(true), | ||
configFolder: './project-a', | ||
rpcPort: 1, | ||
} as unknown as IndexProcessWatcher, | ||
{ | ||
id: ProcessId.Index, | ||
isRpcAvailable: sandbox.stub().returns(true), | ||
configFolder: './project-b', | ||
rpcPort: 2, | ||
} as unknown as IndexProcessWatcher, | ||
]; | ||
}); | ||
|
||
it('prompts the user to choose', async () => { | ||
const quickPick = sandbox.stub(vscode.window, 'showQuickPick'); | ||
quickPick.onFirstCall().resolves({ | ||
label: './project-a', | ||
watcher: processes[0], | ||
} as unknown as vscode.QuickPickItem & { watcher: IndexProcessWatcher }); | ||
|
||
const result = await selectIndexProcess(); | ||
expect(result).to.deep.equal({ | ||
configFolder: './project-a', | ||
rpcPort: 1, | ||
}); | ||
}); | ||
}); | ||
}); |