Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(deno): create module #2565

Merged
merged 22 commits into from Apr 15, 2021
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 36 additions & 0 deletions docs/config/README.md
Expand Up @@ -199,6 +199,7 @@ $docker_context\
$package\
$cmake\
$dart\
$deno\
$dotnet\
$elixir\
$elm\
Expand Down Expand Up @@ -650,6 +651,41 @@ By default the module will be shown if any of the following conditions are met:
format = "via [🔰 $version](bold red) "
```

## Deno

The `deno` module shows you your currently installed version of Deno.
By default the module will be shown if any of the following conditions are met:
- The current directory contains a `mod.ts`, `mod.js`, `deps.ts` or `deps.js` file

### Options

| Option | Default | Description |
| ------------------- | ------------------------------------------------- | ----------------------------------------------- |
| `format` | `"via [$symbol($version )]($style)"` | The format for the module. |
| `symbol` | `"🦕 "` | A format string representing the symbol of Deno |
Milo123459 marked this conversation as resolved.
Show resolved Hide resolved
| `detect_extensions` | `[]` | Which extensions should trigger this module. |
| `detect_files` | `["mod.ts", "mod.js", "deps.ts", "deps.js"]` | Which filenames should trigger this module. |
| `detect_folders` | `[]` | Which folders should trigger this module. |
| `style` | `"green bold"` | The style for the module. |
| `disabled` | `false` | Disables the `deno` module. |

### Variables

| Variable | Example | Description |
| -------- | -------- | ------------------------------------ |
| version | `v1.8.3` | The version of `deno` |
| symbol | | Mirrors the value of option `symbol` |
| style\* | | Mirrors the value of option `style` |

### Example

```toml
# ~/.config/starship.toml

