Add support for shebang at the top of a script

This commit is contained in:
Filip Tibell 2023-03-08 19:23:47 +01:00
parent 7cc1aad114
commit 3163f33887
No known key found for this signature in database
4 changed files with 35 additions and 4 deletions

View file

@ -8,6 +8,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Added support for shebangs at the top of a script, meaning scripts such as this one will now run without throwing a syntax error:
```lua
#!/usr/bin/env lune
print("Hello, world!")
```
## `0.5.5` - March 8th, 2023
### Added

View file

@ -15,7 +15,7 @@ use crate::{
generate_selene_defs_from_definitions, generate_wiki_dir_from_definitions,
},
utils::{
files::discover_script_file_path_including_lune_dirs,
files::{discover_script_file_path_including_lune_dirs, strip_shebang},
listing::{find_lune_scripts, print_lune_scripts, sort_lune_scripts},
},
};
@ -177,7 +177,7 @@ impl Cli {
// Create a new lune object with all globals & run the script
let result = Lune::new()
.with_args(self.script_args)
.try_run(&script_display_name, &script_contents)
.try_run(&script_display_name, strip_shebang(script_contents))
.await;
Ok(match result {
Err(err) => {

View file

@ -157,3 +157,21 @@ pub fn parse_lune_description_from_file(contents: &str) -> Option<String> {
Some(unindented_lines)
}
}
pub fn strip_shebang(mut contents: Vec<u8>) -> Vec<u8> {
if contents.starts_with(b"#!") {
if let Some(first_newline_idx) =
contents
.iter()
.enumerate()
.find_map(|(idx, c)| if *c == b'\n' { Some(idx) } else { None })
{
// NOTE: We keep the newline here on purpose to preserve
// correct line numbers in stack traces, the only reason
// we strip the shebang is to get the lua script to parse
// and the extra newline is not really a problem for that
contents.drain(..first_newline_idx);
}
}
contents
}

View file

@ -23,16 +23,17 @@ pub async fn find_lune_scripts() -> Result<Vec<(String, String)>> {
while let Some(entry) = dir.next_entry().await? {
let meta = entry.metadata().await?;
if meta.is_file() {
let contents = fs::read_to_string(entry.path()).await?;
let contents = fs::read(entry.path()).await?;
files.push((entry, meta, contents));
}
}
let parsed: Vec<_> = files
.iter()
.map(|(entry, _, contents)| {
let contents_str = String::from_utf8_lossy(contents);
let file_path = entry.path().with_extension("");
let file_name = file_path.file_name().unwrap().to_string_lossy();
let description = parse_lune_description_from_file(contents);
let description = parse_lune_description_from_file(&contents_str);
(file_name.to_string(), description.unwrap_or_default())
})
.collect();