From 099f9241f036420749e4eab13662d2ac0654d9f2 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Wed, 20 Sep 2023 01:07:04 +0530 Subject: [PATCH] feat(sozo): support for dev mode with hot reloading (#890) * feat(sozo): #557: suport dev mode with hot reloading. Build is triggered for any modification to Scarb.toml or a filename with 'cairo' extension * sozo: add DojoCompiler for build and dev subcommand * sozo: add copy of non pub functions from scarb required for hot loading * sozo: rebuild project when a cairo file is modified * sozo: add debouncer for dev mode * feat(sozo): #557: update Cargo.lock * feat(sozo): #557: support dev mode with hot reloading Add migration * make it compile * fix formatting * remove TODO * fix file copied from scarb * fix formatting * update manifest on migrate * add NOTE on scarb_internal module --------- Co-authored-by: Patrice Tisserand --- Cargo.lock | 449 ++++++++++-------- crates/sozo/Cargo.toml | 3 + crates/sozo/src/args.rs | 3 + crates/sozo/src/commands/dev.rs | 273 +++++++++++ crates/sozo/src/commands/mod.rs | 6 +- .../sozo/src/commands/scarb_internal/mod.rs | 55 +++ crates/sozo/src/main.rs | 5 +- crates/sozo/src/ops/migration/mod.rs | 75 +-- 8 files changed, 649 insertions(+), 220 deletions(-) create mode 100644 crates/sozo/src/commands/dev.rs create mode 100644 crates/sozo/src/commands/scarb_internal/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 239a9b04f8..f9024e3433 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -122,9 +122,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" @@ -349,9 +349,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b74f44609f0f91493e3082d3734d98497e094777144380ea4db9f9905dd5b6" +checksum = "bb42b2197bf15ccb092b62c74515dbd8b86d0effd934795f6687c93b6e679a2c" dependencies = [ "brotli", "flate2", @@ -498,7 +498,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -509,7 +509,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -607,9 +607,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.3" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "beef" @@ -761,12 +761,12 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.0" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" dependencies = [ "memchr", - "regex-automata 0.3.7", + "regex-automata 0.3.8", "serde", ] @@ -799,9 +799,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] @@ -1062,7 +1062,7 @@ checksum = "170838817fc33ddb65e0a9480526df0b226b148a0fca0a5cd7071be4c6683157" dependencies = [ "cairo-lang-debug", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -1382,7 +1382,7 @@ dependencies = [ "parity-scale-codec", "schemars", "serde", - "time 0.3.28", + "time", ] [[package]] @@ -1464,18 +1464,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits 0.2.16", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets 0.48.5", ] [[package]] @@ -1490,13 +1489,12 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.1" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c8d502cbaec4595d2e7d5f61e318f05417bd2b66fdc3809498f0d3fdf0bea27" +checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] @@ -1511,9 +1509,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.1" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5891c7bc0edb3e1c2204fc5e94009affabeb1821c9e5fdc3959536c5c0bb984d" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" dependencies = [ "anstream", "anstyle", @@ -1523,23 +1521,23 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.0" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" +checksum = "4110a1e6af615a9e6d0a36f805d5c99099f8bab9b8042f5bc1fa220a4a89e36f" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9fd1a5729c4548118d7d70ff234a44868d00489a4b6597b0b020918a0e91a1a" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -1776,7 +1774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f34ba9a9bcb8645379e9de8cb3ecfcf4d1c85ba66d90deb3259206fa5aa193b" dependencies = [ "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -1790,9 +1788,9 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" +checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" dependencies = [ "nix", "windows-sys 0.48.0", @@ -1843,7 +1841,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -1865,14 +1863,14 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] name = "dashmap" -version = "5.5.1" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd72493923899c6f10c641bdbdeddc7183d6396641d99c1a0d1597f37f92e28" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", "hashbrown 0.14.0", @@ -2275,9 +2273,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -2360,9 +2358,9 @@ dependencies = [ [[package]] name = "faster-hex" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9042d281a5eec0f2387f8c3ea6c4514e2cf2732c90a85aaf383b761ee3b290d" +checksum = "239f7bfb930f820ab16a9cd95afc26f88264cf6905c960b340a615384aa3338a" dependencies = [ "serde", ] @@ -2385,6 +2383,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + [[package]] name = "fixed-hash" version = "0.8.0" @@ -2450,6 +2454,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + [[package]] name = "funty" version = "2.0.0" @@ -2523,7 +2536,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -2597,7 +2610,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -2796,14 +2809,14 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e476b4e156f6044d35bf1ce2079d97b7207515cfb5a2bb6fcd489bb697d700" +checksum = "0a825babda995d788e30d306a49dacd1e93d5f5d33d53c7682d0347cef40333c" dependencies = [ "bstr", "itoa", "thiserror", - "time 0.3.28", + "time", ] [[package]] @@ -3056,9 +3069,9 @@ dependencies = [ [[package]] name = "gix-packetline-blocking" -version = "0.16.5" +version = "0.16.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e39142400d3faa7057680ed3947c3b70e46b6a0b16a7c242ec8f0249e37518ba" +checksum = "7d8395f7501c84d6a1fe902035fdfd8cd86d89e2dd6be0200ec1a72fd3c92d39" dependencies = [ "bstr", "faster-hex", @@ -3350,9 +3363,9 @@ dependencies = [ [[package]] name = "handlebars" -version = "4.3.7" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c3372087601b532857d332f5957cbae686da52bb7810bf038c3e3c3cc2fa0d" +checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" dependencies = [ "log", "pest", @@ -3393,9 +3406,9 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ "hashbrown 0.14.0", ] @@ -3412,12 +3425,11 @@ dependencies = [ [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", + "base64 0.21.4", "bytes", "headers-core", "http", @@ -3568,7 +3580,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.6", + "rustls 0.21.7", "tokio", "tokio-rustls 0.24.1", ] @@ -3767,6 +3779,26 @@ version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c785eefb63ebd0e33416dfcb8d6da0bf27ce752843a45632a67bf10d4d4b5c4" +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "inout" version = "0.1.3" @@ -4046,6 +4078,26 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + [[package]] name = "kstring" version = "2.0.0" @@ -4098,9 +4150,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libmimalloc-sys" @@ -4131,9 +4183,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "lock_api" @@ -4208,9 +4260,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76fc44e2588d5b436dbc3c6cf62aef290f90dab6235744a93dfe1cc18f451e2c" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memmap2" @@ -4287,7 +4339,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "log", + "wasi", "windows-sys 0.48.0", ] @@ -4342,9 +4395,9 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" [[package]] name = "nix" -version = "0.26.3" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abbbc55ad7b13aac85f9401c796dcda1b864e07fcad40ad47792eaa8932ea502" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ "bitflags 2.4.0", "cfg-if", @@ -4367,6 +4420,35 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.4.0", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "notify-debouncer-mini" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e55ee272914f4563a2f8b8553eb6811f3c0caea81c756346bad15b7e3ef969f0" +dependencies = [ + "crossbeam-channel", + "notify", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -4482,9 +4564,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -4546,9 +4628,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parity-scale-codec" -version = "3.6.4" +version = "3.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" dependencies = [ "arrayvec", "bitvec", @@ -4560,9 +4642,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.4" +version = "3.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4632,9 +4714,9 @@ checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" [[package]] name = "path-dedot" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d55e486337acb9973cdea3ec5638c1b3bcb22e573b2b7b41969e0c744d5a15e" +checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" dependencies = [ "once_cell", ] @@ -4665,19 +4747,20 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" dependencies = [ "pest", "pest_generator", @@ -4685,22 +4768,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] name = "pest_meta" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" dependencies = [ "once_cell", "pest", @@ -4747,7 +4830,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -4811,7 +4894,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -4834,12 +4917,12 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "poem" -version = "1.3.57" +version = "1.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d92c532a37a9e98c0e9a0411e6852b8acccf9ec07d5e6e450b01cbf947d90b" +checksum = "ebc7ae19f3e791ae8108b08801abb3708d64d3a16490c720e0b81040cae87b5d" dependencies = [ "async-trait", - "base64 0.21.3", + "base64 0.21.4", "bytes", "futures-util", "headers", @@ -4865,14 +4948,14 @@ dependencies = [ [[package]] name = "poem-derive" -version = "1.3.57" +version = "1.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5dd58846a1f582215370384c3090c62c9ef188e9d798ffc67ea90d0a1a8a3b8" +checksum = "2550a0bce7273b278894ef3ccc5a6869e7031b6870042f3cc6826ed9faa980a6" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -5174,13 +5257,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.7", + "regex-automata 0.3.8", "regex-syntax 0.7.5", ] @@ -5195,9 +5278,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", @@ -5240,7 +5323,7 @@ version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.3", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -5257,7 +5340,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.6", + "rustls 0.21.7", "rustls-pemfile", "serde", "serde_json", @@ -5346,9 +5429,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.9" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bfe0f2582b4931a45d1fa608f8a8722e8b3c7ac54dd6d5f3b3212791fedef49" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ "bitflags 2.4.0", "errno", @@ -5359,9 +5442,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring", @@ -5371,9 +5454,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.6" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", @@ -5387,14 +5470,14 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.3", + "base64 0.21.4", ] [[package]] name = "rustls-webpki" -version = "0.101.4" +version = "0.101.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" dependencies = [ "ring", "untrusted", @@ -5594,9 +5677,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "763f8cd0d4c71ed8389c90cb8100cba87e763bd01a8e614d4f0af97bcd50a161" dependencies = [ "dyn-clone", "indexmap 1.9.3", @@ -5607,9 +5690,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "ec0f696e21e10fa546b7ffb1c9672c6de8fbc7a81acf59524386d8639bf12737" dependencies = [ "proc-macro2", "quote", @@ -5681,7 +5764,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -5697,9 +5780,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2" dependencies = [ "itoa", "ryu", @@ -5725,7 +5808,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -5762,7 +5845,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.28", + "time", ] [[package]] @@ -5774,7 +5857,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -5830,9 +5913,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6805d8ff0f66aa61fb79a97a51ba210dcae753a797336dea8a36a3168196fab" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ "lazy_static", ] @@ -5926,9 +6009,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", "windows-sys 0.48.0", @@ -5958,6 +6041,7 @@ dependencies = [ "assert_fs", "async-trait", "cairo-lang-compiler", + "cairo-lang-defs", "cairo-lang-filesystem", "cairo-lang-plugins", "cairo-lang-project", @@ -5974,6 +6058,8 @@ dependencies = [ "dojo-test-utils", "dojo-types", "dojo-world", + "notify", + "notify-debouncer-mini", "scarb", "scarb-ui", "semver", @@ -6018,11 +6104,11 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" dependencies = [ - "itertools 0.10.5", + "itertools 0.11.0", "nom", "unicode_categories", ] @@ -6071,7 +6157,7 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rustls 0.20.8", + "rustls 0.20.9", "rustls-pemfile", "serde", "sha2", @@ -6170,7 +6256,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b796a32a7400f7d85e95d3900b5cee7a392b2adbf7ad16093ed45ec6f8d85de6" dependencies = [ - "base64 0.21.3", + "base64 0.21.4", "flate2", "hex", "serde", @@ -6230,7 +6316,7 @@ checksum = "af6527b845423542c8a16e060ea1bc43f67229848e7cd4c4d80be994a84220ce" dependencies = [ "starknet-curve 0.4.0", "starknet-ff", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -6273,7 +6359,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef846b6bb48fc8c3e9a2aa9b5b037414f04a908d9db56493a3ae69a857eb2506" dependencies = [ "starknet-core", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -6350,10 +6436,11 @@ dependencies = [ [[package]] name = "stringprep" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" dependencies = [ + "finl_unicode", "unicode-bidi", "unicode-normalization", ] @@ -6402,9 +6489,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.29" +version = "2.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" dependencies = [ "proc-macro2", "quote", @@ -6475,22 +6562,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -6523,17 +6610,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.28" @@ -6602,7 +6678,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.3", + "socket2 0.5.4", "tokio-macros", "windows-sys 0.48.0", ] @@ -6625,7 +6701,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -6634,7 +6710,7 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.8", + "rustls 0.20.9", "tokio", "webpki", ] @@ -6645,7 +6721,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.6", + "rustls 0.21.7", "tokio", ] @@ -6662,9 +6738,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" +checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" dependencies = [ "futures-util", "log", @@ -6689,9 +6765,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -6710,9 +6786,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.0.0", "serde", @@ -6729,7 +6805,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.3", + "base64 0.21.4", "bytes", "futures-core", "futures-util", @@ -6820,7 +6896,7 @@ dependencies = [ "async-graphql", "async-graphql-poem", "async-trait", - "base64 0.21.3", + "base64 0.21.4", "camino", "chrono", "dojo-types", @@ -6858,7 +6934,7 @@ dependencies = [ "async-graphql", "async-graphql-poem", "async-trait", - "base64 0.21.3", + "base64 0.21.4", "camino", "chrono", "clap", @@ -6907,12 +6983,12 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ "async-compression", - "base64 0.21.3", + "base64 0.21.4", "bitflags 2.4.0", "bytes", "futures-core", @@ -7002,7 +7078,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -7052,9 +7128,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" +checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" dependencies = [ "byteorder", "bytes", @@ -7086,7 +7162,7 @@ checksum = "29a3151c41d0b13e3d011f98adc24434560ef06673a155a6c7f66b9879eecce2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -7163,9 +7239,9 @@ checksum = "98e90c70c9f0d4d1ee6d0a7d04aa06cb9bbd53d8cfbdd62a0269a7c2eb640552" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -7269,9 +7345,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -7286,12 +7362,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -7319,7 +7389,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", "wasm-bindgen-shared", ] @@ -7353,7 +7423,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7376,9 +7446,9 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" dependencies = [ "ring", "untrusted", @@ -7401,13 +7471,14 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix", ] [[package]] @@ -7627,9 +7698,9 @@ checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e" [[package]] name = "xxhash-rust" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "735a71d46c4d68d71d4b24d03fdc2b98e38cea81730595801db779c04fe80d70" +checksum = "9828b178da53440fa9c766a3d2f73f7cf5d0ac1fe3980c1e5018d899fd19e07b" [[package]] name = "yansi" @@ -7654,7 +7725,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] diff --git a/crates/sozo/Cargo.toml b/crates/sozo/Cargo.toml index 2418e62d6c..460666788f 100644 --- a/crates/sozo/Cargo.toml +++ b/crates/sozo/Cargo.toml @@ -9,6 +9,7 @@ version = "0.2.1" anyhow.workspace = true async-trait.workspace = true cairo-lang-compiler.workspace = true +cairo-lang-defs.workspace = true cairo-lang-filesystem.workspace = true cairo-lang-plugins.workspace = true cairo-lang-project.workspace = true @@ -24,6 +25,8 @@ console.workspace = true dojo-lang = { path = "../dojo-lang" } dojo-types = { path = "../dojo-types" } dojo-world = { path = "../dojo-world" } +notify = "6.0.1" +notify-debouncer-mini = "0.3.0" scarb-ui.workspace = true scarb.workspace = true semver.workspace = true diff --git a/crates/sozo/src/args.rs b/crates/sozo/src/args.rs index 20eb583b12..dacb0b6007 100644 --- a/crates/sozo/src/args.rs +++ b/crates/sozo/src/args.rs @@ -11,6 +11,7 @@ use crate::commands::auth::AuthArgs; use crate::commands::build::BuildArgs; use crate::commands::completions::CompletionsArgs; use crate::commands::component::ComponentArgs; +use crate::commands::dev::DevArgs; use crate::commands::events::EventsArgs; use crate::commands::execute::ExecuteArgs; use crate::commands::init::InitArgs; @@ -57,6 +58,8 @@ pub enum Commands { #[command(about = "Run a migration, declaring and deploying contracts as necessary to \ update the world")] Migrate(Box), + #[command(about = "Developer mode: watcher for building and migration")] + Dev(DevArgs), #[command(about = "Test the project's smart contracts")] Test(TestArgs), #[command(about = "Execute a world's system")] diff --git a/crates/sozo/src/commands/dev.rs b/crates/sozo/src/commands/dev.rs new file mode 100644 index 0000000000..788a0c9132 --- /dev/null +++ b/crates/sozo/src/commands/dev.rs @@ -0,0 +1,273 @@ +use std::mem; +use std::path::{Path, PathBuf}; +use std::sync::mpsc::channel; +use std::time::Duration; + +use anyhow::{anyhow, Result}; +use cairo_lang_compiler::db::RootDatabase; +use cairo_lang_filesystem::db::{AsFilesGroupMut, FilesGroupEx, PrivRawFileContentQuery}; +use cairo_lang_filesystem::ids::FileId; +use clap::Args; +use dojo_world::manifest::Manifest; +use dojo_world::metadata::{dojo_metadata_from_workspace, DojoMetadata}; +use dojo_world::migration::world::WorldDiff; +use notify_debouncer_mini::notify::RecursiveMode; +use notify_debouncer_mini::{new_debouncer, DebouncedEvent, DebouncedEventKind}; +use scarb::compiler::CompilationUnit; +use scarb::core::{Config, Workspace}; +use starknet::accounts::SingleOwnerAccount; +use starknet::core::types::FieldElement; +use starknet::providers::Provider; +use starknet::signers::Signer; +use tracing_log::log; + +use super::options::account::AccountOptions; +use super::options::starknet::StarknetOptions; +use super::options::world::WorldOptions; +use super::scarb_internal::build_scarb_root_database; +use crate::ops::migration; + +#[derive(Args)] +pub struct DevArgs { + #[arg(long)] + #[arg(help = "Name of the World.")] + #[arg(long_help = "Name of the World. It's hash will be used as a salt when deploying the \ + contract to avoid address conflicts.")] + pub name: Option, + + #[command(flatten)] + pub world: WorldOptions, + + #[command(flatten)] + pub starknet: StarknetOptions, + + #[command(flatten)] + pub account: AccountOptions, +} + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +enum DevAction { + None, + Reload, + Build(PathBuf), +} + +fn handle_event(event: &DebouncedEvent) -> DevAction { + let action = match event.kind { + DebouncedEventKind::Any => { + let p = event.path.clone(); + if let Some(filename) = p.file_name() { + if filename == "Scarb.toml" { + return DevAction::Reload; + } else if let Some(extension) = p.extension() { + if extension == "cairo" { + return DevAction::Build(p.clone()); + } + } + } + DevAction::None + } + _ => DevAction::None, + }; + action +} + +struct DevContext<'a> { + pub db: RootDatabase, + pub unit: CompilationUnit, + pub ws: Workspace<'a>, + pub dojo_metadata: Option, +} + +fn load_context(config: &Config) -> Result> { + let ws = scarb::ops::read_workspace(config.manifest_path(), config)?; + let packages: Vec = ws.members().map(|p| p.id).collect(); + let resolve = scarb::ops::resolve_workspace(&ws)?; + let compilation_units = scarb::ops::generate_compilation_units(&resolve, &ws)? + .into_iter() + .filter(|cu| packages.contains(&cu.main_package_id)) + .collect::>(); + // we have only 1 unit in projects + let unit = compilation_units.get(0).unwrap(); + let db = build_scarb_root_database(unit, &ws).unwrap(); + let dojo_metadata = dojo_metadata_from_workspace(&ws); + Ok(DevContext { db, unit: unit.clone(), ws, dojo_metadata }) +} + +fn build(context: &mut DevContext<'_>) -> Result<()> { + let ws = &context.ws; + let unit = &context.unit; + let package_name = unit.main_package_id.name.clone(); + ws.config().compilers().compile(unit.clone(), &mut (context.db), ws).map_err(|err| { + ws.config().ui().anyhow(&err); + + anyhow!("could not compile `{package_name}` due to previous error") + })?; + ws.config().ui().print("šŸ“¦ Rebuild done"); + Ok(()) +} + +async fn migrate( + mut world_address: Option, + account: &SingleOwnerAccount, + name: Option, + ws: &Workspace<'_>, + previous_manifest: Option, +) -> Result<(Manifest, Option)> +where + P: Provider + Sync + Send + 'static, + S: Signer + Sync + Send + 'static, +{ + let target_dir = ws.target_dir().path_existent().unwrap(); + let target_dir = target_dir.join(ws.config().profile().as_str()); + let manifest_path = target_dir.join("manifest.json"); + if !manifest_path.exists() { + return Err(anyhow!("manifest.json not found")); + } + let new_manifest = Manifest::load_from_path(manifest_path)?; + let diff = WorldDiff::compute(new_manifest.clone(), previous_manifest); + let total_diffs = diff.count_diffs(); + let config = ws.config(); + config.ui().print(format!("Total diffs found: {total_diffs}")); + if total_diffs == 0 { + return Ok((new_manifest, world_address)); + } + match migration::apply_diff( + target_dir, + diff, + name.clone(), + world_address, + account, + config, + None, + ) + .await + { + Ok(address) => { + config + .ui() + .print(format!("šŸŽ‰ World at address {} updated!", format_args!("{:#x}", address))); + world_address = Some(address); + } + Err(err) => { + config.ui().error(err.to_string()); + return Err(err); + } + } + + Ok((new_manifest, world_address)) +} + +fn process_event(event: &DebouncedEvent, context: &mut DevContext<'_>) -> DevAction { + let action = handle_event(event); + match &action { + DevAction::None => {} + DevAction::Build(path) => handle_build_action(path, context), + DevAction::Reload => { + handle_reload_action(context); + } + } + action +} + +fn handle_build_action(path: &Path, context: &mut DevContext<'_>) { + context + .ws + .config() + .ui() + .print(format!("šŸ“¦ Need to rebuild {}", path.to_str().unwrap_or_default(),)); + let db = &mut context.db; + let file = FileId::new(db, path.to_path_buf()); + PrivRawFileContentQuery.in_db_mut(db.as_files_group_mut()).invalidate(&file); + db.override_file_content(file, None); +} + +fn handle_reload_action(context: &mut DevContext<'_>) { + let config = context.ws.config(); + config.ui().print("Reloading project"); + let new_context = load_context(config).expect("Failed to load context"); + let _ = mem::replace(context, new_context); +} + +impl DevArgs { + pub fn run(self, config: &Config) -> Result<()> { + let mut context = load_context(config)?; + let (tx, rx) = channel(); + let mut debouncer = new_debouncer(Duration::from_secs(1), None, tx)?; + + debouncer.watcher().watch( + config.manifest_path().parent().unwrap().as_std_path(), + RecursiveMode::Recursive, + )?; + let name = self.name.clone(); + let mut previous_manifest: Option = Option::None; + let result = build(&mut context); + let env_metadata = context.dojo_metadata.as_ref().and_then(|e| e.env.clone()); + + let Some((mut world_address, account)) = context + .ws + .config() + .tokio_handle() + .block_on(migration::setup_env( + self.account, + self.starknet, + self.world, + env_metadata.as_ref(), + config, + name.as_ref(), + )) + .ok() + else { + return Err(anyhow!("Failed to setup environment")); + }; + + match context.ws.config().tokio_handle().block_on(migrate( + world_address, + &account, + name.clone(), + &context.ws, + previous_manifest.clone(), + )) { + Ok((manifest, address)) => { + previous_manifest = Some(manifest); + world_address = address; + } + Err(error) => { + log::error!("Error: {error:?}"); + } + } + loop { + let action = match rx.recv() { + Ok(Ok(events)) => events + .iter() + .map(|event| process_event(event, &mut context)) + .last() + .unwrap_or(DevAction::None), + Ok(Err(_)) => DevAction::None, + Err(error) => { + log::error!("Error: {error:?}"); + break; + } + }; + + if action != DevAction::None && build(&mut context).is_ok() { + match context.ws.config().tokio_handle().block_on(migrate( + world_address, + &account, + name.clone(), + &context.ws, + previous_manifest.clone(), + )) { + Ok((manifest, address)) => { + previous_manifest = Some(manifest); + world_address = address; + } + Err(error) => { + log::error!("Error: {error:?}"); + } + } + } + } + result + } +} diff --git a/crates/sozo/src/commands/mod.rs b/crates/sozo/src/commands/mod.rs index c4e9b7c4f5..9d3ce0dbd7 100644 --- a/crates/sozo/src/commands/mod.rs +++ b/crates/sozo/src/commands/mod.rs @@ -7,6 +7,7 @@ pub(crate) mod auth; pub(crate) mod build; pub(crate) mod completions; pub(crate) mod component; +pub(crate) mod dev; pub(crate) mod events; pub(crate) mod execute; pub(crate) mod init; @@ -16,13 +17,16 @@ pub(crate) mod register; pub(crate) mod system; pub(crate) mod test; +// copy of non pub functions from scarb +pub(crate) mod scarb_internal; + pub fn run(command: Commands, config: &Config) -> Result<()> { match command { Commands::Init(args) => args.run(config), Commands::Test(args) => args.run(config), Commands::Build(args) => args.run(config), Commands::Migrate(args) => args.run(config), - + Commands::Dev(args) => args.run(config), Commands::Auth(args) => args.run(config), Commands::Execute(args) => args.run(config), Commands::Component(args) => args.run(config), diff --git a/crates/sozo/src/commands/scarb_internal/mod.rs b/crates/sozo/src/commands/scarb_internal/mod.rs new file mode 100644 index 0000000000..6f216c16eb --- /dev/null +++ b/crates/sozo/src/commands/scarb_internal/mod.rs @@ -0,0 +1,55 @@ +// I have copied source code from https://github.com/software-mansion/scarb/blob/main/scarb/src/compiler/db.rs +// since build_scarb_root_database is not public +// +// NOTE: This files needs to be updated whenever scarb version is updated +use anyhow::Result; +use cairo_lang_compiler::db::RootDatabase; +use cairo_lang_compiler::project::{ProjectConfig, ProjectConfigContent}; +use cairo_lang_filesystem::ids::Directory; +use scarb::compiler::CompilationUnit; +use scarb::core::Workspace; +use tracing::trace; + +// TODO(mkaput): ScarbDatabase? +pub(crate) fn build_scarb_root_database( + unit: &CompilationUnit, + ws: &Workspace<'_>, +) -> Result { + let mut b = RootDatabase::builder(); + b.with_project_config(build_project_config(unit)?); + b.with_cfg(unit.cfg_set.clone()); + + for plugin_info in &unit.cairo_plugins { + let package_id = plugin_info.package.id; + let plugin = ws.config().cairo_plugins().fetch(package_id)?; + let instance = plugin.instantiate()?; + for macro_plugin in instance.macro_plugins() { + b.with_macro_plugin(macro_plugin); + } + for (name, inline_macro_plugin) in instance.inline_macro_plugins() { + b.with_inline_macro_plugin(&name, inline_macro_plugin); + } + } + + b.build() +} + +fn build_project_config(unit: &CompilationUnit) -> Result { + let crate_roots = unit + .components + .iter() + .filter(|component| !component.package.id.is_core()) + .map(|component| (component.cairo_package_name(), component.target.source_root().into())) + .collect(); + + let corelib = Some(Directory::Real(unit.core_package_component().target.source_root().into())); + + let content = ProjectConfigContent { crate_roots }; + + let project_config = + ProjectConfig { base_path: unit.main_component().package.root().into(), corelib, content }; + + trace!(?project_config); + + Ok(project_config) +} diff --git a/crates/sozo/src/main.rs b/crates/sozo/src/main.rs index 290b8af897..b21d47e172 100644 --- a/crates/sozo/src/main.rs +++ b/crates/sozo/src/main.rs @@ -30,8 +30,9 @@ fn cli_main(args: SozoArgs) -> Result<()> { let mut compilers = CompilerRepository::std(); let cairo_plugins = CairoPluginRepository::new(); - if let Commands::Build(_) = &args.command { - compilers.add(Box::new(DojoCompiler)).unwrap(); + match &args.command { + Commands::Build(_) | Commands::Dev(_) => compilers.add(Box::new(DojoCompiler)).unwrap(), + _ => {} } let manifest_path = scarb::ops::find_manifest_path(args.manifest_path.as_deref())?; diff --git a/crates/sozo/src/ops/migration/mod.rs b/crates/sozo/src/ops/migration/mod.rs index 8b30381fdc..2c790f6282 100644 --- a/crates/sozo/src/ops/migration/mod.rs +++ b/crates/sozo/src/ops/migration/mod.rs @@ -65,41 +65,60 @@ where if total_diffs == 0 { config.ui().print("\nāœØ No changes to be made. Remote World is already up to date!") } else { - // Prepare migration strategy based on the diff. + // Mirate according to the diff. + apply_diff(target_dir, diff, name, world_address, &account, config, Some(args.transaction)) + .await?; + } - let strategy = prepare_migration(target_dir, diff, name, world_address, config)?; + Ok(()) +} - println!(" "); +pub(crate) async fn apply_diff( + target_dir: U, + diff: WorldDiff, + name: Option, + world_address: Option, + account: &SingleOwnerAccount, + config: &Config, + txn_config: Option, +) -> Result +where + U: AsRef, + P: Provider + Sync + Send + 'static, + S: Signer + Sync + Send + 'static, +{ + let strategy = prepare_migration(target_dir, diff, name, world_address, config)?; - let block_height = execute_strategy(&strategy, &account, config, Some(args.transaction)) - .await - .map_err(|e| anyhow!(e)) - .with_context(|| "Problem trying to migrate.")?; - - if let Some(block_height) = block_height { - config.ui().print(format!( - "\nšŸŽ‰ Successfully migrated World on block #{} at address {}", - block_height, - bold_message(format!( - "{:#x}", - strategy.world_address().expect("world address must exist") - )) - )); - } else { - config.ui().print(format!( - "\nšŸŽ‰ Successfully migrated World at address {}", - bold_message(format!( - "{:#x}", - strategy.world_address().expect("world address must exist") - )) - )); - } + println!(" "); + + let block_height = execute_strategy(&strategy, account, config, txn_config) + .await + .map_err(|e| anyhow!(e)) + .with_context(|| "Problem trying to migrate.")?; + + if let Some(block_height) = block_height { + config.ui().print(format!( + "\nšŸŽ‰ Successfully migrated World on block #{} at address {}", + block_height, + bold_message(format!( + "{:#x}", + strategy.world_address().expect("world address must exist") + )) + )); + } else { + config.ui().print(format!( + "\nšŸŽ‰ Successfully migrated World at address {}", + bold_message(format!( + "{:#x}", + strategy.world_address().expect("world address must exist") + )) + )); } - Ok(()) + strategy.world_address() } -async fn setup_env( +pub(crate) async fn setup_env( account: AccountOptions, starknet: StarknetOptions, world: WorldOptions,