spiral_builder¶
In [ ]:
open file_system_operators
open rust.rust_operators
open rust
open sm'_operators
In [ ]:
//// test
open testing
get_args¶
In [ ]:
inl get_args () =
{
fsharp = "fsharp", {
spi_path = "spi-path", 's'
}
cuda = "cuda", {
py_path = "py-path", 'p'
env = "env", 'e'
deps = "deps", 'd'
}
fable = "fable", {
fs_path = "fs-path", 'f'
command = "command", 'c'
}
rust = "rust", {
fs_path = "fs-path", 'f'
deps = "deps", 'd'
wasm = "wasm", 'w'
contract = "contract", 'c'
cleanup = "cleanup", 'l'
}
typescript = "typescript", {
fs_path = "fs-path", 'f'
deps = "deps", 'd'
}
python = "python", {
fs_path = "fs-path", 'f'
deps = "deps", 'd'
}
dib = "dib", {
path = "path", 'p'
retries = "retries", 'r'
working_directory = "working-directory", 'w'
}
}
cuda_env¶
In [ ]:
union cuda_env =
| Pip
| Poetry
get_command¶
In [ ]:
let get_command () =
##"command"
|> runtime.new_command
|> runtime.command_subcommand_required true
|> runtime.command_subcommand (
##(get_args () .fsharp |> fst)
|> runtime.new_command
|> runtime.command_init_arg ((get_args () .fsharp |> snd).spi_path) (
runtime.arg_required true
)
)
|> runtime.command_subcommand (
##(get_args () .cuda |> fst)
|> runtime.new_command
|> runtime.command_init_arg ((get_args () .cuda |> snd).py_path) (
runtime.arg_required true
)
|> runtime.command_init_arg ((get_args () .cuda |> snd).env) (
real runtime.arg_union `cuda_env ignore
)
|> runtime.command_init_arg ((get_args () .cuda |> snd).deps) (
runtime.arg_value_names ;[ ##"NAME"; ##"VERSION" ]
>> runtime.arg_num_args_range (
runtime.new_value_range
false
(am'.Start (1i32 |> convert : unativeint))
(am'.End id)
)
>> runtime.arg_action runtime.Append
)
)
|> runtime.command_subcommand (
##(get_args () .fable |> fst)
|> runtime.new_command
|> runtime.command_init_arg ((get_args () .fable |> snd).fs_path) (
runtime.arg_required true
)
|> runtime.command_init_arg ((get_args () .fable |> snd).command) (
id
)
)
|> runtime.command_subcommand (
##(get_args () .rust |> fst)
|> runtime.new_command
|> runtime.command_init_arg ((get_args () .rust |> snd).fs_path) (
runtime.arg_required true
)
|> runtime.command_init_arg ((get_args () .rust |> snd).deps) (
runtime.arg_value_names ;[ ##"NAME"; ##"VERSION" ]
>> runtime.arg_num_args_range (
runtime.new_value_range
false
(am'.Start (1i32 |> convert : unativeint))
(am'.End id)
)
>> runtime.arg_action runtime.Append
)
|> runtime.command_init_arg ((get_args () .rust |> snd).wasm) (
runtime.arg_num_args_range (
runtime.new_value_range
true
(am'.End id)
(am'.End fun _ => (1i32 |> convert : unativeint))
)
>> runtime.arg_require_equals true
>> runtime.arg_default_missing_value ""
)
|> runtime.command_init_arg ((get_args () .rust |> snd).contract) (
runtime.arg_num_args_range (
runtime.new_value_range
true
(am'.End id)
(am'.End fun _ => (1i32 |> convert : unativeint))
)
>> runtime.arg_require_equals true
>> runtime.arg_default_missing_value ""
)
|> runtime.command_init_arg ((get_args () .rust |> snd).cleanup) (
runtime.arg_default_value "true"
>> runtime.arg_action runtime.SetFalse
)
)
|> runtime.command_subcommand (
##(get_args () .typescript |> fst)
|> runtime.new_command
|> runtime.command_init_arg ((get_args () .typescript |> snd).fs_path) (
runtime.arg_required true
)
|> runtime.command_init_arg ((get_args () .typescript |> snd).deps) (
runtime.arg_value_names ;[ ##"NAME"; ##"VERSION" ]
>> runtime.arg_num_args_range (
runtime.new_value_range
false
(am'.Start (1i32 |> convert : unativeint))
(am'.End id)
)
>> runtime.arg_action runtime.Append
)
)
|> runtime.command_subcommand (
##(get_args () .python |> fst)
|> runtime.new_command
|> runtime.command_init_arg ((get_args () .python |> snd).fs_path) (
runtime.arg_required true
)
|> runtime.command_init_arg ((get_args () .python |> snd).deps) (
runtime.arg_value_names ;[ ##"NAME"; ##"VERSION" ]
>> runtime.arg_num_args_range (
runtime.new_value_range
false
(am'.Start (1i32 |> convert : unativeint))
(am'.End id)
)
>> runtime.arg_action runtime.Append
)
)
|> runtime.command_subcommand (
##(get_args () .dib |> fst)
|> runtime.new_command
|> runtime.command_init_arg ((get_args () .dib |> snd).path) (
runtime.arg_required true
// >> runtime.arg_value_parser (runtime.value_parser_path_buf ())
)
|> runtime.command_init_arg ((get_args () .dib |> snd).retries) (
runtime.arg_value_parser (runtime.value_parser_expr "u8")
)
|> runtime.command_init_arg ((get_args () .dib |> snd).working_directory) (
id
)
)
fable¶
fable_target¶
In [ ]:
union fable_target =
| Rust
| TypeScript
| Python
fable_runtime¶
In [ ]:
union fable_runtime =
| Wasm : string
| Contract : string
execute_dotnet_fable¶
In [ ]:
let execute_dotnet_fable { workspace_root_external fsproj_path extension package_dir runtime } =
open runtime
execution_options fun x => { x with
command =
inl platform =
if platform.is_windows ()
then "_WINDOWS"
else "_LINUX"
inl platform : string = $'$" --define {!platform}"'
inl runtime =
match runtime with
| Some (runtime : fable_runtime) =>
inl runtime = runtime |> reflection.union_to_string |> sm'.to_upper
$'$" --define {!runtime}"'
| None => ""
$'$"dotnet fable \\\"{!fsproj_path}\\\" --optimize --lang {!extension} --extension .{!extension} --outDir \\\"{!package_dir}\\\"{!platform}{!runtime}"'
working_directory = workspace_root_external |> resultm.box |> resultm.ok'
}
|> execute_retry 3u8
get_package_dir¶
In [ ]:
let get_package_dir { workspace_root target name hash } =
inl dir = workspace_root </> "target/spiral_builder" </> name
match hash, (target : option fable_target) with
| Some hash, Some target => dir </> "packages" </> (target |> reflection.union_to_string) </> hash
| _ => dir
persist_code_project¶
In [ ]:
let persist_code_project { workspace_root package_dir packages modules name code } =
package_dir |> file_system.create_dir |> ignore
inl fs_path = package_dir </> $'$"{!name}.fs"' |> file_system.normalize_path
code |> file_system.write_all_text_exists fs_path
inl modules_code =
modules
|> listm.map fun path =>
inl path = workspace_root </> path
$'$"<Compile Include=\\\"{!path}\\\" />"' : string
|> listm'.box
|> seq.of_list'
|> sm'.concat "\\n "
inl packages_code =
packages
|> listm.map fun (package : string) =>
$'$"<PackageReference Include=\\\"{!package}\\\" Version=\\\"*\\\" />"' : string
|> listm'.box
|> seq.of_list'
|> sm'.concat "\\n "
inl fsproj_path = package_dir </> $'$"{!name}.fsproj"' |> file_system.normalize_path
inl fsproj_code : string =
$'$"<Project Sdk=\\\"Microsoft.NET.Sdk\\\">"'
+#. $'$"<PropertyGroup>"'
+#. $'$" <TargetFramework>net9.0</TargetFramework>"'
+#. $'$" <LangVersion>preview</LangVersion>"'
+#. $'$" <RollForward>Major</RollForward>"'
+#. $'$" <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>"'
+#. $'$" <PublishAot>false</PublishAot>"'
+#. $'$" <PublishTrimmed>false</PublishTrimmed>"'
+#. $'$" <PublishSingleFile>true</PublishSingleFile>"'
+#. $'$" <SelfContained>true</SelfContained>"'
+#. $'$" <Version>0.0.1-alpha.1</Version>"'
+#. $'$" <OutputType>Exe</OutputType>"'
+#. $'$"</PropertyGroup>"'
+#. $'$"<PropertyGroup Condition=\\\"$([MSBuild]::IsOSPlatform(\'FreeBSD\'))\\\">"'
+#. $'$" <DefineConstants>_FREEBSD</DefineConstants>"'
+#. $'$"</PropertyGroup>"'
+#. $'$"<PropertyGroup Condition=\\\"$([MSBuild]::IsOSPlatform(\'Linux\'))\\\">"'
+#. $'$" <DefineConstants>_LINUX</DefineConstants>"'
+#. $'$"</PropertyGroup>"'
+#. $'$"<PropertyGroup Condition=\\\"$([MSBuild]::IsOSPlatform(\'OSX\'))\\\">"'
+#. $'$" <DefineConstants>_OSX</DefineConstants>"'
+#. $'$"</PropertyGroup>"'
+#. $'$"<PropertyGroup Condition=\\\"$([MSBuild]::IsOSPlatform(\'Windows\'))\\\">"'
+#. $'$" <DefineConstants>_WINDOWS</DefineConstants>"'
+#. $'$"</PropertyGroup>"'
+#. $'$"<ItemGroup>"'
+#. $'$" {!modules_code}"'
+#. $'$" <Compile Include=\\\"{!fs_path}\\\" />"'
+#. $'$"</ItemGroup>"'
+#. $'$"<ItemGroup>"'
+#. $'$" {!packages_code}"'
+#. $'$"</ItemGroup>"'
+#. $'$"</Project>"'
fsproj_code |> file_system.write_all_text_exists fsproj_path
fsproj_path
build_project¶
In [ ]:
inl build_project runtime' output_dir path =
inl full_path = path |> file_system.get_full_path
inl file_dir = full_path |> file_system.get_directory_name
inl extension = full_path |> file_system.get_extension
trace Debug
fun () => "build_project"
fun () => { full_path }
match extension with
| "fsproj" => ()
| _ => failwith $'$"spiral_builder.build_project / Invalid project file / extension: {!extension}"'
inl runtimes =
runtime'
|> optionm.map listm.singleton
|> optionm'.default_value [ "linux-x64"; "win-x64" ]
inl output_dir = output_dir |> optionm'.default_value "dist"
runtimes
|> listm.map fun runtime' =>
runtime.execution_options fun x => { x with
command = $'$@@"dotnet publish \"\"{!path}\"\" --configuration Release --output \"\"{!output_dir}\"\" --runtime {!runtime'}"'
working_directory = file_dir |> Some |> optionm'.box
}
|> runtime.execute_with_options
|> fst
|> listm'.sum
build_code¶
In [ ]:
inl build_code { workspace_root runtime packages modules output_dir name code } =
inl package_dir = get_package_dir { workspace_root name target = None; hash = None }
inl fsproj_path = persist_code_project { workspace_root package_dir packages modules name code }
inl exit_code = fsproj_path |> build_project runtime output_dir
if exit_code <>. 0 then
trace Critical
fun () => "build_code"
fun () => {
code = code |> sm'.ellipsis_end 400
fsproj_text = fsproj_path |> file_system.read_all_text
}
exit_code
In [ ]:
//// test
///! rust -d encoding_rs encoding_rs_io regex
build_code {
workspace_root = file_system.get_workspace_root ()
runtime = None
packages = []
modules = []
output_dir = None
name = "test1"
code = "1 + 1 |> ignore"
}
|> _assert_eq 0
00:00:00 v #1 file_system.create_dir / { dir = /home/runner/work/polyglot/polyglot/target/spiral_builder/test1 } 00:00:00 d #2 build_project / { full_path = /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj } 00:00:00 d #3 runtime.execute_with_options / { file_name = dotnet; arguments = ["publish", "/home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj", "--configuration", "Release", "--output", "dist", "--runtime", "win-x64"]; options = { command = dotnet publish "/home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj" --configuration Release --output "dist" --runtime win-x64; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = Some( "/home/runner/work/polyglot/polyglot/target/spiral_builder/test1", ) } } 00:00:00 v #4 > MSBuild version 17.10.0-preview-24101-01+07fd5d51f for .NET 00:00:00 v #5 > Determining projects to restore... 00:00:01 v #6 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj (in 282 ms). 00:00:01 v #7 > /usr/share/dotnet/sdk/9.0.100-preview.1.24101.2/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(313,5): message NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy [/home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj] 00:00:02 v #8 > /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fs(1,16): warning FS0988: Main module of program is empty: nothing will happen when it is run [/home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj] 00:00:02 v #9 > test1 -> /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/bin/Release/net9.0/win-x64/test1.dll 00:00:03 v #10 > test1 -> /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/dist 00:00:03 v #11 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 951 } 00:00:03 d #12 runtime.execute_with_options / { file_name = dotnet; arguments = ["publish", "/home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj", "--configuration", "Release", "--output", "dist", "--runtime", "linux-x64"]; options = { command = dotnet publish "/home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj" --configuration Release --output "dist" --runtime linux-x64; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = Some( "/home/runner/work/polyglot/polyglot/target/spiral_builder/test1", ) } } 00:00:03 v #13 > MSBuild version 17.10.0-preview-24101-01+07fd5d51f for .NET 00:00:03 v #14 > Determining projects to restore... 00:00:04 v #15 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj (in 273 ms). 00:00:04 v #16 > /usr/share/dotnet/sdk/9.0.100-preview.1.24101.2/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(313,5): message NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy [/home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj] 00:00:05 v #17 > /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fs(1,16): warning FS0988: Main module of program is empty: nothing will happen when it is run [/home/runner/work/polyglot/polyglot/target/spiral_builder/test1/test1.fsproj] 00:00:06 v #18 > test1 -> /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/bin/Release/net9.0/linux-x64/test1.dll 00:00:06 v #19 > test1 -> /home/runner/work/polyglot/polyglot/target/spiral_builder/test1/dist 00:00:06 v #20 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 953 } __assert_eq / actual: 0 / expected: 0
In [ ]:
//// test
///! rust -d encoding_rs encoding_rs_io regex
build_code {
workspace_root = file_system.get_workspace_root ()
runtime = None
packages = []
modules = []
output_dir = None
name = "test2"
code = "1 + a |> ignore"
}
|> _assert_eq 2
00:00:00 v #1 file_system.create_dir / { dir = /home/runner/work/polyglot/polyglot/target/spiral_builder/test2 } 00:00:00 d #2 build_project / { full_path = /home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj } 00:00:00 d #3 runtime.execute_with_options / { file_name = dotnet; arguments = ["publish", "/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj", "--configuration", "Release", "--output", "dist", "--runtime", "win-x64"]; options = { command = dotnet publish "/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj" --configuration Release --output "dist" --runtime win-x64; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = Some( "/home/runner/work/polyglot/polyglot/target/spiral_builder/test2", ) } } 00:00:00 v #4 > MSBuild version 17.10.0-preview-24101-01+07fd5d51f for .NET 00:00:00 v #5 > Determining projects to restore... 00:00:01 v #6 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj (in 294 ms). 00:00:01 v #7 > /usr/share/dotnet/sdk/9.0.100-preview.1.24101.2/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(313,5): message NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy [/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj] 00:00:02 v #8 > /home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fs(1,5): error FS0039: The value or constructor 'a' is not defined. [/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj] 00:00:02 v #9 runtime.execute_with_options / result / { exit_code = 1; std_trace_length = 732 } 00:00:02 d #10 runtime.execute_with_options / { file_name = dotnet; arguments = ["publish", "/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj", "--configuration", "Release", "--output", "dist", "--runtime", "linux-x64"]; options = { command = dotnet publish "/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj" --configuration Release --output "dist" --runtime linux-x64; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = Some( "/home/runner/work/polyglot/polyglot/target/spiral_builder/test2", ) } } 00:00:02 v #11 > MSBuild version 17.10.0-preview-24101-01+07fd5d51f for .NET 00:00:02 v #12 > Determining projects to restore... 00:00:03 v #13 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj (in 280 ms). 00:00:03 v #14 > /usr/share/dotnet/sdk/9.0.100-preview.1.24101.2/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(313,5): message NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy [/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj] 00:00:04 v #15 > /home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fs(1,5): error FS0039: The value or constructor 'a' is not defined. [/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fsproj] 00:00:04 v #16 runtime.execute_with_options / result / { exit_code = 1; std_trace_length = 732 } 00:00:04 c #17 build_code / { code = 1 + a |> ignore; fsproj_text = <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net9.0</TargetFramework> <LangVersion>preview</LangVersion> <RollForward>Major</RollForward> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <PublishAot>false</PublishAot> <PublishTrimmed>false</PublishTrimmed> <PublishSingleFile>true</PublishSingleFile> <SelfContained>true</SelfContained> <Version>0.0.1-alpha.1</Version> <OutputType>Exe</OutputType> </PropertyGroup> <PropertyGroup Condition="$([MSBuild]::IsOSPlatform('FreeBSD'))"> <DefineConstants>_FREEBSD</DefineConstants> </PropertyGroup> <PropertyGroup Condition="$([MSBuild]::IsOSPlatform('Linux'))"> <DefineConstants>_LINUX</DefineConstants> </PropertyGroup> <PropertyGroup Condition="$([MSBuild]::IsOSPlatform('OSX'))"> <DefineConstants>_OSX</DefineConstants> </PropertyGroup> <PropertyGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))"> <DefineConstants>_WINDOWS</DefineConstants> </PropertyGroup> <ItemGroup> <Compile Include="/home/runner/work/polyglot/polyglot/target/spiral_builder/test2/test2.fs" /> </ItemGroup> <ItemGroup> </ItemGroup> </Project> } __assert_eq / actual: 2 / expected: 2
read_file¶
In [ ]:
inl read_file path =
inl code =
path
|> file_system.read_all_text
|> sm'.replace_regex $'@@"(?P<a> *)(?P<b>let\\s+main\\s+.*?\\s*=)"' "$a[<EntryPoint>]\n$a$b"
inl code_trim = code |> sm'.trim_end []
if code_trim |> sm'.ends_with "\\n()"
then code_trim |> sm'.slice 0i64 ((code_trim |> sm'.length) - 3)
else code
persist_file¶
In [ ]:
inl persist_file { workspace_root package_dir packages modules path } =
inl full_path = path |> file_system.get_full_path
inl name = full_path |> file_system.get_file_name_without_extension
inl code = full_path |> read_file
persist_code_project { workspace_root package_dir packages modules name code }
build_file¶
In [ ]:
inl build_file { workspace_root runtime packages modules path } =
inl full_path = path |> file_system.get_full_path
inl dir = full_path |> file_system.get_directory_name
build_code {
workspace_root
runtime
packages
modules
output_dir = dir </> "dist" |> Some
name = full_path |> file_system.get_file_name_without_extension
code = full_path |> read_file
}
rust¶
get_workspace_cargo_toml_content¶
In [ ]:
inl get_workspace_cargo_toml_content { workspace_root } : string =
inl workspace_root = workspace_root |> file_system.normalize_path
$'$"cargo-features = [\\\"profile-rustflags\\\"]"'
+#. $'$""'
+#. $'$"[workspace]"'
+#. $'$"resolver = \\\"2\\\""'
+#. $'$"members = [\\\"packages/Rust/*\\\"]"'
+#. $'$""'
+#. $'$"[workspace.dependencies.fable_library_rust]"'
+#. $'$"path = \\\"{!workspace_root}/lib/rust/fable/fable_modules/fable-library-rust\\\""'
+#. $'$"default-features = false"'
+#. $'$"features = []"'
+#. $'$""'
+#. $'$"[workspace.dependencies]"'
+#. $'$"inline_colorization = \\\"~0.1\\\""'
+#. $'$""'
+#. $'$"[profile.release]"'
+#. $'$"codegen-units = 1"'
+#. $'$"opt-level = \\\"z\\\""'
+#. $'$"lto = true"'
+#. $'$"debug = false"'
+#. $'$"panic = \\\"abort\\\""'
+#. $'$"overflow-checks = true"'
+#. $'$"rustflags = [\\\"-C\\\", \\\"link-arg=-s\\\"]"'
get_cargo_toml_content¶
In [ ]:
inl get_cargo_toml_content { hash_hex runtime deps static_do_bindings } : string =
$'$"[package]"'
+#. $'$"name = \\\"spiral_builder_{!hash_hex}\\\""'
+#. $'$"version = \\\"0.0.1\\\""'
+#. $'$"edition = \\\"2021\\\""'
+#. $'$""'
+#. $'$"[dependencies]"'
+#. (
if runtime <>. None
then $'$"fable_library_rust = {{ workspace = true }}"'
else
$'$"fable_library_rust = {{"'
+. $'$" workspace = true,"'
+. $'$" features = ["'
+. (
if static_do_bindings
then $'$"\\\"static_do_bindings\\\", \\\"datetime\\\", \\\"guid\\\", \\\"threaded\\\""'
else $'$"\\\"datetime\\\", \\\"guid\\\", \\\"threaded\\\""'
)
+. $'$"]"'
+. $'$"}}"'
)
+#. $'$"inline_colorization = {{ workspace = true }}"'
+#. $'$"{!deps}"'
+#. $'$""'
+#. (
if runtime = None then
$'$"[[bin]]"'
+#. $'$"name = \\\"spiral_builder_{!hash_hex}\\\""'
else
$'$"[lib]"'
+#. $'$"crate-type = [\\\"cdylib\\\"]"'
)
+#. $'$"path = \\\"spiral_builder.rs\\\""'
get_empty_cargo_toml_content¶
In [ ]:
inl get_empty_cargo_toml_content () =
inl guid = date_time.now () |> date_time.new_guid_from_date_time |> sm'.obj_to_string
$'$"[package]"'
+#. $'$"name = \\\"spiral_builder_{!guid}\\\""'
+#. $'$"version = \\\"0.0.1\\\""'
+#. $'$"edition = \\\"2021\\\""'
+#. $'$""'
+#. $'$"[[bin]]"'
+#. $'$"name = \\\"spiral_builder_{!guid}\\\""'
+#. $'$"path = \\\"spiral_builder.rs\\\""'
process_rust¶
In [ ]:
inl process_rust { fs_path deps trace_level runtime cleanup } =
open runtime
inl extension = "rs"
inl code = fs_path |> file_system.read_all_text
inl hash_hex = { extension code runtime } |> sm'.format |> crypto.hash_text
inl workspace_name = "spiral_builder"
inl workspace_root_external = file_system.get_workspace_root_external ()
inl workspace_root = workspace_root_external |> resultm.box |> resultm.unwrap_or_else id
inl package_dir =
get_package_dir { workspace_root name = workspace_name; target = Some Rust; hash = Some hash_hex }
inl fsproj_path =
persist_code_project {
workspace_root
package_dir
packages = [ "Fable.Core" ]
modules = []
name = workspace_name
code
}
inl workspace_dir = package_dir </> "../../.."
inl workspace_cargo_toml_path = workspace_dir </> "Cargo.toml"
if workspace_cargo_toml_path |> file_system.file_exists |> not
then get_empty_cargo_toml_content () |> file_system.write_all_text workspace_cargo_toml_path
inl cargo_toml_path = package_dir </> "Cargo.toml"
if cargo_toml_path |> file_system.file_exists |> not
then get_empty_cargo_toml_content () |> file_system.write_all_text cargo_toml_path
inl lib_link_target_path = workspace_root </> "lib/rust/fable/fable_modules/fable-library-rust"
inl lib_link_path = package_dir </> "fable_modules/fable-library-rust"
lib_link_path |> file_system.link_directory lib_link_target_path
inl exit_code, dotnet_fable_result =
execute_dotnet_fable { workspace_root_external fsproj_path extension package_dir runtime }
inl result' = {
extension = Some extension
code = None
code_path = None
output = None
}
if exit_code <>. 0 then
trace Critical
fun () => "spiral_builder.process_rust / dotnet fable error"
fun () => { exit_code dotnet_fable_result }
{ result' with
output = Some dotnet_fable_result
}
else
inl deps =
inl deps =
if runtime = None
then deps
else
// TODO: simplify
inl has_near_sdk =
deps
|> am'.vec_filter (sm'.from_std_string >> sm'.contains "near-sdk")
|> am'.vec_len
|> i32
|> fun n => n > 0
// TODO: simplify with ++
if has_near_sdk
then deps
else deps |> am'.vec_extend (;[ "near-sdk" |> sm'.to_std_string ] |> am'.to_vec)
deps
|> am'.vec_map fun dep =>
inl dep = dep |> sm'.from_std_string
if dep |> sm'.contains "="
then dep
elif dep |> sm'.ends_with "]"
then dep |> sm'.replace "[" $'$"={{version=\'*\',features=["' |> fun x => $'$"{!x}}}"'
else $'$"{!dep}=\'*\'"'
|> am'.from_vec
|> fun x => x : _ i32 _
|> seq.of_array'
|> sm'.concat "\n"
inl new_code_path = package_dir </> $'$"{!workspace_name}.{!extension}"'
inl new_code = new_code_path |> file_system.read_all_text
inl on_startup_text = "on_startup!" +. (join "(")
inl method0_fn_text = " method0" +. (join "(")
inl static_do_bindings =
(new_code |> sm'.contains on_startup_text)
&& (new_code |> sm'.contains method0_fn_text |> not)
inl cargo_toml_content =
get_cargo_toml_content { hash_hex runtime deps static_do_bindings }
inl workspace_cargo_toml_content = get_workspace_cargo_toml_content { workspace_root }
cargo_toml_content |> file_system.write_all_text_exists cargo_toml_path
workspace_cargo_toml_content |> file_system.write_all_text_exists workspace_cargo_toml_path
inl range_rs_path = lib_link_path </> "src/Range.rs"
if range_rs_path |> file_system.file_exists then
inl text = range_rs_path |> file_system.read_all_text
text
|> sm'.replace "use crate::String_::fromCharCode;" "use crate::String_::fromChar;"
|> sm'.replace "fromCharCode(c)" "std::char::from_u32(c).unwrap()"
|> file_system.write_all_text_exists range_rs_path
inl exit_code, cargo_fmt_result =
fun () =>
inl exit_code, result =
execution_options fun x => { x with
command = $'$"cargo fmt --manifest-path \\\"{!cargo_toml_path}\\\" --"'
working_directory = workspace_root_external |> resultm.box |> resultm.ok'
}
|> execute_with_options
inl return () =
if exit_code = 0
then Ok (exit_code, result)
else Error (exit_code, result)
if result |> sm'.contains "failed to load manifest for workspace member" |> not
then return ()
else
inl missing_toml_path =
"failed to read `(?<a>.*?Cargo.toml)`"
|> sm'.new_regex
|> resultm.unwrap'
|> sm'.regex_captures result
|> am'.from_vec
|> fun x => x : _ i32 _
|> am'.try_item 0
|> optionm.map (mapm.get "a" >> optionm'.unbox)
|> optionm'.flatten
match missing_toml_path with
| None => Error (exit_code, result)
| Some missing_toml_path =>
if missing_toml_path |> file_system.file_exists |> not then
missing_toml_path
|> file_system.get_directory_name
|> file_system.create_dir
|> ignore
get_empty_cargo_toml_content ()
|> file_system.write_all_text missing_toml_path
return ()
|> retry_fn' 3u8
if exit_code <>. 0 then
trace Critical
fun () => "spiral_builder.process_rust / cargo fmt error"
fun () => { exit_code cargo_fmt_result }
inl new_code = new_code_path |> file_system.read_all_text
inl main_code_header =
"pub fn main() -> Result<(), String> " +. (join "{")
inl main_code : string =
if runtime = None
then ""
else
$'$"#[near_sdk::near_bindgen]"'
+#. $'$"#[derive(near_sdk::PanicOnDefault)]"'
+#. $'$"pub struct MainState {{"'
+#. $'$"}}"'
+#. $'$""'
+#. $'$"#[near_sdk::near_bindgen]"'
+#. $'$"impl MainState {{"'
+#. $'$" pub fn state_main() {{"'
+#. $'$" Spiral_builder::method0();"'
+#. $'$" }}"'
+#. $'$"}}"'
+#. (
if runtime = None && (new_code |> sm'.contains (on_startup_text +. "Spiral_builder::method0()"))
then $'$"{!main_code_header} Ok(Spiral_builder::method0()) }}"'
else $'$"{!main_code_header} Ok(()) }}"'
)
inl cached = new_code |> sm'.contains main_code_header
inl new_code' = $'$"{!new_code}\\n\\n{!main_code}\\n"'
inl new_code =
if cached
then new_code
else
new_code'
|> sm'.replace
("),)" +. !\($'"\\\";\\\".into()"'))
"));"
|> sm'.replace
("},)" +. !\($'"\\\";\\\".into()"'))
"});"
|> sm'.replace_regex
"\\s\\sdefaultOf\\(\\);"
" defaultOf::<()>();"
|> sm'.replace
"::Slice'_"
"::Slice__"
|> sm'.replace
" Slice'_"
" Slice__"
|> sm'.replace
("defaultOf()" +. !\($'"\\\",\\\".into()"'))
"defaultOf::<std::sync::Arc<dyn IDisposable>>(),"
|> sm'.replace
("_self" +. !\($'"\\\"_.\\\".into()"'))
"self."
|> sm'.replace
("get_or_insert_wit" +. !\($'"\\\"h\\\".into()"'))
"get_or_init"
|> sm'.replace
("use fable_library_rust::System::Collections::Concurrent::ConcurrentStack_1" +. !\($'"\\\";\\\".into()"'))
"type ConcurrentStack_1<T> = T;"
|> sm'.replace
("use fable_library_rust::System::Collections::Generic" +. !\($'"\\\"::\\\".into()"'))
"use fable_library_rust::Interfaces_::System::Collections::Generic::"
|> sm'.replace
("use fable_library_rust::System::IDisposable" +. !\($'"\\\";\\\".into()"'))
"use fable_library_rust::Interfaces_::System::IDisposable;"
|> sm'.replace
("use fable_library_rust::System::Threading::CancellationToken" +. !\($'"\\\";\\\".into()"'))
"type CancellationToken = ();"
|> sm'.replace
("use fable_library_rust::System::TimeZoneInfo" +. !\($'"\\\";\\\".into()"'))
"type TimeZoneInfo = i64;"
|> sm'.replace
("use fable_library_rust::System::Threading::Tasks::TaskCanceledException" +. !\($'"\\\";\\\".into()"'))
"type TaskCanceledException = ();"
|> if static_do_bindings
then id
else sm'.replace
on_startup_text
("// " +. on_startup_text)
if not cached then
new_code
|> file_system.write_all_text_exists new_code_path
inl command =
if runtime <> None
then $'$"cargo +nightly-2024-07-14 build --release --target wasm32-unknown-unknown --manifest-path \\\"{!cargo_toml_path}\\\""'
else $'$"cargo run --manifest-path \\\"{!cargo_toml_path}\\\""'
inl environment_variables =
if runtime <> None
then ;[]
else
inl fast = false
;[
"TRACE_LEVEL", "Verbose"
"RUSTC_WRAPPER", "sccache"
"RUST_BACKTRACE", "full"
"RUSTFLAGS",
if fast
then "-C prefer-dynamic -C strip=symbols -C link-arg=-s -C debuginfo=0"
else "-C prefer-dynamic"
]
inl exit_code, cargo_result =
execution_options fun x => { x with
command
environment_variables
working_directory = workspace_root_external |> resultm.box |> resultm.ok'
}
|> execute_with_options
inl result =
if runtime = None then
inl external_command =
inl vars =
a environment_variables
|> am.map fun k, v => $'$"$env:{!k}=\'\'{!v}\'\'"' : string
|> fun x => x : _ i32 _
|> seq.of_array
|> sm'.concat ";"
inl command =
a ;[
vars
command
]
|> fun x => x : _ i32 _
|> seq.of_array
|> sm'.concat ";"
$'$"pwsh -c \'{!command}\'"' : string
if exit_code <>. 0 then
trace Critical
fun () => "spiral_builder.process_rust / error"
fun () => { exit_code new_code_path external_command cleanup cargo_result }
result'
else
inl output =
try
fun () =>
cargo_result
|> sm'.split "\n"
|> fun x => a x : _ i32 _
|> am'.skip_while fun line =>
(line |> sm'.contains "profile [optimized] target" |> not)
&& (line |> sm'.contains "profile [unoptimized] target" |> not)
&& (line |> sm'.contains "profile [unoptimized + debuginfo] target" |> not)
|> am'.skip 2
|> seq.of_array
|> sm'.concat "\n"
fun ex =>
trace Critical
fun () => "spiral_builder.process_rust / Exception"
fun () => { ex new_code_path external_command cargo_result }
None
|> optionm'.box
|> optionm'.unwrap
{ result' with
code = Some new_code
code_path = Some new_code_path
output = Some output
}
else
inl wasm_path : string =
$'$"target/spiral_builder/{!workspace_name}/target/wasm32-unknown-unknown/release/spiral_builder_{!hash_hex}.wasm"'
inl command =
inl invoke_block_path = "scripts/invoke-block.ps1"
inl spiral_wasm_command : string =
inl runtime_cmd =
match runtime with
| Some (Wasm cmd) => cmd
| Some (Contract cmd) => cmd
| _ => ""
$'$"\'workspace/target/release/spiral_wasm -w {!wasm_path} -t Debug {!runtime_cmd}\'"'
inl automation = "AUTOMATION" |> env.get_environment_variable
$'$"pwsh -c \\\"pwsh {!invoke_block_path} {!spiral_wasm_command} -Linux -EnvironmentVariables AUTOMATION={!automation}\`nNEAR_RPC_TIMEOUT_SECS=100\\\""'
if exit_code = 0 then
inl exit_code, spiral_wasm_result =
execution_options fun x => { x with
command
working_directory = workspace_root |> optionm'.some'
}
|> execute_with_options
if exit_code = 0 then
{ result' with
code = Some new_code
code_path = Some new_code_path
output = Some spiral_wasm_result
}
else
trace Critical
fun () => "spiral_builder.process_rust / wasm error"
fun () => {
exit_code new_code_path cargo_result cleanup
spiral_wasm_result = $'$"\\n{!spiral_wasm_result}"' : string
}
result'
else
trace Critical
fun () => "spiral_builder.process_rust / cargo error"
fun () => {
exit_code new_code_path wasm_path command cleanup
cargo_result = $'$"\\n{!cargo_result}"' : string
}
result'
if cleanup then
inl cleanup =
inl build_target =
if runtime <> None
then "wasm32-unknown-unknown/release"
else "debug"
[ ".d"; ".exe"; ".pdb"; ".wasm"; "" ]
|> listm.map fun ext =>
workspace_dir </> $'$"target/{!build_target}/spiral_builder_{!hash_hex}{!ext}"'
|> listm.map fun path => path, path |> file_system.file_exists
trace Verbose
fun () => "spiral_builder.process_rust / cleanup"
fun () => { new_code_path cleanup }
cleanup
|> listm'.filter snd
|> listm.iter (fst >> file_system.file_delete)
result
dib¶
process_dib¶
In [ ]:
inl process_dib { path retries working_directory } =
inl exit_code, repl_result =
let rec loop retry =
inl exit_code, repl_result =
runtime.execution_options fun x => { x with
command = $'$"dotnet repl --exit-after-run --run \\\"{!path}\\\" --output-path \\\"{!path}.ipynb\\\""'
environment_variables = ;[
"TRACE_LEVEL", "Verbose"
"AUTOMATION", "True"
]
trace = false
working_directory = working_directory |> optionm'.box
}
|> runtime.execute_with_options
if exit_code = 0 || retry >= retries
then exit_code, repl_result
else
trace Debug
fun () => "spiral_builder.run / repl error"
fun () => { exit_code repl_result retry = $'$"{!retry}/{!retries}"' : string }
loop (retry + 1)
loop 1
inl exit_code, result =
if exit_code <>. 0
then exit_code, repl_result
else
inl exit_code, jupyter_result =
runtime.execution_options fun x => { x with
command = $'$"jupyter nbconvert \\\"{!path}.ipynb\\\" --to html --HTMLExporter.theme=dark"'
}
|> runtime.execute_with_options
trace Debug
fun () => "spiral_builder.run / dib / jupyter nbconvert"
fun () => { exit_code jupyter_result_length = jupyter_result |> sm'.length : i32 }
if exit_code <>. 0
then exit_code, $'$"repl_result: {!repl_result}\n\njupyter_result: {!jupyter_result}"'
else
inl exit_code, pwsh_replace_html_result =
inl path = path |> sm'.replace "'" "''"
runtime.execution_options fun x => { x with
command = $'$"pwsh -c \\\"$counter = 1; $path = \'{!path}.html\'; (Get-Content $path -Raw) -replace \'(id=\\\\\\"cell-id=)[a-fA-F0-9]{{8}}\', {{ $_.Groups[1].Value + $counter++ }} | Set-Content $path\\\""'
}
|> runtime.execute_with_options
trace Debug
fun () => "spiral_builder.run / dib / html cell ids"
fun () => { exit_code pwsh_replace_html_result_length = pwsh_replace_html_result |> sm'.length : i32 }
$'$"{!path}.html"'
|> file_system.read_all_text
|> sm'.replace "\r\n" "\n"
|> file_system.write_all_text $'$"{!path}.html"'
$'$"{!path}.ipynb"'
|> file_system.read_all_text
|> sm'.replace "\r\n" "\n"
|> sm'.replace "\\r\\n" "\\n"
|> file_system.write_all_text $'$"{!path}.ipynb"'
exit_code, $'$"repl_result: {!repl_result}\n\njupyter_result: {!jupyter_result}\n\npwsh_replace_html_result: {!pwsh_replace_html_result}"'
trace Debug
fun () => "spiral_builder.run / dib"
fun () => { exit_code result_length = result |> sm'.length : i32 }
if exit_code <>. 0
then failwith $'$"spiral_builder.run / dib / exit_code: {!exit_code} / result: {!result}"'
;[
"stdio",
result
]
typescript¶
process_typescript¶
In [ ]:
inl process_typescript { fs_path deps trace_level } =
inl extension = "ts"
inl code = fs_path |> file_system.read_all_text
inl hash_hex = (extension, code) |> sm'.format_debug |> crypto.hash_text
inl workspace_name = "spiral_builder"
inl workspace_root_external = file_system.get_workspace_root_external ()
inl workspace_root = workspace_root_external |> resultm.box |> resultm.unwrap_or_else id
inl package_dir =
get_package_dir
{ workspace_root name = workspace_name; target = Some TypeScript; hash = Some hash_hex }
inl fsproj_path =
persist_code_project {
workspace_root
package_dir
packages = [ "Fable.Core" ]
modules = []
name = workspace_name
code
}
inl lib_path = workspace_root </> "lib/typescript/fable/fable_modules"
inl versions : _ (string * string) =
lib_path
|> file_system.new_walk_dir
|> file_system.walk_dir_filter fun entry => async.new_future_move_send fun () =>
entry
|> file_system.dir_entry_file_type
|> async.await_send
|> resultm.map_error' sm'.format'
|> resultm.unbox
|> function
| Ok file_type when file_type |> file_system.file_type_is_dir |> not => file_system.Ignore
| _ =>
inl path =
entry
|> file_system.dir_entry_path
|> file_system.path_buf_display
|> sm'.format'
|> sm'.from_std_string
if path |> file_system.get_directory_name |> sm'.starts_with "fable-library-ts."
then file_system.Continue
else file_system.IgnoreDir
|> async.stream_filter_map_futures fun (entry : _ _ file_system.async_walkdir_error) =>
inl entry = entry |> resultm.map_error' sm'.format' |> resultm.unbox
match entry with
| Ok entry =>
inl path =
entry
|> file_system.dir_entry_path
|> file_system.path_buf_display
|> sm'.format'
|> sm'.from_std_string
inl version =
$'$"fable-library-{!extension}\\.(?<a>[\\d.]+)$"'
|> sm'.new_regex
|> resultm.unwrap'
|> sm'.regex_captures path
|> am'.from_vec
|> fun x => x : _ i32 _
|> am'.try_item 0
|> optionm.map (mapm.get "a" >> optionm'.unbox)
|> optionm'.flatten
match version with
| None => None
| Some version => Some (path, version)
| Error error =>
trace Critical
fun () => "spiral_builder.process_typescript / stream_filter_map"
fun () => { error }
None
|> optionm'.box
|> async.stream_collect_futures
|> async.await
|> async.into_par_iter
|> async.par_map id
|> async.par_collect
inl version =
versions
|> am'.from_vec
|> fun x => x : _ i32 _
|> am'.try_item 0
trace Debug
fun () => "spiral_builder.process_typescript"
fun () => { version }
match version with
| None => ()
| Some (_path, version) =>
inl lib_link_target_path = lib_path </> $'$"fable-library-{!extension}.{!version}"'
inl lib_link_path = package_dir </> $'$"fable_modules/fable-library-{!extension}.{!version}"'
lib_link_path |> file_system.link_directory lib_link_target_path
inl exit_code, dotnet_fable_result =
execute_dotnet_fable { workspace_root_external fsproj_path extension package_dir runtime = None }
if exit_code <>. 0 then
trace Critical
fun () => "spiral_builder.process_typescript"
fun () => { exit_code dotnet_fable_result }
{ extension = Some extension; code = None; code_path = None; output = Some dotnet_fable_result }
else
inl deps =
deps
|> am'.vec_map fun dep =>
inl dep = dep |> sm'.from_std_string
if dep |> sm'.contains "="
then dep
else $'$"\\"{!dep}\\":\\"*\\""'
|> am'.from_vec
|> fun x => x : _ i32 _
|> seq.of_array'
|> sm'.concat ",\n"
inl package_json_content =
$'$"{{"'
+. $'$" \\\"name\\\": \\\"spiral_builder_{!hash_hex}\\\","'
+. $'$" \\\"dependencies\\\": {{"'
+. deps
+. $'$" }},"'
+. $'$" \\\"devDependencies\\\": {{"'
+. $'$" }},"'
+. $'$"}}"'
inl workspace_package_json_content =
""
inl package_json_path = package_dir </> "package.json"
inl workspace_dir = package_dir </> "../.."
inl workspace_package_json_path = workspace_dir </> "package.json"
package_json_content |> file_system.write_all_text_exists package_json_path
workspace_package_json_content |> file_system.write_all_text_exists workspace_package_json_path
inl new_code_path = package_dir </> $'$"{!workspace_name}.{!extension}"'
trace Debug
fun () => "spiral_builder.process_typescript"
fun () => { new_code_path }
inl new_code = new_code_path |> file_system.read_all_text
inl main_code_header =
"// spiral_builder.process_typescript"
inl main_code = "// spiral_builder.process_typescript"
inl cached = new_code |> sm'.contains main_code_header
inl new_code =
if cached
then new_code
else
new_code
|> sm'.replace
$'$"\\\"./fable_modules/fable-library-ts.{!version}/"'
$'$"\\\"{!workspace_root}/lib/typescript/fable/fable_modules/fable-library-ts.{!version}/"'
|> sm'.replace_regex
"\\s\\sdefaultOf\\(\\);"
" defaultOf::<()>();"
if not cached then
$'$"{!new_code}\\n\\n{!main_code}\\n"'
|> file_system.write_all_text_exists new_code_path
inl command = $'$"bun run \\\"{!new_code_path}\\\""'
inl environment_variables =
match "~/.bun/bin" |> env.append_path with
| Some path => [ "PATH", path ]
| None => []
++ [
"TRACE_LEVEL", "Verbose"
]
|> listm'.box
|> listm'.to_array'
inl exit_code, run_result =
runtime.execution_options fun x => { x with
command
environment_variables
working_directory = workspace_root_external |> resultm.box |> resultm.ok'
}
|> runtime.execute_with_options
inl external_command =
inl vars =
a environment_variables
|> am.map fun k, v => $'$"$env:{!k}=\'\'{!v}\'\'"' : string
|> fun x => x : _ i32 _
|> seq.of_array
|> sm'.concat ";"
$'$"pwsh -c \'{!vars}; {!command}\'"' : string
if exit_code = 0 then
inl output =
try
fun () =>
run_result
|> sm'.split "\n"
|> fun x => a x : _ i32 _
|> seq.of_array
|> sm'.concat "\n"
fun ex =>
trace Critical
fun () => "spiral_builder.process_typescript / Exception"
fun () => { ex new_code_path external_command run_result }
None
|> optionm'.box
|> optionm'.unwrap
{
extension = Some extension
code = Some new_code
code_path = Some new_code_path
output = Some output
}
else
trace Critical
fun () => "spiral_builder.process_typescript / error"
fun () => { exit_code run_result new_code_path external_command }
{ extension = Some extension; code = None; code_path = None; output = None }
python¶
process_python¶
In [ ]:
inl process_python { fs_path deps trace_level } =
inl extension = "py"
inl is_trace = trace_level = Verbose
inl _trace (fn : () -> string) =
if is_trace
then trace Info (fun () => $'$"spiral_builder.process_python / {!fn ()}"') id
else fn () |> console.write_line
inl code = fs_path |> file_system.read_all_text
inl hash_hex = (extension, code) |> sm'.format_debug |> crypto.hash_text
inl workspace_name = "spiral_builder"
inl workspace_root_external = file_system.get_workspace_root_external ()
inl workspace_root = workspace_root_external |> resultm.box |> resultm.unwrap_or_else id
inl package_dir =
get_package_dir { workspace_root name = workspace_name; target = Some Python; hash = Some hash_hex }
inl fsproj_path =
persist_code_project {
workspace_root
package_dir
packages = [ "Fable.Core" ]
modules = []
name = workspace_name
code
}
inl lib_path = workspace_root </> "lib/python/fable/fable_modules"
inl lib_link_target_path = lib_path </> $'$"fable_library"'
inl lib_link_path = package_dir </> $'$"fable_modules/fable_library"'
lib_link_path |> file_system.link_directory lib_link_target_path
inl exit_code, dotnet_fable_result =
execute_dotnet_fable { workspace_root_external fsproj_path extension package_dir runtime = None }
if exit_code <>. 0 then
trace Critical
fun () => "spiral_builder.process_python"
fun () => { exit_code dotnet_fable_result }
{ extension = Some extension; code = None; code_path = None; output = Some dotnet_fable_result }
else
inl deps =
deps
|> am'.vec_map fun dep =>
inl dep = dep |> sm'.from_std_string
if dep |> sm'.contains "="
then dep
else $'$"\\"{!dep}\\":\\"*\\""'
|> am'.from_vec
|> fun x => x : _ i32 _
|> seq.of_array'
|> sm'.concat ",\n"
inl package_json_content =
$'$"{{"'
+. $'$" \\\"name\\\": \\\"spiral_builder_{!hash_hex}\\\","'
+. $'$" \\\"dependencies\\\": {{"'
+. deps
+. $'$" }},"'
+. $'$" \\\"devDependencies\\\": {{"'
+. $'$" }},"'
+. $'$"}}"'
inl workspace_package_json_content =
""
inl package_json_path = package_dir </> "package.json"
inl workspace_dir = package_dir </> "../.."
inl workspace_package_json_path = workspace_dir </> "package.json"
package_json_content |> file_system.write_all_text_exists package_json_path
workspace_package_json_content |> file_system.write_all_text_exists workspace_package_json_path
inl new_code_path = package_dir </> $'$"{!workspace_name}.{!extension}"'
trace Debug
fun () => "spiral_builder.process_python"
fun () => { new_code_path }
inl new_code = new_code_path |> file_system.read_all_text
inl main_code_header =
"# spiral_builder.process_python"
inl main_code = "# spiral_builder.process_python"
inl cached = new_code |> sm'.contains main_code_header
inl new_code =
if cached
then new_code
else
new_code
|> sm'.replace
("),)" +. !\($'"\\\";\\\".into()"'))
"));"
|> sm'.replace_regex
"\\s\\sdefaultOf\\(\\);"
" defaultOf::<()>();"
if not cached
then
$'$"{!new_code}\\n\\n{!main_code}\\n"'
|> file_system.write_all_text_exists new_code_path
inl command = $'$"python \\\"{!new_code_path}\\\""'
inl environment_variables =
;[
"TRACE_LEVEL", "Verbose"
]
inl exit_code, run_result =
runtime.execution_options fun x => { x with
command
environment_variables
working_directory = workspace_root_external |> resultm.box |> resultm.ok'
}
|> runtime.execute_with_options
inl external_command =
inl vars =
a environment_variables
|> am.map fun k, v => $'$"$env:{!k}=\'\'{!v}\'\'"' : string
|> fun x => x : _ i32 _
|> seq.of_array
|> sm'.concat ";"
$'$"pwsh -c \'{!vars}; {!command}\'"' : string
if exit_code = 0 then
inl output =
try
fun () =>
run_result
|> sm'.split "\n"
|> fun x => a x : _ i32 _
|> seq.of_array
|> sm'.concat "\n"
fun ex =>
trace Critical
fun () => "spiral_builder.process_python / Exception"
fun () => { ex new_code_path external_command run_result }
None
|> optionm'.box
|> optionm'.unwrap
{
extension = Some extension
code = Some new_code
code_path = Some new_code_path
output = Some output
}
else
trace Critical
fun () => "spiral_builder.process_python / error"
fun () => { exit_code run_result new_code_path external_command }
{ extension = Some extension; code = None; code_path = None; output = None }
cuda¶
process_cuda¶
In [ ]:
inl process_cuda { py_path env deps } =
inl extension = "py"
inl new_code_path = py_path
inl new_code = new_code_path |> file_system.read_all_text
inl workspace_root_external = file_system.get_workspace_root_external ()
inl workspace_root = workspace_root_external |> resultm.box |> resultm.unwrap_or_else id
inl package_dir = new_code_path |> file_system.get_directory_name
inl manifest_path =
match env with
| Pip => package_dir </> "requirements.txt"
| Poetry => package_dir </> "pyproject.toml"
inl deps =
deps
|> am'.vec_map fun dep =>
inl dep = dep |> sm'.from_std_string
if dep |> sm'.contains "="
then dep
elif dep |> sm'.ends_with "]"
then dep |> sm'.replace "[" $'$"={{version=\'*\',features=["' |> fun x => $'$"{!x}}}"'
else $'$"{!dep}=\'*\'"'
|> am'.from_vec
|> fun x => x : _ i32 _
|> seq.of_array'
|> sm'.concat "\n"
inl exit_code, run_result =
if deps = ""
then 0, ""
else
inl manifest =
match env with
| Pip =>
deps
| Poetry =>
$'$"[tool.poetry]"'
+#. $'$"name = \\\"test\\\""'
+#. $'$"version = \\\"0.0.1\\\""'
+#. $'$"description = \\\"\\\""'
+#. $'$"authors = []"'
+#. $'$""'
+#. $'$"[tool.poetry.dependencies]"'
+#. $'$"python=\\\"~3.12\\\""'
+#. $'$"{!deps}"'
+#. $'$""'
+#. $'$"[build-system]"'
+#. $'$"requires = [\\\"poetry-core\\\"]"'
+#. $'$"build-backend = \\\"poetry.core.masonry.api\\\""'
manifest |> file_system.write_all_text_exists manifest_path
runtime.execution_options fun x => { x with
command =
match env with
| Pip => $'$"pip install -r requirements.txt"'
| Poetry => $'$"poetry install"'
working_directory = package_dir |> optionm'.some'
}
|> runtime.execute_with_options
if exit_code <>. 0 then
trace Critical
fun () => "spiral_builder.process_cuda / env install error"
fun () => { env exit_code run_result new_code_path }
{ extension = Some extension; code = None; code_path = None; output = None }
else
inl command =
match env with
| Pip => $'$"python \\\"{!new_code_path}\\\""'
| Poetry => $'$"poetry run python \\\"{!new_code_path}\\\""'
inl environment_variables =
;[
"TRACE_LEVEL", "Verbose"
]
inl exit_code, run_result =
runtime.execution_options fun x => { x with
command
environment_variables
working_directory = package_dir |> optionm'.some'
}
|> runtime.execute_with_options
inl external_command =
inl vars =
a environment_variables
|> am.map fun k, v => $'$"$env:{!k}=\'\'{!v}\'\'"' : string
|> fun x => x : _ i32 _
|> seq.of_array
|> sm'.concat ";"
$'$"pwsh -c \'{!vars}; {!command}\'"' : string
if exit_code = 0
|| (run_result |> sm'.contains "cupy_backends.cuda.api.runtime.CUDARuntimeError: cudaErrorInsufficientDriver") then
inl output =
try
fun () =>
run_result
|> sm'.split "\n"
|> fun x => a x : _ i32 _
|> seq.of_array
|> sm'.concat "\n"
fun ex =>
trace Critical
fun () => "spiral_builder.process_cuda / Exception"
fun () => { ex run_result new_code_path external_command }
None
|> optionm'.box
|> optionm'.unwrap
{
extension = Some extension
code = Some new_code
code_path = Some new_code_path
output = Some output
}
else
trace Critical
fun () => "spiral_builder.process_cuda / error"
fun () => { exit_code run_result new_code_path external_command }
{ extension = Some extension; code = None; code_path = None; output = None }
fsharp¶
process_fsharp¶
In [ ]:
inl process_fsharp { spi_path } =
inl extension = "fsx"
inl new_code_path = spi_path
inl new_code = new_code_path |> file_system.read_all_text
inl workspace_root_external = file_system.get_workspace_root_external ()
inl workspace_root = workspace_root_external |> resultm.box |> resultm.unwrap_or_else id
inl supervisor_path = workspace_root </> $"apps/spiral/dist/Supervisor!(platform.get_executable_suffix ())"
inl code_dir = new_code_path |> file_system.get_directory_name
inl file_name = new_code_path |> file_system.get_file_name_without_extension
inl output_path = code_dir </> $'$"{!file_name}.{!extension}"'
inl command = $'$"{!supervisor_path} --build-file \\\"{!new_code_path}\\\" \\\"{!output_path}\\\""'
inl environment_variables =
;[
"TRACE_LEVEL", "Verbose"
]
inl exit_code, run_result =
runtime.execution_options fun x => { x with
command
environment_variables
working_directory = workspace_root_external |> resultm.box |> resultm.ok'
}
|> runtime.execute_with_options
inl external_command =
inl vars =
a environment_variables
|> am.map fun k, v => $'$"$env:{!k}=\'\'{!v}\'\'"' : string
|> fun x => x : _ i32 _
|> seq.of_array
|> sm'.concat ";"
$'$"pwsh -c \'{!vars}; {!command}\'"' : string
if exit_code = 0 then
inl output =
try
fun () =>
run_result
|> sm'.split "\n"
|> fun x => a x : _ i32 _
|> seq.of_array
|> sm'.concat "\n"
fun ex =>
trace Critical
fun () => "spiral_builder.process_fsharp / Exception"
fun () => { ex run_result new_code_path external_command }
None
|> optionm'.box
|> optionm'.unwrap
{
extension = Some extension
code = Some new_code
code_path = Some new_code_path
output = Some output
}
else
trace Critical
fun () => "spiral_builder.process_fsharp / error"
fun () => { exit_code run_result new_code_path external_command }
{ extension = Some extension; code = None; code_path = None; output = None }
run¶
In [ ]:
let rec run trace_level (matches : runtime.arg_matches) : async.future_pin (resultm.result' string string) =
fun () =>
match matches |> runtime.matches_subcommand |> optionm'.unbox with
| Some (subcommand, arg_matches)
when (subcommand |> sm'.from_std_string) = (get_args () .cuda |> fst) =>
inl py_path =
arg_matches
|> runtime.matches_get_one ((get_args () .cuda |> snd).py_path |> fst)
|> optionm'.unbox
|> optionm.value
|> sm'.from_std_string
inl env =
arg_matches
|> runtime.matches_get_one ((get_args () .cuda |> snd).env |> fst)
|> optionm'.unbox
|> optionm.map (
sm'.from_std_string
>> reflection.union_try_pick
)
|> optionm'.flatten
|> optionm'.default_value Pip
inl deps : am'.vec sm'.std_string =
arg_matches
|> runtime.matches_get_many ((get_args () .cuda |> snd).deps |> fst)
|> optionm'.unbox
|> optionm'.default_value (;[] |> am'.to_vec)
inl command_result =
process_cuda { py_path env deps }
|> fun { extension code output } =>
;[
"extension", extension |> optionm'.default_value ""
"code", code |> optionm'.default_value ""
"output", output |> optionm'.default_value ""
]
;[
"command_result",
command_result
|> am'.to_vec
|> am'.vec_map' fun k, v =>
new_pair (sm'.to_std_string k) (sm'.to_std_string v)
|> mapm.b_tree_map_from_vec_pairs
|> sm'.serialize
|> resultm.unwrap'
|> sm'.from_std_string
]
| Some (subcommand, arg_matches)
when (subcommand |> sm'.from_std_string) = (get_args () .fable |> fst) =>
inl fs_path =
arg_matches
|> runtime.matches_get_one ((get_args () .fable |> snd).fs_path |> fst)
|> optionm'.unbox
|> optionm.value
|> sm'.from_std_string
inl command =
arg_matches
|> runtime.matches_get_one ((get_args () .fable |> snd).command |> fst)
|> optionm'.unbox
|> optionm.map sm'.from_std_string
inl command_result =
match command with
| Some command =>
get_command ()
|> runtime.command_get_matches_from (
$'$"_ {!command} --fs-path \\\"{!fs_path}\\\""' |> runtime.split_args |> resultm.get
)
|> run trace_level
|> async.await
|> resultm.unwrap'
| None => "{}"
;[
"command_result",
command_result
]
| Some (subcommand, arg_matches)
when (subcommand |> sm'.from_std_string) = (get_args () .dib |> fst) =>
inl path =
arg_matches
|> runtime.matches_get_one ((get_args () .dib |> snd).path |> fst)
|> optionm'.map'' (
sm'.from_std_string
>> file_system.absolute_path
)
|> optionm'.unwrap
inl retries =
arg_matches
|> runtime.matches_get_one ((get_args () .dib |> snd).retries |> fst)
|> optionm'.default_value' 1u8
inl working_directory =
arg_matches
|> runtime.matches_get_one ((get_args () .dib |> snd).working_directory |> fst)
|> optionm'.unbox
process_dib { path retries working_directory }
| matches =>
match matches with
| Some (subcommand, arg_matches)
when (subcommand |> sm'.from_std_string) = (get_args () .rust |> fst) =>
inl fs_path =
arg_matches
|> runtime.matches_get_one ((get_args () .rust |> snd).fs_path |> fst)
|> optionm'.unbox
|> optionm.value
|> sm'.from_std_string
inl deps : am'.vec sm'.std_string =
arg_matches
|> runtime.matches_get_many ((get_args () .rust |> snd).deps |> fst)
|> optionm'.unbox
|> optionm'.default_value (;[] |> am'.to_vec)
inl cleanup =
arg_matches
|> runtime.matches_get_flag ((get_args () .rust |> snd).cleanup |> fst)
inl wasm =
arg_matches
|> runtime.matches_get_one ((get_args () .rust |> snd).wasm |> fst)
|> optionm'.unbox
|> optionm.map sm'.from_std_string
inl contract =
arg_matches
|> runtime.matches_get_one ((get_args () .rust |> snd).contract |> fst)
|> optionm'.unbox
|> optionm.map sm'.from_std_string
inl runtime =
match wasm, contract with
| Some wasm, _ => Wasm wasm |> Some
| _, Some contract => Contract contract |> Some
| _ => None
process_rust { fs_path deps trace_level runtime cleanup }
| Some (subcommand, arg_matches)
when (subcommand |> sm'.from_std_string) = (get_args () .typescript |> fst) =>
inl fs_path =
arg_matches
|> runtime.matches_get_one ((get_args () .typescript |> snd).fs_path |> fst)
|> optionm'.unbox
|> optionm.value
|> sm'.from_std_string
inl deps : am'.vec sm'.std_string =
arg_matches
|> runtime.matches_get_many ((get_args () .typescript |> snd).deps |> fst)
|> optionm'.unbox
|> optionm'.default_value (;[] |> am'.to_vec)
process_typescript { fs_path deps trace_level }
| Some (subcommand, arg_matches)
when (subcommand |> sm'.from_std_string) = (get_args () .python |> fst) =>
inl fs_path =
arg_matches
|> runtime.matches_get_one ((get_args () .python |> snd).fs_path |> fst)
|> optionm'.unbox
|> optionm.value
|> sm'.from_std_string
inl deps : am'.vec sm'.std_string =
arg_matches
|> runtime.matches_get_many ((get_args () .python |> snd).deps |> fst)
|> optionm'.unbox
|> optionm'.default_value (;[] |> am'.to_vec)
process_python { fs_path deps trace_level }
| Some (subcommand, arg_matches) =>
trace Debug
fun () => "spiral_builder.run / invalid subcommand"
fun () => { subcommand arg_matches }
{ extension = None; code = None; code_path = None; output = None }
| _ =>
{ extension = None; code = None; code_path = None; output = None }
|> fun { extension code code_path output } =>
;[
"extension", extension |> optionm'.default_value ""
"code", code |> optionm'.default_value ""
"code_path", code_path |> optionm'.default_value ""
"output", output |> optionm'.default_value ""
]
|> am'.to_vec
|> am'.vec_map' fun k, v =>
new_pair (sm'.to_std_string k) (sm'.to_std_string v)
|> mapm.b_tree_map_from_vec_pairs
|> sm'.serialize
|> resultm.map_error' (sm'.format' >> sm'.from_std_string)
|> resultm.map' sm'.from_std_string
|> async.new_future_move
In [ ]:
//// test
///! rust -d async-walkdir chrono clap encoding_rs encoding_rs_io futures rand rayon regex serde_json sha2
inl file_name = "main.fs"
inl code = "let method0 () =\n 3 - 6 |> System.Console.WriteLine\nmethod0 ()\n"
inl temp_dir, disposable =
(file_name, code)
|> sm'.format_debug
|> crypto.hash_text
|> file_system.create_temp_dir'
inl fs_path = temp_dir </> file_name
code |> file_system.write_all_text fs_path
get_command ()
|> runtime.command_get_matches_from ($'$"_ fable -f \\\"{!fs_path}\\\" -c \\\"rust -d regex=\'*\'\\\""' |> runtime.split_args |> resultm.get)
|> run Verbose
|> async.block_on_futures
|> resultm.unwrap'
|> sm'.deserialize
|> resultm.unwrap'
|> mapm.get ("command_result" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> sm'.deserialize
|> resultm.unwrap'
|> fun result =>
result
|> mapm.get ("extension" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> _assert_eq "rs"
result
|> mapm.get ("output" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> _assert_eq "-3"
disposable |> use |> ignore
00:00:00 v #1 file_system.create_dir / { dir = /tmp/!create_temp_path_/spiral_builder_e9782759fa3002c1eba9f575a575e79b1f55ccdb0d0370e1d87082a1739e5614/84b99b0b-d6d4-d4b8-7f79-3c480ce421da } 00:00:00 v #2 file_system.create_dir / { dir = /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026 } 00:00:00 v #3 file_system.create_dir / { dir = /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/fable_modules } 00:00:00 d #4 runtime.execute_with_options / { file_name = dotnet; arguments = ["fable", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/spiral_builder.fsproj", "--optimize", "--lang", "rs", "--extension", ".rs", "--outDir", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026", "--define", "_LINUX"]; options = { command = dotnet fable "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/spiral_builder.fsproj" --optimize --lang rs --extension .rs --outDir "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026" --define _LINUX; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:00 v #5 > Fable 4.21.0: F# to Rust compiler (status: alpha) 00:00:00 v #6 > 00:00:00 v #7 > Thanks to the contributor! @delneg 00:00:00 v #8 > Stand with Ukraine! https://standwithukraine.com.ua 00:00:00 v #9 > 00:00:00 v #10 > Parsing ../../../target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/spiral_builder.fsproj... 00:00:00 v #11 > ../../../target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026> dotnet restore spiral_builder.fable-temp.csproj -p:FABLE_COMPILER=true -p:FABLE_COMPILER_4=true -p:FABLE_COMPILER_RUST=true -p:_LINUX=true 00:00:01 v #12 > Determining projects to restore... 00:00:01 v #13 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/spiral_builder.fable-temp.csproj (in 298 ms). 00:00:03 v #14 > ../../../target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026> dotnet restore /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/spiral_builder.fsproj 00:00:03 v #15 > Determining projects to restore... 00:00:04 v #16 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/spiral_builder.fsproj (in 399 ms). 00:00:04 v #17 > Project and references (1 source files) parsed in 4107ms 00:00:04 v #18 > 00:00:05 v #19 > Started Fable compilation... 00:00:06 v #20 > 00:00:06 v #21 > Fable compilation finished in 1211ms 00:00:06 v #22 > 00:00:06 v #23 > ./../../../target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/spiral_builder.fs(3,0): (3,10) warning FABLE: For Rust, support for F# static and module do bindings is disabled by default. It can be enabled with the 'static_do_bindings' feature. Use at your own risk! 00:00:06 v #24 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 1865 } 00:00:06 d #25 runtime.execute_with_options / { file_name = cargo; arguments = ["fmt", "--manifest-path", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/Cargo.toml", "--"]; options = { command = cargo fmt --manifest-path "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/Cargo.toml" --; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:06 v #26 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 0 } 00:00:06 d #27 runtime.execute_with_options / { file_name = cargo; arguments = ["run", "--manifest-path", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/Cargo.toml"]; options = { command = cargo run --manifest-path "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/Cargo.toml"; cancellation_token = None; environment_variables = Array(MutCell([("TRACE_LEVEL", "Verbose"), ("RUSTC_WRAPPER", "sccache"), ("RUST_BACKTRACE", "full"), ("RUSTFLAGS", "-C prefer-dynamic")])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:06 v #28 ! Compiling fable_library_rust v0.1.0 (/home/runner/work/polyglot/polyglot/lib/rust/fable/fable_modules/fable-library-rust) 00:00:06 v #29 ! Compiling spiral_builder_34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026 v0.0.1 (/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026) 00:00:07 v #30 ! Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s 00:00:07 v #31 ! Running `/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/target/debug/spiral_builder_34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026` 00:00:07 v #32 > -3 00:00:07 v #33 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 726 } 00:00:07 v #34 spiral_builder.process_rust / cleanup / { new_code_path = /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/spiral_builder.rs; cleanup = UH4_1("/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/../../../target/debug/spiral_builder_34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026.d", true, UH4_1("/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/../../../target/debug/spiral_builder_34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026.exe", false, UH4_1("/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/../../../target/debug/spiral_builder_34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026.pdb", false, UH4_1("/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/../../../target/debug/spiral_builder_34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026.wasm", false, UH4_1("/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Rust/34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026/../../../target/debug/spiral_builder_34ab53ebc795bc28e69c93f16f6227b083afc493df0b85441a97d0332fae0026", true, UH4_0))))) } __assert_eq / actual: "rs" / expected: "rs" __assert_eq / actual: "-3" / expected: "-3"
In [ ]:
//// test
///! rust -d async-walkdir chrono clap encoding_rs encoding_rs_io futures rand rayon regex serde_json sha2
inl file_name = "main.fs"
inl code = "3 - 6 |> System.Console.WriteLine\n"
inl temp_dir, disposable =
(file_name, code)
|> sm'.format_debug
|> crypto.hash_text
|> file_system.create_temp_dir'
inl fs_path = temp_dir </> file_name
code |> file_system.write_all_text fs_path
get_command ()
|> runtime.command_get_matches_from ($'$"_ fable -f \\\"{!fs_path}\\\" -c \\\"typescript\\\""' |> runtime.split_args |> resultm.get)
|> run Verbose
|> async.block_on_futures
|> resultm.unwrap'
|> sm'.deserialize
|> resultm.unwrap'
|> mapm.get ("command_result" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> sm'.deserialize
|> resultm.unwrap'
|> fun result =>
result
|> mapm.get ("extension" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> _assert_eq "ts"
result
|> mapm.get ("output" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> _assert_eq "-3"
disposable |> use |> ignore
00:00:00 v #1 file_system.create_dir / { dir = /tmp/!create_temp_path_/spiral_builder_75b6af2fafd5aafc3f9349623603a6ca069fa977e4efb1d62c8b1239849fd36c/c6422374-71e4-07d4-0ba4-c3084b24fbba } 00:00:00 v #2 file_system.create_dir / { dir = /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8 } 00:00:00 d #3 spiral_builder.process_typescript / { version = US46_1 } 00:00:00 d #4 runtime.execute_with_options / { file_name = dotnet; arguments = ["fable", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.fsproj", "--optimize", "--lang", "ts", "--extension", ".ts", "--outDir", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8", "--define", "_LINUX"]; options = { command = dotnet fable "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.fsproj" --optimize --lang ts --extension .ts --outDir "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8" --define _LINUX; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:00 v #5 > Fable 4.21.0: F# to TypeScript compiler 00:00:00 v #6 > Minimum @fable-org/fable-library-ts version (when installed from npm): 1.5.0 00:00:00 v #7 > 00:00:00 v #8 > Thanks to the contributor! @cmeeren 00:00:00 v #9 > Stand with Ukraine! https://standwithukraine.com.ua 00:00:00 v #10 > 00:00:00 v #11 > Parsing ../../../target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.fsproj... 00:00:00 v #12 > ../../../target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8> dotnet restore spiral_builder.fable-temp.csproj -p:FABLE_COMPILER=true -p:FABLE_COMPILER_4=true -p:FABLE_COMPILER_TYPESCRIPT=true -p:_LINUX=true 00:00:01 v #13 > Determining projects to restore... 00:00:01 v #14 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.fable-temp.csproj (in 302 ms). 00:00:02 v #15 > ../../../target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8> dotnet restore /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.fsproj 00:00:03 v #16 > Determining projects to restore... 00:00:04 v #17 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.fsproj (in 297 ms). 00:00:04 v #18 > Project and references (1 source files) parsed in 3784ms 00:00:04 v #19 > 00:00:04 v #20 > Started Fable compilation... 00:00:06 v #21 > 00:00:06 v #22 > Fable compilation finished in 1093ms 00:00:06 v #23 > 00:00:06 v #24 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 1644 } 00:00:06 d #25 spiral_builder.process_typescript / { new_code_path = /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.ts } 00:00:06 d #26 runtime.execute_with_options / { file_name = bun; arguments = ["run", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.ts"]; options = { command = bun run "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/TypeScript/702335b0756baa7db0d02dbbeaf9fc04cf2c3b7dbb45866c578c5109aaa8c4a8/spiral_builder.ts"; cancellation_token = None; environment_variables = Array(MutCell([("PATH", "~/.bun/bin:/opt/microsoft/powershell/7:/home/runner/.local/bin:/opt/hostedtoolcache/Python/3.12.7/x64/bin:/opt/hostedtoolcache/Python/3.12.7/x64:/opt/hostedtoolcache/node/21.7.3/x64/bin:/usr/share/dotnet:/home/runner/.cargo/bin:/snap/bin:/home/runner/.local/bin:/opt/pipx_bin:/home/runner/.cargo/bin:/home/runner/.config/composer/vendor/bin:/usr/local/.ghcup/bin:/home/runner/.dotnet/tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/runner/.cargo/bin:/home/runner/.bun/bin:/home/runner/.cargo/bin:/home/runner/.bun/bin:/home/runner/.cargo/bin:/home/runner/.bun/bin"), ("TRACE_LEVEL", "Verbose")])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:06 v #27 > -3 00:00:06 v #28 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 2 } __assert_eq / actual: "ts" / expected: "ts" __assert_eq / actual: "-3" / expected: "-3"
In [ ]:
//// test
///! rust -d async-walkdir chrono clap encoding_rs encoding_rs_io futures rand rayon regex serde_json sha2
inl file_name = "main.fs"
inl code = "3 - 6 |> System.Console.WriteLine\n"
inl temp_dir, disposable =
(file_name, code)
|> sm'.format_debug
|> crypto.hash_text
|> file_system.create_temp_dir'
inl fs_path = temp_dir </> file_name
code |> file_system.write_all_text fs_path
get_command ()
|> runtime.command_get_matches_from ($'$"_ fable -f \\\"{!fs_path}\\\" -c \\\"python\\\""' |> runtime.split_args |> resultm.get)
|> run Verbose
|> async.block_on_futures
|> resultm.unwrap'
|> sm'.deserialize
|> resultm.unwrap'
|> mapm.get ("command_result" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> sm'.deserialize
|> resultm.unwrap'
|> fun result =>
result
|> mapm.get ("extension" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> _assert_eq "py"
result
|> mapm.get ("output" |> sm'.to_std_string)
|> optionm'.unwrap
|> sm'.from_std_string
|> _assert_eq "-3"
disposable |> use |> ignore
00:00:00 v #1 file_system.create_dir / { dir = /tmp/!create_temp_path_/spiral_builder_5d67cf2bd873cb58ea5c1c7cdbb55878a007173b62b0495a2fd3b4fe429891cb/c6422374-71e4-07d4-0ba4-c3084b24fbba } 00:00:00 v #2 file_system.create_dir / { dir = /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce } 00:00:00 v #3 file_system.create_dir / { dir = /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/fable_modules } 00:00:00 d #4 runtime.execute_with_options / { file_name = dotnet; arguments = ["fable", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.fsproj", "--optimize", "--lang", "py", "--extension", ".py", "--outDir", "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce", "--define", "_LINUX"]; options = { command = dotnet fable "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.fsproj" --optimize --lang py --extension .py --outDir "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce" --define _LINUX; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:00 v #5 > Fable 4.21.0: F# to Python compiler (status: beta) 00:00:00 v #6 > 00:00:00 v #7 > Thanks to the contributor! @JacobChang 00:00:00 v #8 > Stand with Ukraine! https://standwithukraine.com.ua 00:00:00 v #9 > 00:00:00 v #10 > Parsing ../../../target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.fsproj... 00:00:00 v #11 > ../../../target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce> dotnet restore spiral_builder.fable-temp.csproj -p:FABLE_COMPILER=true -p:FABLE_COMPILER_4=true -p:FABLE_COMPILER_PYTHON=true -p:_LINUX=true 00:00:01 v #12 > Determining projects to restore... 00:00:01 v #13 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.fable-temp.csproj (in 308 ms). 00:00:03 v #14 > ../../../target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce> dotnet restore /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.fsproj 00:00:03 v #15 > Determining projects to restore... 00:00:04 v #16 > Restored /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.fsproj (in 303 ms). 00:00:04 v #17 > Project and references (1 source files) parsed in 4020ms 00:00:04 v #18 > 00:00:05 v #19 > Started Fable compilation... 00:00:06 v #20 > 00:00:06 v #21 > Fable compilation finished in 1046ms 00:00:06 v #22 > 00:00:06 v #23 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 1548 } 00:00:06 d #24 spiral_builder.process_python / { new_code_path = /home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.py } 00:00:06 d #25 runtime.execute_with_options / { file_name = python; arguments = ["/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.py"]; options = { command = python "/home/runner/work/polyglot/polyglot/target/spiral_builder/spiral_builder/packages/Python/cb8f3dd33197bb0bc95f09b3f3057a6844a0b70d75477350491883d14d8680ce/spiral_builder.py"; cancellation_token = None; environment_variables = Array(MutCell([("TRACE_LEVEL", "Verbose")])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:06 v #26 > -3 00:00:06 v #27 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 2 } __assert_eq / actual: "py" / expected: "py" __assert_eq / actual: "-3" / expected: "-3"
In [ ]:
//// test
///! rust -d async-walkdir chrono clap encoding_rs encoding_rs_io futures rand rayon regex serde_json sha2
inl file_name = "test.dib"
inl code =
"#!meta\n\n{\"kernelInfo\":{\"defaultKernelName\":\"fsharp\",\"items\":[]}}\n\n#!fsharp\n\n3 - 6\n"
inl temp_dir, disposable =
(file_name, code)
|> sm'.format_debug
|> crypto.hash_text
|> file_system.create_temp_dir'
inl path = temp_dir </> file_name |> file_system.normalize_path
code
|> file_system.write_all_text path
get_command ()
|> runtime.command_get_matches_from ($'$"_ dib -p {!path}"' |> runtime.split_args |> resultm.get)
|> run Verbose
|> async.block_on_futures
|> resultm.unwrap'
|> __assert sm'.contains Silent "<pre>-3 "
$'$"{!path}.html"'
|> file_system.read_all_text
|> __assert sm'.contains Silent "\"cell-id=1\""
disposable |> use |> ignore
00:00:00 v #1 file_system.create_dir / { dir = /tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623 } 00:00:00 d #2 runtime.execute_with_options / { file_name = dotnet; arguments = ["repl", "--exit-after-run", "--run", "/tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib", "--output-path", "/tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib.ipynb"]; options = { command = dotnet repl --exit-after-run --run "/tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib" --output-path "/tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib.ipynb"; cancellation_token = None; environment_variables = Array(MutCell([("TRACE_LEVEL", "Verbose"), ("AUTOMATION", "True")])); on_line = None; stdin = None; trace = false; working_directory = None } } > > ── fsharp ────────────────────────────────────────────────────────────────────── > 3 - 6 > > ╭─[ 3.30s - return value ]─────────────────────────────────────────────────────╮ > │ <div class="dni-plaintext"><pre>-3 │ > │ </pre></div><style> │ > │ .dni-code-hint { │ > │ font-style: italic; │ > │ overflow: hidden; │ > │ white-space: nowrap; │ > │ } │ > │ .dni-treeview { │ > │ white-space: nowrap; │ > │ } │ > │ .dni-treeview td { │ > │ vertical-align: top; │ > │ text-align: start; │ > │ } │ > │ details.dni-treeview { │ > │ padding-left: 1em; │ > │ } │ > │ table td { │ > │ text-align: start; │ > │ } │ > │ table tr { │ > │ vertical-align: top; │ > │ margin: 0em 0px; │ > │ } │ > │ table tr td pre │ > │ { │ > │ vertical-align: top !important; │ > │ margin: 0em 0px !important; │ > │ } │ > │ table th { │ > │ text-align: start; │ > │ } │ > │ </style> │ > ╰──────────────────────────────────────────────────────────────────────────────╯ 00:00:04 v #3 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 3822 } 00:00:04 d #4 runtime.execute_with_options / { file_name = jupyter; arguments = ["nbconvert", "/tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib.ipynb", "--to", "html", "--HTMLExporter.theme=dark"]; options = { command = jupyter nbconvert "/tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib.ipynb" --to html --HTMLExporter.theme=dark; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:05 v #5 ! [NbConvertApp] Converting notebook /tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib.ipynb to html 00:00:05 v #6 ! /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/nbformat/__init__.py:96: MissingIDFieldWarning: Cell is missing an id field, this will become a hard error in future nbformat versions. You may want to use `normalize()` on your notebooks before validations (available since nbformat 5.1.4). Previous versions of nbformat are fixing this issue transparently, and will stop doing so in the future. 00:00:05 v #7 ! validate(nb) 00:00:06 v #8 ! /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/nbconvert/filters/highlight.py:71: UserWarning: IPython3 lexer unavailable, falling back on Python 3 00:00:06 v #9 ! return _pygments_highlight( 00:00:06 v #10 ! [NbConvertApp] Writing 271458 bytes to /tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib.html 00:00:06 v #11 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 1080 } 00:00:06 d #12 spiral_builder.run / dib / jupyter nbconvert / { exit_code = 0; jupyter_result_length = 1080 } 00:00:06 d #13 runtime.execute_with_options / { file_name = pwsh; arguments = ["-c", "$counter = 1; $path = '/tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib.html'; (Get-Content $path -Raw) -replace '(id=\\\"cell-id=)[a-fA-F0-9]{8}', { $_.Groups[1].Value + $counter++ } | Set-Content $path"]; options = { command = pwsh -c "$counter = 1; $path = '/tmp/!create_temp_path_/spiral_builder_f7ffeef9b2fc2c6383cf2c3b15c8e08a7c62f82fc7fab98c9a53a9a1f94eaa1e/af524e22-8e9a-5d18-99ed-bd86e1b74623/test.dib.html'; (Get-Content $path -Raw) -replace '(id=\"cell-id=)[a-fA-F0-9]{8}', { $_.Groups[1].Value + $counter++ } | Set-Content $path"; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:07 v #14 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 0 } 00:00:07 d #15 spiral_builder.run / dib / html cell ids / { exit_code = 0; pwsh_replace_html_result_length = 0 } 00:00:07 d #16 spiral_builder.run / dib / { exit_code = 0; result_length = 4961 }
tests¶
In [ ]:
inl tests () =
testing.run_tests {
verify_app = get_command >> runtime.command_debug_assert
}
main¶
In [ ]:
///! _
inl main (args : array_base string) =
inl trace_state = get_trace_state_or_init None
trace Debug
fun () => "spiral_builder.main"
fun () => { args }
inl command = get_command ()
inl arg_matches = command |> runtime.command_get_matches
inl trace_state_level = trace_state.level
inl result =
arg_matches
|> run *trace_state_level
|> async.block_on_futures
|> resultm.unwrap'
if *trace_state_level = Info
then result |> console.write_line
0i32
inl main () =
$'let tests () = !tests ()' : ()
$'let main args = !main args' : ()