diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ead7f971..41e93707 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: - stable - beta - nightly - - 1.54.0 # minimum supported version + - 1.57.0 # minimum supported version continue-on-error: ${{ matrix.rust == 'nightly' }} steps: - uses: actions/checkout@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 640741db..826b66cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## Unreleased +### Changed +- Update `tokio` dependency, update to `futures=0.3`, rewrite for `async/await` + ## 0.25.3 - 2022-08-05 ### Added - Added `formality` script. diff --git a/Cargo.lock b/Cargo.lock index 94cfc9e5..f0551c72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -29,19 +29,16 @@ dependencies = [ "common-path", "dirs", "futures", - "futures-cpupool", "indexmap", "itertools", "pathdiff", - "semver 1.0.7", + "semver", "serde", "serde_derive", "serde_json", "serde_yaml", "tabwriter", - "tokio-core", - "tokio-process", - "tokio-timer", + "tokio", "typed-arena", ] @@ -69,27 +66,11 @@ dependencies = [ "generic-array", ] -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "bytes" -version = "0.4.12" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" [[package]] name = "cfg-if" @@ -99,16 +80,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.1.8" +version = "3.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" +checksum = "44bbe24bbd31a185bc2c4f7c2abe80bea13a20d57ee4e55be70ac512bdc76417" dependencies = [ "atty", "bitflags", "clap_derive", + "clap_lex", "indexmap", - "lazy_static", - "os_str_bytes", + "once_cell", "strsim", "termcolor", "textwrap", @@ -116,9 +97,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.7" +version = "3.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +checksum = "9ba52acd3b0a5c33aeada5cdaa3267cdc7c594a98731d4268cdc1532f4264cb4" dependencies = [ "heck", "proc-macro-error", @@ -128,12 +109,12 @@ dependencies = [ ] [[package]] -name = "cloudabi" -version = "0.0.3" +name = "clap_lex" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ - "bitflags", + "os_str_bytes", ] [[package]] @@ -142,59 +123,11 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" -[[package]] -name = "crossbeam-deque" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" -dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "crossbeam-utils", - "lazy_static", - "maybe-uninit", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" -dependencies = [ - "cfg-if 0.1.10", - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "lazy_static", -] - [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -228,51 +161,102 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", - "winapi 0.3.9", + "winapi", ] [[package]] name = "either" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" [[package]] -name = "fnv" -version = "1.0.7" +name = "futures" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] [[package]] -name = "fuchsia-zircon" -version = "0.3.3" +name = "futures-channel" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ - "bitflags", - "fuchsia-zircon-sys", + "futures-core", + "futures-sink", ] [[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" +name = "futures-core" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] -name = "futures" -version = "0.1.31" +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] -name = "futures-cpupool" -version = "0.1.8" +name = "futures-macro" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "futures", - "num_cpus", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] @@ -287,20 +271,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" @@ -319,23 +303,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "itertools" version = "0.10.3" @@ -347,149 +322,57 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "libc" -version = "0.2.122" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "linked-hash-map" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "lock_api" -version = "0.3.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "memoffset" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" -dependencies = [ - "autocfg", -] +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mio" -version = "0.6.23" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", "libc", "log", - "miow 0.2.2", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-named-pipes" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" -dependencies = [ - "log", - "mio", - "miow 0.3.7", - "winapi 0.3.9", -] - -[[package]] -name = "mio-uds" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "net2" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "wasi", + "windows-sys", ] [[package]] @@ -502,39 +385,39 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + [[package]] name = "os_str_bytes" -version = "6.0.0" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" [[package]] name = "parking_lot" -version = "0.9.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", "parking_lot_core", - "rustc_version", ] [[package]] name = "parking_lot_core" -version = "0.6.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ - "cfg-if 0.1.10", - "cloudabi", + "cfg-if", "libc", - "redox_syscall 0.1.57", - "rustc_version", + "redox_syscall", "smallvec", - "winapi 0.3.9", + "windows-sys", ] [[package]] @@ -543,6 +426,18 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -569,33 +464,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.37" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -607,30 +496,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall 0.2.13", + "redox_syscall", "thiserror", ] -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "scoped-tls" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "scopeguard" @@ -640,36 +514,21 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" - -[[package]] -name = "semver-parser" -version = "0.7.0" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" [[package]] name = "serde" -version = "1.0.136" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" dependencies = [ "proc-macro2", "quote", @@ -678,9 +537,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ "itoa", "ryu", @@ -689,9 +548,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.23" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ "indexmap", "ryu", @@ -699,19 +558,38 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "0.6.14" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ - "maybe-uninit", + "libc", + "winapi", ] [[package]] @@ -728,13 +606,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.91" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -763,18 +641,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -783,234 +661,34 @@ dependencies = [ [[package]] name = "tokio" -version = "0.1.22" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" -dependencies = [ - "bytes", - "futures", - "mio", - "num_cpus", - "tokio-codec", - "tokio-current-thread", - "tokio-executor", - "tokio-fs", - "tokio-io", - "tokio-reactor", - "tokio-sync", - "tokio-tcp", - "tokio-threadpool", - "tokio-timer", - "tokio-udp", - "tokio-uds", -] - -[[package]] -name = "tokio-codec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" -dependencies = [ - "bytes", - "futures", - "tokio-io", -] - -[[package]] -name = "tokio-core" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87b1395334443abca552f63d4f61d0486f12377c2ba8b368e523f89e828cffd4" -dependencies = [ - "bytes", - "futures", - "iovec", - "log", - "mio", - "scoped-tls", - "tokio", - "tokio-executor", - "tokio-io", - "tokio-reactor", - "tokio-timer", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" -dependencies = [ - "futures", - "tokio-executor", -] - -[[package]] -name = "tokio-executor" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" -dependencies = [ - "crossbeam-utils", - "futures", -] - -[[package]] -name = "tokio-fs" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" -dependencies = [ - "futures", - "tokio-io", - "tokio-threadpool", -] - -[[package]] -name = "tokio-io" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" +checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" dependencies = [ + "autocfg", "bytes", - "futures", - "log", -] - -[[package]] -name = "tokio-process" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f282588e1373af0a4e16bddf0c215c1a68b0bfe9b2dfa9704e540f01c3866de8" -dependencies = [ - "futures", "libc", - "mio", - "mio-named-pipes", - "tokio-core", - "tokio-io", - "tokio-signal", - "winapi 0.3.9", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" -dependencies = [ - "crossbeam-utils", - "futures", - "lazy_static", - "log", + "memchr", "mio", "num_cpus", + "once_cell", "parking_lot", - "slab", - "tokio-executor", - "tokio-io", - "tokio-sync", -] - -[[package]] -name = "tokio-signal" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" -dependencies = [ - "futures", - "libc", - "mio", - "mio-uds", - "tokio-core", - "tokio-io", - "winapi 0.3.9", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "winapi", ] [[package]] -name = "tokio-sync" -version = "0.1.8" +name = "tokio-macros" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ - "fnv", - "futures", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" -dependencies = [ - "bytes", - "futures", - "iovec", - "mio", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" -dependencies = [ - "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils", - "futures", - "lazy_static", - "log", - "num_cpus", - "slab", - "tokio-executor", -] - -[[package]] -name = "tokio-timer" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" -dependencies = [ - "crossbeam-utils", - "futures", - "slab", - "tokio-executor", -] - -[[package]] -name = "tokio-udp" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" -dependencies = [ - "bytes", - "futures", - "log", - "mio", - "tokio-codec", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-uds" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0" -dependencies = [ - "bytes", - "futures", - "iovec", - "libc", - "log", - "mio", - "mio-uds", - "tokio-codec", - "tokio-io", - "tokio-reactor", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1026,16 +704,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] -name = "unicode-width" -version = "0.1.9" +name = "unicode-ident" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-width" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "version_check" @@ -1045,15 +723,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "winapi" -version = "0.2.8" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "winapi" @@ -1065,12 +737,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -1083,7 +749,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1093,15 +759,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "ws2_32-sys" -version = "0.2.1" +name = "windows-sys" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", ] +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 9a9c0872..df543c88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,11 +14,8 @@ serde_derive = "1" serde_yaml = "0.8.4" serde_json = "1" -futures = "0.1" -futures-cpupool = "0.1" -tokio-core = "0.1.12" -tokio-process = "0.1.5" -tokio-timer = "0.2" +futures = "0.3" +tokio = { version = "1.20", features = ["full"] } clap = { version = "3.1", features = ["derive"] } semver = "1.0" diff --git a/src/cli.rs b/src/cli.rs index c6024b7d..7396bebe 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -16,7 +16,7 @@ use crate::config::{Config, Locked, Manifest, Merge, PartialConfig, PrefixPaths, use crate::error::*; use crate::resolver::DependencyResolver; use crate::sess::{Session, SessionArenas, SessionIo}; -use tokio_core::reactor::Core; +use tokio::runtime::Runtime; /// Inner main function which can return an error. pub fn main() -> Result<()> { @@ -154,13 +154,13 @@ pub fn main() -> Result<()> { // Ensure the locally linked packages are up-to-date. { - let mut core = Core::new().unwrap(); - let io = SessionIo::new(&sess, core.handle()); + let rt = Runtime::new()?; + let io = SessionIo::new(&sess); for (path, pkg_name) in &sess.manifest.workspace.package_links { debugln!("main: maintaining link to {} at {:?}", pkg_name, path); // Determine the checkout path for this package. - let pkg_path = core.run(io.checkout(sess.dependency_with_name(pkg_name)?))?; + let pkg_path = rt.block_on(io.checkout(sess.dependency_with_name(pkg_name)?))?; let pkg_path = path .parent() .and_then(|path| pathdiff::diff_paths(pkg_path, path)) @@ -414,9 +414,9 @@ fn execute_plugin(sess: &Session, plugin: &str, matches: Option) -> Re debugln!("main: execute plugin `{}`", plugin); // Obtain a list of declared plugins. - let mut core = Core::new().unwrap(); - let io = SessionIo::new(sess, core.handle()); - let plugins = core.run(io.plugins())?; + let runtime = Runtime::new()?; + let io = SessionIo::new(sess); + let plugins = runtime.block_on(io.plugins())?; // Lookup the requested plugin and complain if it does not exist. let plugin = match plugins.get(plugin) { diff --git a/src/cmd/checkout.rs b/src/cmd/checkout.rs index c25a402e..2a65ab06 100644 --- a/src/cmd/checkout.rs +++ b/src/cmd/checkout.rs @@ -4,7 +4,7 @@ //! The `checkout` subcommand. use clap::{ArgMatches, Command}; -use tokio_core::reactor::Core; +use tokio::runtime::Runtime; use crate::error::*; use crate::sess::{Session, SessionIo}; @@ -16,9 +16,9 @@ pub fn new<'a>() -> Command<'a> { /// Execute the `checkout` subcommand. pub fn run(sess: &Session, _matches: &ArgMatches) -> Result<()> { - let mut core = Core::new().unwrap(); - let io = SessionIo::new(&sess, core.handle()); - let _srcs = core.run(io.sources())?; + let rt = Runtime::new()?; + let io = SessionIo::new(&sess); + let _srcs = rt.block_on(io.sources())?; Ok(()) } diff --git a/src/cmd/clone.rs b/src/cmd/clone.rs index ba52ea7b..f8a4d685 100644 --- a/src/cmd/clone.rs +++ b/src/cmd/clone.rs @@ -4,10 +4,10 @@ //! The `clone` subcommand. use clap::{Arg, ArgMatches, Command}; -use futures::future; +use futures::future::join_all; use std::path::Path; use std::process::Command as SysCommand; -use tokio_core::reactor::Core; +use tokio::runtime::Runtime; use crate::config; use crate::config::{Locked, LockedSource}; @@ -73,8 +73,8 @@ pub fn run(sess: &Session, path: &Path, matches: &ArgMatches) -> Result<()> { println!("{} already has a directory in {}.", dep, path_mod); println!("Please manually ensure the correct checkout."); } else { - let mut core = Core::new().unwrap(); - let io = SessionIo::new(&sess, core.handle()); + let rt = Runtime::new()?; + let io = SessionIo::new(&sess); let ids = matches .values_of("name") @@ -82,11 +82,14 @@ pub fn run(sess: &Session, path: &Path, matches: &ArgMatches) -> Result<()> { .map(|n| Ok((n, sess.dependency_with_name(n)?))) .collect::>>()?; debugln!("main: obtain checkouts {:?}", ids); - let checkouts = core.run(future::join_all( - ids.iter() - .map(|&(_, id)| io.checkout(id)) - .collect::>(), - ))?; + let checkouts = rt + .block_on(join_all( + ids.iter() + .map(|&(_, id)| io.checkout(id)) + .collect::>(), + )) + .into_iter() + .collect::>>()?; debugln!("main: checkouts {:#?}", checkouts); for c in checkouts { if let Some(s) = c.to_str() { diff --git a/src/cmd/parents.rs b/src/cmd/parents.rs index c6e50148..9c23f172 100644 --- a/src/cmd/parents.rs +++ b/src/cmd/parents.rs @@ -7,7 +7,7 @@ use clap::{Arg, ArgMatches, Command}; use std::collections::HashMap; use std::io::Write; use tabwriter::TabWriter; -use tokio_core::reactor::Core; +use tokio::runtime::Runtime; use crate::error::*; use crate::sess::{DependencyConstraint, DependencySource}; @@ -28,8 +28,8 @@ pub fn new<'a>() -> Command<'a> { pub fn run(sess: &Session, matches: &ArgMatches) -> Result<()> { let dep = &matches.value_of("name").unwrap().to_lowercase(); sess.dependency_with_name(dep)?; - let mut core = Core::new().unwrap(); - let io = SessionIo::new(&sess, core.handle()); + let rt = Runtime::new()?; + let io = SessionIo::new(&sess); let parent_array = { let mut map = HashMap::>::new(); @@ -52,7 +52,7 @@ pub fn run(sess: &Session, matches: &ArgMatches) -> Result<()> { let all_deps = deps.iter().map(|&id| sess.dependency(id)); for current_dep in all_deps { if dep == current_dep.name.as_str() { - let dep_manifest = core.run(io.dependency_manifest(pkg)).unwrap(); + let dep_manifest = rt.block_on(io.dependency_manifest(pkg)).unwrap(); // Filter out dependencies without a manifest if dep_manifest.is_none() { warnln!("{} is shown to include dependency, but manifest does not have this information.", pkg_name.to_string()); diff --git a/src/cmd/path.rs b/src/cmd/path.rs index d616b836..b29772a8 100644 --- a/src/cmd/path.rs +++ b/src/cmd/path.rs @@ -4,8 +4,8 @@ //! The `path` subcommand. use clap::{Arg, ArgMatches, Command}; -use futures::future; -use tokio_core::reactor::Core; +use futures::future::join_all; +use tokio::runtime::Runtime; use crate::error::*; use crate::sess::{Session, SessionIo}; @@ -24,8 +24,8 @@ pub fn new<'a>() -> Command<'a> { /// Execute the `path` subcommand. pub fn run(sess: &Session, matches: &ArgMatches) -> Result<()> { - let mut core = Core::new().unwrap(); - let io = SessionIo::new(&sess, core.handle()); + let rt = Runtime::new()?; + let io = SessionIo::new(&sess); let ids = matches .values_of("name") @@ -33,11 +33,14 @@ pub fn run(sess: &Session, matches: &ArgMatches) -> Result<()> { .map(|n| Ok((n, sess.dependency_with_name(&n.to_lowercase())?))) .collect::>>()?; debugln!("main: obtain checkouts {:?}", ids); - let checkouts = core.run(future::join_all( - ids.iter() - .map(|&(_, id)| io.checkout(id)) - .collect::>(), - ))?; + let checkouts = rt + .block_on(join_all( + ids.iter() + .map(|&(_, id)| io.checkout(id)) + .collect::>(), + )) + .into_iter() + .collect::>>()?; debugln!("main: checkouts {:#?}", checkouts); for c in checkouts { if let Some(s) = c.to_str() { diff --git a/src/cmd/script.rs b/src/cmd/script.rs index 3be580dd..051123f8 100644 --- a/src/cmd/script.rs +++ b/src/cmd/script.rs @@ -4,7 +4,7 @@ //! The `script` subcommand. use clap::{Arg, ArgMatches, Command}; -use tokio_core::reactor::Core; +use tokio::runtime::Runtime; use crate::error::*; use crate::sess::{Session, SessionIo}; @@ -161,9 +161,9 @@ where /// Execute the `script` subcommand. pub fn run(sess: &Session, matches: &ArgMatches) -> Result<()> { - let mut core = Core::new().unwrap(); - let io = SessionIo::new(&sess, core.handle()); - let mut srcs = core.run(io.sources())?; + let rt = Runtime::new()?; + let io = SessionIo::new(&sess); + let mut srcs = rt.block_on(io.sources())?; // Format-specific target specifiers. let vivado_targets = &["vivado", "fpga", "xilinx"]; diff --git a/src/cmd/sources.rs b/src/cmd/sources.rs index 1d523e7a..299bee0d 100644 --- a/src/cmd/sources.rs +++ b/src/cmd/sources.rs @@ -8,7 +8,7 @@ use std; use clap::{Arg, ArgMatches, Command}; use serde_json; use std::collections::HashSet; -use tokio_core::reactor::Core; +use tokio::runtime::Runtime; use crate::error::*; use crate::sess::{Session, SessionIo}; @@ -70,9 +70,9 @@ where /// Execute the `sources` subcommand. pub fn run(sess: &Session, matches: &ArgMatches) -> Result<()> { - let mut core = Core::new().unwrap(); - let io = SessionIo::new(&sess, core.handle()); - let mut srcs = core.run(io.sources())?; + let rt = Runtime::new()?; + let io = SessionIo::new(&sess); + let mut srcs = rt.block_on(io.sources())?; // Filter the sources by target. let targets = matches diff --git a/src/error.rs b/src/error.rs index 8025a704..f088b6ea 100644 --- a/src/error.rs +++ b/src/error.rs @@ -142,6 +142,12 @@ impl From for String { } } +impl From for Error { + fn from(err: std::io::Error) -> Error { + Error::chain(format!("Cannot startup runtime."), err) + } +} + /// Format and print stage progress. #[macro_export] macro_rules! stageln { diff --git a/src/git.rs b/src/git.rs index 45a9352a..80333881 100644 --- a/src/git.rs +++ b/src/git.rs @@ -7,30 +7,28 @@ use std::ffi::OsStr; use std::path::Path; -use std::process::Command; -use futures::future; -use futures::Future; -use tokio_process::CommandExt; +use futures::TryFutureExt; +use tokio::process::Command; use crate::error::*; -use crate::sess::SessionIo; +use crate::sess::Session; /// A git repository. /// /// This struct is used to interact with git repositories on disk. It makes /// heavy use of futures to execute the different tasks. #[derive(Copy, Clone)] -pub struct Git<'io, 'sess: 'io, 'ctx: 'sess> { +pub struct Git<'sess, 'ctx: 'sess> { /// The path to the repository. pub path: &'ctx Path, /// The session within which commands will be executed. - pub sess: &'io SessionIo<'sess, 'ctx>, + pub sess: &'sess Session<'ctx>, } -impl<'git, 'io, 'sess: 'io, 'ctx: 'sess> Git<'io, 'sess, 'ctx> { +impl<'git, 'sess, 'ctx: 'sess> Git<'sess, 'ctx> { /// Create a new git context. - pub fn new(path: &'ctx Path, sess: &'io SessionIo<'sess, 'ctx>) -> Git<'io, 'sess, 'ctx> { + pub fn new(path: &'ctx Path, sess: &'sess Session<'ctx>) -> Git<'sess, 'ctx> { Git { path: path, sess: sess, @@ -42,7 +40,7 @@ impl<'git, 'io, 'sess: 'io, 'ctx: 'sess> Git<'io, 'sess, 'ctx> { /// The command will have the form `git ` and be pre-configured /// to operate in the repository's path. pub fn command(self, subcommand: &str) -> Command { - let mut cmd = Command::new(&self.sess.sess.config.git); + let mut cmd = Command::new(&self.sess.config.git); cmd.arg(subcommand); cmd.current_dir(&self.path); cmd @@ -58,8 +56,8 @@ impl<'git, 'io, 'sess: 'io, 'ctx: 'sess> Git<'io, 'sess, 'ctx> { /// /// If `check` is false, the stdout will be returned regardless of the /// command's exit code. - pub fn spawn(self, mut cmd: Command, check: bool) -> GitFuture<'io, String> { - let output = cmd.output_async(&self.sess.handle).map_err(|cause| { + pub async fn spawn(self, mut cmd: Command, check: bool) -> Result { + let output = cmd.output().map_err(|cause| { if cause .to_string() .to_lowercase() @@ -74,7 +72,7 @@ impl<'git, 'io, 'sess: 'io, 'ctx: 'sess> Git<'io, 'sess, 'ctx> { Error::chain("Failed to spawn child process.", cause) } }); - let result = output.and_then(move |output| { + let result = output.and_then(|output| async move { debugln!("git: {:?} in {:?}", cmd, self.path); if output.status.success() || !check { String::from_utf8(output.stdout).map_err(|cause| { @@ -102,132 +100,123 @@ impl<'git, 'io, 'sess: 'io, 'ctx: 'sess> Git<'io, 'sess, 'ctx> { Err(Error::new(msg)) } }); - Box::new(result) + result.await } /// Assemble a command and schedule it for execution. /// - /// This is a convenience function that creates a command, passses it to the + /// This is a convenience function that creates a command, passes it to the /// closure `f` for configuration, then passes it to the `spawn` function /// and returns the future. - pub fn spawn_with(self, f: F) -> GitFuture<'io, String> + pub async fn spawn_with(self, f: F) -> Result where F: FnOnce(&mut Command) -> &mut Command, { - let mut cmd = Command::new(&self.sess.sess.config.git); + let mut cmd = Command::new(&self.sess.config.git); cmd.current_dir(&self.path); f(&mut cmd); - self.spawn(cmd, true) + self.spawn(cmd, true).await } /// Assemble a command and schedule it for execution. /// /// This is the same as `spawn_with()`, but returns the stdout regardless of /// whether the command failed or not. - pub fn spawn_unchecked_with(self, f: F) -> GitFuture<'io, String> + pub async fn spawn_unchecked_with(self, f: F) -> Result where F: FnOnce(&mut Command) -> &mut Command, { - let mut cmd = Command::new(&self.sess.sess.config.git); + let mut cmd = Command::new(&self.sess.config.git); cmd.current_dir(&self.path); f(&mut cmd); - self.spawn(cmd, false) + self.spawn(cmd, false).await } /// Fetch the tags and refs of a remote. - pub fn fetch(self, remote: &str) -> GitFuture<'io, ()> { + pub async fn fetch(self, remote: &str) -> Result<()> { let r1 = String::from(remote); let r2 = String::from(remote); - Box::new( - self.spawn_with(move |c| c.arg("fetch").arg("--prune").arg(r1)) - .and_then(move |_| { - self.spawn_with(|c| c.arg("fetch").arg("--tags").arg("--prune").arg(r2)) - }) - .map(|_| ()), - ) + self.spawn_with(|c| c.arg("fetch").arg("--prune").arg(r1)) + .and_then(|_| self.spawn_with(|c| c.arg("fetch").arg("--tags").arg("--prune").arg(r2))) + .await + .map(|_| ()) } /// List all refs and their hashes. - pub fn list_refs(self) -> GitFuture<'io, Vec<(String, String)>> { - Box::new( - self.spawn_unchecked_with(|c| c.arg("show-ref").arg("--dereference")) - .and_then(move |raw| { - let mut all_revs = raw - .lines() - .map(|line| { - // Parse the line - let mut fields = line.split_whitespace().map(String::from); - let rev = fields.next().unwrap(); - let rf = fields.next().unwrap(); - (rev, rf) - }) - .collect::>(); - // Ensure only commit hashes are returned by using dereferenced values in case they exist - let deref_revs = all_revs - .clone() - .into_iter() - .filter(|tup| tup.1.ends_with("^{}")); - for item in deref_revs { - let index = all_revs - .iter() - .position(|x| *x.1 == item.1.replace("^{}", "")) - .unwrap(); - all_revs.remove(index); - let index = all_revs.iter().position(|x| *x.1 == item.1).unwrap(); - all_revs.remove(index); - all_revs.push((item.0, item.1.replace("^{}", ""))); - } - // Return future - future::ok(all_revs) - }), - ) + pub async fn list_refs(self) -> Result> { + self.spawn_unchecked_with(|c| c.arg("show-ref").arg("--dereference")) + .and_then(|raw| async move { + let mut all_revs = raw + .lines() + .map(|line| { + // Parse the line + let mut fields = line.split_whitespace().map(String::from); + let rev = fields.next().unwrap(); + let rf = fields.next().unwrap(); + (rev, rf) + }) + .collect::>(); + // Ensure only commit hashes are returned by using dereferenced values in case they exist + let deref_revs = all_revs + .clone() + .into_iter() + .filter(|tup| tup.1.ends_with("^{}")); + for item in deref_revs { + let index = all_revs + .iter() + .position(|x| *x.1 == item.1.replace("^{}", "")) + .unwrap(); + all_revs.remove(index); + let index = all_revs.iter().position(|x| *x.1 == item.1).unwrap(); + all_revs.remove(index); + all_revs.push((item.0, item.1.replace("^{}", ""))); + } + // Return future + Ok(all_revs) + }) + .await } /// List all revisions. - pub fn list_revs(self) -> GitFuture<'io, Vec> { - Box::new( - self.spawn_with(|c| c.arg("rev-list").arg("--all").arg("--date-order")) - .map(|raw| raw.lines().map(String::from).collect()), - ) + pub async fn list_revs(self) -> Result> { + self.spawn_with(|c| c.arg("rev-list").arg("--all").arg("--date-order")) + .await + .map(|raw| raw.lines().map(String::from).collect()) } /// Determine the currently checked out revision. - pub fn current_checkout(self) -> GitFuture<'io, Option> { - Box::new( - self.spawn_with(|c| c.arg("rev-parse").arg("--revs-only").arg("HEAD^{commit}")) - .map(|raw| raw.lines().take(1).map(String::from).next()), - ) + pub async fn current_checkout(self) -> Result> { + self.spawn_with(|c| c.arg("rev-parse").arg("--revs-only").arg("HEAD^{commit}")) + .await + .map(|raw| raw.lines().take(1).map(String::from).next()) } /// List files in the directory. /// /// Calls `git ls-tree` under the hood. - pub fn list_files, P: AsRef>( + pub async fn list_files, P: AsRef>( self, rev: R, path: Option

