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.
# 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]]
name = "aho-corasick"
version = "0.7.13"
@ -333,6 +339,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "dlv-list"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b391911b9a786312a10cb9d2b3d0735adfd5a8113eb3648de26a75e91b0826c"
dependencies = [
"rand",
]
[[package]]
name = "doc-comment"
version = "0.3.3"
@ -430,6 +445,15 @@ dependencies = [
"autocfg",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
dependencies = [
"ahash",
]
[[package]]
name = "hermit-abi"
version = "0.1.15"
@ -468,7 +492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9"
dependencies = [
"autocfg",
"hashbrown",
"hashbrown 0.8.2",
]
[[package]]
@ -787,6 +811,16 @@ dependencies = [
"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]]
name = "os_info"
version = "3.0.0"
@ -1020,6 +1054,16 @@ dependencies = [
"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]]
name = "ryu"
version = "1.0.5"
@ -1153,6 +1197,7 @@ dependencies = [
"rand",
"rayon",
"regex",
"rust-ini",
"serde_json",
"shell-words",
"starship_module_config_derive",

View File

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

View File

@ -1,3 +1,4 @@
use ini::Ini;
use std::path::Path;
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> {
context.get_env("VIRTUAL_ENV").and_then(|venv| {
get_prompt_from_venv(Path::new(&venv)).or_else(|| {
Path::new(&venv)
.file_name()
.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)]
@ -120,8 +130,9 @@ mod tests {
use super::*;
use crate::test::ModuleRenderer;
use ansi_term::Color;
use std::fs::File;
use std::fs::{create_dir_all, File};
use std::io;
use std::io::Write;
#[test]
fn test_format_python_version() {
@ -317,6 +328,33 @@ mod tests {
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>) {
let config = starship_config.unwrap_or(toml::toml! {
[python]