diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5cb26e0..dfb585a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,12 +12,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- Added support for reading scripts from stdin by passing `"-"` as the script name
- Added support for close codes in the `net` WebSocket APIs:
- A close code can be sent by passing it to `socket.close`
- A received close code can be checked with the `socket.closeCode` value, which is populated after a socket has been closed - note that using `socket.close` will not set the close code value, it is only set when received and is guaranteed to exist after closure
### Fixed
+- Fixed scripts having to be valid utf8, they may now use any kind of encoding that base Luau supports
- The `net` WebSocket APIs will no longer return `nil` for partial messages being received in `socket.next`, and will instead wait for the full message to arrive
## `0.5.3` - February 26th, 2023
@@ -25,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Fixed `lune --generate-selene-types` generating an invalid Selene definitions file
-- Fixed (maybe) type definition parsing issues on Windows
+- Fixed type definition parsing issues on Windows
## `0.5.2` - February 26th, 2023
diff --git a/docs/pages/Getting Started - 3 Running Scripts.md b/docs/pages/Getting Started - 3 Running Scripts.md
index 73d8be1..fa220fd 100644
--- a/docs/pages/Getting Started - 3 Running Scripts.md
+++ b/docs/pages/Getting Started - 3 Running Scripts.md
@@ -10,9 +10,9 @@ lune script-name
This will look for the file `script-name.luau`**_[1]_** in a few locations:
-- The current directory
-- The folder `lune` in the current directory, if it exists
-- The folder `.lune` in the current directory, if it exists
+- The current directory
+- The folder `lune` in the current directory, if it exists
+- The folder `.lune` in the current directory, if it exists
## 🎛️ Passing Command-Line Arguments
@@ -38,6 +38,12 @@ lune --list
Lists all scripts found in `lune` or `.lune` directories, including any top-level description comments.
Lune description comments are always written at the top of a file and start with a lua-style comment arrow (`-->`).
+```sh
+lune -
+```
+
+Runs a script passed to Lune using stdin. Occasionally useful for running scripts piped to Lune from external sources.
+
---
**_[1]_** _Lune also supports files with the `.lua` extension but using the `.luau` extension is highly recommended. Additionally, if you don't want Lune to look in sub-directories you can provide a full file path with the file extension included, instead of only the file name._
diff --git a/packages/cli/src/cli.rs b/packages/cli/src/cli.rs
index 05fdc68..cadeba9 100644
--- a/packages/cli/src/cli.rs
+++ b/packages/cli/src/cli.rs
@@ -1,10 +1,13 @@
use std::process::ExitCode;
-use anyhow::Result;
+use anyhow::{Context, Result};
use clap::{CommandFactory, Parser};
use lune::Lune;
-use tokio::fs::{read_to_string, write};
+use tokio::{
+ fs::{read as read_to_vec, write},
+ io::{stdin, AsyncReadExt},
+};
use crate::{
gen::{
@@ -153,14 +156,27 @@ impl Cli {
let cmd = Cli::command();
cmd.arg_required_else_help(true).get_matches();
}
- // Parse and read the wanted file
- let file_path = find_parse_file_path(&self.script_path.unwrap())?;
- let file_contents = read_to_string(&file_path).await?;
- // Display the file path relative to cwd with no extensions in stack traces
- let file_display_name = file_path.with_extension("").display().to_string();
+ // Figure out if we should read from stdin or from a file,
+ // reading from stdin is marked by passing a single "-"
+ // (dash) as the script name to run to the cli
+ let script_path = self.script_path.unwrap();
+ let (script_display_name, script_contents) = if script_path == "-" {
+ let mut stdin_contents = Vec::new();
+ stdin()
+ .read_to_end(&mut stdin_contents)
+ .await
+ .context("Failed to read script contents from stdin")?;
+ ("stdin".to_string(), stdin_contents)
+ } else {
+ let file_path = find_parse_file_path(&script_path)?;
+ let file_contents = read_to_vec(&file_path).await?;
+ // NOTE: We skip the extension here to remove it from stack traces
+ let file_display_name = file_path.with_extension("").display().to_string();
+ (file_display_name, file_contents)
+ };
// Create a new lune object with all globals & run the script
let lune = Lune::new().with_args(self.script_args);
- let result = lune.run(&file_display_name, &file_contents).await;
+ let result = lune.run(&script_display_name, &script_contents).await;
Ok(match result {
Err(e) => {
eprintln!("{e}");
diff --git a/packages/lib/src/lib.rs b/packages/lib/src/lib.rs
index 245561b..0563147 100644
--- a/packages/lib/src/lib.rs
+++ b/packages/lib/src/lib.rs
@@ -54,8 +54,8 @@ impl Lune {
*/
pub async fn run(
&self,
- script_name: &str,
- script_contents: &str,
+ script_name: impl AsRef,
+ script_contents: impl AsRef<[u8]>,
) -> Result {
// Create our special lune-flavored Lua object with extra registry values
let lua = create_lune_lua().expect("Failed to create Lua object");
@@ -64,8 +64,8 @@ impl Lune {
lua.set_app_data(sched);
// Create the main thread and schedule it
let main_chunk = lua
- .load(script_contents)
- .set_name(script_name)
+ .load(script_contents.as_ref())
+ .set_name(script_name.as_ref())
.unwrap()
.into_function()
.unwrap();