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();