1use crate::bare::create_bare_venv;
2use camino::{Utf8Path, Utf8PathBuf};
3use dirs::cache_dir;
4use interpreter::InterpreterInfo;
5use std::io;
6use tempfile::PersistError;
7use thiserror::Error;
8
9pub use interpreter::{get_interpreter_info, parse_python_cli};
10
11mod bare;
12mod interpreter;
13#[cfg(feature = "install")]
14mod packages;
15#[cfg(not(feature = "install"))]
16mod virtualenv_cache;
17
18#[derive(Debug, Error)]
19pub enum Error {
20 #[error(transparent)]
21 IO(#[from] io::Error),
22 #[error(transparent)]
24 Persist(#[from] PersistError),
25 #[error("Failed to download wheel from {url} to {path}")]
27 WheelDownload {
28 url: String,
29 path: Utf8PathBuf,
30 #[source]
31 err: io::Error,
32 },
33 #[error("Failed to determine python interpreter to use")]
34 InvalidPythonInterpreter(#[source] Box<dyn std::error::Error + Sync + Send>),
35 #[error("Failed to query python interpreter at {interpreter}")]
36 PythonSubcommand {
37 interpreter: Utf8PathBuf,
38 #[source]
39 err: io::Error,
40 },
41 #[cfg(feature = "install")]
42 #[error("Failed to contact pypi")]
43 MinReq(#[from] minreq::Error),
44 #[cfg(feature = "install")]
45 #[error("Failed to install {package}")]
46 InstallWheel {
47 package: String,
48 #[source]
49 err: install_wheel_rs::Error,
50 },
51}
52
53pub(crate) fn crate_cache_dir() -> io::Result<Utf8PathBuf> {
54 Ok(cache_dir()
55 .and_then(|path| Utf8PathBuf::from_path_buf(path).ok())
56 .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Couldn't detect cache dir"))?
57 .join(env!("CARGO_PKG_NAME")))
58}
59
60pub fn create_venv(
62 location: &Utf8Path,
63 base_python: &Utf8Path,
64 info: &InterpreterInfo,
65 bare: bool,
66) -> Result<(), Error> {
67 let paths = create_bare_venv(location, base_python, info)?;
68
69 if !bare {
70 #[cfg(feature = "install")]
71 {
72 packages::install_base_packages(location, info, &paths)?;
73 }
74 #[cfg(not(feature = "install"))]
75 {
76 virtualenv_cache::install_base_packages(
77 &paths.bin,
78 &paths.interpreter,
79 &paths.site_packages,
80 )?;
81 }
82 }
83
84 Ok(())
85}