diff --git a/.github/workflows/ci-cargo-odra.yml b/.github/workflows/ci-cargo-odra.yml index 63b18de..6c8fee9 100644 --- a/.github/workflows/ci-cargo-odra.yml +++ b/.github/workflows/ci-cargo-odra.yml @@ -32,5 +32,7 @@ jobs: - run: just prepare - run: just check-lint - run: just install - - run: just test-project-generation-on-stable-odra - run: just test-project-generation-on-future-odra + - run: just test-workspace-generation-on-future-odra +# - run: just test-project-generation-on-stable-odra +# - run: just test-workspace-generation-on-stable-odra diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..528a2dc --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2451 @@ +# 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 = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "const-random", + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "aligned" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80a21b9440a626c7fc8573a9e3d3a06b75c7c97754c2949bc7857b90353ca655" +dependencies = [ + "as-slice", +] + +[[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.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "anymap2" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" + +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "btoi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" +dependencies = [ + "num-traits", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "cargo-generate" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b2f627381dc7523340c606559dddf6083cb2e6134368381da5778638f906d8" +dependencies = [ + "anyhow", + "clap", + "console", + "dialoguer", + "env_logger", + "git2", + "gix-config", + "heck", + "home", + "ignore", + "indicatif", + "liquid", + "liquid-core", + "liquid-derive", + "liquid-lib", + "log", + "names", + "paste", + "path-absolutize", + "regex", + "remove_dir_all", + "rhai", + "sanitize-filename", + "semver", + "serde", + "tempfile", + "thiserror", + "toml", + "walkdir", +] + +[[package]] +name = "cargo-odra" +version = "0.1.0" +dependencies = [ + "cargo-generate", + "cargo_toml", + "chrono", + "clap", + "clap_complete_command", + "convert_case", + "glob", + "prettycli", + "regex", + "rm_rf", + "serde", + "serde_derive", + "thiserror", + "toml", + "ureq", +] + +[[package]] +name = "cargo_toml" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "599aa35200ffff8f04c1925aa1acc92fa2e08874379ef42e210a80e527e60838" +dependencies = [ + "serde", + "toml", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[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.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "clap" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +dependencies = [ + "anstream", + "anstyle", + "bitflags 1.3.2", + "clap_lex", + "once_cell", + "strsim", +] + +[[package]] +name = "clap_complete" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc443334c81a804575546c5a8a79b4913b50e28d69232903604cada1de817ce" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_complete_command" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183495371ea78d4c9ff638bfc6497d46fed2396e4f9c50aebc1278a4a9919a3d" +dependencies = [ + "clap", + "clap_complete", + "clap_complete_fig", + "clap_complete_nushell", +] + +[[package]] +name = "clap_complete_fig" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99fee1d30a51305a6c2ed3fc5709be3c8af626c9c958e04dd9ae94e27bcbce9f" +dependencies = [ + "clap", + "clap_complete", +] + +[[package]] +name = "clap_complete_nushell" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d02bc8b1a18ee47c4d2eec3fb5ac034dc68ebea6125b1509e9ccdffcddce66e" +dependencies = [ + "clap", + "clap_complete", +] + +[[package]] +name = "clap_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.25", +] + +[[package]] +name = "clap_lex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.45.0", +] + +[[package]] +name = "const-random" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e" +dependencies = [ + "const-random-macro", + "proc-macro-hack", +] + +[[package]] +name = "const-random-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb" +dependencies = [ + "getrandom", + "once_cell", + "proc-macro-hack", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cvt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ae9bf77fbf2d39ef573205d554d87e86c12f1994e9ea335b0651b9b278bcf1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "dialoguer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" +dependencies = [ + "console", + "shell-words", + "tempfile", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_at" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15550ecca96ea332ec143fb450701074143b70d358e50b32b1f847ccff2e1cf7" +dependencies = [ + "aligned", + "cfg-if", + "cvt", + "libc", + "nix", + "windows-sys 0.48.0", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "git2" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044" +dependencies = [ + "bitflags 1.3.2", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + +[[package]] +name = "gix-actor" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc22b0cdc52237667c301dd7cdc6ead8f8f73c9f824e9942c8ebd6b764f6c0bf" +dependencies = [ + "bstr", + "btoi", + "gix-date", + "itoa", + "nom", + "thiserror", +] + +[[package]] +name = "gix-config" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fbad5ce54a8fc997acc50febd89ec80fa6e97cb7f8d0654cb229936407489d8" +dependencies = [ + "bstr", + "gix-config-value", + "gix-features 0.28.1", + "gix-glob", + "gix-path", + "gix-ref", + "gix-sec", + "log", + "memchr", + "nom", + "once_cell", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "gix-config-value" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d09154c0c8677e4da0ec35e896f56ee3e338e741b9599fae06075edd83a4081c" +dependencies = [ + "bitflags 1.3.2", + "bstr", + "gix-path", + "libc", + "thiserror", +] + +[[package]] +name = "gix-date" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96271912ce39822501616f177dea7218784e6c63be90d5f36322ff3a722aae2" +dependencies = [ + "bstr", + "itoa", + "thiserror", + "time 0.3.23", +] + +[[package]] +name = "gix-features" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b76f9a80f6dd7be66442ae86e1f534effad9546676a392acc95e269d0c21c22" +dependencies = [ + "gix-hash 0.10.4", + "libc", + "sha1_smol", + "walkdir", +] + +[[package]] +name = "gix-features" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf69b0f5c701cc3ae22d3204b671907668f6437ca88862d355eaf9bc47a4f897" +dependencies = [ + "gix-hash 0.11.3", + "libc", +] + +[[package]] +name = "gix-fs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b37a1832f691fdc09910bd267f9a2e413737c1f9ec68c6e31f9e802616278a9" +dependencies = [ + "gix-features 0.29.0", +] + +[[package]] +name = "gix-glob" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e43efd776bc543f46f0fd0ca3d920c37af71a764a16f2aebd89765e9ff2993" +dependencies = [ + "bitflags 1.3.2", + "bstr", +] + +[[package]] +name = "gix-hash" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a258595457bc192d1f1c59d0d168a1e34e2be9b97a614e14995416185de41a7" +dependencies = [ + "hex", + "thiserror", +] + +[[package]] +name = "gix-hash" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0dd58cdbe7ffa4032fc111864c80d5f8cecd9a2c9736c97ae7e5be834188272" +dependencies = [ + "hex", + "thiserror", +] + +[[package]] +name = "gix-lock" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c693d7f05730fa74a7c467150adc7cea393518410c65f0672f80226b8111555" +dependencies = [ + "gix-tempfile", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-object" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df068db9180ee935fbb70504848369e270bdcb576b05c0faa8b9fd3b86fc017" +dependencies = [ + "bstr", + "btoi", + "gix-actor", + "gix-features 0.28.1", + "gix-hash 0.10.4", + "gix-validate", + "hex", + "itoa", + "nom", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-path" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32370dce200bb951df013e03dff35b4233fc7a89458642b047629b91734a7e19" +dependencies = [ + "bstr", + "thiserror", +] + +[[package]] +name = "gix-ref" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e909396ed3b176823991ccc391c276ae2a015e54edaafa3566d35123cfac9d" +dependencies = [ + "gix-actor", + "gix-features 0.28.1", + "gix-hash 0.10.4", + "gix-lock", + "gix-object", + "gix-path", + "gix-tempfile", + "gix-validate", + "memmap2", + "nom", + "thiserror", +] + +[[package]] +name = "gix-sec" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8ffa5bf0772f9b01de501c035b6b084cf9b8bb07dec41e3afc6a17336a65f47" +dependencies = [ + "bitflags 1.3.2", + "dirs", + "gix-path", + "libc", + "windows 0.43.0", +] + +[[package]] +name = "gix-tempfile" +version = "5.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71a0d32f34e71e86586124225caefd78dabc605d0486de580d717653addf182" +dependencies = [ + "gix-fs", + "libc", + "once_cell", + "parking_lot", + "tempfile", +] + +[[package]] +name = "gix-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7058c94f4164fcf5b8457d35f6d8f6e1007f9f7f938c9c7684a7e01d23c6ddde" +dependencies = [ + "fastrand 2.0.0", +] + +[[package]] +name = "gix-validate" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d092b594c8af00a3a31fe526d363ee8a51a6f29d8496cdb991ed2f01ec0ec13" +dependencies = [ + "bstr", + "thiserror", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "globset" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +dependencies = [ + "aho-corasick 0.7.20", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows 0.48.0", +] + +[[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 = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indicatif" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix 0.38.4", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kstring" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +dependencies = [ + "serde", + "static_assertions", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libgit2-sys" +version = "0.15.2+1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a80df2e11fb4a61f4ba2ab42dbe7f74468da143f1a75c74e11dee7c813f694fa" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "libssh2-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + +[[package]] +name = "liquid" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f68ae1011499ae2ef879f631891f21c78e309755f4a5e483c4a8f12e10b609" +dependencies = [ + "doc-comment", + "liquid-core", + "liquid-derive", + "liquid-lib", + "serde", +] + +[[package]] +name = "liquid-core" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e0724dfcaad5cfb7965ea0f178ca0870b8d7315178f4a7179f5696f7f04d5f" +dependencies = [ + "anymap2", + "itertools", + "kstring", + "liquid-derive", + "num-traits", + "pest", + "pest_derive", + "regex", + "serde", + "time 0.3.23", +] + +[[package]] +name = "liquid-derive" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2fb41a9bb4257a3803154bdf7e2df7d45197d1941c9b1a90ad815231630721" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.25", +] + +[[package]] +name = "liquid-lib" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2a17e273a6fb1fb6268f7a5867ddfd0bd4683c7e19b51084f3d567fad4348c0" +dependencies = [ + "itertools", + "liquid-core", + "once_cell", + "percent-encoding", + "regex", + "time 0.3.23", + "unicode-segmentation", +] + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "names" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" +dependencies = [ + "rand", +] + +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "static_assertions", +] + +[[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 = "normpath" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec", + "windows-targets 0.48.1", +] + +[[package]] +name = "paste" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" + +[[package]] +name = "path-absolutize" +version = "3.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1d4993b16f7325d90c18c3c6a3327db7808752db8d208cea0acee0abd52c52" +dependencies = [ + "path-dedot", +] + +[[package]] +name = "path-dedot" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d55e486337acb9973cdea3ec5638c1b3bcb22e573b2b7b41969e0c744d5a15e" +dependencies = [ + "once_cell", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef623c9bbfa0eedf5a0efba11a5ee83209c326653ca31ff019bec3a95bfff2b" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.25", +] + +[[package]] +name = "pest_meta" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01f71cb40bd8bb94232df14b946909e14660e33fc05db3e50ae2a82d7ea0ca0" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "portable-atomic" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d220334a184db82b31b83f5ff093e3315280fb2b6bbc032022b2304a509aab7a" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettycli" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c473f9468f75c869dcab128d9acbafe12a0b1b5f11d9bcc990b219fd83f47d" + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +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 = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +dependencies = [ + "aho-corasick 1.0.2", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "remove_dir_all" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23895cfadc1917fed9c6ed76a8c2903615fa3704f7493ff82b364c6540acc02b" +dependencies = [ + "aligned", + "cfg-if", + "cvt", + "fs_at", + "lazy_static", + "libc", + "normpath", + "windows-sys 0.45.0", +] + +[[package]] +name = "rhai" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd29fa1f740be6dc91982013957e08c3c4232d7efcfe19e12da87d50bad47758" +dependencies = [ + "ahash", + "bitflags 1.3.2", + "instant", + "num-traits", + "rhai_codegen", + "smallvec", + "smartstring", +] + +[[package]] +name = "rhai_codegen" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db74e3fdd29d969a0ec1f8e79171a6f0f71d0429293656901db382d248c4c021" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rm_rf" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3443b7a35aa12ed2e99edfc0ecbefe6a53b4848305cc83e29981dfa1aea1f71e" +dependencies = [ + "stacker", +] + +[[package]] +name = "rustix" +version = "0.37.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.1", + "sct", +] + +[[package]] +name = "rustls-webpki" +version = "0.100.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" + +[[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 = "sanitize-filename" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.25", +] + +[[package]] +name = "serde_json" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand 1.9.0", + "redox_syscall 0.3.5", + "rustix 0.37.23", + "windows-sys 0.45.0", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.25", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "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.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +dependencies = [ + "itoa", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-bom" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63ec69f541d875b783ca40184d655f2927c95f0bffd486faa83cd3ac3529ec32" + +[[package]] +name = "unicode-ident" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "ureq" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" +dependencies = [ + "base64", + "flate2", + "log", + "once_cell", + "rustls", + "rustls-webpki 0.100.1", + "serde", + "serde_json", + "url", + "webpki-roots", +] + +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.25", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.25", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +dependencies = [ + "rustls-webpki 0.100.1", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[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" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" +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" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.1", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.1", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +dependencies = [ + "memchr", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/Cargo.toml b/Cargo.toml index 9785bef..aa9158c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,9 @@ license = "MIT" repository = "https://github.com/odradev/cargo-odra" description = "A cargo utility that helps to create, manage and test your smart contracts written using Odra framework." keywords = ["wasm", "webassembly", "blockchain"] -categories = ["wasm", "smart contracts"] +categories = ["wasm", "development-tools::cargo-plugins"] name = "cargo-odra" -version = "0.0.10" +version = "0.1.0" edition = "2021" [dependencies] diff --git a/justfile b/justfile index 2a48845..8b3fdff 100644 --- a/justfile +++ b/justfile @@ -1,4 +1,4 @@ -DEVELOPMENT_ODRA_BRANCH := "release/0.7.1" +DEVELOPMENT_ODRA_BRANCH := "release/0.8.0" default: just --list @@ -20,14 +20,30 @@ test-project-generation-on-future-odra: cargo odra new --name testproject --source {{DEVELOPMENT_ODRA_BRANCH}} just test-testproject +test-workspace-generation-on-stable-odra: + rm -rf testproject + cargo odra new --name testproject --template workspace + just test-workspace-project + +test-workspace-generation-on-future-odra: + rm -rf testproject + cargo odra new --name testproject --template workspace --source {{DEVELOPMENT_ODRA_BRANCH}} + just test-workspace-project + test-testproject: cd testproject && rustup target add wasm32-unknown-unknown - cd testproject && rustup component add rustfmt --toolchain nightly-2023-03-01-x86_64-unknown-linux-gnu cd testproject && cargo odra generate -c plascoin cd testproject && cargo odra test cd testproject && cargo odra test -b casper cd testproject && cargo odra clean +test-workspace-project: + cd testproject && rustup target add wasm32-unknown-unknown + cd testproject && cargo odra generate -c plascoin -m flipper + cd testproject && cargo odra test + cd testproject && cargo odra test -b casper + cd testproject && cargo odra clean + clippy: cargo clippy --all-targets -- -D warnings diff --git a/src/actions.rs b/src/actions.rs index 9767cf2..b851358 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -4,5 +4,7 @@ pub mod build; pub mod clean; pub mod generate; pub mod init; +pub mod schema; pub mod test; pub mod update; +mod utils; diff --git a/src/actions/build.rs b/src/actions/build.rs index eebc6a3..3c501e7 100644 --- a/src/actions/build.rs +++ b/src/actions/build.rs @@ -1,271 +1,92 @@ -//! Module for managing and building backends. +//! Module for managing and building wasm files. -use std::path::Path; - -use cargo_toml::{Dependency, DependencyDetail, DepsSet}; - -use crate::{ - cargo_toml::odra_dependency, - command, - consts::ODRA_TEMPLATE_GH_RAW_REPO, - errors::Error, - log, - odra_toml::Contract, - paths::{self, BuilderPaths}, - project::Project, - template::TemplateGenerator, -}; +use super::utils; +use crate::{command, errors::Error, log, paths, project::Project}; /// BuildAction configuration. pub struct BuildAction<'a> { - backend: String, contracts_names: Option, - builder_paths: BuilderPaths, project: &'a Project, - template_generator: TemplateGenerator, } /// BuildAction implementation. impl<'a> BuildAction<'a> { /// Crate a new BuildAction for a given backend. - pub fn new(project: &'a Project, backend: String, contracts_names: Option) -> Self { + pub fn new(project: &'a Project, contracts_names: Option) -> Self { BuildAction { - backend: backend.clone(), contracts_names, - builder_paths: BuilderPaths::new(backend, project.project_root.clone()), project, - template_generator: TemplateGenerator::new( - ODRA_TEMPLATE_GH_RAW_REPO.to_string(), - project.project_odra_location(), - ), } } } impl BuildAction<'_> { - /// Returns the name of the backend. - /// It is also the name of the Odra's feature. - pub fn backend_name(&self) -> String { - self.backend.clone() - } - - /// Returns a set of dependencies used by backend. - pub fn builder_dependencies(&self) -> DepsSet { - let mut dependencies = DepsSet::new(); - dependencies.insert(String::from("odra"), self.odra_dependency()); - self.project.members.iter().for_each(|member| { - dependencies.insert(member.name.clone(), self.project_dependency(&member.root)); - }); - dependencies - } - /// Main function that runs the whole workflow for a backend. pub fn build(&self) { - self.check_target_requirements(); - self.validate_contract_name_argument(); - self.prepare_builder(); - self.build_wasm_sources(); - self.format_builder_files(); + utils::check_target_requirements(); + utils::validate_contract_name_argument(self.project, self.contracts_names()); self.build_wasm_files(); - self.copy_wasm_files(); self.optimize_wasm_files(); } - /// Returns list of contract to process. - fn contracts(&self) -> Vec { - let names = self.parse_contracts_names(); - let odra_toml = self.project.odra_toml(); - match names.is_empty() { - true => odra_toml.contracts, - false => odra_toml - .contracts - .into_iter() - .filter(|c| names.contains(&c.name)) - .collect(), - } - } - - /// Check if wasm32-unknown-unknown target is installed. - fn check_target_requirements(&self) { - if !command::command_output("rustup target list --installed") - .contains("wasm32-unknown-unknown") - { - Error::WasmTargetNotInstalled.print_and_die(); - } - } - - /// Check if contract name argument is valid if set. - fn validate_contract_name_argument(&self) { - let names = self.parse_contracts_names(); - names.iter().for_each(|contract_name| { - if !self - .project - .odra_toml() - .contracts - .iter() - .any(|c| c.name == *contract_name) - { - Error::ContractNotFound(contract_name.clone()).print_and_die(); - } - }); - } - - /// Prepare builder directories and all files. - fn prepare_builder(&self) { - log::info(format!( - "Preparing {} builder in {} directory...", - self.backend_name(), - self.builder_paths.root().display() - )); - - command::mkdir(self.builder_paths.src()); - - // Build Cargo.toml - crate::cargo_toml::builder_cargo_toml( - &self.builder_paths, - self.builder_dependencies(), - self.contracts(), - ); - - // Build files. - self.create_build_file() - .unwrap_or_else(|err| err.print_and_die()); - } - - /// Prepare contracts_build.rs files. - fn create_build_file(&self) -> Result<(), Error> { - let path = self.builder_paths.wasm_build(); - if path.exists() { - return Ok(()); - } - - let contracts_names: Vec<_> = self - .project - .odra_toml() - .contracts - .iter() - .map(|contract| (contract.fqn.to_owned(), contract.name.to_owned())) - .collect(); - - let content = self - .template_generator - .wasm_source_builder(contracts_names, &self.backend_name())?; - - command::write_to_file(path, &content); - Ok(()) - } - - /// Prepare _wasm.rs file. - fn build_wasm_sources(&self) { - log::info("Generating _wasm.rs files..."); - let names = self - .contracts() - .iter() - .map(|c| c.name.to_owned()) - .collect::>(); - command::cargo_build_wasm_sources(self.builder_paths.root(), &names); - } - - /// Build _wasm.rs files into .wasm files. + /// Build .wasm files. fn build_wasm_files(&self) { log::info("Generating wasm files..."); - for contract in self.contracts() { - command::cargo_build_wasm_files(self.builder_paths.root(), &contract.name); - } - } - - /// Copy *.wasm files into wasm directory. - fn copy_wasm_files(&self) { - log::info("Copying wasm files..."); command::mkdir(paths::wasm_dir(self.project.project_root())); - for contract in self.contracts() { - let source = paths::wasm_path_in_target(&contract.name, self.project.project_root()); - let target = paths::wasm_path_in_wasm_dir(&contract.name, self.project.project_root()); + + let contracts = + utils::contracts(self.project, self.contracts_names()).unwrap_or_else(|_| { + Error::FailedToParseArgument("contracts_names".to_string()).print_and_die() + }); + + for contract in contracts { + let build_contract = format!("{}_build_contract", &contract.crate_name()); + command::cargo_build_wasm_files( + self.project.project_root(), + &contract.struct_name(), + &contract.crate_name(), + ); + let source = paths::wasm_path_in_target(&build_contract, self.project.project_root()); + let target = + paths::wasm_path_in_wasm_dir(&contract.struct_name(), self.project.project_root()); log::info(format!("Saving {}", target.display())); - command::cp(source, target); + command::cp(source.clone(), target); + // if it's a workspace, copy the file also to the module wasm folder + if self.project.is_workspace() { + let module_wasm_dir = self + .project + .project_root() + .join(contract.crate_name()) + .join("wasm"); + command::mkdir(module_wasm_dir.clone()); + let mut module_wasm_path = module_wasm_dir.clone().join(&contract.struct_name()); + module_wasm_path.set_extension("wasm"); + log::info(format!("Copying to {}", module_wasm_path.display())); + command::cp(source, module_wasm_path); + } } } /// Run wasm-strip on *.wasm files in wasm directory. fn optimize_wasm_files(&self) { log::info("Optimizing wasm files..."); - for contract in self.contracts() { - command::wasm_strip(&contract.name, self.project.project_root()); - } - } - - /// Format Rust files in builder directory. - fn format_builder_files(&self) { - command::cargo_fmt(self.builder_paths.root()); - } - - /// Returns Odra dependency tailored for use by builder. - fn odra_dependency(&self) -> Dependency { - let first_member = self.project.members.first().unwrap(); - match odra_dependency(&first_member.cargo_toml) { - Dependency::Simple(simple) => Dependency::Detailed(DependencyDetail { - version: Some(simple), - ..Default::default() - }), - Dependency::Detailed(mut odra_details) => { - odra_details.features = vec![self.backend_name()]; - odra_details.default_features = false; - if odra_details.path.is_some() { - if self.project.is_workspace() { - odra_details.path = Some(odra_details.path.unwrap()); - } else { - odra_details.path = Some(format!("../{}", odra_details.path.unwrap())); - } - } - Dependency::Detailed(odra_details) - } - Dependency::Inherited(_) => { - Error::NotImplemented("Inherited dependencies are not supported yet.".to_string()) - .print_and_die(); + let contracts = + utils::contracts(self.project, self.contracts_names()).unwrap_or_else(|_| { + Error::FailedToParseArgument("contracts_names".to_string()).print_and_die() + }); + + for contract in contracts { + command::wasm_strip(&contract.struct_name(), self.project.project_root()); + if self.project.is_workspace() { + command::wasm_strip( + &contract.struct_name(), + self.project.project_root().join(contract.crate_name()), + ); } } } - /// Returns project dependency with specific backend feature enabled. - fn project_dependency(&self, location: &Path) -> Dependency { - Dependency::Detailed(DependencyDetail { - path: Some( - location - .to_path_buf() - .into_os_string() - .to_str() - .unwrap() - .to_string(), - ), - features: vec![self.backend_name()], - default_features: false, - ..Default::default() - }) + fn contracts_names(&self) -> String { + self.contracts_names.clone().unwrap_or_default() } - - fn parse_contracts_names(&self) -> Vec { - match &self.contracts_names { - Some(string) => remove_extra_spaces(string) - .map(|string| { - string - .split(' ') - .map(ToString::to_string) - .collect::>() - }) - .unwrap_or_else(|_| { - Error::FailedToParseArgument("contracts_names".to_string()).print_and_die() - }), - None => vec![], - } - } -} - -fn remove_extra_spaces(input: &str) -> Result { - // Ensure there are no other separators - if input.chars().any(|c| c.is_whitespace() && c != ' ') { - return Err("Input contains non-space whitespace characters"); - } - - let trimmed = input.split_whitespace().collect::>().join(" "); - Ok(trimmed) } diff --git a/src/actions/clean.rs b/src/actions/clean.rs index 3b617c3..0b6c9b2 100644 --- a/src/actions/clean.rs +++ b/src/actions/clean.rs @@ -1,24 +1,14 @@ //! Module responsible for cleaning Odra projects. -use std::path::PathBuf; +use crate::{command, project::Project}; -use crate::command; +/// Removes wasm folders, and runs `cargo clean`. +pub fn clean_action(project: &Project) { + project.members.iter().for_each(|member| { + command::rm_dir(member.root.join("wasm")); + }); -/// Removes wasm folder, .builder* folders and runs `cargo clean`. -pub fn clean_action(project_root: PathBuf) { - for folder in glob::glob(project_root.join("wasm/*").as_os_str().to_str().unwrap()) - .unwrap() - .flatten() - { - command::rm_dir(folder); - } + command::rm_dir(project.project_root().join("wasm")); - for folder in glob::glob(project_root.join(".builder*").as_os_str().to_str().unwrap()) - .unwrap() - .flatten() - { - command::rm_dir(folder); - } - - command::cargo_clean(project_root); + command::cargo_clean(project.project_root()); } diff --git a/src/actions/generate.rs b/src/actions/generate.rs index 498326e..5e4c02a 100644 --- a/src/actions/generate.rs +++ b/src/actions/generate.rs @@ -31,7 +31,7 @@ impl<'a> GenerateAction<'a> { pub fn new(project: &'a Project, contract_name: String, module_name: Option) -> Self { GenerateAction { project, - contract_name: paths::to_snake_case(&contract_name), + contract_name: contract_name.clone(), contract_module_ident: contract_name.to_case(Case::UpperCamel), module_root: project.module_root(module_name.clone()), module_name: project.module_name(module_name), @@ -58,8 +58,13 @@ impl GenerateAction<'_> { } /// Returns the module identifier. It is the struct name. - fn module_ident(&self) -> &str { - &self.contract_module_ident + fn module_ident(&self) -> String { + let contract_name = self.contract_name(); + contract_name.to_case(Case::UpperCamel) + } + + fn contract_snake_case(&self) -> String { + paths::to_snake_case(self.contract_name()) } /// Returns the module Ref identifier. @@ -71,7 +76,7 @@ impl GenerateAction<'_> { fn module_file_path(&self) -> PathBuf { self.module_root .join("src") - .join(self.contract_name()) + .join(self.contract_snake_case()) .with_extension("rs") } @@ -80,7 +85,7 @@ impl GenerateAction<'_> { // Rename module name. let contract_body = self .template_generator - .module_template(self.module_ident()) + .module_template(&self.module_ident()) .unwrap_or_else(|err| err.print_and_die()); // Make sure the file do not exists. @@ -98,7 +103,7 @@ impl GenerateAction<'_> { // Prepare code to add. let register_module_code = self .template_generator - .register_module_snippet(self.contract_name(), self.module_ident()) + .register_module_snippet(&self.contract_snake_case(), &self.module_ident()) .unwrap_or_else(|err| err.print_and_die()); // Read the file. @@ -113,7 +118,7 @@ impl GenerateAction<'_> { // Check if he file might have the module registered in another form. if lib_rs.contains(self.contract_name()) - || (lib_rs.contains(self.module_ident()) && lib_rs.contains(&self.module_ref_ident())) + || (lib_rs.contains(&self.module_ident()) && lib_rs.contains(&self.module_ref_ident())) { log::warn(format!( "src/lib.rs probably already has {} enabled. Skipping.", @@ -132,21 +137,20 @@ impl GenerateAction<'_> { /// Add contract definition to Odra.toml. fn update_odra_toml(&self) { let mut odra_toml = self.project.odra_toml(); - let contract_name = self.contract_name(); + let contract_name = self.module_ident(); // Check if Odra.toml has already a contract. - let exists = odra_toml.has_contract(contract_name); + let exists = odra_toml.has_contract(contract_name.as_str()); if exists { - Error::ContractAlreadyInOdraToml(String::from(contract_name)).print_and_die(); + Error::ContractAlreadyInOdraToml(contract_name).print_and_die(); } // Add contract to Odra.toml. odra_toml.contracts.push(Contract { - name: self.contract_name().to_string(), fqn: format!( "{}::{}::{}", self.module_name, - self.contract_name(), + self.module_ident(), self.module_ident() ), }); diff --git a/src/actions/init.rs b/src/actions/init.rs index 82f6bb1..05bc58d 100644 --- a/src/actions/init.rs +++ b/src/actions/init.rs @@ -2,18 +2,228 @@ use std::path::PathBuf; +use cargo_generate::{GenerateArgs, TemplatePath, Vcs}; +use cargo_toml::{Dependency, DependencyDetail}; +use chrono::Utc; +use ureq::serde_json; + +use crate::{ + cli::InitCommand, + command::replace_in_file, + consts::{ODRA_GITHUB_API_DATA, ODRA_TEMPLATE_GH_REPO}, + errors::Error, + log, + paths, + project::OdraLocation, +}; + /// InitAction configuration. #[derive(Clone)] -pub struct InitAction { - pub project_name: String, - pub generate: bool, - pub init: bool, - pub repo_uri: String, - pub source: Option, - pub workspace: bool, - pub template: String, - pub current_dir: PathBuf, -} +pub struct InitAction {} /// InitAction implementation. -impl InitAction {} +impl InitAction { + pub fn generate_project(init_command: InitCommand, current_dir: PathBuf, init: bool) { + if init { + Self::assert_dir_is_empty(current_dir.clone()); + } + + log::info("Generating a new project..."); + + let odra_location = Self::odra_location(init_command.source); + + let template_path = match odra_location.clone() { + OdraLocation::Local(local_path) => TemplatePath { + auto_path: Some(local_path.as_os_str().to_str().unwrap().to_string()), + subfolder: Some(format!("templates/{}", init_command.template)), + test: false, + git: None, + branch: None, + tag: None, + path: None, + favorite: None, + }, + OdraLocation::Remote(repo, branch) => TemplatePath { + auto_path: Some(repo), + subfolder: Some(format!("templates/{}", init_command.template)), + test: false, + git: None, + branch, + tag: None, + path: None, + favorite: None, + }, + OdraLocation::CratesIO(version) => TemplatePath { + auto_path: Some(ODRA_TEMPLATE_GH_REPO.to_string()), + subfolder: Some(format!("templates/{}", init_command.template)), + test: false, + git: None, + branch: Some(format!("release/{}", version)), + tag: None, + path: None, + favorite: None, + }, + }; + + cargo_generate::generate(GenerateArgs { + template_path, + list_favorites: false, + name: Some(paths::to_snake_case(&init_command.name)), + force: true, + verbose: false, + template_values_file: None, + silent: false, + config: None, + vcs: Some(Vcs::Git), + lib: false, + bin: false, + ssh_identity: None, + define: vec![format!("date={}", Utc::now().format("%Y-%m-%d"))], + init, + destination: None, + force_git_init: false, + allow_commands: false, + overwrite: false, + other_args: None, + }) + .unwrap_or_else(|e| { + Error::FailedToGenerateProjectFromTemplate(e.to_string()).print_and_die(); + }); + + let cargo_toml_path = match init { + true => { + let mut path = current_dir; + path.push("Cargo.toml"); + path + } + false => { + let mut path = current_dir; + path.push(paths::to_snake_case(&init_command.name)); + path.push("Cargo.toml"); + path + } + }; + + replace_in_file( + cargo_toml_path.clone(), + "#odra_dependency", + format!( + "odra = {{ {} }}", + toml::to_string(&Self::odra_project_dependency( + odra_location.clone(), + "odra", + init + )) + .unwrap() + .trim_end() + .replace('\n', ", ") + ) + .as_str(), + ); + + replace_in_file( + cargo_toml_path, + "#odra_test_dependency", + format!( + "odra-test = {{ {} }}", + toml::to_string(&Self::odra_project_dependency( + odra_location, + "odra-test", + init + )) + .unwrap() + .trim_end() + .replace('\n', ", ") + ) + .as_str(), + ); + + log::info("Done!"); + } + fn assert_dir_is_empty(dir: PathBuf) { + if dir.read_dir().unwrap().next().is_some() { + Error::CurrentDirIsNotEmpty.print_and_die(); + } + } + + fn odra_location(source: Option) -> OdraLocation { + let source = if let Some(source) = source { + source + } else { + Self::odra_latest_version() + }; + + // location on disk + let local = PathBuf::from(&source); + if local.exists() { + OdraLocation::Local(local) + } else { + // version + let version_regex = regex::Regex::new(r"^\d+\.\d+\.\d+$").unwrap(); + if version_regex.is_match(&source) { + OdraLocation::Remote( + ODRA_TEMPLATE_GH_REPO.to_string(), + Some(format!("release/{}", source)), + ) + } else { + // branch + OdraLocation::Remote(ODRA_TEMPLATE_GH_REPO.to_string(), Some(source)) + } + } + } + fn odra_latest_version() -> String { + let response: serde_json::Value = ureq::get(ODRA_GITHUB_API_DATA) + .call() + .unwrap_or_else(|_| { + Error::FailedToFetchTemplate(ODRA_GITHUB_API_DATA.to_string()).print_and_die() + }) + .into_json() + .unwrap_or_else(|_| { + Error::FailedToParseTemplate(ODRA_GITHUB_API_DATA.to_string()).print_and_die() + }); + response["tag_name"].as_str().unwrap().to_string() + } + + fn odra_project_dependency( + odra_location: OdraLocation, + crate_name: &str, + init: bool, + ) -> Dependency { + let (version, path, git, branch) = match odra_location { + OdraLocation::Local(path) => { + let path = match init { + true => path, + false => PathBuf::from("..").join(path), + }; + let path = path + .join(crate_name) + .into_os_string() + .to_str() + .unwrap() + .to_string(); + (None, Some(path), None, None) + } + OdraLocation::Remote(repo, branch) => match branch { + None => (Some(Self::odra_latest_version()), None, None, None), + Some(branch) => (None, None, Some(repo), Some(branch)), + }, + OdraLocation::CratesIO(version) => (Some(version), None, None, None), + }; + + Dependency::Detailed(DependencyDetail { + version, + registry: None, + registry_index: None, + path, + inherited: false, + git, + branch, + tag: None, + rev: None, + features: vec![], + optional: false, + default_features: false, + package: None, + }) + } +} diff --git a/src/actions/schema.rs b/src/actions/schema.rs new file mode 100644 index 0000000..243d10a --- /dev/null +++ b/src/actions/schema.rs @@ -0,0 +1,49 @@ +//! Module for generating contracts schema. + +use super::utils; +use crate::{command, errors::Error, log, project::Project}; + +/// SchemaAction configuration. +pub struct SchemaAction<'a> { + project: &'a Project, + contracts_names: Option, +} + +impl<'a> SchemaAction<'a> { + /// Crate a new SchemaAction for a given configuration. + pub fn new(project: &'a Project, contracts_names: Option) -> Self { + SchemaAction { + project, + contracts_names, + } + } +} + +impl SchemaAction<'_> { + /// Main function that runs the whole workflow. + pub fn build(&self) { + utils::check_target_requirements(); + utils::validate_contract_name_argument(self.project, self.contracts_names()); + self.generate_schema_files(); + } + + /// Generates *_schema.json files. + fn generate_schema_files(&self) { + log::info("Generating schema files..."); + let contracts = + utils::contracts(self.project, self.contracts_names()).unwrap_or_else(|_| { + Error::FailedToParseArgument("contracts_names".to_string()).print_and_die() + }); + for contract in contracts { + command::cargo_generate_schema_files( + self.project.project_root(), + &contract.struct_name(), + &contract.crate_name(), + ); + } + } + + fn contracts_names(&self) -> String { + self.contracts_names.clone().unwrap_or_default() + } +} diff --git a/src/actions/test.rs b/src/actions/test.rs index 2aa7702..8af9533 100644 --- a/src/actions/test.rs +++ b/src/actions/test.rs @@ -70,7 +70,7 @@ impl TestAction<'_> { /// Build *.wasm files before testing. fn build_wasm_files(&self) { - BuildAction::new(self.project, String::from(self.backend_name()), None).build(); + BuildAction::new(self.project, None).build(); log::info("Building finished.") } } diff --git a/src/actions/update.rs b/src/actions/update.rs index 7f379bf..70577b0 100644 --- a/src/actions/update.rs +++ b/src/actions/update.rs @@ -2,34 +2,11 @@ use std::path::PathBuf; -use crate::{cli::UpdateCommand, command, log, paths}; +use crate::{cli::UpdateCommand, command, log}; -/// Runs `cargo update` on project and backends in .builder* folders. -/// If backend is specified update will be made only in its folder. -pub fn update_action(update_command: UpdateCommand, project_root: PathBuf) { - if let Some(backend) = update_command.backend { - let builder_paths = paths::BuilderPaths::new(backend, project_root); - update_builder(builder_paths.root()); - } else { - update_all_builders(); - update_project(); - } -} - -/// Update a builder crate. -fn update_builder(builder: PathBuf) { - log::info(format!( - "Running cargo update for {} builder...", - builder.to_str().unwrap() - )); - command::cargo_update(builder); -} - -/// Update all builders. -fn update_all_builders() { - for builder_dir in glob::glob(".builder_*").unwrap().flatten() { - update_builder(builder_dir); - } +/// Runs `cargo update` on the project. +pub fn update_action(_update_command: UpdateCommand, _project_root: PathBuf) { + update_project(); } /// Update root project. diff --git a/src/actions/utils.rs b/src/actions/utils.rs new file mode 100644 index 0000000..164297d --- /dev/null +++ b/src/actions/utils.rs @@ -0,0 +1,60 @@ +use crate::{command, errors::Error, odra_toml::Contract, project::Project}; + +/// Check if wasm32-unknown-unknown target is installed. +pub fn check_target_requirements() { + if !command::command_output("rustup target list --installed").contains("wasm32-unknown-unknown") + { + Error::WasmTargetNotInstalled.print_and_die(); + } +} + +/// Returns list of contract to process. +pub fn contracts(project: &Project, names_string: String) -> Result, &'static str> { + let names = parse_contracts_names(names_string)?; + let odra_toml = project.odra_toml(); + Ok(match names.is_empty() { + true => odra_toml.contracts, + false => odra_toml + .contracts + .into_iter() + .filter(|c| names.contains(&c.struct_name())) + .collect(), + }) +} + +/// Check if contract name argument is valid if set. +pub fn validate_contract_name_argument(project: &Project, names_string: String) { + let names = parse_contracts_names(names_string).unwrap_or_default(); + names.iter().for_each(|contract_name| { + if !project + .odra_toml() + .contracts + .iter() + .any(|c| c.struct_name() == *contract_name) + { + Error::ContractNotFound(contract_name.clone()).print_and_die(); + } + }); +} + +fn remove_extra_spaces(input: &str) -> Result { + // Ensure there are no other separators + if input.chars().any(|c| c.is_whitespace() && c != ' ') { + return Err("Input contains non-space whitespace characters"); + } + + let trimmed = input.split_whitespace().collect::>().join(" "); + Ok(trimmed) +} + +fn parse_contracts_names(names_string: String) -> Result, &'static str> { + match names_string.is_empty() { + true => Ok(vec![]), + false => remove_extra_spaces(&names_string).map(|string| { + string + .split(' ') + .map(ToString::to_string) + .collect::>() + }), + } +} diff --git a/src/cargo_toml.rs b/src/cargo_toml.rs index f4b928b..3cff4af 100644 --- a/src/cargo_toml.rs +++ b/src/cargo_toml.rs @@ -1,86 +1,9 @@ //! Module containing functions used by Builder for managing its Cargo.toml file - use std::path::PathBuf; -use cargo_toml::{Dependency, DepsSet, Edition, FeatureSet, Manifest, Package, Product, Workspace}; - -use crate::{command, errors::Error, odra_toml::Contract, paths::BuilderPaths}; - -/// Builds and saves Cargo.toml file for backend. -pub fn builder_cargo_toml( - builder_paths: &BuilderPaths, - builder_deps: DepsSet, - contracts: Vec, -) { - let default_bin = Product { - test: false, - doctest: false, - bench: false, - doc: false, - edition: Edition::E2021, - ..Default::default() - }; - - let mut bins = vec![]; - let build_name = "contracts_build".to_string(); - let path = builder_paths.relative().wasm_build_as_string(); - - bins.push(Product { - path: Some(path), - name: Some(build_name), - ..default_bin.clone() - }); - for contract in contracts { - let path = builder_paths - .relative() - .wasm_source_as_string(&contract.name); - bins.push(Product { - path: Some(path), - name: Some(contract.name.clone()), - ..default_bin.clone() - }); - } - - #[allow(deprecated)] - let cargo_toml: Manifest = cargo_toml::Manifest { - package: Some(Package::new("builder".to_string(), "1.0.0".to_string())), - workspace: Some(Workspace { - members: vec![], - package: None, - default_members: vec![], - exclude: vec![], - metadata: None, - resolver: None, - dependencies: Default::default(), - }), - dependencies: builder_deps, - dev_dependencies: Default::default(), - build_dependencies: Default::default(), - target: Default::default(), - features: FeatureSet::new(), - patch: Default::default(), - lib: None, - profile: Default::default(), - badges: Default::default(), - bin: bins, - bench: vec![], - test: vec![], - example: vec![], - replace: Default::default(), - }; +use cargo_toml::Manifest; - let toml_content = toml::to_string_pretty(&cargo_toml).unwrap(); - command::write_to_file(builder_paths.cargo_toml(), &toml_content); -} - -/// Returns Dependency of Odra, taken from project's Cargo.toml. -pub fn odra_dependency(cargo_toml_path: &PathBuf) -> Dependency { - load_cargo_toml(cargo_toml_path) - .dependencies - .get("odra") - .unwrap_or_else(|| Error::OdraNotADependency.print_and_die()) - .clone() -} +use crate::errors::Error; /// Returns Cargo.toml as Manifest struct. pub fn load_cargo_toml(path: &PathBuf) -> Manifest { diff --git a/src/cli.rs b/src/cli.rs index a63f7db..f201187 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -5,7 +5,15 @@ use std::env; use clap::{CommandFactory, Parser, Subcommand}; use crate::{ - actions::{clean::clean_action, init::InitAction, update::update_action}, + actions::{ + build::BuildAction, + clean::clean_action, + generate::GenerateAction, + init::InitAction, + schema::SchemaAction, + test::TestAction, + update::update_action, + }, consts, errors::Error, project::Project, @@ -44,6 +52,8 @@ pub enum OdraSubcommand { Init(InitCommand), /// Builds the project, including backend and producing wasm files. Build(BuildCommand), + /// Generates schema for a given contract. + Schema(SchemaCommand), /// Runs test. Without the backend parameter, the tests will be run against Mock VM. Test(TestCommand), /// Generates boilerplate code for contracts. @@ -82,10 +92,14 @@ pub struct InitCommand { #[derive(clap::Args)] /// `cargo odra build` pub struct BuildCommand { - /// Name of the backend that will be used for the build process (e.g. casper). - #[clap(value_parser, long, short, value_parser = [consts::ODRA_CASPER_BACKEND])] - pub backend: String, + /// Contracts names separated by a space that matches the names in Odra.toml. + #[clap(value_parser, long, short)] + pub contracts_names: Option, +} +#[derive(clap::Args)] +/// `cargo odra schema` +pub struct SchemaCommand { /// Contracts names separated by a space that matches the names in Odra.toml. #[clap(value_parser, long, short)] pub contracts_names: Option, @@ -135,41 +149,27 @@ pub fn make_action() { .unwrap_or_else(|_| Error::CouldNotDetermineCurrentDirectory.print_and_die()); match args.subcommand { OdraSubcommand::Build(build) => { - Project::detect(current_dir).build(build.backend, build.contracts_names); + let project = Project::detect(current_dir); + BuildAction::new(&project, build.contracts_names).build(); } OdraSubcommand::Test(test) => { - Project::detect(current_dir).test(test); + let project = Project::detect(current_dir); + TestAction::new(&project, test.backend, test.args, test.skip_build).test(); } OdraSubcommand::Generate(generate) => { - Project::detect(current_dir).generate(generate); + let project = Project::detect(current_dir); + GenerateAction::new(&project, generate.contract_name, generate.module) + .generate_contract(); } OdraSubcommand::New(init) => { - Project::init(InitAction { - project_name: init.name, - generate: true, - init: false, - repo_uri: init.repo_uri, - source: init.source, - workspace: false, - template: init.template, - current_dir, - }); + InitAction::generate_project(init, current_dir, false); } OdraSubcommand::Init(init) => { - Project::init(InitAction { - project_name: init.name, - generate: true, - init: true, - repo_uri: init.repo_uri, - source: init.source, - workspace: false, - template: init.template, - current_dir, - }); + InitAction::generate_project(init, current_dir, true); } OdraSubcommand::Clean(_) => { let project = Project::detect(current_dir); - clean_action(project.project_root()); + clean_action(&project); } OdraSubcommand::Update(update) => { let project = Project::detect(current_dir); @@ -178,5 +178,9 @@ pub fn make_action() { OdraSubcommand::Completions { shell } => { shell.generate(&mut Cargo::command(), &mut std::io::stdout()); } + OdraSubcommand::Schema(schema) => { + let project = Project::detect(current_dir); + SchemaAction::new(&project, schema.contracts_names).build(); + } } } diff --git a/src/command.rs b/src/command.rs index 083231c..e3faa56 100644 --- a/src/command.rs +++ b/src/command.rs @@ -11,7 +11,13 @@ use std::{ use clap::Parser; use Error::InvalidInternalCommand; -use crate::{cli::Cargo, consts::ODRA_WASM_PATH_ENV_KEY, errors::Error, log, paths}; +use crate::{ + cli::Cargo, + consts::{ODRA_BACKEND_ENV_KEY, ODRA_MODULE_ENV_KEY}, + errors::Error, + log, + paths, +}; /// Returns output of a command as a String. pub fn command_output(command: &str) -> String { @@ -50,11 +56,6 @@ pub fn cp(source: PathBuf, target: PathBuf) { ); } -/// Creates a directory. -pub fn mkdir(path: PathBuf) { - fs::create_dir_all(path).unwrap(); -} - /// Remove a directory. pub fn rm_dir(path: PathBuf) { log::info(format!("Removing {}...", path.display())); @@ -64,6 +65,11 @@ pub fn rm_dir(path: PathBuf) { }; } +/// Creates a directory. +pub fn mkdir(path: PathBuf) { + fs::create_dir_all(path).unwrap(); +} + /// Runs wasm-strip. pub fn wasm_strip(contract_name: &str, project_root: PathBuf) { let command = Command::new("wasm-strip") @@ -103,7 +109,9 @@ fn cargo(current_dir: PathBuf, command: &str, tail_args: Vec<&str>) { } /// Build wasm files. -pub fn cargo_build_wasm_files(current_dir: PathBuf, contract_name: &str) { +pub fn cargo_build_wasm_files(current_dir: PathBuf, contract_name: &str, module_name: &str) { + env::set_var(ODRA_MODULE_ENV_KEY, contract_name); + let build_contract = format!("{}_build_contract", module_name); cargo( current_dir, "build", @@ -111,28 +119,17 @@ pub fn cargo_build_wasm_files(current_dir: PathBuf, contract_name: &str) { "--target", "wasm32-unknown-unknown", "--bin", - contract_name, + &build_contract, "--release", - "--no-default-features", - "--target-dir", - "../target", ], ); } -/// Build wasm sources. -pub fn cargo_build_wasm_sources(current_dir: PathBuf, contract_names: &[String]) { - let mut args = vec![ - "--bin", - "contracts_build", - "--release", - "--no-default-features", - "--target-dir", - "../target", - "--", - ]; - contract_names.iter().for_each(|name| args.push(name)); - cargo(current_dir, "run", args); +/// Build schema files. +pub fn cargo_generate_schema_files(current_dir: PathBuf, contract_name: &str, module_name: &str) { + env::set_var(ODRA_MODULE_ENV_KEY, contract_name); + let gen_schema = format!("{}_build_schema", module_name); + cargo(current_dir, "run", vec!["--bin", &gen_schema, "--release"]); } /// Update a cargo module. @@ -140,30 +137,21 @@ pub fn cargo_update(current_dir: PathBuf) { cargo(current_dir, "update", vec![]); } -/// Runs cargo fmt. -pub fn cargo_fmt(current_dir: PathBuf) { - cargo(current_dir, "fmt", vec![]); -} - /// Runs cargo test. -pub fn cargo_test_mock_vm(current_dir: PathBuf, args: Vec<&str>) { +pub fn cargo_test_mock_vm(current_dir: PathBuf, mut args: Vec<&str>) { log::info("Running cargo test..."); - cargo(current_dir, "test", args); + let mut tail_args = vec!["--lib"]; + tail_args.append(&mut args); + cargo(current_dir, "test", tail_args); } /// Runs cargo test with backend features. -pub fn cargo_test_backend(project_root: PathBuf, backend_name: &str, tail_args: Vec<&str>) { - env::set_var( - ODRA_WASM_PATH_ENV_KEY, - project_root.join("wasm").to_str().unwrap(), - ); +pub fn cargo_test_backend(project_root: PathBuf, backend_name: &str, mut args: Vec<&str>) { + env::set_var(ODRA_BACKEND_ENV_KEY, backend_name); log::info("Running cargo test..."); - let mut args = vec!["--no-default-features", "--features", backend_name]; - for arg in tail_args { - args.push(arg); - } - - cargo(project_root, "test", args) + let mut tail_args = vec!["--lib"]; + tail_args.append(&mut args); + cargo(project_root, "test", tail_args) } /// Runs cargo clean. diff --git a/src/consts.rs b/src/consts.rs index 65dae39..bc4c73a 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -3,6 +3,12 @@ /// Casper backend name. pub const ODRA_CASPER_BACKEND: &str = "casper"; +/// Odra backend env key +pub const ODRA_BACKEND_ENV_KEY: &str = "ODRA_BACKEND"; + +/// Odra module env key +pub const ODRA_MODULE_ENV_KEY: &str = "ODRA_MODULE"; + /// Template repository path. pub const ODRA_TEMPLATE_GH_REPO: &str = "https://github.com/odradev/odra.git"; @@ -14,18 +20,6 @@ pub const ODRA_GITHUB_API_DATA: &str = "https://api.github.com/repos/odradev/odr /// Default template name. pub const ODRA_TEMPLATE_DEFAULT_TEMPLATE: &str = "full"; -/// WASM Path -pub const ODRA_WASM_PATH_ENV_KEY: &str = "ODRA_WASM_PATH"; - -/// WASM Source builder template. -pub const WASM_SINGLE_SOURCE_BUILDER: &str = "contracts_builder/wasm_source_builder"; - -/// WASM Source builder helper template. -pub const MATCH_CONTRACT_NAME: &str = "contracts_builder/match_contract_name"; - -/// WASM Source builder helper template. -pub const GEN_CONTRACT_MOD: &str = "contracts_builder/gen_contract_mod"; - /// Module template. pub const MODULE_TEMPLATE: &str = "module"; diff --git a/src/errors.rs b/src/errors.rs index 1789e76..9c5afce 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -43,9 +43,6 @@ pub enum Error { #[error("Odra.toml not found at location {0}")] OdraTomlNotFound(PathBuf), - #[error("Not implemented: {0}")] - NotImplemented(String), - #[error("Failed to fetch template: {0}")] FailedToFetchTemplate(String), @@ -93,7 +90,6 @@ impl Error { Error::RemoveDirNotPossible(_) => 10, Error::ModuleNotFound(_) => 11, Error::OdraTomlNotFound(_) => 12, - Error::NotImplemented(_) => 13, Error::FailedToFetchTemplate(_) => 14, Error::FailedToParseTemplate(_) => 15, Error::CouldNotDetermineCurrentDirectory => 16, diff --git a/src/odra_toml.rs b/src/odra_toml.rs index 090ba45..6fa56c2 100644 --- a/src/odra_toml.rs +++ b/src/odra_toml.rs @@ -4,17 +4,36 @@ use std::path::{Path, PathBuf}; use serde_derive::{Deserialize, Serialize}; -use crate::{command, errors::Error}; +use crate::{ + command, + errors::{Error, Error::MalformedFqn}, +}; /// Struct describing contract. #[derive(Deserialize, Serialize, Debug, Clone)] pub struct Contract { - /// Name of the contract - pub name: String, - /// Fully Qualified Name of the contract struct pub fqn: String, } +impl Contract { + /// Extracts first part from fqn + pub fn crate_name(&self) -> String { + self.fqn + .split_terminator("::") + .next() + .unwrap_or_else(|| MalformedFqn.print_and_die()) + .to_string() + } + + pub fn struct_name(&self) -> String { + self.fqn + .split_terminator("::") + .last() + .unwrap_or_else(|| MalformedFqn.print_and_die()) + .to_string() + } +} + /// Odra configuration. #[derive(Deserialize, Serialize, Debug, Clone)] pub struct OdraToml { @@ -45,7 +64,9 @@ impl OdraToml { /// Check if the contract is defined in Odra.toml file. pub fn has_contract(&self, contract_name: &str) -> bool { - self.contracts.iter().any(|c| c.name == contract_name) + self.contracts + .iter() + .any(|c| c.struct_name() == contract_name) } /// Check if any contract in Odra.toml is a part of a module with given name diff --git a/src/paths.rs b/src/paths.rs index 31dbe75..ed86333 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -4,77 +4,6 @@ use std::path::PathBuf; use convert_case::{Boundary, Case, Casing}; -/// Helper struct that can produce builder releated paths. -/// By default all paths starts with .builder_*/. -pub struct BuilderPaths { - backend_name: String, - full: bool, - project_root: PathBuf, -} - -/// Implementation of BuilderPaths struct. -impl BuilderPaths { - /// Creates a new BuilderPath for a given backend. - pub fn new(backend_name: String, project_root: PathBuf) -> Self { - Self { - backend_name, - project_root, - full: true, - } - } - - /// Returns a new instance that produces paths without the .builder*/. - pub fn relative(&self) -> Self { - BuilderPaths { - backend_name: self.backend_name.clone(), - full: false, - project_root: Default::default(), - } - } - - /// Returns root directory of the builder. - pub fn root(&self) -> PathBuf { - if self.full { - self.project_root - .join(PathBuf::from(format!(".builder_{}", self.backend_name))) - } else { - self.project_root.join(PathBuf::new()) - } - } - - /// Returns Cargo.toml path of the builder. - pub fn cargo_toml(&self) -> PathBuf { - self.root().join("Cargo.toml") - } - - /// Returns src directory path of the builder. - pub fn src(&self) -> PathBuf { - self.root().join("src") - } - - pub fn wasm_build(&self) -> PathBuf { - self.src().join("contracts_build.rs") - } - - /// Returns contracts_build.rs path as a String. - pub fn wasm_build_as_string(&self) -> String { - self.wasm_build().into_os_string().into_string().unwrap() - } - - /// Returns *_wasm.rs path. - pub fn wasm_source(&self, contract_name: &str) -> PathBuf { - self.src().join(format!("{contract_name}_wasm.rs")) - } - - /// Returns *_wasm.rs path as a String. - pub fn wasm_source_as_string(&self, contract_name: &str) -> String { - self.wasm_source(contract_name) - .into_os_string() - .into_string() - .unwrap() - } -} - /// Returns *.wasm filename. pub fn wasm_file_name(contract_name: &str) -> PathBuf { PathBuf::from(contract_name).with_extension("wasm") diff --git a/src/project.rs b/src/project.rs index c278e90..9c8f146 100644 --- a/src/project.rs +++ b/src/project.rs @@ -3,21 +3,9 @@ use std::{ path::{Path, PathBuf}, }; -use cargo_generate::{GenerateArgs, TemplatePath, Vcs}; use cargo_toml::{Dependency, DependencyDetail}; -use chrono::Utc; -use ureq::serde_json; -use crate::{ - actions::{build::BuildAction, generate::GenerateAction, init::InitAction, test::TestAction}, - cargo_toml::load_cargo_toml, - cli::{GenerateCommand, TestCommand}, - command::replace_in_file, - consts::{ODRA_GITHUB_API_DATA, ODRA_TEMPLATE_GH_REPO}, - errors::Error, - odra_toml::OdraToml, - paths, -}; +use crate::{cargo_toml::load_cargo_toml, errors::Error, odra_toml::OdraToml}; /// Struct representing the whole project. #[derive(Debug, Clone)] @@ -35,107 +23,6 @@ pub struct Project { } impl Project { - /// Create a new Project. - pub fn init(init_action: InitAction) { - if init_action.generate { - Self::generate_project(init_action); - } - } - - /// Generates a new project. - pub fn generate_project(init_action: InitAction) { - if init_action.init { - Self::assert_dir_is_empty(init_action.current_dir.clone()); - } - - let odra_location = Self::odra_location(init_action.source); - - let template_path = match odra_location.clone() { - OdraLocation::Local(local_path) => TemplatePath { - auto_path: Some(local_path.as_os_str().to_str().unwrap().to_string()), - subfolder: Some(format!("templates/{}", init_action.template)), - test: false, - git: None, - branch: None, - tag: None, - path: None, - favorite: None, - }, - OdraLocation::Remote(repo, branch) => TemplatePath { - auto_path: Some(repo), - subfolder: Some(format!("templates/{}", init_action.template)), - test: false, - git: None, - branch, - tag: None, - path: None, - favorite: None, - }, - OdraLocation::CratesIO(version) => TemplatePath { - auto_path: Some(ODRA_TEMPLATE_GH_REPO.to_string()), - subfolder: Some(format!("templates/{}", init_action.template)), - test: false, - git: None, - branch: Some(format!("release/{}", version)), - tag: None, - path: None, - favorite: None, - }, - }; - - cargo_generate::generate(GenerateArgs { - template_path, - list_favorites: false, - name: Some(paths::to_snake_case(&init_action.project_name)), - force: true, - verbose: false, - template_values_file: None, - silent: false, - config: None, - vcs: Some(Vcs::Git), - lib: false, - bin: false, - ssh_identity: None, - define: vec![format!("date={}", Utc::now().format("%Y-%m-%d"))], - init: init_action.init, - destination: None, - force_git_init: false, - allow_commands: false, - overwrite: false, - other_args: None, - }) - .unwrap_or_else(|e| { - Error::FailedToGenerateProjectFromTemplate(e.to_string()).print_and_die(); - }); - - let cargo_toml_path = match init_action.init { - true => { - let mut path = init_action.current_dir; - path.push("Cargo.toml"); - path - } - false => { - let mut path = init_action.current_dir; - path.push(paths::to_snake_case(&init_action.project_name)); - path.push("Cargo.toml"); - path - } - }; - - replace_in_file( - cargo_toml_path, - "#odra_dependency", - format!( - "odra = {{ {} }}", - toml::to_string(&Self::odra_dependency(odra_location, init_action.init)) - .unwrap() - .trim_end() - .replace('\n', ", ") - ) - .as_str(), - ); - } - /// Detects an existing project. pub fn detect(path: PathBuf) -> Project { let odra_toml_path = Self::find_odra_toml(path.clone()).unwrap_or_else(|| { @@ -145,7 +32,7 @@ impl Project { Error::NotAnOdraProject.print_and_die(); }); let root = odra_toml_path.parent().unwrap().to_path_buf(); - let members = Self::find_members(&cargo_toml_path, &odra_toml_path); + let members = Self::members(&cargo_toml_path, &odra_toml_path); let name = match load_cargo_toml(&cargo_toml_path).package { None => { let cwd = env::current_dir().unwrap(); @@ -166,21 +53,6 @@ impl Project { } } - /// Builds the project - pub fn build(&self, backend: String, contracts_names: Option) { - BuildAction::new(self, backend, contracts_names).build(); - } - - /// Runs test in the Project. - pub fn test(&self, test: TestCommand) { - TestAction::new(self, test.backend, test.args, test.skip_build).test(); - } - - /// Generates a new contract in the Project. - pub fn generate(&self, generate: GenerateCommand) { - GenerateAction::new(self, generate.contract_name, generate.module).generate_contract(); - } - /// Root directory of the module. /// If the project does not use workspaces, the root directory is the same as the project root. pub fn module_root(&self, module_name: Option) -> PathBuf { @@ -215,6 +87,11 @@ impl Project { } } + /// Checks if the project is a workspace. + pub fn is_workspace(&self) -> bool { + !self.members.is_empty() + } + /// Searches for main Projects' Cargo.toml. pub fn find_cargo_toml(path: PathBuf) -> Option { match Self::find_file_upwards("Odra.toml", path) { @@ -235,23 +112,12 @@ impl Project { self.project_root.clone() } - /// Check if the project is a workspace. - pub fn is_workspace(&self) -> bool { - self.members.len() > 1 || self.members[0].root != self.project_root() - } - /// Returns project's OdraToml. pub fn odra_toml(&self) -> OdraToml { OdraToml::load(&self.odra_toml_location) } - fn assert_dir_is_empty(dir: PathBuf) { - if dir.read_dir().unwrap().next().is_some() { - Error::CurrentDirIsNotEmpty.print_and_die(); - } - } - - fn find_members(cargo_toml_path: &PathBuf, odra_toml_path: &Path) -> Vec { + pub fn members(cargo_toml_path: &PathBuf, odra_toml_path: &Path) -> Vec { Self::detect_members(cargo_toml_path, odra_toml_path) .iter() .map(|member| { @@ -293,66 +159,10 @@ impl Project { .filter(|member| odra_toml.has_module(member)) .map(|member| (member.clone(), member.clone())) .collect(), - None => vec![(Self::detect_project_name(cargo_toml_path), "".to_string())], + None => vec![], } } - fn detect_project_name(cargo_toml_path: &PathBuf) -> String { - load_cargo_toml(cargo_toml_path).package.unwrap().name - } - - fn odra_dependency(odra_location: OdraLocation, init: bool) -> Dependency { - let (version, path, git, branch) = match odra_location { - OdraLocation::Local(path) => { - let path = match init { - true => path, - false => PathBuf::from("..").join(path), - }; - let path = path - .join("core") - .into_os_string() - .to_str() - .unwrap() - .to_string(); - (None, Some(path), None, None) - } - OdraLocation::Remote(repo, branch) => match branch { - None => (Some(Self::odra_latest_version()), None, None, None), - Some(branch) => (None, None, Some(repo), Some(branch)), - }, - OdraLocation::CratesIO(version) => (Some(version), None, None, None), - }; - - Dependency::Detailed(DependencyDetail { - version, - registry: None, - registry_index: None, - path, - inherited: false, - git, - branch, - tag: None, - rev: None, - features: vec![], - optional: false, - default_features: false, - package: None, - }) - } - - fn odra_latest_version() -> String { - let response: serde_json::Value = ureq::get(ODRA_GITHUB_API_DATA) - .call() - .unwrap_or_else(|_| { - Error::FailedToFetchTemplate(ODRA_GITHUB_API_DATA.to_string()).print_and_die() - }) - .into_json() - .unwrap_or_else(|_| { - Error::FailedToParseTemplate(ODRA_GITHUB_API_DATA.to_string()).print_and_die() - }); - response["tag_name"].as_str().unwrap().to_string() - } - pub fn project_odra_location(&self) -> OdraLocation { let cargo_toml = load_cargo_toml(&self.cargo_toml_location); let dependencies = match cargo_toml.workspace { @@ -397,32 +207,6 @@ impl Project { } } } - - fn odra_location(source: Option) -> OdraLocation { - let source = if let Some(source) = source { - source - } else { - Self::odra_latest_version() - }; - - // location on disk - let local = PathBuf::from(&source); - if local.exists() { - OdraLocation::Local(local) - } else { - // version - let version_regex = regex::Regex::new(r"^\d+\.\d+\.\d+$").unwrap(); - if version_regex.is_match(&source) { - OdraLocation::Remote( - ODRA_TEMPLATE_GH_REPO.to_string(), - Some(format!("release/{}", source)), - ) - } else { - // branch - OdraLocation::Remote(ODRA_TEMPLATE_GH_REPO.to_string(), Some(source)) - } - } - } } #[derive(Debug, Clone)] diff --git a/src/template.rs b/src/template.rs index 2d27a58..ed2fffe 100644 --- a/src/template.rs +++ b/src/template.rs @@ -2,13 +2,7 @@ use ureq::get; use crate::{ command::read_file_content, - consts::{ - GEN_CONTRACT_MOD, - MATCH_CONTRACT_NAME, - MODULE_REGISTER, - MODULE_TEMPLATE, - WASM_SINGLE_SOURCE_BUILDER, - }, + consts::{MODULE_REGISTER, MODULE_TEMPLATE}, errors::Error, project::OdraLocation, }; @@ -69,39 +63,6 @@ impl TemplateGenerator { } } - /// Returns content of the new contracts_builder.rs file. - pub fn wasm_source_builder( - &self, - contracts_names: Vec<(String, String)>, - backend_name: &str, - ) -> Result { - let contract_matcher = contracts_names - .iter() - .map(|(_, contract_name)| { - self.fetch_template(MATCH_CONTRACT_NAME) - .map(|t| t.replace("#contract_name", contract_name)) - }) - .collect::, Error>>()? - .join("\n"); - - let gen_contract_mod = contracts_names - .iter() - .map(|(fqn, contract_name)| { - self.fetch_template(GEN_CONTRACT_MOD).map(|t| { - t.replace("#fqn", fqn) - .replace("#contract_name", contract_name) - .replace("#backend_name", backend_name) - }) - }) - .collect::, Error>>()? - .join("\n"); - - Ok(self - .fetch_template(WASM_SINGLE_SOURCE_BUILDER)? - .replace("#code_gen_modules", &gen_contract_mod) - .replace("#contract_matcher", &contract_matcher)) - } - /// Returns content of the new module file. pub fn module_template(&self, module_name: &str) -> Result { Ok(self