[deno]
format = "via [🦕 $version](green bold) "
```

## Directory

The `directory` module shows the path to your current directory, truncated to
Expand Down
29 changes: 29 additions & 0 deletions src/configs/deno.rs
@@ -0,0 +1,29 @@
use crate::config::ModuleConfig;

use serde::Serialize;
use starship_module_config_derive::ModuleConfig;

#[derive(Clone, ModuleConfig, Serialize)]
pub struct DenoConfig<'a> {
pub format: &'a str,
pub symbol: &'a str,
pub style: &'a str,
pub disabled: bool,
pub detect_extensions: Vec<&'a str>,
pub detect_files: Vec<&'a str>,
pub detect_folders: Vec<&'a str>,
}

impl<'a> Default for DenoConfig<'a> {
fn default() -> Self {
DenoConfig {
format: "via [$symbol($version )]($style)",
symbol: "🦕 ",
Milo123459 marked this conversation as resolved.
Show resolved Hide resolved
style: "green bold",
disabled: false,
detect_extensions: vec![],
detect_files: vec!["mod.ts", "deps.ts", "mod.js", "deps.js"],
detect_folders: vec![],
}
}
}
2 changes: 2 additions & 0 deletions src/configs/mod.rs
Expand Up @@ -12,6 +12,7 @@ pub mod conda;
pub mod crystal;
pub mod custom;
pub mod dart;
pub mod deno;
pub mod directory;
pub mod docker_context;
pub mod dotnet;
Expand Down Expand Up @@ -80,6 +81,7 @@ pub struct FullConfig<'a> {
conda: conda::CondaConfig<'a>,
crystal: crystal::CrystalConfig<'a>,
dart: dart::DartConfig<'a>,
deno: deno::DenoConfig<'a>,
directory: directory::DirectoryConfig<'a>,
docker_context: docker_context::DockerContextConfig<'a>,
dotnet: dotnet::DotnetConfig<'a>,
Expand Down
1 change: 1 addition & 0 deletions src/configs/starship_root.rs
Expand Up @@ -34,6 +34,7 @@ pub const PROMPT_ORDER: &[&str] = &[
// (Let's keep these sorted alphabetically)
"cmake",
"dart",
"deno",
"dotnet",
"elixir",
"elm",
Expand Down
1 change: 1 addition & 0 deletions src/module.rs
Expand Up @@ -17,6 +17,7 @@ pub const ALL_MODULES: &[&str] = &[
"cmd_duration",
"conda",
"dart",
"deno",
"directory",
"docker_context",
"dotnet",
Expand Down
125 changes: 125 additions & 0 deletions src/modules/deno.rs
@@ -0,0 +1,125 @@
use super::{Context, Module, RootModuleConfig};

use crate::configs::deno::DenoConfig;
use crate::formatter::StringFormatter;

/// Creates a module with the current Deno version
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut module = context.new_module("deno");
let config = DenoConfig::try_load(module.config);
let is_deno_project = context
.try_begin_scan()?
.set_files(&config.detect_files)
.is_match();

if !is_deno_project {
return None;
}

let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter
.map_meta(|var, _| match var {
"symbol" => Some(config.symbol),
_ => None,
})
.map_style(|variable| match variable {
"style" => Some(Ok(config.style)),
_ => None,
})
.map(|variable| match variable {
"version" => context
.exec_cmd("deno", &["-V"])
.and_then(|output| parse_deno_version(output.stdout.trim()))
Milo123459 marked this conversation as resolved.
Show resolved Hide resolved
.map(Ok),
_ => None,
})
.parse(None)
});

module.set_segments(match parsed {
Ok(segments) => segments,
Err(error) => {
log::warn!("Error in module `deno`:\n{}", error);
return None;
}
});

Some(module)
}

fn parse_deno_version(deno_version: &str) -> Option<String> {
let version = deno_version
// split into ["deno", "1.8.3"]
.split_whitespace()
// return "1.8.3"
.nth(1)?;

Some(format!("v{}", version))
}

#[cfg(test)]
mod tests {
use super::parse_deno_version;
use crate::test::ModuleRenderer;
use ansi_term::Color;
use std::fs::File;
use std::io;

#[test]
fn test_parse_deno_version() {
const OUTPUT: &str = "deno 1.8.3\n";
assert_eq!(
parse_deno_version(OUTPUT.trim()),
Some("v1.8.3".to_string())
)
}

#[test]
fn folder_without_deno_files() -> io::Result<()> {
let dir = tempfile::tempdir()?;
let actual = ModuleRenderer::new("deno").path(dir.path()).collect();
let expected = None;
assert_eq!(expected, actual);
dir.close()
}

#[test]
fn folder_with_mod_ts() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("mod.ts"))?.sync_all()?;
let actual = ModuleRenderer::new("deno").path(dir.path()).collect();
let expected = Some(format!("via {}", Color::Green.bold().paint("🦕 v1.8.3 ")));
assert_eq!(expected, actual);
dir.close()
}

#[test]
fn folder_with_mod_js() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("mod.js"))?.sync_all()?;
let actual = ModuleRenderer::new("deno").path(dir.path()).collect();
let expected = Some(format!("via {}", Color::Green.bold().paint("🦕 v1.8.3 ")));
assert_eq!(expected, actual);
dir.close()
}

#[test]
fn folder_with_deps_ts() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("deps.ts"))?.sync_all()?;
let actual = ModuleRenderer::new("deno").path(dir.path()).collect();
let expected = Some(format!("via {}", Color::Green.bold().paint("🦕 v1.8.3 ")));
assert_eq!(expected, actual);
dir.close()
}

#[test]
fn folder_with_deps_js() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("deps.js"))?.sync_all()?;
let actual = ModuleRenderer::new("deno").path(dir.path()).collect();
let expected = Some(format!("via {}", Color::Green.bold().paint("🦕 v1.8.3 ")));
assert_eq!(expected, actual);
dir.close()
}
}
3 changes: 3 additions & 0 deletions src/modules/mod.rs
Expand Up @@ -7,6 +7,7 @@ mod conda;
mod crystal;
pub(crate) mod custom;
mod dart;
mod deno;
mod directory;
mod docker_context;
mod dotnet;
Expand Down Expand Up @@ -80,6 +81,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
"cmd_duration" => cmd_duration::module(context),
"conda" => conda::module(context),
"dart" => dart::module(context),
"deno" => deno::module(context),
"directory" => directory::module(context),
"docker_context" => docker_context::module(context),
"dotnet" => dotnet::module(context),
Expand Down Expand Up @@ -162,6 +164,7 @@ pub fn description(module: &str) -> &'static str {
"conda" => "The current conda environment, if $CONDA_DEFAULT_ENV is set",
"crystal" => "The currently installed version of Crystal",
"dart" => "The currently installed version of Dart",
"deno" => "The currently installed version of Deno",
"directory" => "The current working directory",
"docker_context" => "The current docker context",
"dotnet" => "The relevant version of the .NET Core SDK for the current directory",
Expand Down
4 changes: 4 additions & 0 deletions src/utils.rs
Expand Up @@ -57,6 +57,10 @@ Default target: x86_64-apple-macosx\n",
"Dart VM version: 2.8.4 (stable) (Wed Jun 3 12:26:04 2020 +0200) on \"macos_x64\"",
),
}),
"deno -V" => Some(CommandOutput {
stdout: String::from("deno 1.8.3\n"),
stderr: String::default()
}),
"dummy_command" => Some(CommandOutput {
stdout: String::from("stdout ok!\n"),
stderr: String::from("stderr ok!\n"),
Expand Down