-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathlib.rs
More file actions
125 lines (112 loc) · 3.7 KB
/
Copy pathlib.rs
File metadata and controls
125 lines (112 loc) · 3.7 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
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use std::path::Path;
use pet_core::{
python_environment::{PythonEnvironment, PythonEnvironmentBuilder, PythonEnvironmentKind},
reporter::Reporter,
Locator,
};
use pet_python_utils::version;
use pet_python_utils::{env::PythonEnv, executable::find_executables};
pub fn is_virtualenv(env: &PythonEnv) -> bool {
if env.prefix.is_none() {
let mut bin = env.executable.clone();
bin.pop();
// Check if the executable is in a bin or Scripts directory.
// Possible for some reason we do not have the prefix.
if !bin.ends_with("bin") && !bin.ends_with("Scripts") {
return false;
}
}
if let Some(bin) = env.executable.parent() {
return is_virtualenv_dir(bin);
}
false
}
pub fn is_virtualenv_dir(path: &Path) -> bool {
// Check if the executable is in a bin or Scripts directory.
// Possible for some reason we do not have the prefix.
let mut path = path.to_path_buf();
if !path.ends_with("bin") && !path.ends_with("Scripts") {
if cfg!(windows) {
path = path.join("Scripts");
} else {
path = path.join("bin");
}
}
// Check if there are any activate.* files in the same directory as the interpreter.
//
// env
// |__ activate, activate.* <--- check if any of these files exist
// |__ python <--- interpreterPath
// if let Some(parent_path) = PathBuf::from(env.)
// const directory = path.dirname(interpreterPath);
// const files = await fsapi.readdir(directory);
// const regex = /^activate(\.([A-z]|\d)+)?$/i;
if path.join("activate").exists() || path.join("activate.bat").exists() {
return true;
}
// Support for activate.ps, etc.
if let Ok(files) = std::fs::read_dir(path) {
for file in files.filter_map(Result::ok).map(|e| e.path()) {
if file
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default()
.starts_with("activate")
{
return true;
}
}
}
false
}
pub struct VirtualEnv {}
impl VirtualEnv {
pub fn new() -> VirtualEnv {
VirtualEnv {}
}
}
impl Default for VirtualEnv {
fn default() -> Self {
Self::new()
}
}
impl Locator for VirtualEnv {
fn get_name(&self) -> &'static str {
"VirtualEnv"
}
fn supported_categories(&self) -> Vec<PythonEnvironmentKind> {
vec![PythonEnvironmentKind::VirtualEnv]
}
fn try_from(&self, env: &PythonEnv) -> Option<PythonEnvironment> {
if is_virtualenv(env) {
let version = match env.version {
Some(ref v) => Some(v.clone()),
None => match &env.prefix {
Some(prefix) => version::from_creator_for_virtual_env(prefix),
None => None,
},
};
let mut symlinks = vec![];
if let Some(ref prefix) = env.prefix {
symlinks.append(&mut find_executables(prefix));
}
Some(
PythonEnvironmentBuilder::new(Some(PythonEnvironmentKind::VirtualEnv))
.executable(Some(env.executable.clone()))
.version(version)
.prefix(env.prefix.clone())
.symlinks(Some(symlinks))
.build(),
)
} else {
None
}
}
fn find(&self, _reporter: &dyn Reporter) {
// There are no common global locations for virtual environments.
// We expect the user of this class to call `is_compatible`
}
}