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: Add a julia module #1030

Merged
merged 3 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ prompt_order = [
"golang",
"haskell",
"java",
"julia",
"nodejs",
"php",
"python",
Expand Down Expand Up @@ -794,6 +795,31 @@ symbol = "+ "
threshold = 4
```

## Julia

The `julia` module shows the currently installed version of Julia.
The module will be shown if any of the following conditions are met:

- The current directory contains a `Project.toml` file
- The current directory contains a `Manifest.toml` file
- The current directory contains a file with the `.jl` extension

### Options

| Variable | Default | Description |
| ---------- | ------------- | -------------------------------------------------------- |
| `symbol` | `"👸 "` | The symbol used before displaying the version of Julia. |
| `style` | `"bold purple"` | The style for the module. |
| `disabled` | `false` | Disables the `julia` module. |

### Example

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

[julia]
symbol = "🤴 "
```
## Kubernetes

Displays the current Kubernetes context name and, if set, the namespace from
Expand Down
23 changes: 23 additions & 0 deletions src/configs/julia.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig};

use ansi_term::{Color, Style};
use starship_module_config_derive::ModuleConfig;

#[derive(Clone, ModuleConfig)]
pub struct JuliaConfig<'a> {
pub symbol: SegmentConfig<'a>,
pub version: SegmentConfig<'a>,
pub style: Style,
pub disabled: bool,
}

impl<'a> RootModuleConfig<'a> for JuliaConfig<'a> {
fn new() -> Self {
JuliaConfig {
symbol: SegmentConfig::new("👸 "),
version: SegmentConfig::default(),
style: Color::Purple.bold(),
disabled: false,
}
}
}
1 change: 1 addition & 0 deletions src/configs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod hg_branch;
pub mod hostname;
pub mod java;
pub mod jobs;
pub mod julia;
pub mod kubernetes;
pub mod memory_usage;
pub mod nix_shell;
Expand Down
1 change: 1 addition & 0 deletions src/configs/starship_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ impl<'a> RootModuleConfig<'a> for StarshipRootConfig<'a> {
"golang",
"haskell",
"java",
"julia",
"nodejs",
"php",
"python",
Expand Down
1 change: 1 addition & 0 deletions src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub const ALL_MODULES: &[&str] = &[
"hostname",
"java",
"jobs",
"julia",
"kubernetes",
"line_break",
"memory_usage",
Expand Down
112 changes: 112 additions & 0 deletions src/modules/julia.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use super::{Context, Module, RootModuleConfig};

use crate::configs::julia::JuliaConfig;
use crate::utils;

/// Creates a module with the current Julia version
///
/// Will display the Julia version if any of the following criteria are met:
/// - Current directory contains a `Project.toml` file
/// - Current directory contains a `Manifest.toml` file
/// - Current directory contains a file with the `.jl` extension
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let is_julia_project = context
.try_begin_scan()?
.set_files(&["Project.toml", "Manifest.toml"])
.set_extensions(&["jl"])
.is_match();

if !is_julia_project {
return None;
}

let mut module = context.new_module("julia");
let config: JuliaConfig = JuliaConfig::try_load(module.config);

module.set_style(config.style);
module.create_segment("symbol", &config.symbol);

let formatted_version =
format_julia_version(&utils::exec_cmd("julia", &["--version"])?.stdout.as_str())?;
module.create_segment("version", &config.version.with_value(&formatted_version));

Some(module)
}

fn format_julia_version(julia_stdout: &str) -> Option<String> {
// julia version output looks like this:
// julia version 1.4.0

let version = julia_stdout
// split into ["", "1.4.0"]
.splitn(2, "julia version")
// return "1.4.0"
.nth(1)?
.split_whitespace()
.next()?;

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

#[cfg(test)]
mod tests {
use super::*;
use crate::modules::utils::test::render_module;
use ansi_term::Color;
use std::fs::File;
use std::io;
use tempfile;

#[test]
fn folder_without_julia_file() -> io::Result<()> {
let dir = tempfile::tempdir()?;

let actual = render_module("julia", dir.path());

let expected = None;
assert_eq!(expected, actual);
dir.close()
}

#[test]
fn folder_with_julia_file() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("hello.jl"))?.sync_all()?;

let actual = render_module("julia", dir.path());

let expected = Some(format!("via {} ", Color::Purple.bold().paint("👸 v1.4.0")));
assert_eq!(expected, actual);
dir.close()
}

#[test]
fn folder_with_project_toml() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("Project.toml"))?.sync_all()?;

let actual = render_module("julia", dir.path());

let expected = Some(format!("via {} ", Color::Purple.bold().paint("👸 v1.4.0")));
assert_eq!(expected, actual);
dir.close()
}

#[test]
fn folder_with_manifest_toml() -> io::Result<()> {
let dir = tempfile::tempdir()?;
File::create(dir.path().join("Manifest.toml"))?.sync_all()?;

let actual = render_module("julia", dir.path());

let expected = Some(format!("via {} ", Color::Purple.bold().paint("👸 v1.4.0")));
assert_eq!(expected, actual);
dir.close()
}

#[test]
fn test_format_julia_version() {
let input = "julia version 1.4.0";
assert_eq!(format_julia_version(input), Some("v1.4.0".to_string()));
}
}
3 changes: 3 additions & 0 deletions src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod hg_branch;
mod hostname;
mod java;
mod jobs;
mod julia;
mod kubernetes;
mod line_break;
mod memory_usage;
Expand Down Expand Up @@ -67,6 +68,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
"hostname" => hostname::module(context),
"java" => java::module(context),
"jobs" => jobs::module(context),
"julia" => julia::module(context),
"kubernetes" => kubernetes::module(context),
"line_break" => line_break::module(context),
"memory_usage" => memory_usage::module(context),
Expand Down Expand Up @@ -110,6 +112,7 @@ pub fn description(module: &str) -> &'static str {
"hostname" => "The system hostname",
"java" => "The currently installed version of Java",
"jobs" => "The current number of jobs running",
"julia" => "The currently installed version of Julia",
"kubernetes" => "The current Kubernetes context name and, if set, the namespace",
"line_break" => "Separates the prompt into two lines",
"memory_usage" => "Current system memory and swap usage",
Expand Down
4 changes: 4 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option<CommandOutput> {
stdout: String::from("go version go1.12.1 linux/amd64"),
stderr: String::default(),
}),
"julia --version" => Some(CommandOutput {
stdout: String::from("julia version 1.4.0"),
stderr: String::default(),
}),
"node --version" => Some(CommandOutput {
stdout: String::from("v12.0.0"),
stderr: String::default(),
Expand Down