-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathlib.rs
More file actions
154 lines (144 loc) · 5.23 KB
/
lib.rs
File metadata and controls
154 lines (144 loc) · 5.23 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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use std::{any::Any, path::PathBuf};
use env::PythonEnv;
use manager::EnvManager;
use python_environment::{PythonEnvironment, PythonEnvironmentKind};
use reporter::Reporter;
pub mod arch;
pub mod cache;
pub mod env;
pub mod manager;
pub mod os_environment;
pub mod python_environment;
pub mod pyvenv_cfg;
pub mod reporter;
pub mod telemetry;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LocatorResult {
pub managers: Vec<EnvManager>,
pub environments: Vec<PythonEnvironment>,
}
#[derive(Debug, Default, Clone)]
pub struct Configuration {
/// These are paths like workspace folders, where we can look for environments.
pub workspace_directories: Option<Vec<PathBuf>>,
pub executables: Option<Vec<PathBuf>>,
pub conda_executable: Option<PathBuf>,
pub pipenv_executable: Option<PathBuf>,
pub poetry_executable: Option<PathBuf>,
/// Custom locations where environments can be found.
/// These are different from search_paths, as these are specific directories where environments are expected.
/// environment_directories on the other hand can be any directory such as a workspace folder, where envs might never exist.
pub environment_directories: Option<Vec<PathBuf>>,
/// Directory to cache the Python environment details.
pub cache_directory: Option<PathBuf>,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum LocatorKind {
Conda,
Homebrew,
LinuxGlobal,
MacCommandLineTools,
MacPythonOrg,
MacXCode,
PipEnv,
Pixi,
Poetry,
PyEnv,
Uv,
Venv,
VirtualEnv,
VirtualEnvWrapper,
WinPython,
WindowsRegistry,
WindowsStore,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RefreshStatePersistence {
/// The locator keeps no mutable state across requests.
Stateless,
/// The locator keeps configured inputs only; refresh must not copy them back.
ConfiguredOnly,
/// The locator keeps cache-like state, but later requests can repopulate it on demand.
SelfHydratingCache,
/// The locator keeps refresh-discovered state that later requests depend on for correctness.
SyncedDiscoveryState,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RefreshStateSyncScope {
Full,
GlobalFiltered(PythonEnvironmentKind),
Workspace,
}
pub trait Locator: Any + Send + Sync {
/// Returns the name of the locator.
fn get_kind(&self) -> LocatorKind;
/// Configures the locator with the given configuration.
///
/// Override this method if you need to store configuration in the locator.
///
/// # Why `&self` instead of `&mut self`?
///
/// Locators are shared across threads via `Arc<dyn Locator>` and may be
/// configured while other operations are in progress. Using `&self` allows
/// concurrent access without requiring the caller to hold an exclusive lock
/// on the entire locator.
///
/// Implementations that need to store configuration should use interior
/// mutability (e.g., `Mutex<T>` or `RwLock<T>`) for the mutable fields only.
///
/// # Example
///
/// ```ignore
/// use std::sync::Mutex;
/// use std::path::PathBuf;
///
/// struct MyLocator {
/// workspace_dirs: Mutex<Vec<PathBuf>>,
/// }
///
/// impl Locator for MyLocator {
/// fn configure(&self, config: &Configuration) {
/// if let Some(dirs) = &config.workspace_directories {
/// *self.workspace_dirs.lock().expect("workspace_dirs mutex poisoned") = dirs.clone();
/// }
/// }
/// // ... other required methods
/// }
/// ```
fn configure(&self, _config: &Configuration) {
//
}
/// Describes what mutable state, if any, must survive a refresh boundary.
///
/// Refresh runs execute against transient locator graphs and then invoke
/// `sync_refresh_state_from()` on the long-lived shared locators.
fn refresh_state(&self) -> RefreshStatePersistence {
RefreshStatePersistence::Stateless
}
/// Copies correctness-critical post-refresh state from a transient locator into this
/// long-lived shared locator.
///
/// Override this only when `refresh_state()` returns
/// `RefreshStatePersistence::SyncedDiscoveryState`.
fn sync_refresh_state_from(&self, _source: &dyn Locator, _scope: &RefreshStateSyncScope) {
//
}
/// Returns a list of supported categories for this locator.
fn supported_categories(&self) -> Vec<PythonEnvironmentKind>;
/// Given a Python executable, and some optional data like prefix,
/// this method will attempt to convert it to a PythonEnvironment that can be supported by this particular locator.
/// If an environment is not supported by this locator, then None is returned.
///
/// Note: The returned environment could have some missing information.
/// This is because the `from` will do a best effort to get the environment information without spawning Python.
fn try_from(&self, env: &PythonEnv) -> Option<PythonEnvironment>;
/// Finds all environments specific to this locator.
fn find(&self, reporter: &dyn Reporter);
}
impl dyn Locator {
pub fn as_any(&self) -> &dyn Any {
self
}
}