fix(python): Read venv prompt from pyvenv.cfg (#1747)

*  Add  --prompt rendering to python virtualenv

* Use pyvenv.cfg to find prompt

* Remove usage of VIRTUAL_ENV_PROMPT variable

Seeing how both venv and virtualenv set a pyvenv.cfg, this isn't needed.
Additionally pyvenv.cfg is set in earlier versions than VIRTUAL_ENV_PROMPT,
which at this moment is in the unrelased python 3.10

* Smarter result unwrapping thanks to clippy
This commit is contained in:
Tomer 2020-10-08 10:58:00 +03:00 committed by GitHub
parent 7c941af11a
commit a9f6d0f81e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 5 deletions

47
Cargo.lock generated
View File

@ -1,5 +1,11 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]]
name = "ahash"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0adac150c2dd5a9c864d054e07bda5e6bc010cd10036ea5f17e82a2f5867f735"
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.13" version = "0.7.13"
@ -333,6 +339,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "dlv-list"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b391911b9a786312a10cb9d2b3d0735adfd5a8113eb3648de26a75e91b0826c"
dependencies = [
"rand",
]
[[package]] [[package]]
name = "doc-comment" name = "doc-comment"
version = "0.3.3" version = "0.3.3"
@ -430,6 +445,15 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
dependencies = [
"ahash",
]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.15" version = "0.1.15"
@ -468,7 +492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9" checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown", "hashbrown 0.8.2",
] ]
[[package]] [[package]]
@ -787,6 +811,16 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "ordered-multimap"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87a6df8506c2d359d5105344891f283e8e7ef81a7c6a542d516f8707e4a09b6b"
dependencies = [
"dlv-list",
"hashbrown 0.9.1",
]
[[package]] [[package]]
name = "os_info" name = "os_info"
version = "3.0.0" version = "3.0.0"
@ -1020,6 +1054,16 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "rust-ini"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcdbf249a931ceb503aa80e08ca016675dbc7884eda8e2d88e85533d4dbade62"
dependencies = [
"cfg-if",
"ordered-multimap",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.5" version = "1.0.5"
@ -1153,6 +1197,7 @@ dependencies = [
"rand", "rand",
"rayon", "rayon",
"regex", "regex",
"rust-ini",
"serde_json", "serde_json",
"shell-words", "shell-words",
"starship_module_config_derive", "starship_module_config_derive",

View File

@ -33,6 +33,7 @@ ansi_term = "0.12.1"
dirs-next = "1.0.1" dirs-next = "1.0.1"
git2 = { version = "0.13.11", default-features = false } git2 = { version = "0.13.11", default-features = false }
toml = { version = "0.5.6", features = ["preserve_order"] } toml = { version = "0.5.6", features = ["preserve_order"] }
rust-ini = "0.16"
serde_json = "1.0.58" serde_json = "1.0.58"
rayon = "1.4.1" rayon = "1.4.1"
log = { version = "0.4.11", features = ["std"] } log = { version = "0.4.11", features = ["std"] }

View File

@ -1,3 +1,4 @@
use ini::Ini;
use std::path::Path; use std::path::Path;
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, RootModuleConfig};
@ -109,10 +110,19 @@ fn format_python_version(python_stdout: &str) -> String {
fn get_python_virtual_env(context: &Context) -> Option<String> { fn get_python_virtual_env(context: &Context) -> Option<String> {
context.get_env("VIRTUAL_ENV").and_then(|venv| { context.get_env("VIRTUAL_ENV").and_then(|venv| {
get_prompt_from_venv(Path::new(&venv)).or_else(|| {
Path::new(&venv) Path::new(&venv)
.file_name() .file_name()
.map(|filename| String::from(filename.to_str().unwrap_or(""))) .map(|filename| String::from(filename.to_str().unwrap_or("")))
}) })
})
}
fn get_prompt_from_venv(venv_path: &Path) -> Option<String> {
Ini::load_from_file(venv_path.join("pyvenv.cfg"))
.ok()?
.general_section()
.get("prompt")
.map(String::from)
} }
#[cfg(test)] #[cfg(test)]
@ -120,8 +130,9 @@ mod tests {
use super::*; use super::*;
use crate::test::ModuleRenderer; use crate::test::ModuleRenderer;
use ansi_term::Color; use ansi_term::Color;
use std::fs::File; use std::fs::{create_dir_all, File};
use std::io; use std::io;
use std::io::Write;
#[test] #[test]
fn test_format_python_version() { fn test_format_python_version() {
@ -317,6 +328,33 @@ mod tests {
dir.close() dir.close()
} }
#[test]
fn with_active_venv_and_prompt() -> io::Result<()> {
let dir = tempfile::tempdir()?;
create_dir_all(dir.path().join("my_venv"))?;
let mut venv_cfg = File::create(dir.path().join("my_venv").join("pyvenv.cfg"))?;
venv_cfg.write_all(
br#"
home = something
prompt = 'foo'
"#,
)?;
venv_cfg.sync_all()?;
let actual = ModuleRenderer::new("python")
.path(dir.path())
.env("VIRTUAL_ENV", dir.path().join("my_venv").to_str().unwrap())
.collect();
let expected = Some(format!(
"via {} ",
Color::Yellow.bold().paint("🐍 v2.7.17 (foo)")
));
assert_eq!(actual, expected);
dir.close()
}
fn check_python2_renders(dir: &tempfile::TempDir, starship_config: Option<toml::Value>) { fn check_python2_renders(dir: &tempfile::TempDir, starship_config: Option<toml::Value>) {
let config = starship_config.unwrap_or(toml::toml! { let config = starship_config.unwrap_or(toml::toml! {
[python] [python]