Skip to content

Commit 5590027

Browse files
Add a basic env locator.
1 parent 590ed53 commit 5590027

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
import { Event, Uri } from 'vscode';
5+
import { iterEmpty } from '../../common/utils/async';
6+
import { PythonEnvInfo, PythonEnvKind } from './info';
7+
import {
8+
BasicPythonEnvsChangedEvent,
9+
BasicPythonEnvsWatcher,
10+
IPythonEnvsWatcher,
11+
PythonEnvsChangedEvent,
12+
PythonEnvsWatcher
13+
} from './watcher';
14+
15+
/**
16+
* An async iterator of `PythonEnvInfo`.
17+
*/
18+
export type PythonEnvsIterator = AsyncIterator<PythonEnvInfo | void, void>;
19+
20+
/**
21+
* An empty Python envs iterator.
22+
*/
23+
export const NOOP_ITERATOR: PythonEnvsIterator = iterEmpty<PythonEnvInfo>();
24+
25+
/**
26+
* The most basic info to send to a locator when requesting environments.
27+
*
28+
* This is directly correlated with the `BasicPythonEnvsChangedEvent`
29+
* emitted by watchers.
30+
*
31+
* @prop kinds - if provided, results should be limited to these env kinds
32+
*/
33+
export type BasicPythonLocatorQuery = {
34+
kinds?: PythonEnvKind[];
35+
};
36+
37+
/**
38+
* The full set of possible info to send to a locator when requesting environments.
39+
*
40+
* This is directly correlated with the `PythonEnvsChangedEvent`
41+
* emitted by watchers.
42+
*
43+
* @prop - searchLocations - if provided, results should be limited to
44+
* within these locations
45+
*/
46+
export type PythonLocatorQuery = BasicPythonLocatorQuery & {
47+
searchLocations?: Uri[];
48+
};
49+
50+
type QueryForEvent<E> = E extends PythonEnvsChangedEvent ? PythonLocatorQuery : BasicPythonLocatorQuery;
51+
52+
/**
53+
* A single Python environment locator.
54+
*
55+
* Each locator object is responsible for identifying the Python
56+
* environments in a single location, whether a directory, a directory
57+
* tree, or otherwise. That location is identified when the locator
58+
* is instantiated.
59+
*
60+
* Based on the narrow focus of each locator, the assumption is that
61+
* calling iterEnvs() to pick up a changed env is effectively no more
62+
* expensive than tracking down that env specifically. Consequently,
63+
* events emitted via `onChanged` do not need to provide information
64+
* for the specific environments that changed.
65+
*/
66+
export interface ILocator<E extends BasicPythonEnvsChangedEvent = PythonEnvsChangedEvent>
67+
extends IPythonEnvsWatcher<E> {
68+
/**
69+
* Iterate over the enviroments known tos this locator.
70+
*
71+
* @param query - if provided, the locator will limit results to match
72+
*/
73+
iterEnvs(query?: QueryForEvent<E>): PythonEnvsIterator;
74+
}
75+
76+
interface IBasicEmitter {
77+
fire(e: BasicPythonEnvsChangedEvent): void;
78+
trigger(kind?: PythonEnvKind): void;
79+
}
80+
interface IFullEmitter {
81+
fire(e: PythonEnvsChangedEvent): void;
82+
trigger(kind?: PythonEnvKind, searchLocation?: Uri): void;
83+
}
84+
type EmitterForEvent<E> = E extends PythonEnvsChangedEvent ? IFullEmitter : IBasicEmitter;
85+
86+
/**
87+
* The base for locators.
88+
*
89+
* Subclasses will call `this.emitter.fire()` or `this.emitter.trigger()`
90+
* to emit events.
91+
*/
92+
abstract class Locator<E extends BasicPythonEnvsChangedEvent> {
93+
public readonly onChanged: Event<E>;
94+
protected readonly emitter: EmitterForEvent<E>;
95+
constructor(watcher: IPythonEnvsWatcher<E> & EmitterForEvent<E>) {
96+
this.emitter = watcher;
97+
this.onChanged = watcher.onChanged;
98+
}
99+
100+
public abstract iterEnvs(query?: QueryForEvent<E>): PythonEnvsIterator;
101+
}
102+
103+
/**
104+
* The base for locators that deal only with basic info for Python environments.
105+
*
106+
* Subclasses will call `this.emitter.fire()` or `this.emitter.trigger()`
107+
* to emit events.
108+
*/
109+
export abstract class BasicLocator extends Locator<BasicPythonEnvsChangedEvent> {
110+
constructor() {
111+
super(new BasicPythonEnvsWatcher());
112+
}
113+
}
114+
115+
/**
116+
* The base for locators that deal with full info for Python environments.
117+
*
118+
* Subclasses will call `this.emitter.fire()` or `this.emitter.trigger()`
119+
* to emit events.
120+
*/
121+
export abstract class FullLocator extends Locator<PythonEnvsChangedEvent> {
122+
constructor() {
123+
super(new PythonEnvsWatcher());
124+
}
125+
}

0 commit comments

Comments
 (0)