1use std::io;
2use std::path::Path;
3
4use thiserror::Error;
5
6use uv_preview::Preview;
7use uv_python::{Interpreter, PythonEnvironment};
8
9pub use virtualenv::{OnExisting, RemovalReason, remove_virtualenv};
10
11mod virtualenv;
12
13#[derive(Debug, Error)]
14pub enum Error {
15 #[error(transparent)]
16 Io(#[from] io::Error),
17 #[error(
18 "Could not find a suitable Python executable for the virtual environment based on the interpreter: {0}"
19 )]
20 NotFound(String),
21 #[error(transparent)]
22 Python(#[from] uv_python::managed::Error),
23}
24
25#[derive(Debug)]
27pub enum Prompt {
28 CurrentDirectoryName,
30 Static(String),
32 None,
35}
36
37impl Prompt {
38 pub fn from_args(prompt: Option<String>) -> Self {
40 match prompt {
41 Some(prompt) if prompt == "." => Self::CurrentDirectoryName,
42 Some(prompt) => Self::Static(prompt),
43 None => Self::None,
44 }
45 }
46}
47
48#[allow(clippy::fn_params_excessive_bools)]
50pub fn create_venv(
51 location: &Path,
52 interpreter: Interpreter,
53 prompt: Prompt,
54 system_site_packages: bool,
55 on_existing: OnExisting,
56 relocatable: bool,
57 seed: bool,
58 upgradeable: bool,
59 preview: Preview,
60) -> Result<PythonEnvironment, Error> {
61 let virtualenv = virtualenv::create(
63 location,
64 &interpreter,
65 prompt,
66 system_site_packages,
67 on_existing,
68 relocatable,
69 seed,
70 upgradeable,
71 preview,
72 )?;
73
74 let interpreter = interpreter.with_virtualenv(virtualenv);
76 Ok(PythonEnvironment::from_interpreter(interpreter))
77}