mirror of
https://github.com/lune-org/lune.git
synced 2025-04-07 20:10:55 +01:00
feat: proper args support for standalone binaries
This commit is contained in:
parent
cf2f93d480
commit
2af8ed3b9f
3 changed files with 97 additions and 65 deletions
|
@ -60,4 +60,4 @@ for rowIndex, row in csvTable do
|
||||||
print(string.format("┣%s┫", thiccLine))
|
print(string.format("┣%s┫", thiccLine))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
print(string.format("┗%s┛", thiccLine))
|
print(string.format("┗%s┛", thiccLine))
|
||||||
|
|
|
@ -44,17 +44,17 @@ pub async fn build_standalone<T: AsRef<Path> + Into<PathBuf>>(
|
||||||
patched_bin.append(&mut signature.clone());
|
patched_bin.append(&mut signature.clone());
|
||||||
|
|
||||||
// Write the compiled binary to file
|
// Write the compiled binary to file
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(target_family = "unix")]
|
||||||
OpenOptions::new()
|
OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.mode(0o770)
|
.mode(0o770) // read, write and execute permissions for user and group
|
||||||
.open(&output_path)
|
.open(&output_path)
|
||||||
.await?
|
.await?
|
||||||
.write_all(&patched_bin)
|
.write_all(&patched_bin)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_family = "windows")]
|
||||||
fs::write(&output_path, &patched_bin).await?;
|
fs::write(&output_path, &patched_bin).await?;
|
||||||
|
|
||||||
Ok(ExitCode::SUCCESS)
|
Ok(ExitCode::SUCCESS)
|
||||||
|
|
154
src/cli/mod.rs
154
src/cli/mod.rs
|
@ -92,6 +92,99 @@ impl Cli {
|
||||||
|
|
||||||
let is_standalone = bin[bin.len() - signature.len()..bin.len()] == signature;
|
let is_standalone = bin[bin.len() - signature.len()..bin.len()] == signature;
|
||||||
|
|
||||||
|
if is_standalone {
|
||||||
|
let mut bytecode_offset = 0;
|
||||||
|
let mut bytecode_size = 0;
|
||||||
|
|
||||||
|
// standalone binary structure (reversed, 8 bytes per field)
|
||||||
|
// [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).
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
// Binary is guaranteed to be standalone, we've confirmed this before
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 mut reserved_args = Vec::new();
|
||||||
|
|
||||||
|
macro_rules! include_reserved_args {
|
||||||
|
($($arg_bool:expr=> $mapping:literal),*) => {
|
||||||
|
$(
|
||||||
|
if $arg_bool {
|
||||||
|
reserved_args.push($mapping.to_string())
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut real_args = Vec::new();
|
||||||
|
|
||||||
|
if let Some(first_arg) = self.script_path {
|
||||||
|
println!("{first_arg}");
|
||||||
|
|
||||||
|
real_args.push(first_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
include_reserved_args! {
|
||||||
|
self.setup => "--setup",
|
||||||
|
self.generate_docs_file => "--generate-docs-file",
|
||||||
|
self.generate_selene_types => "--generate-selene-types",
|
||||||
|
self.generate_luau_types => "--generate-luau-types",
|
||||||
|
self.list => "--list",
|
||||||
|
self.build => "--build"
|
||||||
|
}
|
||||||
|
|
||||||
|
real_args.append(&mut reserved_args);
|
||||||
|
real_args.append(&mut self.script_args.clone());
|
||||||
|
|
||||||
|
let result = Lune::new()
|
||||||
|
.with_args(real_args) // TODO: args should also include lune reserved ones
|
||||||
|
.run(
|
||||||
|
"STANDALONE",
|
||||||
|
&bin[usize::try_from(bytecode_offset)?
|
||||||
|
..usize::try_from(bytecode_offset + bytecode_size)?],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
return Ok(match result {
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("{err}");
|
||||||
|
ExitCode::FAILURE
|
||||||
|
}
|
||||||
|
Ok(code) => code,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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 && !is_standalone {
|
if self.list && !is_standalone {
|
||||||
|
@ -157,67 +250,6 @@ impl Cli {
|
||||||
return Ok(ExitCode::SUCCESS);
|
return Ok(ExitCode::SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_standalone {
|
|
||||||
let mut bytecode_offset = 0;
|
|
||||||
let mut bytecode_size = 0;
|
|
||||||
|
|
||||||
// standalone binary structure (reversed, 8 bytes per field)
|
|
||||||
// [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).
|
|
||||||
|
|
||||||
// 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()) // 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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue