diff --git a/Cargo.lock b/Cargo.lock index 65473af..b9e119a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "backtrace" version = "0.3.68" @@ -67,6 +73,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" + [[package]] name = "bitflags" version = "1.3.2" @@ -79,6 +91,18 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "camino" version = "1.1.6" @@ -168,6 +192,22 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "diener" version = "0.4.7" @@ -178,11 +218,22 @@ dependencies = [ "git-url-parse", "log", "pathdiff", + "reqwest", + "serde_json", "structopt", "toml_edit", "walkdir", ] +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_logger" version = "0.10.0" @@ -233,6 +284,33 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.0" @@ -242,6 +320,54 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "gimli" version = "0.27.3" @@ -262,6 +388,31 @@ dependencies = [ "url", ] +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.0" @@ -298,12 +449,83 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "idna" version = "0.4.0" @@ -320,6 +542,16 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.0.0" @@ -327,9 +559,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.0", ] +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + [[package]] name = "is-terminal" version = "0.4.9" @@ -347,6 +585,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[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 = "lazy_static" version = "1.4.0" @@ -377,6 +624,12 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -386,6 +639,45 @@ dependencies = [ "adler", ] +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.2", + "libc", +] + [[package]] name = "object" version = "0.31.1" @@ -401,6 +693,50 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl" +version = "0.10.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +dependencies = [ + "bitflags 2.3.3", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[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.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "owo-colors" version = "3.5.0" @@ -425,6 +761,18 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -467,6 +815,15 @@ dependencies = [ "proc-macro2", ] +[[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 = "regex" version = "1.9.3" @@ -496,6 +853,44 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -536,6 +931,38 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.18" @@ -576,6 +1003,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -585,6 +1024,35 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "strsim" version = "0.8.0" @@ -656,6 +1124,40 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -719,6 +1221,46 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.4", + "windows-sys", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml_datetime" version = "0.6.3" @@ -731,11 +1273,17 @@ version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap", + "indexmap 2.0.0", "toml_datetime", "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.37" @@ -790,6 +1338,12 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -840,6 +1394,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" @@ -862,6 +1422,97 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[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.28", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[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.28", + "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 = "winapi" version = "0.3.9" @@ -967,3 +1618,13 @@ checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" dependencies = [ "memchr", ] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] diff --git a/Cargo.toml b/Cargo.toml index 6212539..44c4d4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,5 @@ env_logger = "0.10" log = "0.4" pathdiff = "0.2" anyhow = "1.0" +reqwest = { version = "0.11.4", features = ["blocking", "json"] } +serde_json = "1.0.64" diff --git a/src/update.rs b/src/update.rs index 9d567e2..af5b6a4 100644 --- a/src/update.rs +++ b/src/update.rs @@ -1,5 +1,7 @@ -use anyhow::{bail, ensure, Context, Result}; +use anyhow::{anyhow, bail, ensure, Context, Ok, Result}; use git_url_parse::GitUrl; +use reqwest::header::USER_AGENT; +use std::collections::HashMap; use std::{env::current_dir, fs, path::PathBuf, str::FromStr}; use structopt::StructOpt; use toml_edit::{Document, InlineTable, Value}; @@ -15,12 +17,21 @@ enum Rewrite { Beefy(Option), } +/// The different sources `Version` can be generated from. +#[derive(Debug, Clone)] +enum VersionSource { + CratesIO, + Url(String), + File(String), +} + /// The version the dependencies should be switched to. #[derive(Debug, Clone)] -enum Version { +enum Key { Tag(String), Branch(String), Rev(String), + Version(VersionSource), } /// `update` subcommand options. @@ -50,37 +61,54 @@ pub struct Update { #[structopt(long, short = "a")] all: bool, + /// Rewrite the `git` url to the give one. + #[structopt(long, conflicts_with_all = &[ "version" ])] + git: Option, + /// The `branch` that the dependencies should use. - #[structopt(long, conflicts_with_all = &[ "rev", "tag" ])] + #[structopt(long, conflicts_with_all = &[ "rev", "tag", "version" ])] branch: Option, /// The `rev` that the dependencies should use. - #[structopt(long, conflicts_with_all = &[ "branch", "tag" ])] + #[structopt(long, conflicts_with_all = &[ "branch", "tag", "version" ])] rev: Option, /// The `tag` that the dependencies should use. - #[structopt(long, conflicts_with_all = &[ "rev", "branch" ])] + #[structopt(long, conflicts_with_all = &[ "rev", "branch", "version" ])] tag: Option, - /// Rewrite the `git` url to the give one. + /// The `version` source the crates should be updated from. + /// There are three valid sources: + /// - `latest` - The latest version from crates.io + /// - `https://...` - A URL to a raw Cargo.lock file + /// - `path/to/Cargo.lock` - A path to a Cargo.lock file + #[structopt(long, conflicts_with_all = &[ "git" ])] + version: Option, + + /// Path to a toml file with the list of dependencies to exclude from updating. + /// Expects a `[diener_exclude]` manifest key in the toml file, + /// which lists the crates that should not be updated. #[structopt(long)] - git: Option, + exclude: Option, } impl Update { - /// Convert the options into the parts `Rewrite`, `Version`, `Option`. - fn into_parts(self) -> Result<(Rewrite, Version, Option)> { - let version = if let Some(branch) = self.branch { - Version::Branch(branch) + /// Convert the options into the parts `Rewrite`, `Key`, `Option`. + fn into_parts(self) -> Result<(Rewrite, Key, Option, Option)> { + let key = if let Some(branch) = self.branch { + Key::Branch(branch) } else if let Some(rev) = self.rev { - Version::Rev(rev) + Key::Rev(rev) } else if let Some(tag) = self.tag { - Version::Tag(tag) + Key::Tag(tag) + } else if let Some(version) = self.version.clone() { + let source = get_version_source(&version)?; + Key::Version(source) } else { - bail!("You need to pass `--branch`, `--tag` or `--rev`"); + bail!("You need to pass `--branch`, `--tag`, `--rev` or `--version`."); }; - let rewrite = if self.all { + let rewrite = if self.all || self.version.is_some() { if self.git.is_some() { bail!("You need to pass `--substrate`, `--polkadot`, `--cumulus` or `--beefy` for `--git`."); } else { @@ -98,12 +126,16 @@ impl Update { bail!("You must specify one of `--substrate`, `--polkadot`, `--cumulus`, `--beefy` or `--all`."); }; - Ok((rewrite, version, self.path)) + Ok((rewrite, key, self.path, self.exclude)) } /// Run this subcommand. pub fn run(self) -> Result<()> { - let (rewrite, version, path) = self.into_parts()?; + let mut packages_version: HashMap = HashMap::new(); + let mut cargo_lock: Option = None; + let mut excluded_packages: HashMap = HashMap::new(); + + let (rewrite, key, path, exclude_path) = self.into_parts()?; let path = path .map(Ok) @@ -122,6 +154,39 @@ impl Update { .unwrap_or(false) }; + // Populate `excluded_packages` + if let Some(exclude_path) = exclude_path { + let mut exclude_doc = Document::from_str( + &fs::read_to_string(exclude_path) + .map_err(|err| anyhow!("Failed trying to open exclude toml file: {}", err))?, + )?; + + exclude_doc + .clone() + .iter() + // filter out everything that is not a exclude table + .filter(|(k, _)| k.contains("diener_exclude")) + .filter_map(|(k, v)| v.as_table().map(|t| (k, t))) + .for_each(|(k, t)| { + t.iter() + // Filter everything that is not an inline table (`{ foo = bar }`) + .filter_map(|v| v.1.as_inline_table().map(|_| v.0)) + .for_each(|dn| { + let table = exclude_doc[k][dn] + .as_inline_table_mut() + .expect("We filter by `is_inline_table`; qed"); + let value_package = &Value::from(dn); + let read_package = + value_package.as_str().expect("We just created it`; qed"); + let package = table + .get("package") + .and_then(|v| v.as_str()) + .unwrap_or(read_package); + excluded_packages.insert(package.to_string(), true); + }) + }); + } + WalkDir::new(path) .follow_links(true) .into_iter() @@ -130,59 +195,115 @@ impl Update { .filter(|e| { e.file_type().is_file() && e.file_name().to_string_lossy().ends_with("Cargo.toml") }) - .try_for_each(|toml| handle_toml_file(toml.into_path(), &rewrite, &version)) + .try_for_each(|toml| { + handle_toml_file( + toml.into_path(), + &rewrite, + &key, + &mut packages_version, + &mut cargo_lock, + &mut excluded_packages, + ) + }) } } /// Handle a given dependency. /// /// This directly modifies the given `dep` in the requested way. -fn handle_dependency(name: &str, dep: &mut InlineTable, rewrite: &Rewrite, version: &Version) { - let git = if let Some(git) = dep - .get("git") - .and_then(|v| v.as_str()) - .and_then(|d| GitUrl::parse(d).ok()) - { - git +fn handle_dependency( + name: &str, + dep: &mut InlineTable, + rewrite: &Rewrite, + key: &Key, + excluded_packages: &mut HashMap, + cargo_lock: &mut Option, + packages_version: &mut HashMap, +) -> Result<()> { + let dep_clone = dep.clone(); + let package = if let Some(package_name) = dep_clone.get("package").and_then(|v| v.as_str()) { + package_name } else { - return; + name }; - let new_git = match rewrite { - Rewrite::All => &None, - Rewrite::Substrate(new_git) if git.name == "substrate" => new_git, - Rewrite::Polkadot(new_git) if git.name == "polkadot" => new_git, - Rewrite::Cumulus(new_git) if git.name == "cumulus" => new_git, - Rewrite::Beefy(new_git) if git.name == "grandpa-bridge-gadget" => new_git, - _ => return, - }; - - if let Some(new_git) = new_git { - *dep.get_or_insert("git", "") = Value::from(new_git.as_str()).decorated(" ", ""); + // Ignore the excluded packages + if excluded_packages.get(package).cloned().is_some() { + log::debug!("Skipping update for the excluded package '{}' ", package); + return Ok(()); } - dep.remove("tag"); - dep.remove("branch"); - dep.remove("rev"); + // If we want to update a dependency with a git reference + if expect_git_ref(key) { + let git = if let Some(git) = dep + .get("git") + .and_then(|v| v.as_str()) + .and_then(|d| GitUrl::parse(d).ok()) + { + git + } else { + // return if there is not any git reference to update + return Ok(()); + }; - match version { - Version::Tag(tag) => { - *dep.get_or_insert("tag", "") = Value::from(tag.as_str()).decorated(" ", " "); + let new_git = match rewrite { + Rewrite::All => &None, + Rewrite::Substrate(new_git) if git.name == "substrate" => new_git, + Rewrite::Polkadot(new_git) if git.name == "polkadot" => new_git, + Rewrite::Cumulus(new_git) if git.name == "cumulus" => new_git, + Rewrite::Beefy(new_git) if git.name == "grandpa-bridge-gadget" => new_git, + _ => return Ok(()), + }; + + if let Some(new_git) = new_git { + *dep.get_or_insert("git", "") = Value::from(new_git.as_str()).decorated(" ", ""); } - Version::Branch(branch) => { - *dep.get_or_insert("branch", "") = Value::from(branch.as_str()).decorated(" ", " "); + + match key { + Key::Tag(tag) => { + remove_keys(dep); + *dep.get_or_insert("tag", "") = Value::from(tag.as_str()).decorated(" ", " "); + } + Key::Branch(branch) => { + remove_keys(dep); + *dep.get_or_insert("branch", "") = Value::from(branch.as_str()).decorated(" ", " "); + } + Key::Rev(rev) => { + remove_keys(dep); + *dep.get_or_insert("rev", "") = Value::from(rev.as_str()).decorated(" ", " "); + } + _ => unreachable!(), } - Version::Rev(rev) => { - *dep.get_or_insert("rev", "") = Value::from(rev.as_str()).decorated(" ", " "); + // If we want to update a dependency with a crate version or path + } else { + match key { + Key::Version(source) => { + let version = get_version(name, package, source, packages_version, cargo_lock)?; + *dep.get_or_insert("version", "") = + Value::from(version.as_str()).decorated(" ", " "); + remove_keys(dep); + dep.remove("path"); + dep.remove("git"); + } + _ => unreachable!(), } } - log::debug!(" updated: {:?} <= {}", version, name); + + log::debug!("Updated: {:?} <= {}", key, name); + Ok(()) } /// Handle a given `Cargo.toml`. /// /// This means scanning all dependencies and rewrite the requested onces. -fn handle_toml_file(path: PathBuf, rewrite: &Rewrite, version: &Version) -> Result<()> { +fn handle_toml_file( + path: PathBuf, + rewrite: &Rewrite, + key: &Key, + packages_version: &mut HashMap, + cargo_lock: &mut Option, + excluded_packages: &mut HashMap, +) -> Result<()> { log::info!("Processing: {}", path.display()); let mut toml_doc = Document::from_str(&fs::read_to_string(&path)?)?; @@ -203,10 +324,158 @@ fn handle_toml_file(path: PathBuf, rewrite: &Rewrite, version: &Version) -> Resu let table = toml_doc[k][dn] .as_inline_table_mut() .expect("We filter by `is_inline_table`; qed"); - handle_dependency(dn, table, rewrite, version); + let _ = handle_dependency( + dn, + table, + rewrite, + key, + excluded_packages, + cargo_lock, + packages_version, + ) + .map_err(|err| { + log::error!("Error handling dependency: {}", err); + }); }) }); fs::write(&path, toml_doc.to_string())?; Ok(()) } + +/// Get the source of where to get the versions from. +fn get_version_source(version: &String) -> Result { + let source = if version.starts_with("http://") || version.starts_with("https://") { + VersionSource::Url(version.clone()) + } else { + let path = PathBuf::from(version); + if path.exists() && path.file_name() == Some("Cargo.lock".as_ref()) { + VersionSource::File(version.clone()) + } else if version == "latest" { + VersionSource::CratesIO + } else { + bail!("Invalid 'version' source: {}", version) + } + }; + Ok(source) +} + +/// Get the version of a package from a given source. +fn get_version_by_source( + package: &str, + source: &VersionSource, + cargo_lock: &mut Option, +) -> Result { + let version = match source { + VersionSource::CratesIO => { + let url = format!("https://crates.io/api/v1/crates/{}", package); + let client = reqwest::blocking::Client::new(); + + let body = client + .get(url) + .header(USER_AGENT, "diener_crawler (admin@parity.io)") + .send()? + .text()?; + + log::trace!("Crates IO plain response: {}", body); + + let json: serde_json::Value = serde_json::from_str(&body).map_err(|_| { + anyhow!( + "error trying to JSON parse the crates.io response: {}", + body + ) + })?; + + log::trace!("Crates IO json response: {}", json); + + json["crate"]["max_version"] + .as_str() + .ok_or(anyhow!("package '{}' not found on crates.io", package))? + .to_string() + } + VersionSource::Url(url) => { + let get_body = || -> Result { Ok(reqwest::blocking::get(url)?.text()?) }; + + let body = get_cargo_lock(get_body, cargo_lock)?; + + log::trace!("Url {} plain response: {}", url, body); + + get_version_from_cargo_lock_file(body, package) + .ok_or(anyhow!("package '{}' not found in Cargo.lock", package))? + } + VersionSource::File(path) => { + let get_body = || -> Result { + let path = PathBuf::from(path); + Ok(fs::read_to_string(path)?) + }; + + let body = get_cargo_lock(get_body, cargo_lock)?; + + get_version_from_cargo_lock_file(body, package) + .ok_or(anyhow!("package '{}' not found in Cargo.lock", package))? + } + }; + Ok(version) +} + +/// Get the version of a package from a Cargo.lock file. +fn get_version_from_cargo_lock_file(body: String, package_name: &str) -> Option { + let doc = body.parse::().ok()?; + let package_table = doc["package"].as_array_of_tables()?; + + for package in package_table.iter() { + if let Some(name) = package["name"].as_str() { + if name == package_name { + if let Some(version) = package["version"].as_str() { + return Some(version.to_string()); + } + } + } + } + None +} + +/// If version exists in `packages_version`, use it +/// if not, get it from source and insert it into `packages_version` +fn get_version( + name: &str, + package: &str, + source: &VersionSource, + packages_version: &mut HashMap, + cargo_lock: &mut Option, +) -> Result { + if let Some(version) = packages_version.get(name).cloned() { + Ok(version) + } else { + let version = get_version_by_source(package, source, cargo_lock)?; + (*packages_version).insert(name.to_string(), version.clone()); + Ok(version) + } +} + +/// If a Cargo.lock exists in `cargo_lock`, use it +/// if not, get it from source and insert it into `cargo_lock` +fn get_cargo_lock( + f: impl FnOnce() -> Result, + cargo_lock: &mut Option, +) -> Result { + if let Some(cargo_lock) = cargo_lock.clone() { + Ok(cargo_lock) + } else { + let new_cargo_lock = f()?; + *cargo_lock = Some(new_cargo_lock.clone()); + Ok(new_cargo_lock) + } +} + +/// Check if the given key is expecting a git reference. +fn expect_git_ref(key: &Key) -> bool { + matches!(key, Key::Tag(_) | Key::Branch(_) | Key::Rev(_)) +} + +/// Revome the `tag`, `branch` and `rev` keys from a given dependency. +fn remove_keys(dep: &mut InlineTable) { + dep.remove("tag"); + dep.remove("branch"); + dep.remove("rev"); +}