mirror of
https://github.com/lune-org/lune.git
synced 2025-04-19 11:23:57 +01:00
feat: disable unneeded CLI args for standalone
This commit is contained in:
parent
2bf68c1e2a
commit
4bb0eba589
1 changed files with 117 additions and 107 deletions
224
src/cli/mod.rs
224
src/cli/mod.rs
|
@ -85,9 +85,16 @@ impl Cli {
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub async fn run(self) -> Result<ExitCode> {
|
pub async fn run(self) -> Result<ExitCode> {
|
||||||
|
// Signature which is only present in standalone lune binaries
|
||||||
|
let signature: Vec<u8> = vec![0x4f, 0x3e, 0xf8, 0x41, 0xc3, 0x3a, 0x52, 0x16];
|
||||||
|
// Read the current lune binary to memory
|
||||||
|
let bin = read_to_vec(env::current_exe()?).await?;
|
||||||
|
|
||||||
|
let is_standalone = bin[bin.len() - signature.len()..bin.len()] == signature;
|
||||||
|
|
||||||
// List files in `lune` and `.lune` directories, if wanted
|
// List files in `lune` and `.lune` directories, if wanted
|
||||||
// This will also exit early and not run anything else
|
// This will also exit early and not run anything else
|
||||||
if self.list {
|
if self.list && !is_standalone {
|
||||||
let sorted_relative = find_lune_scripts(false).await.map(sort_lune_scripts);
|
let sorted_relative = find_lune_scripts(false).await.map(sort_lune_scripts);
|
||||||
|
|
||||||
let sorted_home_dir = find_lune_scripts(true).await.map(sort_lune_scripts);
|
let sorted_home_dir = find_lune_scripts(true).await.map(sort_lune_scripts);
|
||||||
|
@ -150,125 +157,128 @@ impl Cli {
|
||||||
return Ok(ExitCode::SUCCESS);
|
return Ok(ExitCode::SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signature which is only present in standalone lune binaries
|
if is_standalone {
|
||||||
let signature: Vec<u8> = vec![0x4f, 0x3e, 0xf8, 0x41, 0xc3, 0x3a, 0x52, 0x16];
|
let mut bytecode_offset = 0;
|
||||||
|
let mut bytecode_size = 0;
|
||||||
|
|
||||||
// Read the current lune binary to memory
|
// standalone binary structure (reversed, 8 bytes per field)
|
||||||
let bin = read_to_vec(env::current_exe()?).await?;
|
// [0] => signature
|
||||||
|
// ----------------
|
||||||
|
// -- META Chunk --
|
||||||
|
// [1] => file count
|
||||||
|
// [2] => bytecode size
|
||||||
|
// [3] => bytecode offset
|
||||||
|
// ----------------
|
||||||
|
// -- MISC Chunk --
|
||||||
|
// [4..n] => bytecode (variable size)
|
||||||
|
// ----------------
|
||||||
|
// NOTE: All integers are 8 byte unsigned 64 bit (u64's).
|
||||||
|
|
||||||
let mut bytecode_offset = 0;
|
// The rchunks will have unequally sized sections in the beginning
|
||||||
let mut bytecode_size = 0;
|
// but that doesn't matter to us because we don't need anything past the
|
||||||
|
// middle chunks where the bytecode is stored
|
||||||
// standalone binary structure (reversed, 8 bytes per field)
|
for (idx, chunk) in bin.rchunks(signature.len()).enumerate() {
|
||||||
// [0] => signature
|
if idx == 0 && chunk != signature {
|
||||||
// ----------------
|
// We don't have a standalone binary
|
||||||
// -- META Chunk --
|
break;
|
||||||
// [1] => file count
|
|
||||||
// [2] => bytecode size
|
|
||||||
// [3] => bytecode offset
|
|
||||||
// ----------------
|
|
||||||
// -- MISC Chunk --
|
|
||||||
// [4..n] => bytecode (variable size)
|
|
||||||
// ----------------
|
|
||||||
// NOTE: All integers are 8 byte unsigned 64 bit (u64's).
|
|
||||||
|
|
||||||
// The rchunks will have unequally sized sections in the beginning
|
|
||||||
// but that doesn't matter to us because we don't need anything past the
|
|
||||||
// middle chunks where the bytecode is stored
|
|
||||||
for (idx, chunk) in bin.rchunks(signature.len()).enumerate() {
|
|
||||||
if idx == 0 && chunk != signature {
|
|
||||||
// We don't have a standalone binary
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if idx == 3 {
|
|
||||||
bytecode_offset = u64::from_ne_bytes(chunk.try_into()?);
|
|
||||||
}
|
|
||||||
|
|
||||||
if idx == 2 {
|
|
||||||
bytecode_size = u64::from_ne_bytes(chunk.try_into()?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we were able to retrieve the required metadata, we load
|
|
||||||
// and execute the bytecode
|
|
||||||
if bytecode_offset != 0 && bytecode_size != 0 {
|
|
||||||
// FIXME: Passing arguments does not work like it should, because the first
|
|
||||||
// argument provided is treated as the script path. We should probably also not
|
|
||||||
// allow any runner functionality within standalone binaries
|
|
||||||
|
|
||||||
let result = Lune::new()
|
|
||||||
.with_args(self.script_args.clone())
|
|
||||||
.run(
|
|
||||||
"STANDALONE",
|
|
||||||
&bin[usize::try_from(bytecode_offset).unwrap()
|
|
||||||
..usize::try_from(bytecode_offset + bytecode_size).unwrap()],
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return Ok(match result {
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("{err}");
|
|
||||||
ExitCode::FAILURE
|
|
||||||
}
|
}
|
||||||
Ok(code) => code,
|
|
||||||
});
|
if idx == 3 {
|
||||||
|
bytecode_offset = u64::from_ne_bytes(chunk.try_into()?);
|
||||||
|
}
|
||||||
|
|
||||||
|
if idx == 2 {
|
||||||
|
bytecode_size = u64::from_ne_bytes(chunk.try_into()?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we were able to retrieve the required metadata, we load
|
||||||
|
// and execute the bytecode
|
||||||
|
if bytecode_offset != 0 && bytecode_size != 0 {
|
||||||
|
// FIXME: Passing arguments does not work like it should, because the first
|
||||||
|
// argument provided is treated as the script path. We should probably also not
|
||||||
|
// allow any runner functionality within standalone binaries
|
||||||
|
|
||||||
|
let result = Lune::new()
|
||||||
|
.with_args(self.script_args.clone()) // TODO: args should also include lune reserved ones
|
||||||
|
.run(
|
||||||
|
"STANDALONE",
|
||||||
|
&bin[usize::try_from(bytecode_offset).unwrap()
|
||||||
|
..usize::try_from(bytecode_offset + bytecode_size).unwrap()],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
return Ok(match result {
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("{err}");
|
||||||
|
ExitCode::FAILURE
|
||||||
|
}
|
||||||
|
Ok(code) => code,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not in a standalone context and we don't have any arguments
|
// If not in a standalone context and we don't have any arguments
|
||||||
// display the interactive REPL interface
|
// display the interactive REPL interface
|
||||||
return repl::show_interface().await;
|
return repl::show_interface().await;
|
||||||
}
|
}
|
||||||
// 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 == "-" {
|
if !is_standalone {
|
||||||
let mut stdin_contents = Vec::new();
|
// Figure out if we should read from stdin or from a file,
|
||||||
stdin()
|
// reading from stdin is marked by passing a single "-"
|
||||||
.read_to_end(&mut stdin_contents)
|
// (dash) as the script name to run to the cli
|
||||||
.await
|
let script_path = self.script_path.unwrap();
|
||||||
.context("Failed to read script contents from stdin")?;
|
|
||||||
("stdin".to_string(), stdin_contents)
|
|
||||||
} else {
|
|
||||||
let file_path = discover_script_path_including_lune_dirs(&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)
|
|
||||||
};
|
|
||||||
|
|
||||||
if self.build {
|
let (script_display_name, script_contents) = if script_path == "-" {
|
||||||
let output_path =
|
let mut stdin_contents = Vec::new();
|
||||||
PathBuf::from(script_path.clone()).with_extension(env::consts::EXE_EXTENSION);
|
stdin()
|
||||||
println!(
|
.read_to_end(&mut stdin_contents)
|
||||||
"Building {script_path} to {}",
|
.await
|
||||||
output_path.to_string_lossy()
|
.context("Failed to read script contents from stdin")?;
|
||||||
);
|
("stdin".to_string(), stdin_contents)
|
||||||
|
} else {
|
||||||
|
let file_path = discover_script_path_including_lune_dirs(&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)
|
||||||
|
};
|
||||||
|
|
||||||
return Ok(
|
if self.build {
|
||||||
match build_standalone(output_path, strip_shebang(script_contents.clone())).await {
|
let output_path =
|
||||||
Ok(exitcode) => exitcode,
|
PathBuf::from(script_path.clone()).with_extension(env::consts::EXE_EXTENSION);
|
||||||
Err(err) => {
|
println!(
|
||||||
eprintln!("{err}");
|
"Building {script_path} to {}",
|
||||||
ExitCode::FAILURE
|
output_path.to_string_lossy()
|
||||||
}
|
);
|
||||||
},
|
|
||||||
);
|
return Ok(
|
||||||
|
match build_standalone(output_path, strip_shebang(script_contents.clone()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(exitcode) => exitcode,
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("{err}");
|
||||||
|
ExitCode::FAILURE
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new lune object with all globals & run the script
|
||||||
|
let result = Lune::new()
|
||||||
|
.with_args(self.script_args)
|
||||||
|
.run(&script_display_name, strip_shebang(script_contents))
|
||||||
|
.await;
|
||||||
|
return Ok(match result {
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("{err}");
|
||||||
|
ExitCode::FAILURE
|
||||||
|
}
|
||||||
|
Ok(code) => code,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new lune object with all globals & run the script
|
Ok(ExitCode::SUCCESS)
|
||||||
let result = Lune::new()
|
|
||||||
.with_args(self.script_args)
|
|
||||||
.run(&script_display_name, strip_shebang(script_contents))
|
|
||||||
.await;
|
|
||||||
Ok(match result {
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("{err}");
|
|
||||||
ExitCode::FAILURE
|
|
||||||
}
|
|
||||||
Ok(code) => code,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue