From f3984eaf16a795482ac573cc6f9ab16ff7d7abe3 Mon Sep 17 00:00:00 2001 From: Pratik Chaudhary Date: Sun, 9 May 2021 10:23:16 +0545 Subject: feat(package): add support for nimble project package version (#2569) * feat(nim): add support for nimble project package version * Replace find_file with context scanner. Fixes the failing tests. * Replace `utils::exec_cmd` with `context.exec_cmd` so that it uses global timeout * Add tests for nimble project version * Add docs for nimble in package version module for english language * Update docs/config/README.md Co-authored-by: David Knaack * Add test for a case when nimble is not available * Remove extract_vlang_version I don't know why it did not come up while I was fixing merge conflicts on rebase. Co-authored-by: David Knaack --- docs/config/README.md | 6 +-- src/modules/package.rs | 137 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 135 insertions(+), 8 deletions(-) diff --git a/docs/config/README.md b/docs/config/README.md index 1f30d1258..0aee51188 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -2006,13 +2006,13 @@ symbol = "☁️ " ## Package Version The `package` module is shown when the current directory is the repository for a -package, and shows its current version. The module currently supports `npm`, `cargo`, +package, and shows its current version. The module currently supports `npm`, `nimble`, `cargo`, `poetry`, `composer`, `gradle`, `julia`, `mix` and `helm` packages. - [**npm**](https://docs.npmjs.com/cli/commands/npm) – The `npm` package version is extracted from the `package.json` present in the current directory -- [**cargo**](https://doc.rust-lang.org/cargo/) – The `cargo` package version is extracted from the `Cargo.toml` present - in the current directory +- [**cargo**](https://doc.rust-lang.org/cargo/) – The `cargo` package version is extracted from the `Cargo.toml` present in the current directory +- [**nimble**](https://github.com/nim-lang/nimble) - The `nimble` package version is extracted from the `*.nimble` file present in the current directory with the `nimble dump` command - [**poetry**](https://python-poetry.org/) – The `poetry` package version is extracted from the `pyproject.toml` present in the current directory - [**composer**](https://getcomposer.org/) – The `composer` package version is extracted from the `composer.json` present diff --git a/src/modules/package.rs b/src/modules/package.rs index 718ef21ea..8aba829aa 100644 --- a/src/modules/package.rs +++ b/src/modules/package.rs @@ -1,5 +1,3 @@ -use std::path::Path; - use super::{Context, Module, RootModuleConfig}; use crate::configs::package::PackageConfig; use crate::formatter::StringFormatter; @@ -16,7 +14,7 @@ use serde_json as json; pub fn module<'a>(context: &'a Context) -> Option> { let mut module = context.new_module("package"); let config: PackageConfig = PackageConfig::try_load(module.config); - let module_version = get_package_version(&context.current_dir, &config)?; + let module_version = get_package_version(context, &config)?; let parsed = StringFormatter::new(config.format).and_then(|formatter| { formatter @@ -54,6 +52,16 @@ fn extract_cargo_version(file_contents: &str) -> Option { Some(formatted_version) } +fn extract_nimble_version(context: &Context) -> Option { + let cmd_output = context.exec_cmd("nimble", &["dump", "--json"])?; + + let nimble_json: json::Value = json::from_str(&cmd_output.stdout).ok()?; + let raw_version = nimble_json.get("version")?.as_str()?; + + let formatted_version = format_version(raw_version); + Some(formatted_version) +} + fn extract_package_version(file_contents: &str, display_private: bool) -> Option { let package_json: json::Value = json::from_str(file_contents).ok()?; @@ -194,9 +202,17 @@ fn extract_vpkg_version(file_contents: &str) -> Option { Some(formatted_version) } -fn get_package_version(base_dir: &Path, config: &PackageConfig) -> Option { +fn get_package_version(context: &Context, config: &PackageConfig) -> Option { + let base_dir = &context.current_dir; + if let Ok(cargo_toml) = utils::read_file(base_dir.join("Cargo.toml")) { extract_cargo_version(&cargo_toml) + } else if context + .try_begin_scan()? + .set_extensions(&["nimble"]) + .is_match() + { + extract_nimble_version(context) } else if let Ok(package_json) = utils::read_file(base_dir.join("package.json")) { extract_package_version(&package_json, config.display_private) } else if let Ok(poetry_toml) = utils::read_file(base_dir.join("pyproject.toml")) { @@ -236,7 +252,7 @@ fn format_version(version: &str) -> String { #[cfg(test)] mod tests { use super::*; - use crate::test::ModuleRenderer; + use crate::{test::ModuleRenderer, utils::CommandOutput}; use ansi_term::Color; use std::fs::File; use std::io; @@ -274,6 +290,117 @@ mod tests { project_dir.close() } + #[test] + fn test_extract_nimble_package_version() -> io::Result<()> { + let config_name = "test_project.nimble"; + + let config_content = r##" +version = "0.1.0" +author = "Mr. nimble" +description = "A new awesome nimble package" +license = "MIT" +"##; + + let project_dir = create_project_dir()?; + fill_config(&project_dir, config_name, Some(&config_content))?; + + let starship_config = toml::toml! { + [package] + disabled = false + }; + let actual = ModuleRenderer::new("package") + .cmd( + "nimble dump --json", + Some(CommandOutput { + stdout: r##" +{ + "name": "test_project.nimble", + "version": "0.1.0", + "author": "Mr. nimble", + "desc": "A new awesome nimble package", + "license": "MIT", + "skipDirs": [], + "skipFiles": [], + "skipExt": [], + "installDirs": [], + "installFiles": [], + "installExt": [], + "requires": [], + "bin": [], + "binDir": "", + "srcDir": "", + "backend": "c" +} +"## + .to_owned(), + stderr: "".to_owned(), + }), + ) + .path(project_dir.path()) + .config(starship_config) + .collect(); + + let expected = Some(format!( + "is {} ", + Color::Fixed(208).bold().paint(format!("📦 {}", "v0.1.0")) + )); + + assert_eq!(actual, expected); + project_dir.close() + } + + #[test] + fn test_extract_nimble_package_version_for_nimble_directory_when_nimble_is_not_available( + ) -> io::Result<()> { + let config_name = "test_project.nimble"; + + let config_content = r##" +version = "0.1.0" +author = "Mr. nimble" +description = "A new awesome nimble package" +license = "MIT" +"##; + + let project_dir = create_project_dir()?; + fill_config(&project_dir, config_name, Some(&config_content))?; + + let starship_config = toml::toml! { + [package] + disabled = false + }; + let actual = ModuleRenderer::new("package") + .cmd("nimble dump --json", None) + .path(project_dir.path()) + .config(starship_config) + .collect(); + + let expected = None; + + assert_eq!(actual, expected); + project_dir.close() + } + + #[test] + fn test_extract_nimble_package_version_for_non_nimble_directory() -> io::Result<()> { + // Only create an empty directory. There's no .nibmle file for this case. + let project_dir = create_project_dir()?; + + let starship_config = toml::toml! { + [package] + disabled = false + }; + let actual = ModuleRenderer::new("package") + .cmd("nimble dump --json", None) + .path(project_dir.path()) + .config(starship_config) + .collect(); + + let expected = None; + + assert_eq!(actual, expected); + project_dir.close() + } + #[test] fn test_extract_package_version() -> io::Result<()> { let config_name = "package.json"; -- cgit v1.2.3