mirror of
https://github.com/Llewellynvdm/starship.git
synced 2024-11-24 21:57:41 +00:00
perf(package): only try to read files that exist (#3904)
* perf(package): only try to read files that exist Have refactored the package module to improve performance. Before this change the module would try to open every single file that could contain some package information until it found a valid version. This resulted in a lot of unneeded disk IO. Have added a new fn, `read_file_from_pwd` that uses the current context to check if that file already exists and fast failing if it doesn't. From my local testing this speeds up the package module from taking ~1ms to ~50µs in an empty directory. * refactor: move read_file_from_pwd to context * refactor(haskell): use read_files_from_pwd * refactor(nodejs): use read_files_from_pwd
This commit is contained in:
parent
4471e3654c
commit
2a650bfd14
@ -1,7 +1,7 @@
|
|||||||
use crate::config::{ModuleConfig, StarshipConfig};
|
use crate::config::{ModuleConfig, StarshipConfig};
|
||||||
use crate::configs::StarshipRootConfig;
|
use crate::configs::StarshipRootConfig;
|
||||||
use crate::module::Module;
|
use crate::module::Module;
|
||||||
use crate::utils::{create_command, exec_timeout, CommandOutput};
|
use crate::utils::{create_command, exec_timeout, read_file, CommandOutput};
|
||||||
|
|
||||||
use crate::modules;
|
use crate::modules;
|
||||||
use crate::utils::{self, home_dir};
|
use crate::utils::{self, home_dir};
|
||||||
@ -342,6 +342,18 @@ impl<'a> Context<'a> {
|
|||||||
.iter()
|
.iter()
|
||||||
.find_map(|attempt| self.exec_cmd(attempt[0], &attempt[1..]))
|
.find_map(|attempt| self.exec_cmd(attempt[0], &attempt[1..]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the string contents of a file from the current working directory
|
||||||
|
pub fn read_file_from_pwd(&self, file_name: &str) -> Option<String> {
|
||||||
|
if !self.try_begin_scan()?.set_files(&[file_name]).is_match() {
|
||||||
|
log::debug!(
|
||||||
|
"Not attempting to read {file_name} because, it was not found during scan."
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_file(self.current_dir.join(file_name)).ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -2,7 +2,6 @@ use super::{Context, Module, ModuleConfig};
|
|||||||
|
|
||||||
use crate::configs::haskell::HaskellConfig;
|
use crate::configs::haskell::HaskellConfig;
|
||||||
use crate::formatter::StringFormatter;
|
use crate::formatter::StringFormatter;
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
/// Creates a module with the current Haskell version
|
/// Creates a module with the current Haskell version
|
||||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
@ -64,7 +63,7 @@ fn get_snapshot(context: &Context) -> Option<String> {
|
|||||||
if !is_stack_project(context) {
|
if !is_stack_project(context) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let file_contents = utils::read_file(context.current_dir.join("stack.yaml")).ok()?;
|
let file_contents = context.read_file_from_pwd("stack.yaml")?;
|
||||||
let yaml = yaml_rust::YamlLoader::load_from_str(&file_contents).ok()?;
|
let yaml = yaml_rust::YamlLoader::load_from_str(&file_contents).ok()?;
|
||||||
let version = yaml.first()?["resolver"]
|
let version = yaml.first()?["resolver"]
|
||||||
.as_str()
|
.as_str()
|
||||||
|
@ -2,7 +2,6 @@ use super::{Context, Module, ModuleConfig};
|
|||||||
|
|
||||||
use crate::configs::nodejs::NodejsConfig;
|
use crate::configs::nodejs::NodejsConfig;
|
||||||
use crate::formatter::{StringFormatter, VersionFormatter};
|
use crate::formatter::{StringFormatter, VersionFormatter};
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
@ -10,7 +9,6 @@ use semver::Version;
|
|||||||
use semver::VersionReq;
|
use semver::VersionReq;
|
||||||
use serde_json as json;
|
use serde_json as json;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
/// Creates a module with the current Node.js version
|
/// Creates a module with the current Node.js version
|
||||||
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
@ -45,7 +43,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
|||||||
})
|
})
|
||||||
.map_style(|variable| match variable {
|
.map_style(|variable| match variable {
|
||||||
"style" => {
|
"style" => {
|
||||||
let engines_version = get_engines_version(&context.current_dir);
|
let engines_version = get_engines_version(context);
|
||||||
let in_engines_range =
|
let in_engines_range =
|
||||||
check_engines_version(nodejs_version.deref().as_ref()?, engines_version);
|
check_engines_version(nodejs_version.deref().as_ref()?, engines_version);
|
||||||
if in_engines_range {
|
if in_engines_range {
|
||||||
@ -87,8 +85,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
|||||||
Some(module)
|
Some(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_engines_version(base_dir: &Path) -> Option<String> {
|
fn get_engines_version(context: &Context) -> Option<String> {
|
||||||
let json_str = utils::read_file(base_dir.join("package.json")).ok()?;
|
let json_str = context.read_file_from_pwd("package.json")?;
|
||||||
let package_json: json::Value = json::from_str(&json_str).ok()?;
|
let package_json: json::Value = json::from_str(&json_str).ok()?;
|
||||||
let raw_version = package_json.get("engines")?.get("node")?.as_str()?;
|
let raw_version = package_json.get("engines")?.get("node")?.as_str()?;
|
||||||
Some(raw_version.to_string())
|
Some(raw_version.to_string())
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use super::{Context, Module, ModuleConfig};
|
use super::{Context, Module, ModuleConfig};
|
||||||
use crate::configs::package::PackageConfig;
|
use crate::configs::package::PackageConfig;
|
||||||
use crate::formatter::{StringFormatter, VersionFormatter};
|
use crate::formatter::{StringFormatter, VersionFormatter};
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
use ini::Ini;
|
use ini::Ini;
|
||||||
use quick_xml::events::Event as QXEvent;
|
use quick_xml::events::Event as QXEvent;
|
||||||
@ -44,7 +43,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_node_package_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_node_package_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(&context.current_dir.join("package.json")).ok()?;
|
let file_contents = context.read_file_from_pwd("package.json")?;
|
||||||
let package_json: json::Value = json::from_str(&file_contents).ok()?;
|
let package_json: json::Value = json::from_str(&file_contents).ok()?;
|
||||||
|
|
||||||
if !config.display_private
|
if !config.display_private
|
||||||
@ -68,7 +67,7 @@ fn get_node_package_version(context: &Context, config: &PackageConfig) -> Option
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_poetry_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_poetry_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(&context.current_dir.join("pyproject.toml")).ok()?;
|
let file_contents = context.read_file_from_pwd("pyproject.toml")?;
|
||||||
let poetry_toml: toml::Value = toml::from_str(&file_contents).ok()?;
|
let poetry_toml: toml::Value = toml::from_str(&file_contents).ok()?;
|
||||||
let raw_version = poetry_toml
|
let raw_version = poetry_toml
|
||||||
.get("tool")?
|
.get("tool")?
|
||||||
@ -80,7 +79,7 @@ fn get_poetry_version(context: &Context, config: &PackageConfig) -> Option<Strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_setup_cfg_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_setup_cfg_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("setup.cfg")).ok()?;
|
let file_contents = context.read_file_from_pwd("setup.cfg")?;
|
||||||
let ini = Ini::load_from_str(&file_contents).ok()?;
|
let ini = Ini::load_from_str(&file_contents).ok()?;
|
||||||
let raw_version = ini.get_from(Some("metadata"), "version")?;
|
let raw_version = ini.get_from(Some("metadata"), "version")?;
|
||||||
|
|
||||||
@ -92,7 +91,7 @@ fn get_setup_cfg_version(context: &Context, config: &PackageConfig) -> Option<St
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_gradle_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_gradle_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("build.gradle")).ok()?;
|
let file_contents = context.read_file_from_pwd("build.gradle")?;
|
||||||
let re = Regex::new(r#"(?m)^version ['"](?P<version>[^'"]+)['"]$"#).unwrap();
|
let re = Regex::new(r#"(?m)^version ['"](?P<version>[^'"]+)['"]$"#).unwrap();
|
||||||
let caps = re.captures(&file_contents)?;
|
let caps = re.captures(&file_contents)?;
|
||||||
|
|
||||||
@ -100,7 +99,7 @@ fn get_gradle_version(context: &Context, config: &PackageConfig) -> Option<Strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_composer_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_composer_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("composer.json")).ok()?;
|
let file_contents = context.read_file_from_pwd("composer.json")?;
|
||||||
let composer_json: json::Value = json::from_str(&file_contents).ok()?;
|
let composer_json: json::Value = json::from_str(&file_contents).ok()?;
|
||||||
let raw_version = composer_json.get("version")?.as_str()?;
|
let raw_version = composer_json.get("version")?.as_str()?;
|
||||||
|
|
||||||
@ -108,7 +107,7 @@ fn get_composer_version(context: &Context, config: &PackageConfig) -> Option<Str
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_julia_project_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_julia_project_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("Project.toml")).ok()?;
|
let file_contents = context.read_file_from_pwd("Project.toml")?;
|
||||||
let project_toml: toml::Value = toml::from_str(&file_contents).ok()?;
|
let project_toml: toml::Value = toml::from_str(&file_contents).ok()?;
|
||||||
let raw_version = project_toml.get("version")?.as_str()?;
|
let raw_version = project_toml.get("version")?.as_str()?;
|
||||||
|
|
||||||
@ -116,7 +115,7 @@ fn get_julia_project_version(context: &Context, config: &PackageConfig) -> Optio
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_helm_package_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_helm_package_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("Chart.yaml")).ok()?;
|
let file_contents = context.read_file_from_pwd("Chart.yaml")?;
|
||||||
let yaml = yaml_rust::YamlLoader::load_from_str(&file_contents).ok()?;
|
let yaml = yaml_rust::YamlLoader::load_from_str(&file_contents).ok()?;
|
||||||
let version = yaml.first()?["version"].as_str()?;
|
let version = yaml.first()?["version"].as_str()?;
|
||||||
|
|
||||||
@ -124,7 +123,7 @@ fn get_helm_package_version(context: &Context, config: &PackageConfig) -> Option
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_mix_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_mix_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("mix.exs")).ok()?;
|
let file_contents = context.read_file_from_pwd("mix.exs")?;
|
||||||
let re = Regex::new(r#"(?m)version: "(?P<version>[^"]+)""#).unwrap();
|
let re = Regex::new(r#"(?m)version: "(?P<version>[^"]+)""#).unwrap();
|
||||||
let caps = re.captures(&file_contents)?;
|
let caps = re.captures(&file_contents)?;
|
||||||
|
|
||||||
@ -132,8 +131,8 @@ fn get_mix_version(context: &Context, config: &PackageConfig) -> Option<String>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_maven_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_maven_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let pom_file = utils::read_file(context.current_dir.join("pom.xml")).ok()?;
|
let file_contents = context.read_file_from_pwd("pom.xml")?;
|
||||||
let mut reader = QXReader::from_str(&pom_file);
|
let mut reader = QXReader::from_str(&file_contents);
|
||||||
reader.trim_text(true);
|
reader.trim_text(true);
|
||||||
|
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
@ -171,8 +170,8 @@ fn get_maven_version(context: &Context, config: &PackageConfig) -> Option<String
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_meson_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_meson_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("meson.build"))
|
let file_contents = context
|
||||||
.ok()?
|
.read_file_from_pwd("meson.build")?
|
||||||
.split_ascii_whitespace()
|
.split_ascii_whitespace()
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
|
|
||||||
@ -183,14 +182,14 @@ fn get_meson_version(context: &Context, config: &PackageConfig) -> Option<String
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_vmod_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_vmod_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("v.mod")).ok()?;
|
let file_contents = context.read_file_from_pwd("v.mod")?;
|
||||||
let re = Regex::new(r"(?m)^\s*version\s*:\s*'(?P<version>[^']+)'").unwrap();
|
let re = Regex::new(r"(?m)^\s*version\s*:\s*'(?P<version>[^']+)'").unwrap();
|
||||||
let caps = re.captures(&file_contents)?;
|
let caps = re.captures(&file_contents)?;
|
||||||
format_version(&caps["version"], config.version_format)
|
format_version(&caps["version"], config.version_format)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_vpkg_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_vpkg_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("vpkg.json")).ok()?;
|
let file_contents = context.read_file_from_pwd("vpkg.json")?;
|
||||||
let vpkg_json: json::Value = json::from_str(&file_contents).ok()?;
|
let vpkg_json: json::Value = json::from_str(&file_contents).ok()?;
|
||||||
let raw_version = vpkg_json.get("version")?.as_str()?;
|
let raw_version = vpkg_json.get("version")?.as_str()?;
|
||||||
|
|
||||||
@ -198,14 +197,14 @@ fn get_vpkg_version(context: &Context, config: &PackageConfig) -> Option<String>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_sbt_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_sbt_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(context.current_dir.join("build.sbt")).ok()?;
|
let file_contents = context.read_file_from_pwd("build.sbt")?;
|
||||||
let re = Regex::new(r"(?m)^(.*/)*\s*version\s*:=\s*.(?P<version>[\d\.]+)").unwrap();
|
let re = Regex::new(r"(?m)^(.*/)*\s*version\s*:=\s*.(?P<version>[\d\.]+)").unwrap();
|
||||||
let caps = re.captures(&file_contents)?;
|
let caps = re.captures(&file_contents)?;
|
||||||
format_version(&caps["version"], config.version_format)
|
format_version(&caps["version"], config.version_format)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cargo_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_cargo_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(&context.current_dir.join("Cargo.toml")).ok()?;
|
let file_contents = context.read_file_from_pwd("Cargo.toml")?;
|
||||||
|
|
||||||
let cargo_toml: toml::Value = toml::from_str(&file_contents).ok()?;
|
let cargo_toml: toml::Value = toml::from_str(&file_contents).ok()?;
|
||||||
let raw_version = cargo_toml.get("package")?.get("version")?.as_str()?;
|
let raw_version = cargo_toml.get("package")?.get("version")?.as_str()?;
|
||||||
@ -231,7 +230,7 @@ fn get_nimble_version(context: &Context, config: &PackageConfig) -> Option<Strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_shard_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_shard_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(&context.current_dir.join("shard.yml")).ok()?;
|
let file_contents = context.read_file_from_pwd("shard.yml")?;
|
||||||
|
|
||||||
let data = yaml_rust::YamlLoader::load_from_str(&file_contents).ok()?;
|
let data = yaml_rust::YamlLoader::load_from_str(&file_contents).ok()?;
|
||||||
let raw_version = data.first()?["version"].as_str()?;
|
let raw_version = data.first()?["version"].as_str()?;
|
||||||
@ -240,7 +239,7 @@ fn get_shard_version(context: &Context, config: &PackageConfig) -> Option<String
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_dart_pub_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
fn get_dart_pub_version(context: &Context, config: &PackageConfig) -> Option<String> {
|
||||||
let file_contents = utils::read_file(&context.current_dir.join("pubspec.yaml")).ok()?;
|
let file_contents = context.read_file_from_pwd("pubspec.yaml")?;
|
||||||
|
|
||||||
let data = yaml_rust::YamlLoader::load_from_str(&file_contents).ok()?;
|
let data = yaml_rust::YamlLoader::load_from_str(&file_contents).ok()?;
|
||||||
let raw_version = data.first()?["version"].as_str()?;
|
let raw_version = data.first()?["version"].as_str()?;
|
||||||
|
Loading…
Reference in New Issue
Block a user