, - ) -> GitFuture<'io, Vec> { - Box::new( - self.spawn_with(|c| { - c.arg("ls-tree").arg(rev); - if let Some(p) = path { - c.arg(p); - } - c - }) - .map(|raw| raw.lines().map(TreeEntry::parse).collect()), - ) + ) -> Result> { + self.spawn_with(|c| { + c.arg("ls-tree").arg(rev); + if let Some(p) = path { + c.arg(p); + } + c + }) + .await + .map(|raw| raw.lines().map(TreeEntry::parse).collect()) } /// Read the content of a file. - pub fn cat_file>(self, hash: O) -> GitFuture<'io, String> { - Box::new(self.spawn_with(|c| c.arg("cat-file").arg("blob").arg(hash))) + pub async fn cat_file>(self, hash: O) -> Result { + self.spawn_with(|c| c.arg("cat-file").arg("blob").arg(hash)) + .await } } -/// A future returned from any of the git functions. -pub type GitFuture<'io, T> = Box + 'io>; - /// A single entry in a git tree. /// /// The `list_files` command returns a vector of these. diff --git a/src/main.rs b/src/main.rs index 23bbfeee..38695d8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,9 +10,7 @@ extern crate serde_json; extern crate serde_yaml; extern crate futures; -extern crate futures_cpupool; -extern crate tokio_core; -extern crate tokio_process; +extern crate tokio; extern crate blake2; extern crate clap; @@ -26,7 +24,7 @@ pub mod error; pub mod cli; pub mod cmd; pub mod config; -pub mod future_throttle; +// pub mod future_throttle; pub mod git; pub mod resolver; pub mod sess; diff --git a/src/resolver.rs b/src/resolver.rs index 99ac374f..4b127210 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -11,9 +11,8 @@ use std::fs; use std::mem; use futures::future::join_all; -use futures::Future; use indexmap::{IndexMap, IndexSet}; -use tokio_core::reactor::Core; +use tokio::runtime::Runtime; extern crate itertools; use self::itertools::Itertools; @@ -22,7 +21,7 @@ extern crate atty; use std::io::{self, Write}; -use crate::config; +use crate::config::{self, Manifest}; use crate::error::*; use crate::sess::{ self, DependencyConstraint, DependencyRef, DependencyVersion, DependencyVersions, Session, @@ -64,8 +63,8 @@ impl<'ctx> DependencyResolver<'ctx> { /// Resolve dependencies. pub fn resolve(mut self) -> Result { - let mut core = Core::new().unwrap(); - let io = SessionIo::new(self.sess, core.handle()); + let rt = Runtime::new()?; + let io = SessionIo::new(self.sess); // Store path dependencies already in checkout_dir match self.sess.manifest.workspace.checkout_dir.clone() { @@ -93,7 +92,7 @@ impl<'ctx> DependencyResolver<'ctx> { self.register_dependencies_in_manifest( &self.sess.config.plugins, self.sess.manifest, - &mut core, + &rt, &io, )?; @@ -101,7 +100,7 @@ impl<'ctx> DependencyResolver<'ctx> { self.register_dependencies_in_manifest( &self.sess.manifest.dependencies, self.sess.manifest, - &mut core, + &rt, &io, )?; @@ -120,13 +119,13 @@ impl<'ctx> DependencyResolver<'ctx> { // Go through each dependency's versions and apply the constraints // imposed by the others. - self.mark(&mut core, &io)?; + self.mark(&rt, &io)?; // Pick a version for each dependency. any_changes = self.pick()?; // Close the dependency set. - self.close(&mut core, &io)?; + self.close(&rt, &io)?; } debugln!("resolve: resolved after {} iterations", iteration); @@ -209,7 +208,7 @@ impl<'ctx> DependencyResolver<'ctx> { &mut self, deps: &'ctx HashMap, manifest: &'ctx config::Manifest, - core: &mut Core, + rt: &Runtime, io: &SessionIo<'ctx, 'ctx>, ) -> Result<()> { // Map the dependencies to unique IDs. @@ -229,10 +228,16 @@ impl<'ctx> DependencyResolver<'ctx> { // Determine the available versions for the dependencies. let versions: Vec<_> = ids .iter() - .map(|&id| io.dependency_versions(id, false).map(move |v| (id, v))) + .map(|&id| async move { + io.dependency_versions(id, false) + .await + .map(move |v| (id, v)) + }) .collect(); - let versions: HashMap<_, _> = core - .run(join_all(versions))? + let versions: HashMap<_, _> = rt + .block_on(join_all(versions)) + .into_iter() + .collect::>>()? .into_iter() .collect::>(); // debugln!("resolve: versions {:#?}", versions); @@ -286,7 +291,7 @@ impl<'ctx> DependencyResolver<'ctx> { } /// Apply constraints to each dependency's versions. - fn mark(&mut self, core: &mut Core, io: &SessionIo<'ctx, 'ctx>) -> Result<()> { + fn mark(&mut self, rt: &Runtime, io: &SessionIo<'ctx, 'ctx>) -> Result<()> { use std::iter::once; // Gather the constraints from the available manifests. Group them by @@ -339,7 +344,7 @@ impl<'ctx> DependencyResolver<'ctx> { for &(_, ref con) in &cons { debugln!("resolve: impose `{}` on `{}`", con, name); for src in table.get_mut(name).unwrap().sources.values_mut() { - self.impose(name, &con, src, &cons, core, io)?; + self.impose(name, &con, src, &cons, rt, io)?; } } } @@ -456,7 +461,7 @@ impl<'ctx> DependencyResolver<'ctx> { con: &DependencyConstraint, src: &mut DependencySource<'ctx>, all_cons: &[(&str, DependencyConstraint)], - core: &mut Core, + rt: &Runtime, io: &SessionIo<'ctx, 'ctx>, ) -> Result<()> { let indices = match self.req_indices(name, con, src) { @@ -469,7 +474,7 @@ impl<'ctx> DependencyResolver<'ctx> { // debugln!("resolve: restricting `{}` to versions {:?}", name, indices); if indices.is_empty() { - src.versions = core.run(io.dependency_versions(src.id, true))?; + src.versions = rt.block_on(io.dependency_versions(src.id, true))?; let indices = match self.req_indices(name, con, src) { Ok(o) => match o { @@ -649,9 +654,9 @@ impl<'ctx> DependencyResolver<'ctx> { } /// Close the set of dependencies. - fn close(&mut self, core: &mut Core, io: &SessionIo<'ctx, 'ctx>) -> Result<()> { + fn close(&mut self, rt: &Runtime, io: &SessionIo<'ctx, 'ctx>) -> Result<()> { debugln!("resolve: computing closure over dependencies"); - let manifests = { + let manifests: Vec<(&str, Option<&Manifest>)> = { let mut sub_deps = Vec::new(); for dep in self.table.values() { let src = dep.source(); @@ -660,14 +665,16 @@ impl<'ctx> DependencyResolver<'ctx> { None => continue, }; let manifest = io.dependency_manifest_version(src.id, version); - sub_deps.push(manifest.map(move |m| (dep.name, m))); + sub_deps.push(async move { manifest.await.map(move |m| (dep.name, m)) }); } - core.run(join_all(sub_deps))? + rt.block_on(join_all(sub_deps)) + .into_iter() + .collect::)>>>()? }; for (name, manifest) in manifests { if let Some(m) = manifest { debugln!("resolve: for `{}` loaded manifest {:#?}", name, m); - self.register_dependencies_in_manifest(&m.dependencies, m, core, io)?; + self.register_dependencies_in_manifest(&m.dependencies, m, rt, io)?; } let ref mut existing = self.table.get_mut(name).unwrap().manifest; *existing = manifest; diff --git a/src/sess.rs b/src/sess.rs index 54b575a8..73aec4db 100644 --- a/src/sess.rs +++ b/src/sess.rs @@ -16,18 +16,15 @@ use std::sync::atomic::AtomicUsize; use std::sync::{Arc, Mutex}; use std::time::SystemTime; +use crate::futures::{FutureExt, TryFutureExt}; use futures::future::{self, join_all}; -use futures::Future; -use semver; -use serde_yaml; -use tokio_core::reactor::Handle; use typed_arena::Arena; use crate::cli::read_manifest; use crate::config::Validate; use crate::config::{self, Config, Manifest}; use crate::error::*; -use crate::future_throttle::FutureThrottle; +// use crate::future_throttle::FutureThrottle; use crate::git::Git; use crate::src::SourceGroup; use crate::target::TargetSpec; @@ -69,8 +66,8 @@ pub struct Session<'ctx> { plugins: Mutex>, /// The session cache. pub cache: SessionCache<'ctx>, - /// A throttle for futures performing git network operations. - git_throttle: FutureThrottle, + // /// A throttle for futures performing git network operations. + // git_throttle: FutureThrottle, /// A toggle to disable remote fetches & clones pub local_only: bool, } @@ -107,7 +104,7 @@ impl<'sess, 'ctx: 'sess> Session<'ctx> { sources: Mutex::new(None), plugins: Mutex::new(None), cache: Default::default(), - git_throttle: FutureThrottle::new(8), + // git_throttle: FutureThrottle::new(8), local_only: local_only, } } @@ -409,39 +406,37 @@ impl<'sess, 'ctx: 'sess> Session<'ctx> { pub struct SessionIo<'sess, 'ctx: 'sess> { /// The underlying session. pub sess: &'sess Session<'ctx>, - /// The event loop where IO will be run. - pub handle: Handle, git_versions: Mutex>>, } impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { /// Create a new session wrapper. - pub fn new(sess: &'sess Session<'ctx>, handle: Handle) -> SessionIo<'sess, 'ctx> { + pub fn new(sess: &'sess Session<'ctx>) -> SessionIo<'sess, 'ctx> { SessionIo { sess: sess, - handle: handle, git_versions: Mutex::new(HashMap::new()), } } /// Determine the available versions for a dependency. - pub fn dependency_versions( + pub async fn dependency_versions( &'io self, dep_id: DependencyRef, force_fetch: bool, - ) -> Box, Error = Error> + 'io> { + ) -> Result> { self.sess.stats.num_calls_dependency_versions.increment(); let dep = self.sess.dependency(dep_id); match dep.source { DependencySource::Registry => { unimplemented!("determine available versions of registry dependency"); } - DependencySource::Path(_) => Box::new(future::ok(DependencyVersions::Path)), - DependencySource::Git(ref url) => Box::new( - self.git_database(&dep.name, url, force_fetch) - .and_then(move |db| self.git_versions(db)) - .map(DependencyVersions::Git), - ), + DependencySource::Path(_) => Ok(DependencyVersions::Path), + DependencySource::Git(ref url) => { + let db = self.git_database(&dep.name, url, force_fetch).await?; + self.git_versions_func(db) + .await + .map(DependencyVersions::Git) + } } } @@ -449,12 +444,12 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { /// /// If the database does not exist, it is created. If the database has not /// been updated recently, the remote is fetched. - fn git_database( + async fn git_database( &'io self, name: &str, url: &str, force_fetch: bool, - ) -> Box, Error = Error> + 'io> { + ) -> Result> { // TODO: Make the assembled future shared and keep it in a lookup table. // Then use that table to return the future if it already exists. // This ensures that the gitdb is setup only once, and makes the @@ -480,13 +475,13 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { match std::fs::create_dir_all(db_dir) { Ok(_) => (), Err(cause) => { - return Box::new(future::err(Error::chain( + return Err(Error::chain( format!("Failed to create git database directory {:?}.", db_dir), cause, - ))) + )) } }; - let git = Git::new(db_dir, self); + let git = Git::new(db_dir, self.sess); let name2 = String::from(name); let url = String::from(url); let url2 = url.clone(); @@ -495,103 +490,86 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { // Either initialize the repository or update it if needed. if !db_dir.join("config").exists() { if self.sess.local_only { - return Box::new(future::err(Error::new(format!( + return Err(Error::new(format!( "Bender --local argument set, unable to initialize git dependency. \n\ \tPlease update without --local, or provide a path to the missing dependency." - )))); + ))); } // Initialize. self.sess.stats.num_database_init.increment(); - Box::new( - self.sess.git_throttle.spawn( - future::lazy(move || { - stageln!("Cloning", "{} ({})", name2, url2); - Ok(()) - }) - .and_then(move |_| git.spawn_with(|c| c.arg("init").arg("--bare"))) - .and_then(move |_| { - git.spawn_with(|c| c.arg("remote").arg("add").arg("origin").arg(url)) - }) - .and_then(move |_| git.fetch("origin")) - .map_err(move |cause| { - if url3.contains("git@") { - warnln!( - "Please ensure your public ssh key is added to the git server." - ); - } - warnln!("Please ensure the url is correct and you have access to the repository."); - Error::chain( - format!("Failed to initialize git database in {:?}.", db_dir), - cause, - ) - }) - .map(move |_| git), - ), - ) + // TODO MICHAERO: May need throttle + future::lazy(|_| { + stageln!("Cloning", "{} ({})", name2, url2); + Ok(()) + }) + .and_then(|_| git.spawn_with(|c| c.arg("init").arg("--bare"))) + .and_then(|_| git.spawn_with(|c| c.arg("remote").arg("add").arg("origin").arg(url))) + .and_then(|_| git.fetch("origin")) + .await + .map_err(move |cause| { + if url3.contains("git@") { + warnln!("Please ensure your public ssh key is added to the git server."); + } + warnln!("Please ensure the url is correct and you have access to the repository."); + Error::chain( + format!("Failed to initialize git database in {:?}.", db_dir), + cause, + ) + }) + .map(move |_| git) } else { // Update if the manifest has been modified since the last fetch. let db_mtime = try_modification_time(db_dir.join("FETCH_HEAD")); if (self.sess.manifest_mtime < db_mtime && !force_fetch) || self.sess.local_only { debugln!("sess: skipping fetch of {:?}", db_dir); - return Box::new(future::ok(git)); + return Ok(git); } self.sess.stats.num_database_fetch.increment(); - Box::new( - self.sess.git_throttle.spawn( - future::lazy(move || { - stageln!("Fetching", "{} ({})", name2, url2); - Ok(()) - }) - .and_then(move |_| git.fetch("origin")) - .map_err(move |cause| { - if url3.contains("git@") { - warnln!( - "Please ensure your public ssh key is added to the git server." - ); - } - warnln!("Please ensure the url is correct and you have access to the repository."); - Error::chain( - format!("Failed to update git database in {:?}.", db_dir), - cause, - ) - }) - .map(move |_| git), - ), - ) + // TODO MICHAERO: May need throttle + future::lazy(|_| { + stageln!("Fetching", "{} ({})", name2, url2); + Ok(()) + }) + .and_then(|_| git.fetch("origin")) + .await + .map_err(move |cause| { + if url3.contains("git@") { + warnln!("Please ensure your public ssh key is added to the git server."); + } + warnln!("Please ensure the url is correct and you have access to the repository."); + Error::chain( + format!("Failed to update git database in {:?}.", db_dir), + cause, + ) + }) + .map(move |_| git) } } /// Determine the list of versions available for a git dependency. - fn git_versions( - &'io self, - git: Git<'io, 'sess, 'ctx>, - ) -> Box, Error = Error> + 'io> { - match self - .git_versions - .lock() - .unwrap() - .get(&git.path.to_path_buf()) - { + pub async fn git_versions_func(&'io self, git: Git<'sess, 'ctx>) -> Result> { + let versions_tmp = self.git_versions.lock().unwrap().clone(); + + match versions_tmp.get(&git.path.to_path_buf()) { Some(result) => { debugln!("sess: git_versions from stored"); - Box::new(future::ok(GitVersions { + Ok(GitVersions { versions: result.versions.clone(), refs: result.refs.clone(), revs: result.revs.clone(), - })) + }) } None => { debugln!("sess: git_versions get new"); - let dep_refs = git.list_refs(); - let dep_revs = git.list_revs(); - let dep_refs_and_revs = - dep_refs.and_then(|refs| -> Box> { - if refs.is_empty() { - Box::new(future::ok((refs, vec![]))) - } else { - Box::new(dep_revs.map(move |revs| (refs, revs))) - } - }); + let dep_refs = git.list_refs().await; + let dep_revs = git.list_revs().await; + let dep_refs_and_revs = dep_refs.and_then(|refs| -> Result<_> { + if refs.is_empty() { + Ok((refs, vec![])) + } else { + dep_revs.map(move |revs| (refs, revs)) + } + }); let out = dep_refs_and_revs.and_then(move |(refs, revs)| { let refs: Vec<_> = refs .into_iter() @@ -667,7 +645,7 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { revs: revs, }) }); - Box::new(out) + out } } } @@ -719,13 +697,10 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { } /// Ensure that a dependency is checked out and obtain its path. - pub fn checkout( - &'io self, - dep_id: DependencyRef, - ) -> Box + 'io> { + pub async fn checkout(&'io self, dep_id: DependencyRef) -> Result<&'ctx Path> { // Check if the checkout is already in the cache. if let Some(&cached) = self.sess.cache.checkout.lock().unwrap().get(&dep_id) { - return Box::new(future::ok(cached)); + return Ok(cached); } self.sess.stats.num_calls_checkout.increment(); @@ -738,7 +713,7 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { let path = self .sess .intern_path(self.get_package_path(dep_id).as_path()); - return Box::new(future::ok(path)); + return Ok(path); } } @@ -747,13 +722,14 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { match dep.source { DependencySource::Path(..) => unreachable!(), DependencySource::Registry => unimplemented!(), - DependencySource::Git(ref url) => Box::new( - self.checkout_git( + DependencySource::Git(ref url) => self + .checkout_git( self.sess.intern_string(&dep.name), checkout_dir, self.sess.intern_string(url), self.sess.intern_string(dep.revision.as_ref().unwrap()), ) + .await .and_then(move |path| { self.sess .cache @@ -763,7 +739,6 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { .insert(dep_id, path); Ok(path) }), - ), } } @@ -771,49 +746,49 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { /// /// If the directory is not a proper git repository, it is deleted and /// re-created from scratch. - fn checkout_git( + async fn checkout_git( &'io self, name: &'ctx str, path: &'ctx Path, url: &'ctx str, revision: &'ctx str, - ) -> Box + 'io> { + ) -> Result<&'ctx Path> { // First check if we have to get rid of the current checkout. This is // the case if it either does not exist or the checked out revision does // not match what we expect. - let scrapped = future::lazy(move || future::ok(path.exists())) - .and_then(move |exists| -> Box> { + future::lazy(|_| Ok(path.exists())) + .and_then(|exists| async move { if exists { // Never scrap checkouts the user asked for explicitly in // the workspace configuration. if self.sess.manifest.workspace.checkout_dir.is_some() { - return Box::new(future::ok(false)); + return Ok(false); } // Scrap checkouts with the wrong tag. - Box::new( - Git::new(path, self) - .current_checkout() - .then(move |current| { - future::ok(match current { - Ok(Some(current)) => { - debugln!( - "checkout_git: currently `{}` (want `{}`)", - current, - revision - ); - current != revision - } - _ => true, - }) - }), - ) + + Git::new(path, self.sess) + .current_checkout() + .then(|current| async { + Ok(match current { + Ok(Some(current)) => { + debugln!( + "checkout_git: currently `{}` (want `{}`)", + current, + revision + ); + current != revision + } + _ => true, + }) + }) + .await } else { // Don't do anything if there is no checkout. - Box::new(future::ok(false)) + Ok(false) } }) - .and_then(move |clear| { + .and_then(|clear| async move { if clear { debugln!("checkout_git: clear checkout {:?}", path); std::fs::remove_dir_all(path) @@ -825,59 +800,49 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { }) .into() } else { - future::ok(()) + Ok(()) } - }); + }) + .await?; // Perform the checkout if necessary. - let updated = scrapped.and_then(move |_| -> Box> { - if !path.exists() { - stageln!("Checkout", "{} ({})", name, url); - - // First generate a tag to be cloned in the database. This is - // necessary since `git clone` does not accept commits, but only - // branches or tags for shallow clones. - let tag_name_0 = format!("bender-tmp-{}", revision); - let tag_name_1 = tag_name_0.clone(); - let f = self - .git_database(name, url, false) - .and_then(move |git| { - git.clone() - .spawn_with(move |c| { - c.arg("tag").arg(tag_name_0).arg(revision).arg("--force") - }) - .map(move |_| git) - }) - .and_then(move |git| { - git.clone().spawn_with(move |c| { - c.arg("clone") - .arg(git.path) - .arg(path) - .arg("--recursive") - .arg("--branch") - .arg(tag_name_1) - }) - }) - .map(|_| ()); - - Box::new(f) - } else { - Box::new(future::ok(())) - } - }); - - Box::new(updated.map(move |_| path)) + // TODO MICHAERO: May need proper chaining to previous future using and_then + if !path.exists() { + stageln!("Checkout", "{} ({})", name, url); + + // First generate a tag to be cloned in the database. This is + // necessary since `git clone` does not accept commits, but only + // branches or tags for shallow clones. + let tag_name_0 = format!("bender-tmp-{}", revision); + let tag_name_1 = tag_name_0.clone(); + let git = self.git_database(name, url, false).await?; + // .and_then(move |git| { + git.clone() + .spawn_with(move |c| c.arg("tag").arg(tag_name_0).arg(revision).arg("--force")) + .await?; + git.clone() + .spawn_with(move |c| { + c.arg("clone") + .arg(git.path) + .arg(path) + .arg("--recursive") + .arg("--branch") + .arg(tag_name_1) + }) + .await?; + } + Ok(path) } /// Load the manifest for a specific version of a dependency. /// /// Loads and returns the manifest for a dependency at a specific version. /// Returns `None` if the dependency has no manifest. - pub fn dependency_manifest_version( + pub async fn dependency_manifest_version( &'io self, dep_id: DependencyRef, version: DependencyVersion<'ctx>, - ) -> Box, Error = Error> + 'io> { + ) -> Result> { // Check if the manifest is already in the cache. let cache_key = (dep_id, version.clone()); if let Some(&cached) = self @@ -888,7 +853,7 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { .unwrap() .get(&cache_key) { - return Box::new(future::ok(cached)); + return Ok(cached); } self.sess @@ -911,12 +876,12 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { warnln!("Dependency name and package name do not match for {:?} / {:?}, this can cause unwanted behavior", dep.name, m.package.name); // TODO: This should be an error } - Box::new(future::ok(Some(self.sess.intern_manifest(m)))) + Ok(Some(self.sess.intern_manifest(m))) } - Err(e) => Box::new(future::err(e)), + Err(e) => Err(e), } } else { - Box::new(future::ok(None)) + Ok(None) } } (&DepSrc::Registry, DepVer::Registry(_hash)) => { @@ -924,81 +889,76 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { } (&DepSrc::Git(ref url), DepVer::Git(rev)) => { let dep_name = self.sess.intern_string(dep.name.as_str()); - Box::new( - self.git_database(&dep.name, url, false) - .and_then(move |db| { - db.list_files(rev, Some("Bender.yml")).and_then( - move |entries| -> Box> { - match entries.into_iter().next() { - None => Box::new(future::ok(None)), - Some(entry) => { - Box::new(db.cat_file(entry.hash).map(|f| Some(f))) - } - } - }, + // TODO MICHAERO: May need proper chaining using and_then + let db = self.git_database(&dep.name, url, false).await?; + let entries = db.list_files(rev, Some("Bender.yml")).await?; + let data = match entries.into_iter().next() { + None => Ok(None), + Some(entry) => db.cat_file(entry.hash).await.map(|f| Some(f)), + }?; + let manifest: Result<_> = match data { + Some(data) => { + let partial: config::PartialManifest = serde_yaml::from_str(&data) + .map_err(|cause| { + Error::chain( + format!( + "Syntax error in manifest of dependency `{}` at \ + revision `{}`.", + dep_name, rev + ), + cause, + ) + })?; + let mut full = partial.validate().map_err(|cause| { + Error::chain( + format!( + "Error in manifest of dependency `{}` at revision \ + `{}`.", + dep_name, rev + ), + cause, ) - }) - .and_then(move |data| match data { - Some(data) => { - let partial: config::PartialManifest = serde_yaml::from_str(&data) - .map_err(|cause| { - Error::chain( - format!( - "Syntax error in manifest of dependency `{}` at \ - revision `{}`.", - dep_name, rev - ), - cause, - ) - })?; - let mut full = partial.validate().map_err(|cause| { - Error::chain( - format!( - "Error in manifest of dependency `{}` at revision \ - `{}`.", - dep_name, rev - ), - cause, - ) - })?; - // Add base path to path dependencies within git repositories - for dep in full.dependencies.iter_mut() { - match dep { - (_, config::Dependency::Path(ref path)) => { - if !path.starts_with("/") { - if !self.get_package_path(dep_id).exists() { - warnln!("Please note that dependencies for {:?} may not be available unless {:?} is properly checked out.\n (to checkout run `bender sources` and then `bender update` again).", dep.0, full.package.name); - } - *dep.1 = config::Dependency::Path(self.get_package_path(dep_id).join(path).clone()); - } - }, - (_, _) => {}, + })?; + // Add base path to path dependencies within git repositories + for dep in full.dependencies.iter_mut() { + match dep { + (_, config::Dependency::Path(ref path)) => { + if !path.starts_with("/") { + if !self.get_package_path(dep_id).exists() { + warnln!("Please note that dependencies for {:?} may not be available unless {:?} is properly checked out.\n (to checkout run `bender sources` and then `bender update` again).", dep.0, full.package.name); + } + *dep.1 = config::Dependency::Path( + self.get_package_path(dep_id).join(path).clone(), + ); } } - Ok(Some(self.sess.intern_manifest(full))) + (_, _) => {} } - None => Ok(None), - }) - .and_then(move |manifest| { - self.sess - .cache - .dependency_manifest_version - .lock() - .unwrap() - .insert(cache_key, manifest); - if dep.name != match manifest { + } + Ok(Some(self.sess.intern_manifest(full))) + } + None => Ok(None), + }; + let manifest = manifest?; + self.sess + .cache + .dependency_manifest_version + .lock() + .unwrap() + .insert(cache_key, manifest); + if dep.name + != match manifest { + Some(x) => &x.package.name, + None => "dead", + } + { + warnln!("Dependency name and package name do not match for {:?} / {:?}, this can cause unwanted behavior", + dep.name, match manifest { Some(x) => &x.package.name, None => "dead" - } { - warnln!("Dependency name and package name do not match for {:?} / {:?}, this can cause unwanted behavior", - dep.name, match manifest { - Some(x) => &x.package.name, - None => "dead" - }); // TODO (micprog): This should be an error - } - Ok(manifest) - }), - ) + }); // TODO (micprog): This should be an error + } + Ok(manifest) } _ => panic!( "incompatible source {:?} and version {:?}", @@ -1010,10 +970,10 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { /// Load the manifest for a dependency. /// /// Loads and returns the manifest for a dependency at the resolved version. - pub fn dependency_manifest( + pub async fn dependency_manifest( &'io self, dep_id: DependencyRef, - ) -> Box, Error = Error> + 'io> { + ) -> Result> { // Check if the manifest is already in the cache. if let Some(&cached) = self .sess @@ -1023,101 +983,99 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { .unwrap() .get(&dep_id) { - return Box::new(future::ok(cached)); + return Ok(cached); } // Otherwise ensure that there is a checkout of the dependency and read // the manifest there. self.sess.stats.num_calls_dependency_manifest.increment(); - Box::new( - self.checkout(dep_id) - .and_then(move |path| { - let manifest_path = path.join("Bender.yml"); - if manifest_path.exists() { - match read_manifest(&manifest_path) { - Ok(m) => Ok(Some(self.sess.intern_manifest(m))), - Err(e) => Err(e), - } - } else { - Ok(None) + self.checkout(dep_id) + .await + .and_then(move |path| { + let manifest_path = path.join("Bender.yml"); + if manifest_path.exists() { + match read_manifest(&manifest_path) { + Ok(m) => Ok(Some(self.sess.intern_manifest(m))), + Err(e) => Err(e), } - }) - .and_then(move |manifest| { - self.sess - .cache - .dependency_manifest - .lock() - .unwrap() - .insert(dep_id, manifest); - Ok(manifest) - }), - ) + } else { + Ok(None) + } + }) + .and_then(move |manifest| { + self.sess + .cache + .dependency_manifest + .lock() + .unwrap() + .insert(dep_id, manifest); + Ok(manifest) + }) } /// Load the source file manifest. /// /// Loads and returns the source file manifest for the root package and all /// its dependencies.. - pub fn sources(&'io self) -> Box, Error = Error> + 'io> { + pub async fn sources(&'io self) -> Result> { // Check if we already have the source manifest. if let Some(ref cached) = *self.sess.sources.lock().unwrap() { - return Box::new(future::ok((*cached).clone())); + return Ok((*cached).clone()); } // Load the manifests of all packages. - let manifests = join_all( + let ranks = join_all( self.sess .packages() .iter() - .map(move |pkgs| { + .map(move |pkgs| async move { join_all( - pkgs.iter() - .map(move |&pkg| self.dependency_manifest(pkg)) - .collect::>(), - ) + pkgs.iter() + .map(move |&pkg| async move { + self.dependency_manifest(pkg).await.unwrap() + }) + .collect::>(), + ) + .await }) .collect::>(), - ); + ) + .await; // Extract the sources of each package and concatenate them into a long // manifest. - Box::new( - manifests - .and_then(move |ranks| { - use std::iter::once; - - // Create HashMap of the export_include_dirs for each package - let mut all_export_include_dirs: HashMap> = HashMap::new(); - let tmp_export_include_dirs: Vec> = ranks - .clone() - .into_iter() - .chain(once(vec![Some(self.sess.manifest)])) - .map(|manifests| { - manifests - .clone() - .into_iter() - .filter_map(|m| m) - .map(|m| { - ( - m.package.name.clone(), - m.export_include_dirs - .iter() - .map(PathBuf::as_path) - .collect(), - ) - }) - .collect() - }) - .collect(); - for element in tmp_export_include_dirs { - all_export_include_dirs.extend(element); - } - debugln!( - "export_include_dirs for each package: {:?}", - all_export_include_dirs - ); - let files = ranks + use std::iter::once; + + // Create HashMap of the export_include_dirs for each package + let mut all_export_include_dirs: HashMap> = HashMap::new(); + let tmp_export_include_dirs: Vec> = ranks + .clone() + .into_iter() + .chain(once(vec![Some(self.sess.manifest)])) + .map(|manifests| { + manifests + .clone() + .into_iter() + .filter_map(|m| m) + .map(|m| { + ( + m.package.name.clone(), + m.export_include_dirs.iter().map(PathBuf::as_path).collect(), + ) + }) + .collect() + }) + .collect(); + for element in tmp_export_include_dirs { + all_export_include_dirs.extend(element); + } + debugln!( + "export_include_dirs for each package: {:?}", + all_export_include_dirs + ); + + let files = ranks .into_iter() .chain(once(vec![Some(self.sess.manifest)])) .map(|manifests| { @@ -1176,117 +1134,111 @@ impl<'io, 'sess: 'io, 'ctx: 'sess> SessionIo<'sess, 'ctx> { }) .collect(); - // Create a source group covering all ranks, i.e. the root - // source group. - Ok(SourceGroup { - package: None, - independent: false, - target: TargetSpec::Wildcard, - include_dirs: Vec::new(), - export_incdirs: HashMap::new(), - defines: HashMap::new(), - files: files, - dependencies: Vec::new(), - } - .simplify()) - }) - .and_then(move |sources| { - *self.sess.sources.lock().unwrap() = Some(sources.clone()); - Ok(sources) - }), - ) + // Create a source group covering all ranks, i.e. the root source group. + let sources = SourceGroup { + package: None, + independent: false, + target: TargetSpec::Wildcard, + include_dirs: Vec::new(), + export_incdirs: HashMap::new(), + defines: HashMap::new(), + files: files, + dependencies: Vec::new(), + } + .simplify(); + + *self.sess.sources.lock().unwrap() = Some(sources.clone()); + Ok(sources) } /// Load the plugins declared by any of the dependencies. - pub fn plugins(&'io self) -> Box + 'io> { + pub async fn plugins(&'io self) -> Result<&'ctx Plugins> { // Check if we already have the list of plugins. if let Some(cached) = *self.sess.plugins.lock().unwrap() { - return Box::new(future::ok(cached)); + return Ok(cached); } // Load the manifests of all packages. - let manifests = join_all( + let ranks = join_all( self.sess .packages() .iter() - .map(move |pkgs| { + .map(move |pkgs| async move { join_all( pkgs.iter() - .map(move |&pkg| self.dependency_manifest(pkg).map(move |m| (pkg, m))) + .map(move |&pkg| async move { + self.dependency_manifest(pkg) + .await + .map(move |m| (pkg, m)) + .unwrap() + }) .collect::>(), ) + .await }) .collect::>(), ) - .map(|ranks| { - ranks - .into_iter() - .flat_map(|manifests| { - manifests - .into_iter() - .filter_map(|(pkg, m)| m.map(|m| (pkg, m))) - }) - .collect::>() - }); + .await; + + let manifests = ranks + .into_iter() + .flat_map(|manifests| { + manifests + .into_iter() + .filter_map(|(pkg, m)| m.map(|m| (pkg, m))) + }) + .collect::>(); // Extract the plugins from the manifests. - Box::new( - manifests - .and_then(move |manifests| { - let mut plugins = HashMap::new(); - for (package, manifest) in manifests { - for (name, plugin) in &manifest.plugins { - debugln!( - "sess: plugin `{}` declared by package `{}`", - name, - manifest.package.name - ); - let existing = plugins.insert( - name.clone(), - Plugin { - name: name.clone(), - package: package, - path: plugin.clone(), - }, - ); - if let Some(existing) = existing { - return Err(Error::new(format!( - "Plugin `{}` declared by multiple packages (`{}` and `{}`).", - name, - self.sess.dependency_name(existing.package), - self.sess.dependency_name(package), - ))); - } - } - } - let root_plugins = &self.sess.manifest.plugins; - for (name, plugin) in root_plugins.into_iter() { - debugln!("sess: plugin `{}` declared by root package", name); - let existing = plugins.insert( - name.clone(), - Plugin { - name: name.clone(), - package: DependencyRef(0), // FIXME: unclean implementation - path: plugin.clone(), - }, - ); - if let Some(existing) = existing { - return Err(Error::new(format!( - "Plugin `{}` declared by multiple packages (`{}` and `{}`).", - name, - self.sess.dependency_name(existing.package), - "root", - ))); - } - } - Ok(plugins) - }) - .and_then(move |plugins| { - let allocd = self.sess.arenas.plugins.alloc(plugins) as &_; - *self.sess.plugins.lock().unwrap() = Some(allocd); - Ok(allocd) - }), - ) + let mut plugins = HashMap::new(); + for (package, manifest) in manifests { + for (name, plugin) in &manifest.plugins { + debugln!( + "sess: plugin `{}` declared by package `{}`", + name, + manifest.package.name + ); + let existing = plugins.insert( + name.clone(), + Plugin { + name: name.clone(), + package: package, + path: plugin.clone(), + }, + ); + if let Some(existing) = existing { + return Err(Error::new(format!( + "Plugin `{}` declared by multiple packages (`{}` and `{}`).", + name, + self.sess.dependency_name(existing.package), + self.sess.dependency_name(package), + ))); + } + } + } + let root_plugins = &self.sess.manifest.plugins; + for (name, plugin) in root_plugins.into_iter() { + debugln!("sess: plugin `{}` declared by root package", name); + let existing = plugins.insert( + name.clone(), + Plugin { + name: name.clone(), + package: DependencyRef(0), // FIXME: unclean implementation + path: plugin.clone(), + }, + ); + if let Some(existing) = existing { + return Err(Error::new(format!( + "Plugin `{}` declared by multiple packages (`{}` and `{}`).", + name, + self.sess.dependency_name(existing.package), + "root", + ))); + } + } + let allocd = self.sess.arenas.plugins.alloc(plugins) as &_; + *self.sess.plugins.lock().unwrap() = Some(allocd); + Ok(allocd) } }