forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlocator.ts
More file actions
137 lines (124 loc) · 4.75 KB
/
locator.ts
File metadata and controls
137 lines (124 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { Event, Uri } from 'vscode';
import { iterEmpty } from '../../common/utils/async';
import { PythonEnvInfo, PythonEnvKind } from './info';
import { BasicPythonEnvsChangedEvent, IPythonEnvsWatcher, PythonEnvsChangedEvent, PythonEnvsWatcher } from './watcher';
/**
* An async iterator of `PythonEnvInfo`.
*/
export type PythonEnvsIterator = AsyncIterator<PythonEnvInfo, void>;
/**
* An empty Python envs iterator.
*/
export const NOOP_ITERATOR: PythonEnvsIterator = iterEmpty<PythonEnvInfo>();
/**
* The most basic info to send to a locator when requesting environments.
*
* This is directly correlated with the `BasicPythonEnvsChangedEvent`
* emitted by watchers.
*
* @prop kinds - if provided, results should be limited to these env kinds
*/
export type BasicPythonLocatorQuery = {
kinds?: PythonEnvKind[];
};
/**
* The full set of possible info to send to a locator when requesting environments.
*
* This is directly correlated with the `PythonEnvsChangedEvent`
* emitted by watchers.
*
* @prop - searchLocations - if provided, results should be limited to
* within these locations
*/
export type PythonLocatorQuery = BasicPythonLocatorQuery & {
searchLocations?: Uri[];
};
type QueryForEvent<E> = E extends PythonEnvsChangedEvent ? PythonLocatorQuery : BasicPythonLocatorQuery;
/**
* A single Python environment locator.
*
* Each locator object is responsible for identifying the Python
* environments in a single location, whether a directory, a directory
* tree, or otherwise. That location is identified when the locator
* is instantiated.
*
* Based on the narrow focus of each locator, the assumption is that
* calling iterEnvs() to pick up a changed env is effectively no more
* expensive than tracking down that env specifically. Consequently,
* events emitted via `onChanged` do not need to provide information
* for the specific environments that changed.
*/
export interface ILocator<E extends BasicPythonEnvsChangedEvent = PythonEnvsChangedEvent>
extends IPythonEnvsWatcher<E> {
/**
* Iterate over the enviroments known tos this locator.
*
* Locators are not required to have provide all info about
* an environment. However, each yielded item will at least
* include all the `PythonEnvBaseInfo` data.
*
* @param query - if provided, the locator will limit results to match
*/
iterEnvs(query?: QueryForEvent<E>): PythonEnvsIterator;
/**
* Find the given Python environment and fill in as much missing info as possible.
*
* If the locator can find the environment then the result is as
* much info about that env as the locator has. At the least this
* will include all the `PythonEnvBaseInfo` data. If a `PythonEnvInfo`
* was provided then the result will be a copy with any updates or
* extra info applied.
*
* If the locator could not find the environment then `undefined`
* is returned.
*
* @param env - the Python executable path or partial env info to find and update
*/
resolveEnv(env: string | PythonEnvInfo): Promise<PythonEnvInfo | undefined>;
}
interface IEmitter<E extends BasicPythonEnvsChangedEvent> {
fire(e: E): void;
}
/**
* The generic base for Python envs locators.
*
* By default `resolveEnv()` returns undefined. Subclasses may override
* the method to provide an implementation.
*
* Subclasses will call `this.emitter.fire()` to emit events.
*
* Also, in most cases the default event type (`PythonEnvsChangedEvent`)
* should be used. Only in low-level cases should you consider using
* `BasicPythonEnvsChangedEvent`.
*/
export abstract class LocatorBase<E extends BasicPythonEnvsChangedEvent = PythonEnvsChangedEvent> implements ILocator<E> {
public readonly onChanged: Event<E>;
protected readonly emitter: IEmitter<E>;
constructor(watcher: IPythonEnvsWatcher<E> & IEmitter<E>) {
this.emitter = watcher;
this.onChanged = watcher.onChanged;
}
public abstract iterEnvs(query?: QueryForEvent<E>): PythonEnvsIterator;
public async resolveEnv(_env: string | PythonEnvInfo): Promise<PythonEnvInfo | undefined> {
return undefined;
}
}
/**
* The base for most Python envs locators.
*
* By default `resolveEnv()` returns undefined. Subclasses may override
* the method to provide an implementation.
*
* Subclasses will call `this.emitter.fire()` * to emit events.
*
* In most cases this is the class you will want to subclass.
* Only in low-level cases should you consider subclassing `LocatorBase`
* using `BasicPythonEnvsChangedEvent.
*/
export abstract class Locator extends LocatorBase {
constructor() {
super(new PythonEnvsWatcher());
}
}