mirror of
https://github.com/Llewellynvdm/starship.git
synced 2024-11-24 13:47:38 +00:00
feat: add Raku module (#4048)
* feat: add Raku module * Update docs/config/README.md Co-authored-by: Thomas O'Donnell <andytom@users.noreply.github.com> Co-authored-by: Thomas O'Donnell <andytom@users.noreply.github.com>
This commit is contained in:
parent
73425e7417
commit
1a4fac63f7
79
.github/config-schema.json
vendored
79
.github/config-schema.json
vendored
@ -1091,6 +1091,31 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"raku": {
|
||||||
|
"default": {
|
||||||
|
"detect_extensions": [
|
||||||
|
"p6",
|
||||||
|
"pm6",
|
||||||
|
"pod6",
|
||||||
|
"raku",
|
||||||
|
"rakumod"
|
||||||
|
],
|
||||||
|
"detect_files": [
|
||||||
|
"META6.json"
|
||||||
|
],
|
||||||
|
"detect_folders": [],
|
||||||
|
"disabled": false,
|
||||||
|
"format": "via [$symbol($version-$vm_version )]($style)",
|
||||||
|
"style": "149 bold",
|
||||||
|
"symbol": "🦋 ",
|
||||||
|
"version_format": "${raw}"
|
||||||
|
},
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/RakuConfig"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"red": {
|
"red": {
|
||||||
"default": {
|
"default": {
|
||||||
"detect_extensions": [
|
"detect_extensions": [
|
||||||
@ -3948,6 +3973,60 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"RakuConfig": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"format": {
|
||||||
|
"default": "via [$symbol($version-$vm_version )]($style)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"version_format": {
|
||||||
|
"default": "${raw}",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"symbol": {
|
||||||
|
"default": "🦋 ",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"default": "149 bold",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"default": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"detect_extensions": {
|
||||||
|
"default": [
|
||||||
|
"p6",
|
||||||
|
"pm6",
|
||||||
|
"pod6",
|
||||||
|
"raku",
|
||||||
|
"rakumod"
|
||||||
|
],
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"detect_files": {
|
||||||
|
"default": [
|
||||||
|
"META6.json"
|
||||||
|
],
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"detect_folders": {
|
||||||
|
"default": [],
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"RedConfig": {
|
"RedConfig": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -115,6 +115,9 @@ format = '\[[$symbol($version)]($style)\]'
|
|||||||
[python]
|
[python]
|
||||||
format = '\[[${symbol}${pyenv_prefix}(${version})(\($virtualenv\))]($style)\]'
|
format = '\[[${symbol}${pyenv_prefix}(${version})(\($virtualenv\))]($style)\]'
|
||||||
|
|
||||||
|
[raku]
|
||||||
|
format = '\[[$symbol($version-$vm_version)]($style)\]'
|
||||||
|
|
||||||
[red]
|
[red]
|
||||||
format = '\[[$symbol($version)]($style)\]'
|
format = '\[[$symbol($version)]($style)\]'
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@ format = 'via [$symbol]($style)'
|
|||||||
[python]
|
[python]
|
||||||
format = 'via [$symbol]($style)'
|
format = 'via [$symbol]($style)'
|
||||||
|
|
||||||
|
[raku]
|
||||||
|
format = 'via [$symbol]($style)'
|
||||||
|
|
||||||
[red]
|
[red]
|
||||||
format = 'via [$symbol]($style)'
|
format = 'via [$symbol]($style)'
|
||||||
|
|
||||||
|
@ -109,6 +109,9 @@ symbol = "purs "
|
|||||||
[python]
|
[python]
|
||||||
symbol = "py "
|
symbol = "py "
|
||||||
|
|
||||||
|
[raku]
|
||||||
|
symbol = "raku "
|
||||||
|
|
||||||
[ruby]
|
[ruby]
|
||||||
symbol = "rb "
|
symbol = "rb "
|
||||||
|
|
||||||
|
@ -2928,6 +2928,45 @@ any of the following conditions are met:
|
|||||||
format = "with [📐 $version](blue bold) "
|
format = "with [📐 $version](blue bold) "
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Raku
|
||||||
|
|
||||||
|
The `raku` module shows the currently installed version of [Raku](https://www.raku.org/).
|
||||||
|
By default the module will be shown if any of the following conditions are met:
|
||||||
|
|
||||||
|
- The current directory contains a `META6.json` file
|
||||||
|
- The current directory contains a `.p6`, `.pm6`, `.raku`, `.rakumod` or `.pod6`
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
| Option | Default | Description |
|
||||||
|
| ------------------- | ------------------------------------------------ | ------------------------------------------------------------------------- |
|
||||||
|
| `format` | `"via [$symbol($version-$vm_version )]($style)"` | The format string for the module. |
|
||||||
|
| `version_format` | `"v${raw}"` | The version format. Available vars are `raw`, `major`, `minor`, & `patch` |
|
||||||
|
| `symbol` | `"🦋 "` | The symbol used before displaying the version of Raku |
|
||||||
|
| `detect_extensions` | `["p6", "pm6", "pod6", "raku", "rakumod"]` | Which extensions should trigger this module. |
|
||||||
|
| `detect_files` | `["META6.json"]` | Which filenames should trigger this module. |
|
||||||
|
| `detect_folders` | `[]` | Which folders should trigger this module. |
|
||||||
|
| `style` | `"bold 149"` | The style for the module. |
|
||||||
|
| `disabled` | `false` | Disables the `raku` module. |
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
|
||||||
|
| Variable | Example | Description |
|
||||||
|
| ---------- | ------- | ------------------------------------ |
|
||||||
|
| version | `v6.d` | The version of `raku` |
|
||||||
|
| vm_version | `moar` | The version of VM `raku` is built on |
|
||||||
|
| symbol | | Mirrors the value of option `symbol` |
|
||||||
|
| style\* | | Mirrors the value of option `style` |
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# ~/.config/starship.toml
|
||||||
|
|
||||||
|
[raku]
|
||||||
|
format = "via [🦪 $version]($style) "
|
||||||
|
```
|
||||||
|
|
||||||
## Red
|
## Red
|
||||||
|
|
||||||
By default the `red` module shows the currently installed version of [Red](https://www.red-lang.org/).
|
By default the `red` module shows the currently installed version of [Red](https://www.red-lang.org/).
|
||||||
|
@ -56,6 +56,7 @@ pub mod php;
|
|||||||
pub mod pulumi;
|
pub mod pulumi;
|
||||||
pub mod purescript;
|
pub mod purescript;
|
||||||
pub mod python;
|
pub mod python;
|
||||||
|
pub mod raku;
|
||||||
pub mod red;
|
pub mod red;
|
||||||
pub mod rlang;
|
pub mod rlang;
|
||||||
pub mod ruby;
|
pub mod ruby;
|
||||||
@ -198,6 +199,8 @@ pub struct FullConfig<'a> {
|
|||||||
#[serde(borrow)]
|
#[serde(borrow)]
|
||||||
python: python::PythonConfig<'a>,
|
python: python::PythonConfig<'a>,
|
||||||
#[serde(borrow)]
|
#[serde(borrow)]
|
||||||
|
raku: raku::RakuConfig<'a>,
|
||||||
|
#[serde(borrow)]
|
||||||
red: red::RedConfig<'a>,
|
red: red::RedConfig<'a>,
|
||||||
#[serde(borrow)]
|
#[serde(borrow)]
|
||||||
rlang: rlang::RLangConfig<'a>,
|
rlang: rlang::RLangConfig<'a>,
|
||||||
|
30
src/configs/raku.rs
Normal file
30
src/configs/raku.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
#[cfg_attr(feature = "config-schema", derive(schemars::JsonSchema))]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct RakuConfig<'a> {
|
||||||
|
pub format: &'a str,
|
||||||
|
pub version_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 RakuConfig<'a> {
|
||||||
|
fn default() -> Self {
|
||||||
|
RakuConfig {
|
||||||
|
format: "via [$symbol($version-$vm_version )]($style)",
|
||||||
|
version_format: "${raw}",
|
||||||
|
symbol: "🦋 ",
|
||||||
|
style: "149 bold",
|
||||||
|
disabled: false,
|
||||||
|
detect_extensions: vec!["p6", "pm6", "pod6", "raku", "rakumod"],
|
||||||
|
detect_files: vec!["META6.json"],
|
||||||
|
detect_folders: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -61,6 +61,7 @@ pub const PROMPT_ORDER: &[&str] = &[
|
|||||||
"pulumi",
|
"pulumi",
|
||||||
"purescript",
|
"purescript",
|
||||||
"python",
|
"python",
|
||||||
|
"raku",
|
||||||
"rlang",
|
"rlang",
|
||||||
"red",
|
"red",
|
||||||
"ruby",
|
"ruby",
|
||||||
|
@ -64,6 +64,7 @@ pub const ALL_MODULES: &[&str] = &[
|
|||||||
"pulumi",
|
"pulumi",
|
||||||
"purescript",
|
"purescript",
|
||||||
"python",
|
"python",
|
||||||
|
"raku",
|
||||||
"red",
|
"red",
|
||||||
"rlang",
|
"rlang",
|
||||||
"ruby",
|
"ruby",
|
||||||
|
@ -53,6 +53,7 @@ mod php;
|
|||||||
mod pulumi;
|
mod pulumi;
|
||||||
mod purescript;
|
mod purescript;
|
||||||
mod python;
|
mod python;
|
||||||
|
mod raku;
|
||||||
mod red;
|
mod red;
|
||||||
mod rlang;
|
mod rlang;
|
||||||
mod ruby;
|
mod ruby;
|
||||||
@ -145,6 +146,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
|
|||||||
"pulumi" => pulumi::module(context),
|
"pulumi" => pulumi::module(context),
|
||||||
"purescript" => purescript::module(context),
|
"purescript" => purescript::module(context),
|
||||||
"python" => python::module(context),
|
"python" => python::module(context),
|
||||||
|
"raku" => raku::module(context),
|
||||||
"rlang" => rlang::module(context),
|
"rlang" => rlang::module(context),
|
||||||
"red" => red::module(context),
|
"red" => red::module(context),
|
||||||
"ruby" => ruby::module(context),
|
"ruby" => ruby::module(context),
|
||||||
@ -248,6 +250,7 @@ pub fn description(module: &str) -> &'static str {
|
|||||||
"pulumi" => "The current username, stack, and installed version of Pulumi",
|
"pulumi" => "The current username, stack, and installed version of Pulumi",
|
||||||
"purescript" => "The currently installed version of PureScript",
|
"purescript" => "The currently installed version of PureScript",
|
||||||
"python" => "The currently installed version of Python",
|
"python" => "The currently installed version of Python",
|
||||||
|
"raku" => "The currently installed version of Raku",
|
||||||
"red" => "The currently installed version of Red",
|
"red" => "The currently installed version of Red",
|
||||||
"rlang" => "The currently installed version of R",
|
"rlang" => "The currently installed version of R",
|
||||||
"ruby" => "The currently installed version of Ruby",
|
"ruby" => "The currently installed version of Ruby",
|
||||||
|
199
src/modules/raku.rs
Normal file
199
src/modules/raku.rs
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
use super::{Context, Module, ModuleConfig};
|
||||||
|
|
||||||
|
use crate::configs::raku::RakuConfig;
|
||||||
|
use crate::formatter::StringFormatter;
|
||||||
|
use crate::formatter::VersionFormatter;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
/// Creates a module with the current raku version
|
||||||
|
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
|
let mut module = context.new_module("raku");
|
||||||
|
let config: RakuConfig = RakuConfig::try_load(module.config);
|
||||||
|
let is_raku_project = context
|
||||||
|
.try_begin_scan()?
|
||||||
|
.set_extensions(&config.detect_extensions)
|
||||||
|
.set_files(&config.detect_files)
|
||||||
|
.set_folders(&config.detect_folders)
|
||||||
|
.is_match();
|
||||||
|
|
||||||
|
if !is_raku_project {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let versions = Lazy::new(|| get_raku_version(context));
|
||||||
|
|
||||||
|
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" => versions
|
||||||
|
.deref()
|
||||||
|
.as_ref()
|
||||||
|
.map(|(raku_version, _)| raku_version)
|
||||||
|
.map(|raku_version| {
|
||||||
|
VersionFormatter::format_module_version(
|
||||||
|
module.get_name(),
|
||||||
|
raku_version,
|
||||||
|
config.version_format,
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.map(Ok),
|
||||||
|
"vm_version" => versions
|
||||||
|
.deref()
|
||||||
|
.as_ref()
|
||||||
|
.map(|(_, vm_version)| vm_version.to_string())
|
||||||
|
.map(Ok),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.parse(None, Some(context))
|
||||||
|
});
|
||||||
|
|
||||||
|
module.set_segments(match parsed {
|
||||||
|
Ok(segments) => segments,
|
||||||
|
Err(error) => {
|
||||||
|
log::warn!("Error in module `raku`:\n{}", error);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Some(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_raku_version(context: &Context) -> Option<(String, String)> {
|
||||||
|
let output = context.exec_cmd("raku", &["--version"])?.stdout;
|
||||||
|
|
||||||
|
parse_raku_version(&output)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_raku_version(version: &str) -> Option<(String, String)> {
|
||||||
|
let mut lines = version.lines();
|
||||||
|
// skip 1st line
|
||||||
|
let _ = lines.next()?;
|
||||||
|
// split 2nd line into ["Implement", "the", "Raku®", ..., "v6.d."], take "v6.d."
|
||||||
|
// get rid of the trailing "."
|
||||||
|
let raku_version = lines
|
||||||
|
.next()?
|
||||||
|
.split_whitespace()
|
||||||
|
.nth(5)?
|
||||||
|
.strip_suffix('.')?
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
// split line into ["Built", "on", "MoarVM", ...], take "MoarVM"
|
||||||
|
// and change MoarVM to Moar (community's preference), leave other VMs as they are
|
||||||
|
let vm_version = lines
|
||||||
|
.next()?
|
||||||
|
.split_whitespace()
|
||||||
|
.nth(2)?
|
||||||
|
.replace("MoarVM", "Moar");
|
||||||
|
|
||||||
|
Some((raku_version.to_lowercase(), vm_version.to_lowercase()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::test::ModuleRenderer;
|
||||||
|
use ansi_term::Color;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_raku_version() {
|
||||||
|
let moar_input = "\
|
||||||
|
Welcome to Rakudo™ v2021.12.
|
||||||
|
Implementing the Raku® Programming Language v6.d.
|
||||||
|
Built on MoarVM version 2021.12.
|
||||||
|
";
|
||||||
|
let jvm_input = "\
|
||||||
|
Welcome to Rakudo™ v2021.12.
|
||||||
|
Implementing the Raku® Programming Language v6.d.
|
||||||
|
Built on JVM version 2021.12.
|
||||||
|
";
|
||||||
|
assert_eq!(
|
||||||
|
parse_raku_version(moar_input),
|
||||||
|
Some(("v6.d".to_string(), "moar".to_string()))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_raku_version(jvm_input),
|
||||||
|
Some(("v6.d".to_string(), "jvm".to_string()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn folder_without_raku_files() -> io::Result<()> {
|
||||||
|
let dir = tempfile::tempdir()?;
|
||||||
|
let actual = ModuleRenderer::new("raku").path(dir.path()).collect();
|
||||||
|
let expected = None;
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
|
dir.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn folder_with_meta6_json_file() -> io::Result<()> {
|
||||||
|
let dir = tempfile::tempdir()?;
|
||||||
|
File::create(dir.path().join("META6.json"))?.sync_all()?;
|
||||||
|
|
||||||
|
let actual = ModuleRenderer::new("raku").path(dir.path()).collect();
|
||||||
|
|
||||||
|
let expected = Some(format!(
|
||||||
|
"via {}",
|
||||||
|
Color::Fixed(149).bold().paint("🦋 v6.d-moar ")
|
||||||
|
));
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
dir.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn folder_with_raku_file() -> io::Result<()> {
|
||||||
|
let dir = tempfile::tempdir()?;
|
||||||
|
File::create(dir.path().join("any.raku"))?.sync_all()?;
|
||||||
|
|
||||||
|
let actual = ModuleRenderer::new("raku").path(dir.path()).collect();
|
||||||
|
|
||||||
|
let expected = Some(format!(
|
||||||
|
"via {}",
|
||||||
|
Color::Fixed(149).bold().paint("🦋 v6.d-moar ")
|
||||||
|
));
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
dir.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn folder_with_raku_module_file() -> io::Result<()> {
|
||||||
|
let dir = tempfile::tempdir()?;
|
||||||
|
File::create(dir.path().join("any.rakumod"))?.sync_all()?;
|
||||||
|
|
||||||
|
let actual = ModuleRenderer::new("raku").path(dir.path()).collect();
|
||||||
|
|
||||||
|
let expected = Some(format!(
|
||||||
|
"via {}",
|
||||||
|
Color::Fixed(149).bold().paint("🦋 v6.d-moar ")
|
||||||
|
));
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
dir.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn folder_with_rakudoc_file() -> io::Result<()> {
|
||||||
|
let dir = tempfile::tempdir()?;
|
||||||
|
File::create(dir.path().join("any.pod6"))?.sync_all()?;
|
||||||
|
|
||||||
|
let actual = ModuleRenderer::new("raku").path(dir.path()).collect();
|
||||||
|
|
||||||
|
let expected = Some(format!(
|
||||||
|
"via {}",
|
||||||
|
Color::Fixed(149).bold().paint("🦋 v6.d-moar ")
|
||||||
|
));
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
dir.close()
|
||||||
|
}
|
||||||
|
}
|
@ -319,6 +319,15 @@ For more information about these matters see
|
|||||||
https://www.gnu.org/licenses/."#
|
https://www.gnu.org/licenses/."#
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
"raku --version" => Some(CommandOutput {
|
||||||
|
stdout: String::from(
|
||||||
|
"\
|
||||||
|
Welcome to Rakudo™ v2021.12.
|
||||||
|
Implementing the Raku® Programming Language v6.d.
|
||||||
|
Built on MoarVM version 2021.12.\n",
|
||||||
|
),
|
||||||
|
stderr: String::default(),
|
||||||
|
}),
|
||||||
"red --version" => Some(CommandOutput {
|
"red --version" => Some(CommandOutput {
|
||||||
stdout: String::from("0.6.4\n"),
|
stdout: String::from("0.6.4\n"),
|
||||||
stderr: String::default()
|
stderr: String::default()
|
||||||
|
Loading…
Reference in New Issue
Block a user