Skip to content

Commit

Permalink
feat(Zsh microkernel): Add Zsh microkernel
Browse files Browse the repository at this point in the history
Zsh is now the default shell on MacOS (since Catalina).
  • Loading branch information
nokome committed Dec 7, 2021
1 parent dbafd8e commit f2d2746
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions rust/kernel-zsh/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "kernel-zsh"
description = "A microkernel for Zsh"
version = "0.0.0"
edition = "2021"

[dependencies]
kernel = { path = "../kernel", version = "0.0.0" }
kernel-micro = { path = "../kernel-micro", version = "0.0.0" }

[dev-dependencies]
tokio = { version = "1.13.0", features = ["macros"] }
test-utils = { path = "../test-utils", version = "0.0.0" }
73 changes: 73 additions & 0 deletions rust/kernel-zsh/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use kernel_micro::{include_file, MicroKernel};

/// A microkernel for Zsh
///
/// The `kernel-zsh.sh` script relies on `/dev/stdin`, `/dev/stdout`,
/// and `/dev/stderr` so this kernel is not available on Windows.
pub fn new() -> MicroKernel {
MicroKernel::new(
"zsh-micro",
&["zsh"],
&["linux", "macos", "windows"],
("zsh", "*"),
&["{{script}}"],
include_file!("zsh-kernel.sh"),
&[],
"{{name}}=\"{{json}}\"",
"echo ${{name}}",
)
}

#[cfg(test)]
mod tests {
use super::*;
use kernel::{eyre::Result, stencila_schema::Node, KernelTrait};
use test_utils::{assert_json_eq, print_logs, serde_json::json};

/// Tests of basic functionality
/// This test is replicated in all the microkernels.
/// Other test should be written for language specific quirks and regressions.
#[tokio::test]
async fn basics() -> Result<()> {
print_logs();

let mut kernel = new();
if !kernel.available().await {
return Ok(());
} else {
kernel.start().await?;
}

// Assign a variable and output it
let (outputs, messages) = kernel.exec("a=2\necho $a").await?;
assert_json_eq!(messages, json!([]));
assert_json_eq!(outputs, [2]);

// Syntax error
let (outputs, messages) = kernel.exec("if").await?;
messages[0]
.error_message
.ends_with("syntax error: unexpected end of file\n");

assert_json_eq!(outputs, json!([]));

// Runtime error
let (outputs, messages) = kernel.exec("foo").await?;
messages[0]
.error_message
.ends_with("foo: command not found\n");
assert_json_eq!(outputs, json!([]));

// Set and get another variable
kernel.set("b", Node::Integer(3)).await?;
let b = kernel.get("b").await?;
assert_json_eq!(b, 3);

// Use both variables
let (outputs, messages) = kernel.exec("echo $a$b").await?;
assert_json_eq!(messages, json!([]));
assert_json_eq!(outputs, [23]);

Ok(())
}
}
8 changes: 8 additions & 0 deletions rust/kernel-zsh/src/zsh-kernel.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env zsh

while read -r code
do
print -v unescaped "$code"
eval "$unescaped"
print "\U10ACDC" | tee /dev/stderr
done < "${1:-/dev/stdin}"
1 change: 1 addition & 0 deletions rust/kernels/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ kernel-node = { path = "../kernel-node", version = "0.0.0", optional = true }
kernel-python = { path = "../kernel-python", version = "0.0.0", optional = true }
kernel-r = { path = "../kernel-r", version = "0.0.0", optional = true }
kernel-store = { path = "../kernel-store", version = "0.0.0", optional = true }
kernel-zsh = { path = "../kernel-zsh", version = "0.0.0", optional = true }
slug = "0.1.4"
2 changes: 2 additions & 0 deletions rust/kernels/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ impl MetaKernel {
microkernel_new!("kernel-node", kernel_node, &selector);
microkernel_new!("kernel-python", kernel_python, &selector);
microkernel_new!("kernel-r", kernel_r, &selector);
microkernel_new!("kernel-zsh", kernel_zsh, &selector);

bail!(
"Unable to create an execution kernel for selector `{}`",
Expand Down Expand Up @@ -542,6 +543,7 @@ pub async fn available() -> Result<Vec<Kernel>> {
microkernel_available!("kernel-node", kernel_node, available);
microkernel_available!("kernel-python", kernel_python, available);
microkernel_available!("kernel-r", kernel_r, available);
microkernel_available!("kernel-zsh", kernel_zsh, available);

Ok(available)
}
Expand Down
1 change: 1 addition & 0 deletions rust/stencila/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ default = [
"kernels/kernel-python",
"kernels/kernel-r",
"kernels/kernel-store",
"kernels/kernel-zsh",

# Binaries
"binaries/cli",
Expand Down

0 comments on commit f2d2746

Please sign in to comment.