diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 8223322e..34d15eaf 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -51,12 +51,16 @@ jobs: run: | version=$(echo "$GITHUB_SHA" | cut -c 1-9) rclone copy target/release/moon "aws:${{ secrets.AWS_BUCKET_NAME }}/bleeding-moon/$version/$(uname -s)-$(uname -m)/" + rclone copy target/release/moonrun "aws:${{ secrets.AWS_BUCKET_NAME }}/bleeding-moonrun/$version/$(uname -s)-$(uname -m)/" + rclone copy target/release/moonrun "aws:cli.moonbitlang.com/moon-ci/$(uname -s)-$(uname -m)/" - name: Upload(Windows) if: ${{ matrix.os == 'windows-latest' }} run: | $version = "$env:GITHUB_SHA".Substring(0, 9) rclone copyto -L .\target\release\moon.exe "aws:${{ secrets.AWS_BUCKET_NAME }}/bleeding-moon/$version/Windows-x86_64/moon.exe" + rclone copyto -L .\target\release\moonrun.exe "aws:${{ secrets.AWS_BUCKET_NAME }}/bleeding-moonrun/$version/Windows-x86_64/moonrun.exe" + rclone copyto -L .\target\release\moonrun.exe "aws:cli.moonbitlang.com/moon-ci/Windows-x86_64/moonrun.exe" - name: Checkout moonc-version (macos-latest) if: ${{ matrix.os == 'macos-latest' }} @@ -139,3 +143,5 @@ jobs: version="$(echo "$GITHUB_SHA" | cut -c 1-9)" echo "$version" rclone copy target/release/moon "aws:${{ secrets.AWS_BUCKET_NAME }}/bleeding-moon/$version/$(uname -s)-$(uname -m)/" + rclone copy target/release/moonrun "aws:${{ secrets.AWS_BUCKET_NAME }}/bleeding-moonrun/$version/$(uname -s)-$(uname -m)/" + rclone copy target/release/moonrun "aws:cli.moonbitlang.com/moon-ci/$(uname -s)-$(uname -m)/" diff --git a/Cargo.lock b/Cargo.lock index 8ddd1e4f..6f0b1514 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,6 +174,29 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which 4.4.2", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -219,6 +242,15 @@ version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -243,6 +275,17 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.13" @@ -651,6 +694,16 @@ dependencies = [ "libc", ] +[[package]] +name = "fslock" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04412b8935272e3a9bae6f48c7bfff74c2911f60525404edfdd28e49884c3bfb" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "futures" version = "0.3.30" @@ -755,6 +808,21 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gzip-header" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95cc527b92e6029a62960ad99aa8a6660faa4555fe5f731aab13aa6a921795a2" +dependencies = [ + "crc32fast", +] + [[package]] name = "h2" version = "0.3.26" @@ -1054,6 +1122,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1095,12 +1172,28 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + [[package]] name = "line-index" version = "0.1.1" @@ -1154,6 +1247,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.4" @@ -1218,7 +1317,7 @@ dependencies = [ "tempfile", "tokio", "walkdir", - "which", + "which 6.0.2", ] [[package]] @@ -1292,6 +1391,26 @@ dependencies = [ "zip", ] +[[package]] +name = "moonrun" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "clap", + "expect-test", + "rand", + "serde", + "serde_json_lenient", + "snapbox", + "tempfile", + "tracing", + "tracing-subscriber", + "v8", + "vergen", + "walkdir", +] + [[package]] name = "moonutil" version = "0.1.0" @@ -1368,6 +1487,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "normalize-line-endings" version = "0.3.0" @@ -1511,6 +1640,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1560,6 +1695,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -1949,6 +2094,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -2261,9 +2412,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.32" @@ -2296,6 +2459,7 @@ dependencies = [ "once_cell", "regex", "sharded-slab", + "smallvec", "thread_local", "tracing", "tracing-core", @@ -2367,6 +2531,23 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "v8" +version = "0.102.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a710d5b95bff79a90708203cf9f74384e080d21fc6664aa4df463f2c66ac83" +dependencies = [ + "bindgen", + "bitflags 2.6.0", + "fslock", + "gzip-header", + "home", + "miniz_oxide", + "once_cell", + "paste", + "which 6.0.2", +] + [[package]] name = "valuable" version = "0.1.0" @@ -2511,6 +2692,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "which" version = "6.0.2" diff --git a/Cargo.toml b/Cargo.toml index 98a945fa..e638d0e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ mooncake = { path = "./crates/mooncake", version = "*" } moonutil = { path = "./crates/moonutil", version = "*" } anyhow = { version = "1.0.86" } bincode = "1.3.3" -clap = { version = "4.5.4", features = ["derive"] } +clap = { version = "4.5.4", features = ["derive", "string"] } colored = "2.1.0" ctrlc = { version = "3.4.4", features = ["termination"] } dunce = "1.0.4" diff --git a/crates/moonrun/Cargo.lock b/crates/moonrun/Cargo.lock new file mode 100644 index 00000000..78c80bd7 --- /dev/null +++ b/crates/moonrun/Cargo.lock @@ -0,0 +1,1192 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which 4.4.2", +] + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "dissimilar" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "expect-test" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e0be0a561335815e06dab7c62e50353134c796e7a6155402a64bcff66b6a5e0" +dependencies = [ + "dissimilar", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fslock" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04412b8935272e3a9bae6f48c7bfff74c2911f60525404edfdd28e49884c3bfb" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gzip-header" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95cc527b92e6029a62960ad99aa8a6660faa4555fe5f731aab13aa6a921795a2" +dependencies = [ + "crc32fast", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "indexmap" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "moonrun" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "clap", + "expect-test", + "rand", + "serde", + "serde_json_lenient", + "snapbox", + "tempfile", + "tracing", + "tracing-subscriber", + "v8", + "vergen", + "walkdir", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3cc72858054fcff6d7dea32df2aeaee6a7c24227366d7ea429aada2f26b16ad" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json_lenient" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d0bae483150302560d7cb52e7932f39b69a6fbdd099e48d33ef060a8c9c078" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "similar" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "snapbox" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b831b6e80fbcd2889efa75b185d24005f85981431495f995292b25836519d84" +dependencies = [ + "anstream", + "anstyle", + "normalize-line-endings", + "similar", + "snapbox-macros", +] + +[[package]] +name = "snapbox-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f4c14672714436c09254801c934b203196a51182a5107fb76591c7cc56424d" +dependencies = [ + "anstream", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "v8" +version = "0.102.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a710d5b95bff79a90708203cf9f74384e080d21fc6664aa4df463f2c66ac83" +dependencies = [ + "bindgen", + "bitflags", + "fslock", + "gzip-header", + "home", + "miniz_oxide", + "once_cell", + "paste", + "which 6.0.2", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vergen" +version = "8.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525" +dependencies = [ + "anyhow", + "cfg-if", + "rustversion", + "time", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "which" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d9c5ed668ee1f17edb3b627225343d210006a90bb1e3745ce1f30b1fb115075" +dependencies = [ + "either", + "home", + "rustix", + "winsafe", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" diff --git a/crates/moonrun/Cargo.toml b/crates/moonrun/Cargo.toml new file mode 100644 index 00000000..c458e104 --- /dev/null +++ b/crates/moonrun/Cargo.toml @@ -0,0 +1,48 @@ +# moon: The build system and package manager for MoonBit. +# Copyright (C) 2024 International Digital Economy Academy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +[package] +name = "moonrun" +version = "0.1.0" +edition.workspace = true +readme = "README.md" +rust-version.workspace = true + +[dependencies] +anyhow.workspace = true +clap.workspace = true +serde.workspace = true +serde_json_lenient.workspace = true +rand = "0.8.5" +tracing = "0.1.40" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +v8 = "0.102.0" + +[build-dependencies] +vergen = { version = "8.0.0", features = ["build", "git", "gitcl"] } +chrono.workspace = true + +[dev-dependencies] +snapbox = "0.4.15" +tempfile = "3.6.0" +walkdir = "2.5.0" +expect-test.workspace = true + +[[bin]] +name = "moonrun" +bench = false diff --git a/crates/moonrun/README.md b/crates/moonrun/README.md new file mode 100644 index 00000000..9abba1ff --- /dev/null +++ b/crates/moonrun/README.md @@ -0,0 +1,25 @@ +![check](https://github.com/moonbitlang/moonrun/actions/workflows/ci.yml/badge.svg) + +# moonrun + +Moonrun is the WebAssembly runtime for MoonBit, utilizing V8 at its core to offer an efficient and flexible environment for executing WASM. + +# Building and Running + +## Building + +To build the project, ensure that Rust and Cargo are installed. Then execute: +``` +cargo build +``` + +## Running + +To run a WebAssembly file: +``` +./target/debug/moonrun path/to/your/file.wasm +``` + +# Contribution + +To contribute, please read the contribution guidelines at [docs/dev](./docs/dev/README.md). \ No newline at end of file diff --git a/crates/moonrun/build.rs b/crates/moonrun/build.rs new file mode 100644 index 00000000..2c323e90 --- /dev/null +++ b/crates/moonrun/build.rs @@ -0,0 +1,34 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +use chrono::DateTime; +use std::{ + error::Error, + time::{SystemTime, UNIX_EPOCH}, +}; +use vergen::EmitBuilder; + +pub fn main() -> Result<(), Box> { + EmitBuilder::builder().build_date().git_sha(true).emit()?; + + let time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + let datetime = DateTime::from_timestamp(time.as_secs() as i64, 0).unwrap(); + let date_str = datetime.format("%Y%m%d").to_string(); + println!("cargo:rustc-env=CARGO_PKG_VERSION=0.1.{}", date_str); + Ok(()) +} diff --git a/crates/moonrun/docs/dev/README.md b/crates/moonrun/docs/dev/README.md new file mode 100644 index 00000000..2b49acd8 --- /dev/null +++ b/crates/moonrun/docs/dev/README.md @@ -0,0 +1,24 @@ +# Contributing Quick Start + +## How to Build and Test + +```bash +cargo build +cargo test +``` + +## Before PR + +We encourage to add the following prefix to your commit message and PR title: feat, fix, internal, or minor. + +It's recommended to run the following command before you submit a PR, which may help discover some potential ci failure ASAP + +```bash +cargo fmt + +cargo clippy --all-targets --all-features -- -D warnings + +cargo test +``` + +We use [typos](https://github.com/crate-ci/typos) to avoid potential typos, you can also download and run it locally before PR. diff --git a/crates/moonrun/src/fs_api_temp.rs b/crates/moonrun/src/fs_api_temp.rs new file mode 100644 index 00000000..a390080a --- /dev/null +++ b/crates/moonrun/src/fs_api_temp.rs @@ -0,0 +1,88 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +//! Temporary-use FS API. Only has whole-file read/write and no other features. + +/// `fn read_file_to_string(path: JSString) -> JSString` +fn read_file_to_string( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let path = args.get(0); + let path = path.to_string(scope).unwrap(); + let path = path.to_rust_string_lossy(scope); + + let contents = std::fs::read_to_string(path).expect("Failed to read file"); + let contents = v8::String::new(scope, &contents).unwrap(); + ret.set(contents.into()); +} + +/// `fn write_string_to_file(path: JSString, contents: JSString) -> Unit` +fn write_string_to_file( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let path = args.get(0); + let path = path.to_string(scope).unwrap(); + let path = path.to_rust_string_lossy(scope); + + let contents = args.get(1); + let contents = contents.to_string(scope).unwrap(); + let contents = contents.to_rust_string_lossy(scope); + + std::fs::write(path, contents).expect("Failed to write file"); + + ret.set_undefined() +} + +fn path_exists( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let path = args.get(0); + let path = path.to_string(scope).unwrap(); + let path = path.to_rust_string_lossy(scope); + + let exists = std::path::Path::new(&path).exists(); + ret.set_bool(exists); +} + +pub fn init_fs<'s>( + obj: v8::Local<'s, v8::Object>, + scope: &mut v8::HandleScope<'s>, +) -> v8::Local<'s, v8::Object> { + let read_file_to_string = v8::FunctionTemplate::new(scope, read_file_to_string); + let read_file_to_string = read_file_to_string.get_function(scope).unwrap(); + let ident = v8::String::new(scope, "read_file_to_string").unwrap(); + obj.set(scope, ident.into(), read_file_to_string.into()); + + let write_string_to_file = v8::FunctionTemplate::new(scope, write_string_to_file); + let write_string_to_file = write_string_to_file.get_function(scope).unwrap(); + let ident = v8::String::new(scope, "write_string_to_file").unwrap(); + obj.set(scope, ident.into(), write_string_to_file.into()); + + let path_exists = v8::FunctionTemplate::new(scope, path_exists); + let path_exists = path_exists.get_function(scope).unwrap(); + let ident = v8::String::new(scope, "path_exists").unwrap(); + obj.set(scope, ident.into(), path_exists.into()); + + obj +} diff --git a/crates/moonrun/src/js.rs b/crates/moonrun/src/js.rs new file mode 100644 index 00000000..71157317 --- /dev/null +++ b/crates/moonrun/src/js.rs @@ -0,0 +1,113 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +/* + +fn begin_create_string() -> StringCreateHandle = "__moonbit_fs_unstable" "begin_create_string" + +fn string_append_char(handle : StringCreateHandle, ch : Char) = "__moonbit_fs_unstable" "string_append_char" + +fn finish_create_string(handle : StringCreateHandle) -> ExternString = "__moonbit_fs_unstable" "finish_create_string" + + +fn begin_read_string(s : ExternString) -> StringReadHandle = "__moonbit_fs_unstable" "begin_read_string" + +/// Read one char from the string, returns -1 if the end of the string is reached. +/// The number returned is the unicode codepoint of the character. +fn string_read_char(handle : StringReadHandle) -> Int = "__moonbit_fs_unstable" "string_read_char" + +fn finish_read_string(handle : StringReadHandle) = "__moonbit_fs_unstable" "finish_read_string" + +*/ + +use v8::{Function, Local, Object}; + +const INIT_JS_API: &str = r#" + (() => function(obj) { + // String ops + + function begin_create_string() { + return { s: "" } + } + + function string_append_char(handle, ch) { + handle.s += String.fromCharCode(ch) + } + + function finish_create_string(handle) { + return handle.s + } + + function begin_read_string(s) { + return { s: s, i: 0 } + } + + function string_read_char(handle) { + if (handle.i >= handle.s.length) { + return -1 + } + return handle.s.charCodeAt(handle.i++) + } + + function finish_read_string(handle) { + return + } + + // Array ops + + function array_len(arr) { + return arr.length + } + + function array_get(arr, idx) { + return arr[idx] + } + + // JSValue + + function jsvalue_is_string(v) { + return typeof v === "string" + } + + obj.begin_create_string = begin_create_string + obj.string_append_char = string_append_char + obj.finish_create_string = finish_create_string + obj.begin_read_string = begin_read_string + obj.string_read_char = string_read_char + obj.finish_read_string = finish_read_string + + obj.array_len = array_len + obj.array_get = array_get + + obj.jsvalue_is_string = jsvalue_is_string + })() +"#; + +pub fn init_env<'s>( + obj: v8::Local<'s, Object>, + scope: &mut v8::HandleScope<'s>, +) -> v8::Local<'s, Object> { + let code = v8::String::new(scope, INIT_JS_API).unwrap(); + let code_origin = super::create_script_origin(scope, "js_api_init"); + let script = v8::Script::compile(scope, code, Some(&code_origin)).unwrap(); + let func = script.run(scope).unwrap(); + let func: Local = func.try_into().unwrap(); + let undefined = v8::undefined(scope); + func.call(scope, undefined.into(), &[obj.into()]); + obj +} diff --git a/crates/moonrun/src/main.rs b/crates/moonrun/src/main.rs new file mode 100644 index 00000000..6b001d25 --- /dev/null +++ b/crates/moonrun/src/main.rs @@ -0,0 +1,503 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +use clap::Parser; +use std::any::Any; +use std::io::{self, Write}; +use std::{cell::Cell, io::Read, path::PathBuf, time::Instant}; + +mod fs_api_temp; +mod js; +mod sys_api; +mod util; + +use rand::rngs::StdRng; +use rand::Rng; +use rand::SeedableRng; + +const BUILTIN_SCRIPT_ORIGIN_PREFIX: &str = "__$moonrun_v8_builtin_script$__"; + +#[derive(Default)] +struct PrintEnv { + dangling_high_half: Cell>, +} + +fn instant_now( + scope: &mut v8::HandleScope, + mut args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let now = Box::new(Instant::now()); + let ptr = Box::::leak(now) as *mut Instant; + let weak_rc = std::rc::Rc::new(std::cell::Cell::new(None)); + let weak = v8::Weak::with_finalizer( + unsafe { args.get_isolate() }, + v8::External::new(scope, ptr as *mut std::ffi::c_void), + Box::new({ + let weak_rc = weak_rc.clone(); + move |isolate| unsafe { + drop(Box::from_raw(ptr)); + drop(v8::Weak::from_raw(isolate, weak_rc.get())); + } + }), + ); + let local = weak.to_local(scope).unwrap(); + weak_rc.set(weak.into_raw()); + ret.set(local.into()); +} + +fn instant_elapsed_as_secs_f64( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let arg = args.get(0); + let instant: v8::Local = arg.try_into().unwrap(); + let instant = unsafe { &*(instant.value() as *mut Instant) }; + let elapsed = instant.elapsed().as_secs_f64(); + ret.set(v8::Number::new(scope, elapsed).into()); +} + +fn print_char( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let print_env = { + let data = args.data(); + assert!(data.is_external()); + let data: v8::Local = data.into(); + let ptr = v8::Local::::try_from(data).unwrap().value(); + unsafe { &*(ptr as *const PrintEnv) } + }; + + let arg = args.get(0); + let c = arg.integer_value(scope).unwrap() as u32; + if (0xd800..=0xdbff).contains(&c) { + // high surrogate + let high = c - 0xd800; + if print_env.dangling_high_half.get().is_some() { + // Print previous char as invalid unicode + print!("{}", std::char::from_u32(0xfffd).unwrap()); + } + print_env.dangling_high_half.set(Some(high)); + } else { + let c = { + if (0xdc00..=0xdfff).contains(&c) { + // low surrogate + if let Some(high) = print_env.dangling_high_half.take() { + 0x10000 + (high << 10) + (c - 0xdc00) + } else { + 0xfffd + } + } else { + c + } + }; + let c = std::char::from_u32(c).unwrap(); + print!("{}", c); + } + ret.set_undefined() +} + +fn console_elog( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut _ret: v8::ReturnValue, +) { + let arg = args.get(0); + let arg = arg.to_string(scope).unwrap(); + let arg = arg.to_rust_string_lossy(scope); + eprintln!("{}", arg); +} + +fn console_log( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut _ret: v8::ReturnValue, +) { + let arg = args.get(0); + let arg = arg.to_string(scope).unwrap(); + let arg = arg.to_rust_string_lossy(scope); + println!("{}", arg); +} + +pub fn get_array_buffer_ptr(ab: v8::Local) -> *mut u8 { + unsafe { std::mem::transmute(ab.data()) } +} + +fn read_utf8_char() -> io::Result> { + let mut buffer = [0; 4]; + let stdin = io::stdin(); + let mut handle = stdin.lock(); + + let size = handle.read(&mut buffer[0..1])?; + if size == 0 { + return Ok(None); + } + + let num_bytes = match buffer[0] { + 0..=0x7F => 1, + 0xC0..=0xDF => 2, + 0xE0..=0xEF => 3, + 0xF0..=0xF7 => 4, + _ => { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "invalid UTF-8 first byte", + )) + } + }; + + if num_bytes > 1 { + handle.read_exact(&mut buffer[1..num_bytes])?; + } + + let char = std::str::from_utf8(&buffer[..num_bytes]) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))? + .chars() + .next() + .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "no character found"))?; + + Ok(Some(char)) +} + +fn read_char( + _scope: &mut v8::HandleScope, + _args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let result = read_utf8_char(); + match result { + Ok(Some(c)) => { + ret.set_int32(c as i32); + } + _ => ret.set_int32(-1), + } +} + +fn write_char( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut _ret: v8::ReturnValue, +) { + let fd = args.get(0).int32_value(scope).unwrap(); + let c = args.get(1).integer_value(scope).unwrap() as u32; + let c = std::char::from_u32(c).unwrap(); + match fd { + 1 => print!("{}", c), + 2 => eprint!("{}", c), + _ => {} + } +} + +fn flush( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut _ret: v8::ReturnValue, +) { + let fd = args.get(0).int32_value(scope).unwrap(); + match fd { + 1 => std::io::stdout().flush().unwrap(), + 2 => std::io::stderr().flush().unwrap(), + _ => {} + } +} + +fn stdrng_seed_from_u64( + scope: &mut v8::HandleScope, + mut args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let seed = args.get(0).int32_value(scope).unwrap_or(0) as u64; + let rng = Box::new(StdRng::seed_from_u64(seed)); + let ptr = Box::::leak(rng) as *mut StdRng; + let weak_rc = std::rc::Rc::new(std::cell::Cell::new(None)); + let weak = v8::Weak::with_finalizer( + unsafe { args.get_isolate() }, + v8::External::new(scope, ptr as *mut std::ffi::c_void), + Box::new({ + let weak_rc = weak_rc.clone(); + move |isolate| unsafe { + drop(Box::from_raw(ptr)); + drop(v8::Weak::from_raw(isolate, weak_rc.get())); + } + }), + ); + let local = weak.to_local(scope).unwrap(); + weak_rc.set(weak.into_raw()); + ret.set(local.into()); +} + +fn stdrng_gen_range( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut ret: v8::ReturnValue, +) { + let arg = args.get(0); + let rng: v8::Local = arg.try_into().unwrap(); + let rng = unsafe { &mut *(rng.value() as *mut StdRng) }; + + let ubound = args.get(1).int32_value(scope).unwrap(); + let num = rng.gen_range(0..ubound); + ret.set_int32(num); +} + +fn exit( + scope: &mut v8::HandleScope, + args: v8::FunctionCallbackArguments, + mut _ret: v8::ReturnValue, +) { + let code = args.get(0).to_int32(scope).unwrap(); + std::process::exit(code.value()); +} + +fn init_env(dtors: &mut Vec>, scope: &mut v8::HandleScope, args: &[String]) { + let global_proxy = scope.get_current_context().global(scope); + + let print_env_box = Box::::default(); + let identifier = v8::String::new(scope, "print").unwrap(); + let print_env = &*print_env_box as *const PrintEnv; + let print_env = v8::External::new(scope, print_env as *mut std::ffi::c_void); + let value = v8::Function::builder(print_char) + .data(print_env.into()) + .build(scope) + .unwrap(); + global_proxy.set(scope, identifier.into(), value.into()); + dtors.push(print_env_box); + + { + let identifier = v8::String::new(scope, "console_elog").unwrap(); + let value = v8::Function::builder(console_elog).build(scope).unwrap(); + global_proxy.set(scope, identifier.into(), value.into()); + } + + { + let identifier = v8::String::new(scope, "console_log").unwrap(); + let value = v8::Function::builder(console_log).build(scope).unwrap(); + global_proxy.set(scope, identifier.into(), value.into()); + } + + { + let identifier = v8::String::new(scope, "__moonbit_time_unstable").unwrap(); + let obj = v8::Object::new(scope); + global_proxy.set(scope, identifier.into(), obj.into()); + + let identifier = v8::String::new(scope, "instant_now").unwrap(); + let value = v8::Function::builder(instant_now).build(scope).unwrap(); + obj.set(scope, identifier.into(), value.into()); + + let identifier = v8::String::new(scope, "instant_elapsed_as_secs_f64").unwrap(); + let value = v8::Function::builder(instant_elapsed_as_secs_f64) + .build(scope) + .unwrap(); + obj.set(scope, identifier.into(), value.into()); + } + + // API for the fs module + let identifier = v8::String::new(scope, "__moonbit_fs_unstable").unwrap(); + let obj = v8::Object::new(scope); + let obj = js::init_env(obj, scope); + let obj = sys_api::init_env(obj, scope, args); + let obj = fs_api_temp::init_fs(obj, scope); + global_proxy.set(scope, identifier.into(), obj.into()); + + { + let identifier = v8::String::new(scope, "__moonbit_io_unstable").unwrap(); + let obj = v8::Object::new(scope); + global_proxy.set(scope, identifier.into(), obj.into()); + + let identifier = v8::String::new(scope, "read_char").unwrap(); + let value = v8::Function::builder(read_char).build(scope).unwrap(); + obj.set(scope, identifier.into(), value.into()); + + let identifier = v8::String::new(scope, "write_char").unwrap(); + let value = v8::Function::builder(write_char).build(scope).unwrap(); + obj.set(scope, identifier.into(), value.into()); + + let identifier = v8::String::new(scope, "flush").unwrap(); + let value = v8::Function::builder(flush).build(scope).unwrap(); + obj.set(scope, identifier.into(), value.into()); + } + + { + let identifier = v8::String::new(scope, "__moonbit_rand_unstable").unwrap(); + let obj = v8::Object::new(scope); + global_proxy.set(scope, identifier.into(), obj.into()); + + let identifier = v8::String::new(scope, "stdrng_seed_from_u64").unwrap(); + let value = v8::Function::builder(stdrng_seed_from_u64) + .build(scope) + .unwrap(); + obj.set(scope, identifier.into(), value.into()); + + let identifier = v8::String::new(scope, "stdrng_gen_range").unwrap(); + let value = v8::Function::builder(stdrng_gen_range) + .build(scope) + .unwrap(); + obj.set(scope, identifier.into(), value.into()); + } + + { + let identifier = v8::String::new(scope, "__moonbit_sys_unstable").unwrap(); + let obj = v8::Object::new(scope); + global_proxy.set(scope, identifier.into(), obj.into()); + + let exit = v8::FunctionTemplate::new(scope, exit); + let exit = exit.get_function(scope).unwrap(); + let ident = v8::String::new(scope, "exit").unwrap(); + obj.set(scope, ident.into(), exit.into()); + } +} + +fn create_script_origin<'s>(scope: &mut v8::HandleScope<'s>, name: &str) -> v8::ScriptOrigin<'s> { + let name = format!("{}{}", BUILTIN_SCRIPT_ORIGIN_PREFIX, name); + let name = v8::String::new(scope, &name).unwrap(); + v8::ScriptOrigin::new( + scope, + name.into(), + 0, + 0, + false, + 0, + None, + false, + false, + false, + None, + ) +} + +fn wasm_mode( + file: &PathBuf, + args: &[String], + no_stack_trace: bool, + test_mode: bool, +) -> anyhow::Result<()> { + v8::V8::set_flags_from_string("--experimental-wasm-exnref"); + let platform = v8::new_default_platform(0, false).make_shared(); + v8::V8::initialize_platform(platform); + v8::V8::initialize(); + + let isolate = &mut v8::Isolate::new(Default::default()); + let scope = &mut v8::HandleScope::new(isolate); + let context = v8::Context::new(scope, Default::default()); + let scope = &mut v8::ContextScope::new(scope, context); + + { + let global_proxy = scope.get_current_context().global(scope); + + let file = std::fs::read(file)?; + let wasm_mod = v8::WasmModuleObject::compile(scope, &file) + .ok_or_else(|| anyhow::format_err!("Failed to compile wasm module"))?; + let module_key = v8::String::new(scope, "module").unwrap().into(); + global_proxy.set(scope, module_key, wasm_mod.into()); + } + + let mut dtors = Vec::new(); + init_env(&mut dtors, scope, args); + + let mut script = format!( + r#"const BUILTIN_SCRIPT_ORIGIN_PREFIX = "{}";"#, + BUILTIN_SCRIPT_ORIGIN_PREFIX + ); + if test_mode { + let test_args = serde_json_lenient::from_str::(&args.join(" ")).unwrap(); + let file_and_index = test_args.file_and_index; + + let mut test_params: Vec<[String; 2]> = vec![]; + for (file, index) in file_and_index { + for i in index { + test_params.push([file.clone(), i.to_string()]); + } + } + script.push_str(&format!("const package = {:?};", test_args.package)); + script.push_str(&format!("const test_params = {:?};", test_params)); + } + script.push_str(&format!("const no_stack_trace = {};", no_stack_trace)); + script.push_str(&format!("const test_mode = {};", test_mode)); + let js_glue = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/template/js_glue.js" + )); + script.push_str(js_glue); + + let code = v8::String::new(scope, &script).unwrap(); + let script_origin = create_script_origin(scope, "wasm_mode_entry"); + let script = v8::Script::compile(scope, code, Some(&script_origin)).unwrap(); + script.run(scope); + drop(dtors); + Ok(()) +} + +#[derive(serde::Deserialize, Clone)] +pub struct TestArgs { + pub package: String, + pub file_and_index: Vec<(String, std::ops::Range)>, +} + +pub fn get_moonrun_version() -> String { + format!( + "{} ({} {})", + env!("CARGO_PKG_VERSION"), + env!("VERGEN_GIT_SHA"), + std::env!("VERGEN_BUILD_DATE") + ) +} + +#[derive(Debug, clap::Parser)] +#[command(version = get_moonrun_version())] +struct Commandline { + /// The path of the file to run + path: PathBuf, + + /// Additional arguments + args: Vec, + + /// Don't print stack trace + #[clap(long)] + no_stack_trace: bool, + + #[clap(long)] + test_mode: bool, +} + +fn main() -> anyhow::Result<()> { + tracing_subscriber::FmtSubscriber::builder() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .compact() + .init(); + + let matches = Commandline::parse(); + + let file = &matches.path; + + if !file.exists() { + anyhow::bail!("no such file"); + } + + match file.extension().unwrap().to_str() { + Some("wasm") => wasm_mode( + file, + &matches.args, + matches.no_stack_trace, + matches.test_mode, + ), + _ => anyhow::bail!("Unsupported file type"), + } +} diff --git a/crates/moonrun/src/sys_api.rs b/crates/moonrun/src/sys_api.rs new file mode 100644 index 00000000..6994a356 --- /dev/null +++ b/crates/moonrun/src/sys_api.rs @@ -0,0 +1,81 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +const INIT_SYS_API: &str = r#" + (() => function(obj, run_env) { + // Return the value of the environment variable + function env_get_var(name) { + return run_env.env_vars.get(name) || "" + } + + // Get the list of arguments passed to the program + function args_get() { + return run_env.args + } + + obj.env_get_var = env_get_var + obj.args_get = args_get + })() +"#; + +fn construct_args_list<'s>( + args: &[String], + scope: &mut v8::HandleScope<'s>, +) -> v8::Local<'s, v8::Array> { + let arr = v8::Array::new(scope, args.len() as i32); + for (i, arg) in args.iter().enumerate() { + let arg = v8::String::new(scope, arg).unwrap(); + arr.set_index(scope, i as u32, arg.into()); + } + arr +} + +fn construct_env_vars<'s>(scope: &mut v8::HandleScope<'s>) -> v8::Local<'s, v8::Map> { + let map = v8::Map::new(scope); + for (k, v) in std::env::vars() { + let key = v8::String::new(scope, &k).unwrap(); + let val = v8::String::new(scope, &v).unwrap(); + map.set(scope, key.into(), val.into()); + } + map +} + +pub fn init_env<'s>( + obj: v8::Local<'s, v8::Object>, + scope: &mut v8::HandleScope<'s>, + args: &[String], +) -> v8::Local<'s, v8::Object> { + let code = v8::String::new(scope, INIT_SYS_API).unwrap(); + let code_origin = super::create_script_origin(scope, "sys_api_init"); + let script = v8::Script::compile(scope, code, Some(&code_origin)).unwrap(); + let func = script.run(scope).unwrap(); + let func: v8::Local = func.try_into().unwrap(); + + // Construct the object to pass to the JS function + let args_list = construct_args_list(args, scope); + let env_vars = construct_env_vars(scope); + let env_obj = v8::Object::new(scope); + let env_vars_key = v8::String::new(scope, "env_vars").unwrap().into(); + env_obj.set(scope, env_vars_key, env_vars.into()); + let args_key = v8::String::new(scope, "args").unwrap().into(); + env_obj.set(scope, args_key, args_list.into()); + + let undefined = v8::undefined(scope); + func.call(scope, undefined.into(), &[obj.into(), env_obj.into()]); + obj +} diff --git a/crates/moonrun/src/template/js_glue.js b/crates/moonrun/src/template/js_glue.js new file mode 100644 index 00000000..d6edf5aa --- /dev/null +++ b/crates/moonrun/src/template/js_glue.js @@ -0,0 +1,75 @@ +const tag = new WebAssembly.Tag({ parameters: [] }); +const console = { + elog: (x) => console_elog(x), + log: (x) => console_log(x), +}; +const spectest = { + spectest: { + print_char: (x) => print(x), + read_char: () => read_char(), + }, + Instant: { + now() { + return instant_now(); + }, + elapsed_as_secs_f64(instant) { + return instant_elapsed_as_secs_f64(instant); + } + }, + __moonbit_fs_unstable: __moonbit_fs_unstable, + __moonbit_rand_unstable: __moonbit_rand_unstable, + __moonbit_io_unstable: __moonbit_io_unstable, + __moonbit_sys_unstable: __moonbit_sys_unstable, + __moonbit_time_unstable: __moonbit_time_unstable, + moonbit: { + string_to_js_string() { + print(arguments[0]); + } + }, + exception: { + tag: tag, + throw: () => { + throw new WebAssembly.Exception(tag, [], { traceStack: true }) + }, + }, + test: { + get_file_name: () => globalThis.testParams.fileName, + get_index: () => globalThis.testParams.index, + } +}; + +try { + let instance = new WebAssembly.Instance(module, spectest); + if (instance.exports._start) { + if (test_mode) { + for (param of test_params) { + try { + globalThis.testParams = { + fileName: param[0], + index: param[1] + }; + instance.exports._start(); + } catch (e) { + console.log("----- BEGIN MOON TEST RESULT -----") + console.log(`{"package": "${package}", "filename": "${param[0]}", "index": "${param[1]}", "test_name": "${param[1]}", "message": "${e.stack.toString().split('\n').join('\\n')}"}`); + console.log("----- END MOON TEST RESULT -----") + } + } + } + else { + instance.exports._start(); + } + } +} +catch (e) { + for (const line of e.stack.toString().split('\n')) { + if (!line.includes(BUILTIN_SCRIPT_ORIGIN_PREFIX)) { + console.elog(line); + } + if (no_stack_trace) { + break; + } + } + __moonbit_sys_unstable.exit(1); + +} diff --git a/crates/moonrun/src/util.rs b/crates/moonrun/src/util.rs new file mode 100644 index 00000000..e7853d31 --- /dev/null +++ b/crates/moonrun/src/util.rs @@ -0,0 +1,38 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +use std::rc::Rc; + +#[allow(unused)] +pub unsafe fn get_rc(args: &v8::FunctionCallbackArguments) -> Rc { + let data = args.data(); + assert!(data.is_external()); + let data: v8::Local = data.into(); + let ptr = v8::Local::::try_from(data).unwrap().value(); + unsafe { Rc::increment_strong_count(ptr as *const T) } + unsafe { Rc::from_raw(ptr as *const T) } +} + +#[allow(unused)] +pub unsafe fn get_ref<'t, T>(args: &v8::FunctionCallbackArguments<'t>) -> &'t T { + let data = args.data(); + assert!(data.is_external()); + let data: v8::Local = data.into(); + let ptr = v8::Local::::try_from(data).unwrap().value(); + unsafe { &*(ptr as *const T) } +} diff --git a/crates/moonrun/tests/test.rs b/crates/moonrun/tests/test.rs new file mode 100644 index 00000000..866c107c --- /dev/null +++ b/crates/moonrun/tests/test.rs @@ -0,0 +1,183 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +use std::path::{Path, PathBuf}; + +use expect_test::{expect, Expect}; + +struct TestDir { + // tempfile::TempDir has a drop implementation that will remove the directory + // copy the test directory to a temporary directory to abvoid conflict with other tests when `cargo test` parallelly testing + path: tempfile::TempDir, +} + +impl TestDir { + // create a new TestDir with the test directory in tests/test_cases/ + fn new(sub: &str) -> Self { + let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("tests/test_cases") + .join(sub); + let tmp_dir = tempfile::TempDir::new().unwrap(); + copy(&dir, tmp_dir.path()).unwrap(); + Self { path: tmp_dir } + } + + fn join(&self, sub: &str) -> PathBuf { + self.path.path().join(sub) + } +} + +impl AsRef for TestDir { + fn as_ref(&self) -> &Path { + self.path.path() + } +} + +fn copy(src: &Path, dest: &Path) -> anyhow::Result<()> { + if src.is_dir() { + if !dest.exists() { + std::fs::create_dir_all(dest)?; + } + for entry in walkdir::WalkDir::new(src) { + let entry = entry?; + let path = entry.path(); + let relative_path = path.strip_prefix(src)?; + let dest_path = dest.join(relative_path); + if path.is_dir() { + if !dest_path.exists() { + std::fs::create_dir_all(dest_path)?; + } + } else { + std::fs::copy(path, dest_path)?; + } + } + } else { + std::fs::copy(src, dest)?; + } + Ok(()) +} + +fn check(actual: &str, expect: Expect) { + expect.assert_eq(actual) +} + +#[test] +fn test_moonrun_version() { + let out = snapbox::cmd::Command::new(snapbox::cmd::cargo_bin("moonrun")) + .arg("--version") + .assert() + .success() + .get_output() + .stdout + .to_owned(); + let s = std::str::from_utf8(&out).unwrap().to_string(); + assert!(s.contains("moonrun")); +} + +#[test] +fn test_moonrun_wasm_stack_trace() { + let dir = TestDir::new("test_stack_trace.in"); + + snapbox::cmd::Command::new(snapbox::cmd::cargo_bin("moon")) + .current_dir(&dir) + .arg("build") + .assert() + .success(); + + let main_wasm = dir.join("target/wasm-gc/release/build/main/main.wasm"); + + let out = snapbox::cmd::Command::new(snapbox::cmd::cargo_bin("moonrun")) + .arg(&main_wasm) + .assert() + .failure() + .get_output() + .stderr + .to_owned(); + let s = std::str::from_utf8(&out).unwrap().to_string(); + check( + &s, + expect![[r#" + RuntimeError: unreachable + at wasm://wasm/37dd63fa:wasm-function[1]:0x8c + at wasm://wasm/37dd63fa:wasm-function[3]:0x9b + "#]], + ); + + let out = snapbox::cmd::Command::new(snapbox::cmd::cargo_bin("moonrun")) + .arg(&main_wasm) + .arg("--no-stack-trace") + .assert() + .failure() + .get_output() + .stderr + .to_owned(); + let s = std::str::from_utf8(&out).unwrap().to_string(); + check( + &s, + expect![[r#" + RuntimeError: unreachable + "#]], + ); +} + +#[test] +fn test_moon_run_with_cli_args() { + let dir = TestDir::new("test_cli_args.in"); + + snapbox::cmd::Command::new(snapbox::cmd::cargo_bin("moon")) + .current_dir(&dir) + .arg("build") + .assert() + .success(); + + let wasm_file = dir.join("target/wasm-gc/release/build/main/main.wasm"); + + let out = snapbox::cmd::Command::new(snapbox::cmd::cargo_bin("moonrun")) + .arg(&wasm_file) + .assert() + .success() + .get_output() + .stdout + .to_owned(); + let s = std::str::from_utf8(&out).unwrap().to_string(); + + check( + &s, + expect![[r#" + [] + "#]], + ); + + let out = snapbox::cmd::Command::new(snapbox::cmd::cargo_bin("moonrun")) + .arg(&wasm_file) + .arg("--") + .args(["δΈ­ζ–‡", "πŸ˜„πŸ‘", "hello", "1242"]) + .assert() + .success() + .get_output() + .stdout + .to_owned(); + let s = std::str::from_utf8(&out).unwrap().to_string(); + + check( + &s, + expect![[r#" + ["δΈ­ζ–‡", "πŸ˜„πŸ‘", "hello", "1242"] + "#]], + ); +} diff --git a/crates/moonrun/tests/test_cases/test_cli_args.in/.gitignore b/crates/moonrun/tests/test_cases/test_cli_args.in/.gitignore new file mode 100644 index 00000000..b1283a74 --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_cli_args.in/.gitignore @@ -0,0 +1,2 @@ +target/ +.mooncakes/ diff --git a/crates/moonrun/tests/test_cases/test_cli_args.in/README.md b/crates/moonrun/tests/test_cases/test_cli_args.in/README.md new file mode 100644 index 00000000..ae00983f --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_cli_args.in/README.md @@ -0,0 +1 @@ +# username/hello \ No newline at end of file diff --git a/crates/moonrun/tests/test_cases/test_cli_args.in/main/main.mbt b/crates/moonrun/tests/test_cases/test_cli_args.in/main/main.mbt new file mode 100644 index 00000000..b9363700 --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_cli_args.in/main/main.mbt @@ -0,0 +1,111 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +fn main { + let args = get_args() + println(args) +} + + +fn env_get_var(s : ExternString) -> ExternString = "__moonbit_fs_unstable" "env_get_var" + +fn args_get() -> JSArray = "__moonbit_fs_unstable" "args_get" + +fn get_env_var(name : String) -> String? { + let res = env_get_var(string_to_extern(name)) + let mbt_string = string_from_extern(res) + if mbt_string == "" { + None + } else { + Some(mbt_string) + } +} + +fn get_args() -> Array[String] { + let arr = args_get() + let len = array_len(arr) + let res = [] + for i = 0; i < len; i = i + 1 { + let val = arr[i] + if jsvalue_is_string(val).not() { + abort("Expected all strings in array") + } + res.push(string_from_extern(jsvalue_get_string(val))) + } + res +} + +type JSValue + +fn jsvalue_is_string(v : JSValue) -> Bool = "__moonbit_fs_unstable" "jsvalue_is_string" + +fn jsvalue_get_string(v : JSValue) -> ExternString = "%identity" + + +type JSArray + +fn array_len(arr : JSArray) -> Int = "__moonbit_fs_unstable" "array_len" + +fn array_get(arr : JSArray, idx : Int) -> JSValue = "__moonbit_fs_unstable" "array_get" + +fn JSArray::op_get(self : JSArray, idx : Int) -> JSValue { + return array_get(self, idx) +} + + + +type StringCreateHandle + +type StringReadHandle + +type ExternString + +fn begin_create_string() -> StringCreateHandle = "__moonbit_fs_unstable" "begin_create_string" + +fn string_append_char(handle : StringCreateHandle, ch : Char) = "__moonbit_fs_unstable" "string_append_char" + +fn finish_create_string(handle : StringCreateHandle) -> ExternString = "__moonbit_fs_unstable" "finish_create_string" + +fn string_to_extern(s : String) -> ExternString { + let handle = begin_create_string() + s.iter().each(fn(ch) { string_append_char(handle, ch) }) + finish_create_string(handle) +} + +fn begin_read_string(s : ExternString) -> StringReadHandle = "__moonbit_fs_unstable" "begin_read_string" + +/// Read one char from the string, returns -1 if the end of the string is reached. +/// The number returned is the unicode codepoint of the character. +fn string_read_char(handle : StringReadHandle) -> Int = "__moonbit_fs_unstable" "string_read_char" + +fn finish_read_string(handle : StringReadHandle) = "__moonbit_fs_unstable" "finish_read_string" + +fn string_from_extern(e : ExternString) -> String { + let buf = Buffer::new() + let handle = begin_read_string(e) + while true { + let ch = string_read_char(handle) + if ch == -1 { + break + } else { + buf.write_char(Char::from_int(ch)) + } + } + finish_read_string(handle) + buf.to_string() +} diff --git a/crates/moonrun/tests/test_cases/test_cli_args.in/main/moon.pkg.json b/crates/moonrun/tests/test_cases/test_cli_args.in/main/moon.pkg.json new file mode 100644 index 00000000..fcc86bad --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_cli_args.in/main/moon.pkg.json @@ -0,0 +1,3 @@ +{ + "is-main": true +} \ No newline at end of file diff --git a/crates/moonrun/tests/test_cases/test_cli_args.in/moon.mod.json b/crates/moonrun/tests/test_cases/test_cli_args.in/moon.mod.json new file mode 100644 index 00000000..8e79206f --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_cli_args.in/moon.mod.json @@ -0,0 +1,9 @@ +{ + "name": "username/hello", + "version": "0.1.0", + "readme": "README.md", + "repository": "", + "license": "Apache-2.0", + "keywords": [], + "description": "" +} \ No newline at end of file diff --git a/crates/moonrun/tests/test_cases/test_stack_trace.in/.gitignore b/crates/moonrun/tests/test_cases/test_stack_trace.in/.gitignore new file mode 100644 index 00000000..b1283a74 --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_stack_trace.in/.gitignore @@ -0,0 +1,2 @@ +target/ +.mooncakes/ diff --git a/crates/moonrun/tests/test_cases/test_stack_trace.in/README.md b/crates/moonrun/tests/test_cases/test_stack_trace.in/README.md new file mode 100644 index 00000000..ae00983f --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_stack_trace.in/README.md @@ -0,0 +1 @@ +# username/hello \ No newline at end of file diff --git a/crates/moonrun/tests/test_cases/test_stack_trace.in/main/main.mbt b/crates/moonrun/tests/test_cases/test_stack_trace.in/main/main.mbt new file mode 100644 index 00000000..1b3440d4 --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_stack_trace.in/main/main.mbt @@ -0,0 +1,21 @@ +// moon: The build system and package manager for MoonBit. +// Copyright (C) 2024 International Digital Economy Academy +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// For inquiries, you can contact us via e-mail at jichuruanjian@idea.edu.cn. + +fn main { + abort("This is an abort msg") +} diff --git a/crates/moonrun/tests/test_cases/test_stack_trace.in/main/moon.pkg.json b/crates/moonrun/tests/test_cases/test_stack_trace.in/main/moon.pkg.json new file mode 100644 index 00000000..fcc86bad --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_stack_trace.in/main/moon.pkg.json @@ -0,0 +1,3 @@ +{ + "is-main": true +} \ No newline at end of file diff --git a/crates/moonrun/tests/test_cases/test_stack_trace.in/moon.mod.json b/crates/moonrun/tests/test_cases/test_stack_trace.in/moon.mod.json new file mode 100644 index 00000000..8e79206f --- /dev/null +++ b/crates/moonrun/tests/test_cases/test_stack_trace.in/moon.mod.json @@ -0,0 +1,9 @@ +{ + "name": "username/hello", + "version": "0.1.0", + "readme": "README.md", + "repository": "", + "license": "Apache-2.0", + "keywords": [], + "description": "" +} \ No newline at end of file diff --git a/licenserc.toml b/licenserc.toml index 591c7bb9..80b81033 100644 --- a/licenserc.toml +++ b/licenserc.toml @@ -46,4 +46,6 @@ excludes = [ "crates/moonbuild/template/**", ".justfile", "moon.test", + "*.js", + "*.wasm", ]