diff --git a/src/lune/builtins/fs/copy.rs b/src/lune/builtins/fs/copy.rs index 10c77fc2..bcad01fb 100644 --- a/src/lune/builtins/fs/copy.rs +++ b/src/lune/builtins/fs/copy.rs @@ -150,6 +150,8 @@ pub async fn copy( } } + fs::create_dir_all(target).await?; + // FUTURE: Write dirs / files concurrently // to potentially speed these operations up for (_, dir) in &contents.dirs { diff --git a/src/lune/util/formatting.rs b/src/lune/util/formatting.rs index 2107c14f..19f9a884 100644 --- a/src/lune/util/formatting.rs +++ b/src/lune/util/formatting.rs @@ -103,9 +103,9 @@ pub fn style_from_style_str>(s: S) -> LuaResult, depth: usize, ) -> std::fmt::Result { - // TODO: Handle tables with cyclic references match &value { LuaValue::Nil => write!(buffer, "nil")?, LuaValue::Boolean(true) => write!(buffer, "{}", COLOR_YELLOW.apply_to("true"))?, @@ -123,10 +123,14 @@ pub fn pretty_format_value( ) )?, LuaValue::Table(ref tab) => { + let table_addr = Some(format!("{:p}", tab.to_pointer())); + if depth >= MAX_FORMAT_DEPTH { write!(buffer, "{}", STYLE_DIM.apply_to("{ ... }"))?; } else if let Some(s) = call_table_tostring_metamethod(tab) { write!(buffer, "{s}")?; + } else if depth >= 1 && parent_table_addr.eq(&table_addr) { + write!(buffer, "{}", STYLE_DIM.apply_to(""))? } else { let mut is_empty = false; let depth_indent = INDENT.repeat(depth); @@ -144,11 +148,11 @@ pub fn pretty_format_value( )?, _ => { write!(buffer, "\n{depth_indent}{INDENT}[")?; - pretty_format_value(buffer, &key, depth)?; + pretty_format_value(buffer, &key, parent_table_addr.clone(), depth)?; write!(buffer, "] {} ", STYLE_DIM.apply_to("="))?; } } - pretty_format_value(buffer, &value, depth + 1)?; + pretty_format_value(buffer, &value, parent_table_addr.clone(), depth + 1)?; write!(buffer, "{}", STYLE_DIM.apply_to(","))?; is_empty = false; } @@ -192,7 +196,9 @@ pub fn pretty_format_multi_value(multi: &LuaMultiValue) -> LuaResult { if let LuaValue::String(s) = value { write!(buffer, "{}", s.to_string_lossy()).into_lua_err()?; } else { - pretty_format_value(&mut buffer, value, 0).into_lua_err()?; + let addr = format!("{:p}", value.to_pointer()); + + pretty_format_value(&mut buffer, value, Some(addr), 0).into_lua_err()?; } if counter < multi.len() { write!(&mut buffer, " ").into_lua_err()?; diff --git a/types/fs.luau b/types/fs.luau index d81ce6de..1d806045 100644 --- a/types/fs.luau +++ b/types/fs.luau @@ -29,9 +29,9 @@ export type MetadataPermissions = { * `kind` - If the target path is a `file`, `dir` or `symlink` * `exists` - If the target path exists - * `createdAt` - The timestamp at which the file or directory was created - * `modifiedAt` - The timestamp at which the file or directory was last modified - * `accessedAt` - The timestamp at which the file or directory was last accessed + * `createdAt` - The timestamp represented as a `DateTime` object at which the file or directory was created + * `modifiedAt` - The timestamp represented as a `DateTime` object at which the file or directory was last modified + * `accessedAt` - The timestamp represented as a `DateTime` object at which the file or directory was last accessed * `permissions` - Current permissions for the file or directory Note that timestamps are relative to the unix epoch, and diff --git a/types/luau.luau b/types/luau.luau index 189254bb..a810ee5b 100644 --- a/types/luau.luau +++ b/types/luau.luau @@ -2,16 +2,15 @@ @interface CompileOptions @within Luau - The Luau compiler options used in generating luau bytecode + The options passed to the luau compiler while compiling bytecode. This is a dictionary that may contain one or more of the following values: - * `optimizationLevel` - Sets the compiler option "optimizationLevel". Defaults to `1` - * `coverageLevel` - Sets the compiler option "coverageLevel". Defaults to `0` - * `debugLevel` - Sets the compiler option "debugLevel". Defaults to `1` + * `optimizationLevel` - Sets the compiler option "optimizationLevel". Defaults to `1`. + * `coverageLevel` - Sets the compiler option "coverageLevel". Defaults to `0`. + * `debugLevel` - Sets the compiler option "debugLevel". Defaults to `1`. - Documentation regarding what these values represent can be found here; - * https://github.com/Roblox/luau/blob/bd229816c0a82a8590395416c81c333087f541fd/Compiler/include/luacode.h#L13 + Documentation regarding what these values represent can be found [here](https://github.com/Roblox/luau/blob/bd229816c0a82a8590395416c81c333087f541fd/Compiler/include/luacode.h#L13-L39). ]=] export type CompileOptions = { optimizationLevel: number?, @@ -23,11 +22,11 @@ export type CompileOptions = { @interface LoadOptions @within Luau - The Luau load options are used for generating a lua function from either bytecode or sourcecode + The options passed while loading a luau chunk from an arbitrary string, or bytecode. This is a dictionary that may contain one or more of the following values: - * `debugName` - The debug name of the closure. Defaults to `luau.load(...)` + * `debugName` - The debug name of the closure. Defaults to `luau.load(...)`. * `environment` - Environment values to set and/or override. Includes default globals unless overwritten. ]=] export type LoadOptions = { @@ -53,6 +52,9 @@ export type LoadOptions = { callableFn() ``` + + Since luau bytecode is highly compressible, it may also make sense to compress it using the `serde` library + while transmitting large amounts of it. ]=] local luau = {} @@ -68,15 +70,16 @@ local luau = {} ```lua local luau = require("@lune/luau") + -- Compile the source to some highly optimized bytecode local bytecode = luau.compile("print('Hello, World!')", { - optimizationLevel: 1, - coverageLevel: 0, - debugLevel: 1, + optimizationLevel = 2, + coverageLevel = 0, + debugLevel = 1, }) ``` - @param source The string that'll be compiled into bytecode - @param compileOptions The luau compiler options used when compiling the source string + @param source The string that will be compiled into bytecode + @param compileOptions The options passed to the luau compiler that will output the bytecode @return luau bytecode ]=] @@ -104,10 +107,10 @@ end callableFn() ``` - @param source Either bytecode or sourcecode - @param loadOptions The load options used when creating a callbable function + @param source Either luau bytecode or string source code + @param loadOptions The options passed to luau for loading the chunk - @return luau function + @return luau chunk ]=] function luau.load(source: string, loadOptions: LoadOptions?): (...any) -> ...any return nil :: any