From 7543333179624c951a2092ab17049a2fbdccfff3 Mon Sep 17 00:00:00 2001 From: Tim Jentzsch Date: Sun, 29 Sep 2024 11:59:43 +0200 Subject: [PATCH 1/7] Add functionality to run the bevy app --- Cargo.lock | 669 +++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 + assets/web/index.html | 163 ++++++++++ src/lib.rs | 1 + src/run/args.rs | 48 +++ src/run/mod.rs | 48 +++ src/run/serve.rs | 60 ++++ 7 files changed, 981 insertions(+), 11 deletions(-) create mode 100644 assets/web/index.html create mode 100644 src/run/args.rs create mode 100644 src/run/mod.rs create mode 100644 src/run/serve.rs diff --git a/Cargo.lock b/Cargo.lock index ea9ad28..0d6cc8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,212 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cf780eb737f2d4a49ffbd512324d53ad089070f813f7be7f99dbd5123a7f448" +[[package]] +name = "actix-codec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" +dependencies = [ + "bitflags 2.6.0", + "bytes", + "futures-core", + "futures-sink", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "actix-files" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0773d59061dedb49a8aed04c67291b9d8cf2fe0b60130a381aab53c6dd86e9be" +dependencies = [ + "actix-http", + "actix-service", + "actix-utils", + "actix-web", + "bitflags 2.6.0", + "bytes", + "derive_more", + "futures-core", + "http-range", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "v_htmlescape", +] + +[[package]] +name = "actix-http" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash", + "base64", + "bitflags 2.6.0", + "brotli", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "flate2", + "futures-core", + "h2 0.3.26", + "http 0.2.12", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha1", + "smallvec", + "tokio", + "tokio-util", + "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-router" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" +dependencies = [ + "bytestring", + "cfg-if", + "http 0.2.12", + "regex", + "regex-lite", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "socket2", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash", + "bytes", + "bytestring", + "cfg-if", + "cookie", + "derive_more", + "encoding_rs", + "futures-core", + "futures-util", + "impl-more", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "regex-lite", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2", + "time", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "addr2line" version = "0.24.1" @@ -55,6 +261,21 @@ dependencies = [ "as-slice", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.18" @@ -249,6 +470,8 @@ dependencies = [ name = "bevy_cli" version = "0.1.0-dev" dependencies = [ + "actix-files", + "actix-web", "anyhow", "cargo-generate", "clap", @@ -259,6 +482,7 @@ dependencies = [ "serde", "serde_json", "toml_edit 0.22.21", + "webbrowser", ] [[package]] @@ -576,6 +800,36 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "brotli" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bstr" version = "1.10.0" @@ -611,6 +865,15 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +[[package]] +name = "bytestring" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" +dependencies = [ + "bytes", +] + [[package]] name = "cargo-generate" version = "0.22.0" @@ -664,6 +927,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.0" @@ -744,6 +1013,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -802,6 +1081,23 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -812,6 +1108,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -827,6 +1133,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -895,6 +1210,19 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + [[package]] name = "dialoguer" version = "0.11.0" @@ -1045,6 +1373,16 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1452,6 +1790,25 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.6" @@ -1463,7 +1820,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -1503,6 +1860,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -1521,7 +1889,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -1532,17 +1900,29 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http", + "http 1.1.0", "http-body", "pin-project-lite", ] +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + [[package]] name = "httparse" version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "humantime" version = "2.1.0" @@ -1558,8 +1938,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", + "h2 0.4.6", + "http 1.1.0", "http-body", "httparse", "itoa", @@ -1576,7 +1956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http", + "http 1.1.0", "hyper", "hyper-util", "rustls", @@ -1611,7 +1991,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", + "http 1.1.0", "http-body", "hyper", "pin-project-lite", @@ -1648,6 +2028,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "impl-more" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" + [[package]] name = "indexmap" version = "2.5.0" @@ -1742,6 +2128,28 @@ dependencies = [ "jiff-tzdb", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.32" @@ -1770,6 +2178,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + [[package]] name = "lazy_static" version = "1.5.0" @@ -1895,6 +2309,23 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "local-channel" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" +dependencies = [ + "futures-core", + "futures-sink", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" + [[package]] name = "lock_api" version = "0.4.12" @@ -1941,6 +2372,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -1958,6 +2399,7 @@ checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", + "log", "wasi", "windows-sys 0.52.0", ] @@ -1988,6 +2430,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "nix" version = "0.29.0" @@ -2046,6 +2494,40 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", +] + [[package]] name = "object" version = "0.36.4" @@ -2402,6 +2884,12 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -2440,8 +2928,8 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", + "h2 0.4.6", + "http 1.1.0", "http-body", "http-body-util", "hyper", @@ -2531,6 +3019,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.37" @@ -2631,7 +3128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "libc", "security-framework-sys", @@ -2709,6 +3206,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha1_smol" version = "1.0.1" @@ -2747,6 +3255,15 @@ 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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "slab" version = "0.4.9" @@ -2849,7 +3366,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -2996,7 +3513,9 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", + "signal-hook-registry", "socket2", "windows-sys 0.52.0", ] @@ -3128,6 +3647,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3218,6 +3738,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -3289,6 +3818,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "v_htmlescape" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" + [[package]] name = "valuable" version = "0.1.0" @@ -3419,6 +3954,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e5f07fb9bc8de2ddfe6b24a71a75430673fd679e568c48b52716cef1cfae923" +dependencies = [ + "block2", + "core-foundation 0.10.0", + "home", + "jni", + "log", + "ndk-context", + "objc2", + "objc2-foundation", + "url", + "web-sys", +] + [[package]] name = "winapi" version = "0.3.9" @@ -3480,6 +4033,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -3507,6 +4069,21 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -3538,6 +4115,12 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -3550,6 +4133,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3562,6 +4151,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3580,6 +4175,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3592,6 +4193,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3604,6 +4211,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3616,6 +4229,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3672,3 +4291,31 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 58047a2..6130871 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,3 +40,6 @@ toml_edit = { version = "0.22.21", default-features = false, features = [ # Understanding package versions semver = { version = "1.0.23", features = ["serde"] } +actix-files = "0.6.6" +actix-web = "4.9.0" +webbrowser = "1.0.2" diff --git a/assets/web/index.html b/assets/web/index.html new file mode 100644 index 0000000..d21f98b --- /dev/null +++ b/assets/web/index.html @@ -0,0 +1,163 @@ + + + + + Bevy App + + + + +
+
+ +
+ + Javascript and canvas support is required +
+ + + + + + + + diff --git a/src/lib.rs b/src/lib.rs index 220164b..fd57a5b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,4 +4,5 @@ pub mod build; pub mod external_cli; pub mod lint; pub mod manifest; +pub mod run; pub mod template; diff --git a/src/run/args.rs b/src/run/args.rs new file mode 100644 index 0000000..94659e3 --- /dev/null +++ b/src/run/args.rs @@ -0,0 +1,48 @@ +use clap::{ArgAction, Args, Subcommand}; + +use crate::external_cli::{arg_builder::ArgBuilder, cargo::run::CargoRunArgs}; + +#[derive(Debug, Args)] +pub struct RunArgs { + /// The subcommands available for the run command. + #[command(subcommand)] + pub subcommand: Option, + + /// Commands to forward to `cargo run`. + #[clap(flatten)] + pub cargo_args: CargoRunArgs, +} + +impl RunArgs { + /// Whether to run the app in the browser. + pub(crate) fn is_web(&self) -> bool { + matches!(self.subcommand, Some(RunSubcommands::Web(_))) + } + + /// The profile used to compile the app. + pub(crate) fn profile(&self) -> &str { + self.cargo_args.compilation_args.profile() + } + + /// Generate arguments for `cargo`. + pub(crate) fn cargo_args_builder(&self) -> ArgBuilder { + self.cargo_args.args_builder(self.is_web()) + } +} + +#[derive(Debug, Subcommand)] +pub enum RunSubcommands { + /// Run your app in the browser. + Web(RunWebArgs), +} + +#[derive(Debug, Args)] +pub struct RunWebArgs { + /// The port to run the web server on. + #[arg(short, long, default_value_t = 4000)] + pub port: u16, + + /// Open the app in the browser. + #[arg(short = 'o', long = "open", action = ArgAction::SetTrue, default_value_t = false)] + pub do_open: bool, +} diff --git a/src/run/mod.rs b/src/run/mod.rs new file mode 100644 index 0000000..b3fb254 --- /dev/null +++ b/src/run/mod.rs @@ -0,0 +1,48 @@ +use args::RunSubcommands; + +use crate::{ + build::ensure_web_setup, + external_cli::{cargo, wasm_bindgen, CommandHelpers}, + manifest::package_name, +}; + +pub use self::args::RunArgs; + +mod args; +mod serve; + +pub fn run(args: &RunArgs) -> anyhow::Result<()> { + let cargo_args = args.cargo_args_builder(); + + if let Some(RunSubcommands::Web(web_args)) = &args.subcommand { + ensure_web_setup()?; + + // If targeting the web, run a web server with the WASM build + println!("Building for WASM..."); + cargo::build::command().args(cargo_args).ensure_status()?; + + println!("Bundling for the web..."); + wasm_bindgen::bundle(&package_name()?, args.profile())?; + + let port = web_args.port; + let url = format!("http://127.0.0.1:{port}"); + + // Serving the app is blocking, so we open the page first + if web_args.do_open { + if webbrowser::open(&url).is_err() { + println!("Failed to open the browser automatically, open the app on <{url}>"); + } else { + println!("Your app is running on <{url}>"); + } + } else { + println!("Open your app on <{url}>"); + } + + serve::serve(port, args.profile())?; + } else { + // For native builds, wrap `cargo run` + cargo::run::command().args(cargo_args).ensure_status()?; + } + + Ok(()) +} diff --git a/src/run/serve.rs b/src/run/serve.rs new file mode 100644 index 0000000..92b6a0a --- /dev/null +++ b/src/run/serve.rs @@ -0,0 +1,60 @@ +//! Serving the app locally for the browser. +use actix_web::{rt, web, App, HttpResponse, HttpServer, Responder}; +use std::path::Path; + +use crate::external_cli::wasm_bindgen; + +/// If the user didn't provide an `index.html`, serve a default one. +async fn serve_default_index() -> impl Responder { + let content = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/assets/web/index.html" + )); + + // Build the HTTP response with appropriate headers to serve the content as a file + HttpResponse::Ok() + .insert_header(( + actix_web::http::header::CONTENT_TYPE, + "text/html; charset=utf-8", + )) + .body(content) +} + +/// Launch a web server running the Bevy app. +pub(crate) fn serve(port: u16, profile: &str) -> anyhow::Result<()> { + let profile = profile.to_string(); + + rt::System::new().block_on( + HttpServer::new(move || { + let mut app = App::new(); + + // Serve the build artifacts at the `/build/*` route + // A custom `index.html` will have to call `/build/bevy_app.js` + let js_path = Path::new("bevy_app.js"); + let wasm_path = Path::new("bevy_app_bg.wasm"); + app = app.service( + actix_files::Files::new("/build", wasm_bindgen::get_target_folder(&profile)) + .path_filter(move |path, _| path == js_path || path == wasm_path), + ); + + // If the app has an assets folder, serve it under `/assets` + if Path::new("assets").exists() { + app = app.service(actix_files::Files::new("/assets", "./assets")) + } + + if Path::new("web").exists() { + // Serve the contents of the `web` folder under `/`, if it exists + app = app.service(actix_files::Files::new("/", "./web").index_file("index.html")); + } else { + // If the user doesn't provide a custom web setup, serve a default `index.html` + app = app.route("/", web::get().to(serve_default_index)) + } + + app + }) + .bind(("127.0.0.1", port))? + .run(), + )?; + + Ok(()) +} From 35d6a284f151a435dbb759f41fc6de946c5e32aa Mon Sep 17 00:00:00 2001 From: Tim Jentzsch Date: Sun, 29 Sep 2024 12:01:50 +0200 Subject: [PATCH 2/7] Add bevy run to CLI --- src/bin/main.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index d792269..35f42a4 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use bevy_cli::build::BuildArgs; +use bevy_cli::{build::BuildArgs, run::RunArgs}; use clap::{Args, Parser, Subcommand}; fn main() -> Result<()> { @@ -11,6 +11,7 @@ fn main() -> Result<()> { } Subcommands::Lint { args } => bevy_cli::lint::lint(args)?, Subcommands::Build(args) => bevy_cli::build::build(&args)?, + Subcommands::Run(args) => bevy_cli::run::run(&args)?, } Ok(()) @@ -29,16 +30,14 @@ pub struct Cli { } /// Available subcommands for `bevy`. -#[expect( - clippy::large_enum_variant, - reason = "Only constructed once, not expected to have a performance impact." -)] #[derive(Subcommand)] pub enum Subcommands { /// Create a new Bevy project from a specified template. New(NewArgs), /// Build your Bevy app. Build(BuildArgs), + /// Run your Bevy app. + Run(RunArgs), /// Check the current project using Bevy-specific lints. /// /// This command requires `bevy_lint` to be installed, and will fail if it is not. Please see From 0dbe6fd05727afec7c340e1e5426eee94c0ae208 Mon Sep 17 00:00:00 2001 From: Tim Jentzsch Date: Sun, 29 Sep 2024 12:06:58 +0200 Subject: [PATCH 3/7] Add comments for new dependencies --- Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 6130871..0300397 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,10 @@ toml_edit = { version = "0.22.21", default-features = false, features = [ # Understanding package versions semver = { version = "1.0.23", features = ["serde"] } + +# Serving the app for the browser actix-files = "0.6.6" actix-web = "4.9.0" + +# Opening the app in the browser webbrowser = "1.0.2" From 07ba6bc0852670f446edba806cc56a60724f44ba Mon Sep 17 00:00:00 2001 From: Tim Jentzsch Date: Thu, 3 Oct 2024 15:04:49 +0200 Subject: [PATCH 4/7] Simplify link to `localhost` --- src/run/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/run/mod.rs b/src/run/mod.rs index b3fb254..def2e2d 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -25,7 +25,7 @@ pub fn run(args: &RunArgs) -> anyhow::Result<()> { wasm_bindgen::bundle(&package_name()?, args.profile())?; let port = web_args.port; - let url = format!("http://127.0.0.1:{port}"); + let url = format!("http://localhost:{port}"); // Serving the app is blocking, so we open the page first if web_args.do_open { From 46e8c09cd394aa795e785119f9c8a3e77c06776a Mon Sep 17 00:00:00 2001 From: Tim Jentzsch Date: Thu, 3 Oct 2024 15:08:47 +0200 Subject: [PATCH 5/7] Improve web browser opening behavior --- src/run/mod.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/run/mod.rs b/src/run/mod.rs index def2e2d..f6f3a71 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -29,13 +29,14 @@ pub fn run(args: &RunArgs) -> anyhow::Result<()> { // Serving the app is blocking, so we open the page first if web_args.do_open { - if webbrowser::open(&url).is_err() { - println!("Failed to open the browser automatically, open the app on <{url}>"); - } else { - println!("Your app is running on <{url}>"); + match webbrowser::open(&url) { + Ok(()) => println!("Your app is running at <{url}>!"), + Err(error) => { + println!("Failed to open the browser automatically, open the app at <{url}>. (Error: {error:?}") + } } } else { - println!("Open your app on <{url}>"); + println!("Open your app at <{url}>!"); } serve::serve(port, args.profile())?; From 2ceaac25b641cba5df6f51dc6bc1b273819f5a9c Mon Sep 17 00:00:00 2001 From: Tim Jentzsch Date: Thu, 3 Oct 2024 15:10:22 +0200 Subject: [PATCH 6/7] Rename open arg --- src/run/args.rs | 2 +- src/run/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/run/args.rs b/src/run/args.rs index 94659e3..4723330 100644 --- a/src/run/args.rs +++ b/src/run/args.rs @@ -44,5 +44,5 @@ pub struct RunWebArgs { /// Open the app in the browser. #[arg(short = 'o', long = "open", action = ArgAction::SetTrue, default_value_t = false)] - pub do_open: bool, + pub open: bool, } diff --git a/src/run/mod.rs b/src/run/mod.rs index f6f3a71..b786323 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -28,7 +28,7 @@ pub fn run(args: &RunArgs) -> anyhow::Result<()> { let url = format!("http://localhost:{port}"); // Serving the app is blocking, so we open the page first - if web_args.do_open { + if web_args.open { match webbrowser::open(&url) { Ok(()) => println!("Your app is running at <{url}>!"), Err(error) => { From dd111a939e7ddcd153c3a1391819405dec5624aa Mon Sep 17 00:00:00 2001 From: Tim Jentzsch Date: Thu, 3 Oct 2024 15:19:53 +0200 Subject: [PATCH 7/7] Move wasm-bindgen file filter to the wasm-bindgen module --- src/external_cli/wasm_bindgen.rs | 12 +++++++++++- src/run/serve.rs | 4 +--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/external_cli/wasm_bindgen.rs b/src/external_cli/wasm_bindgen.rs index a0fc7b3..46738a1 100644 --- a/src/external_cli/wasm_bindgen.rs +++ b/src/external_cli/wasm_bindgen.rs @@ -1,4 +1,4 @@ -use std::process::Command; +use std::{path::Path, process::Command}; use super::arg_builder::ArgBuilder; @@ -28,3 +28,13 @@ pub(crate) fn bundle(package_name: &str, profile: &str) -> anyhow::Result<()> { anyhow::ensure!(status.success(), "Failed to bundle project for the web."); Ok(()) } + +/// Determine if a file path in the target folder is an artifact generated by wasm-bindgen. +pub(crate) fn is_bindgen_artifact(path: &Path) -> bool { + // The JS interface wrapping the WASM binary + let js_path = Path::new("bevy_app.js"); + // The WASM bindgen + let wasm_path = Path::new("bevy_app_bg.wasm"); + + path == js_path || path == wasm_path +} diff --git a/src/run/serve.rs b/src/run/serve.rs index 92b6a0a..9f2752a 100644 --- a/src/run/serve.rs +++ b/src/run/serve.rs @@ -30,11 +30,9 @@ pub(crate) fn serve(port: u16, profile: &str) -> anyhow::Result<()> { // Serve the build artifacts at the `/build/*` route // A custom `index.html` will have to call `/build/bevy_app.js` - let js_path = Path::new("bevy_app.js"); - let wasm_path = Path::new("bevy_app_bg.wasm"); app = app.service( actix_files::Files::new("/build", wasm_bindgen::get_target_folder(&profile)) - .path_filter(move |path, _| path == js_path || path == wasm_path), + .path_filter(|path, _| wasm_bindgen::is_bindgen_artifact(path)), ); // If the app has an assets folder, serve it under `/assets`