summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThomas O'Donnell <andytom@users.noreply.github.com>2022-04-25 16:18:01 +0200
committerGitHub <noreply@github.com>2022-04-25 16:18:01 +0200
commit2a650bfd140d561f955705cae124fb254ec549a1 (patch)
treef562e86e2ddf8e38944e6b38bc3dc5772fd76e75 /src
parent4471e3654c27948455c1ae509c50acdc469895de (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/context.rs14
-rw-r--r--src/modules/haskell.rs3
-rw-r--r--src/modules/nodejs.rs8
-rw-r--r--src/modules/package.rs37
4 files changed, 35 insertions, 27 deletions
diff --git a/src/context.rs b/src/context.rs
index f84a07cb3..8c95ec687 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -1,7 +1,7 @@
use crate::config::{ModuleConfig, StarshipConfig};
use crate::configs::StarshipRootConfig;
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::utils::{self, home_dir};
@@ -342,6 +342,18 @@ impl<'a> Context<'a> {
.iter()
.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)]
diff --git a/src/modules/haskell.rs b/src/modules/haskell.rs
index a913aeb53..afdb6ed35 100644
--- a/src/modules/haskell.rs
+++ b/src/modules/haskell.rs
@@ -2,7 +2,6 @@ use super::{Context, Module, ModuleConfig};
use crate::configs::haskell::HaskellConfig;
use crate::formatter::StringFormatter;
-use crate::utils;
/// Creates a module with the current Haskell version
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) {
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 version = yaml.first()?["resolver"]
.as_str()
diff --git a/src/modules/nodejs.rs b/src/modules/nodejs.rs
index 07a5790a5..46e8079dd 100644
--- a/src/modules/nodejs.rs
+++ b/src/modules/nodejs.rs
@@ -2,7 +2,6 @@ use super::{Context, Module, ModuleConfig};
use crate::configs::nodejs::NodejsConfig;
use crate::formatter::{StringFormatter, VersionFormatter};
-use crate::utils;
use once_cell::sync::Lazy;
use regex::Regex;
@@ -10,7 +9,6 @@ use semver::Version;
use semver::VersionReq;
use serde_json as json;
use std::ops::Deref;
-use std::path::Path;
/// Creates a module with the current Node.js version
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 {
"style" => {
- let engines_version = get_engines_version(&context.current_dir);
+ let engines_version = get_engines_version(context);
let in_engines_range =
check_engines_version(nodejs_version.deref().as_ref()?, engines_version);
if in_engines_range {
@@ -87,8 +85,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
Some(module)
}
-fn get_engines_version(base_dir: &Path) -> Option<String> {
- let json_str = utils::read_file(base_dir.join("package.json")).ok()?;
+fn get_engines_version(context: &Context) -> Option<String> {
+ let json_str = context.read_file_from_pwd("package.json")?;
let package_json: json::Value = json::from_str(&json_str).ok()?;
let raw_version = package_json.get("engines")?.get("node")?.as_str()?;
Some(raw_version.to_string())
diff --git a/src/modules/package.rs b/src/modules/package.rs
index 31f167b01..d8de5468f 100644
--- a/src/modules/package.rs
+++ b/src/modules/package.rs
@@ -1,7 +1,6 @@
use super::{Context, Module, ModuleConfig};
use crate::configs::package::PackageConfig;
use crate::formatter::{StringFormatter, VersionFormatter};
-use crate::utils;
use ini::Ini;
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> {
- 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()?;
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> {
- 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 raw_version = poetry_toml
.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> {
- 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 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> {
- 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 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> {
- 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 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> {
- 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 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> {
- 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 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> {
- 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 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> {
- let pom_file = utils::read_file(context.current_dir.join("pom.xml")).ok()?;
- let mut reader = QXReader::from_str(&pom_file);
+ let file_contents = context.read_file_from_pwd("pom.xml")?;
+ let mut reader = QXReader::from_str(&file_contents);
reader.trim_text(true);
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> {
- let file_contents = utils::read_file(context.current_dir.join("meson.build"))
- .ok()?
+ let file_contents = context
+ .read_file_from_pwd("meson.build")?
.split_ascii_whitespace()
.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> {
- 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 caps = re.captures(&file_contents)?;
format_version(&caps["version"], config.version_format)
}
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 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> {
- 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 caps = re.captures(&file_contents)?;
format_version(&caps["version"], config.version_format)
}
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 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> {
- 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 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> {
- 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 raw_version = data.first()?["version"].as_str()?;