From dbe514d67c97dcb16acf88c9151ec8e37c772997 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 1 Nov 2023 16:11:24 -0500 Subject: [PATCH] fix: Always use sparse index --- Cargo.lock | 597 ++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 3 +- src/error.rs | 3 +- src/ops/cargo.rs | 27 +- src/ops/index.rs | 121 +++++++++ src/ops/mod.rs | 1 + src/steps/hook.rs | 4 +- src/steps/mod.rs | 4 +- src/steps/publish.rs | 14 +- src/steps/release.rs | 13 +- src/steps/replace.rs | 4 +- 11 files changed, 733 insertions(+), 58 deletions(-) create mode 100644 src/ops/index.rs diff --git a/Cargo.lock b/Cargo.lock index 0029311f4..dfe17cb8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -86,6 +95,19 @@ dependencies = [ "tempfile", ] +[[package]] +name = "async-compression" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f658e2baef915ba0f26f1f7c42bfb8e12f532a01f449a090ded75ae7a07e9ba2" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + [[package]] name = "atty" version = "0.2.14" @@ -103,12 +125,33 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base16ct" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + [[package]] name = "base64ct" version = "1.6.0" @@ -153,6 +196,12 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +[[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.4" @@ -184,7 +233,6 @@ dependencies = [ "clap", "clap-cargo", "concolor-control", - "crates-index", "difflib", "dirs-next", "dunce", @@ -201,9 +249,11 @@ dependencies = [ "predicates", "quick-error", "regex", + "reqwest", "semver", "serde", "snapbox", + "tame-index", "termcolor", "time", "toml 0.8.6", @@ -408,27 +458,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crates-index" -version = "0.19.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65aa5fcd68f892b56202f15a18a53308b2d489b728958dbce48d2d1f3bbaa685" -dependencies = [ - "git2", - "hex", - "home", - "memchr", - "num_cpus", - "rayon", - "rustc-hash", - "semver", - "serde", - "serde_derive", - "serde_json", - "smol_str", - "toml 0.7.6", -] - [[package]] name = "crates-io" version = "0.36.1" @@ -533,7 +562,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2", + "socket2 0.4.9", "winapi", ] @@ -664,6 +693,15 @@ dependencies = [ "zeroize", ] +[[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" @@ -776,6 +814,54 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -800,6 +886,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "git-conventional" version = "0.12.4" @@ -867,6 +959,25 @@ dependencies = [ "subtle", ] +[[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" @@ -914,9 +1025,6 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] [[package]] name = "hkdf" @@ -945,6 +1053,40 @@ dependencies = [ "windows-sys 0.48.0", ] +[[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" @@ -961,6 +1103,44 @@ dependencies = [ "serde", ] +[[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-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "idna" version = "0.3.0" @@ -1028,6 +1208,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is-terminal" version = "0.4.7" @@ -1173,6 +1359,12 @@ dependencies = [ "autocfg", ] +[[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" @@ -1182,6 +1374,17 @@ 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 0.48.0", +] + [[package]] name = "miow" version = "0.5.0" @@ -1216,6 +1419,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -1319,6 +1531,18 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkcs8" version = "0.10.2" @@ -1488,6 +1712,48 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "async-compression", + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -1499,10 +1765,24 @@ dependencies = [ ] [[package]] -name = "rustc-hash" -version = "1.1.0" +name = "ring" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" @@ -1531,6 +1811,37 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustls" +version = "0.21.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.13" @@ -1561,6 +1872,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sec1" version = "0.7.2" @@ -1624,6 +1945,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 = "sha2" version = "0.10.6" @@ -1663,6 +1996,15 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smol_str" version = "0.2.0" @@ -1713,6 +2055,22 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" version = "0.7.2" @@ -1723,6 +2081,12 @@ dependencies = [ "der", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.10.0" @@ -1746,6 +2110,47 @@ 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 = "tame-index" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239b73acdc37c857aae3832bdc739b937b038e5e8b148191a79545a2beb5af74" +dependencies = [ + "camino", + "home", + "http", + "memchr", + "reqwest", + "semver", + "serde", + "serde_json", + "smol_str", + "thiserror", + "toml 0.7.6", + "twox-hash", +] + [[package]] name = "tar" version = "0.4.38" @@ -1866,6 +2271,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 0.48.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml" version = "0.7.6" @@ -1925,6 +2370,37 @@ dependencies = [ "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.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "trycmd" version = "0.14.19" @@ -1941,6 +2417,16 @@ dependencies = [ "toml_edit 0.20.7", ] +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + [[package]] name = "typenum" version = "1.16.0" @@ -1977,6 +2463,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.3.1" @@ -2025,6 +2517,15 @@ 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" @@ -2056,6 +2557,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.86" @@ -2085,6 +2598,22 @@ version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +[[package]] +name = "web-sys" +version = "0.3.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + [[package]] name = "winapi" version = "0.3.9" @@ -2272,6 +2801,16 @@ 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 0.48.0", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 442c3f7a0..1e0b0af7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,8 @@ vendored-openssl = ["git2/vendored-openssl"] [dependencies] cargo_metadata = "0.18" -crates-index = "0.19" +tame-index = "0.5" +reqwest = { version = "0.11", default-features = false, features = ["blocking", "rustls-tls", "gzip"] } git2 = { version = "0.17.2", default-features = false } toml_edit = "0.20.7" toml = "0.8.6" diff --git a/src/error.rs b/src/error.rs index 6d5dccd66..f7b68ee1d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -31,7 +31,8 @@ process_error_from!(anyhow::Error); process_error_from!(std::io::Error); process_error_from!(semver::Error); process_error_from!(ignore::Error); -process_error_from!(crates_index::Error); +process_error_from!(tame_index::Error); +process_error_from!(reqwest::Error); process_error_from!(cargo_metadata::Error); process_error_from!(toml::ser::Error); process_error_from!(toml_edit::ser::Error); diff --git a/src/ops/cargo.rs b/src/ops/cargo.rs index 1d8356868..7c19a8a96 100644 --- a/src/ops/cargo.rs +++ b/src/ops/cargo.rs @@ -111,7 +111,7 @@ pub fn publish( } pub fn wait_for_publish( - index: &mut crates_index::Index, + index: &mut crate::ops::index::CratesIoIndex, name: &str, version: &str, timeout: std::time::Duration, @@ -122,9 +122,7 @@ pub fn wait_for_publish( let sleep_time = std::time::Duration::from_secs(1); let mut logged = false; loop { - if let Err(e) = index.update() { - log::debug!("crate index update failed with {}", e); - } + index.update_krate(name); if is_published(index, name, version) { break; } else if timeout < now.elapsed() { @@ -145,12 +143,21 @@ pub fn wait_for_publish( Ok(()) } -pub fn is_published(index: &crates_index::Index, name: &str, version: &str) -> bool { - let crate_data = index.crate_(name); - crate_data - .iter() - .flat_map(|c| c.versions().iter()) - .any(|v| v.version() == version) +pub fn is_published( + index: &mut crate::ops::index::CratesIoIndex, + name: &str, + version: &str, +) -> bool { + match index.has_krate_version(name, version) { + Ok(has_krate_version) => has_krate_version.unwrap_or(false), + Err(err) => { + // For both http and git indices, this _might_ be an error that goes away in + // a future call, but at least printing out something should give the user + // an indication something is amiss + log::warn!("failed to read metadata for {name}: {err:#}"); + false + } + } } pub fn set_workspace_version( diff --git a/src/ops/index.rs b/src/ops/index.rs new file mode 100644 index 000000000..0b75a1611 --- /dev/null +++ b/src/ops/index.rs @@ -0,0 +1,121 @@ +use tame_index::krate::IndexKrate; + +pub struct CratesIoIndex { + index: RemoteIndex, + cache: std::collections::HashMap>, +} + +impl CratesIoIndex { + #[inline] + pub fn open() -> Result { + Ok(Self { + index: RemoteIndex::open()?, + cache: Default::default(), + }) + } + + /// Determines if the specified crate exists in the crates.io index + #[inline] + pub fn has_krate(&mut self, name: &str) -> Result { + Ok(self.krate(name)?.map(|_| true).unwrap_or(false)) + } + + /// Determines if the specified crate version exists in the crates.io index + #[inline] + pub fn has_krate_version( + &mut self, + name: &str, + version: &str, + ) -> Result, crate::error::CliError> { + let krate = self.krate(name)?; + Ok(krate.map(|ik| ik.versions.iter().any(|iv| iv.version == version))) + } + + #[inline] + pub fn update_krate(&mut self, name: &str) { + self.cache.remove(name); + } + + pub(crate) fn krate( + &mut self, + name: &str, + ) -> Result, crate::error::CliError> { + if let Some(entry) = self.cache.get(name) { + log::trace!("Reusing index for {name}"); + return Ok(entry.clone()); + } + + log::trace!("Downloading index for {name}"); + let entry = self.index.krate(name)?; + self.cache.insert(name.to_owned(), entry.clone()); + Ok(entry) + } +} + +pub struct RemoteIndex { + index: tame_index::SparseIndex, + client: reqwest::blocking::Client, + etags: Vec<(String, String)>, +} + +impl RemoteIndex { + #[inline] + pub fn open() -> Result { + let index = tame_index::SparseIndex::new(tame_index::IndexLocation::new( + tame_index::IndexUrl::CratesIoSparse, + ))?; + let client = reqwest::blocking::ClientBuilder::new() + .http2_prior_knowledge() + .build()?; + + Ok(Self { + index, + client, + etags: Vec::new(), + }) + } + + pub(crate) fn krate( + &mut self, + name: &str, + ) -> Result, crate::error::CliError> { + let etag = self + .etags + .iter() + .find_map(|(krate, etag)| (krate == name).then_some(etag.as_str())) + .unwrap_or(""); + + let krate_name = name.try_into()?; + let req = self.index.make_remote_request(krate_name, Some(etag))?; + let res = self.client.execute(req.try_into()?)?; + + // Grab the etag if it exists for future requests + if let Some(etag) = res.headers().get(reqwest::header::ETAG) { + if let Ok(etag) = etag.to_str() { + if let Some(i) = self.etags.iter().position(|(krate, _)| krate == name) { + self.etags[i].1 = etag.to_owned(); + } else { + self.etags.push((name.to_owned(), etag.to_owned())); + } + } + } + + let mut builder = tame_index::external::http::Response::builder() + .status(res.status()) + .version(res.version()); + + builder + .headers_mut() + .unwrap() + .extend(res.headers().iter().map(|(k, v)| (k.clone(), v.clone()))); + + let body = res.bytes()?; + let response = builder + .body(body.to_vec()) + .map_err(|e| tame_index::Error::from(tame_index::error::HttpError::from(e)))?; + + self.index + .parse_remote_response(krate_name, response, false) + .map_err(Into::into) + } +} diff --git a/src/ops/mod.rs b/src/ops/mod.rs index 39e92464c..d7b9c7469 100644 --- a/src/ops/mod.rs +++ b/src/ops/mod.rs @@ -1,6 +1,7 @@ pub mod cargo; pub mod cmd; pub mod git; +pub mod index; pub mod replace; pub mod shell; pub mod version; diff --git a/src/steps/hook.rs b/src/steps/hook.rs index 744896961..6f57d3f89 100644 --- a/src/steps/hook.rs +++ b/src/steps/hook.rs @@ -47,7 +47,7 @@ pub struct HookStep { impl HookStep { pub fn run(&self) -> Result<(), CliError> { git::git_version()?; - let index = crates_index::Index::new_cargo_default()?; + let mut index = crate::ops::index::CratesIoIndex::open()?; if self.dry_run { let _ = @@ -87,7 +87,7 @@ impl HookStep { { let version = &pkg.initial_version; if !crate::ops::cargo::is_published( - &index, + &mut index, crate_name, &version.full_version_string, ) { diff --git a/src/steps/mod.rs b/src/steps/mod.rs index d393a821d..6003fa748 100644 --- a/src/steps/mod.rs +++ b/src/steps/mod.rs @@ -213,7 +213,7 @@ pub fn verify_monotonically_increasing( pub fn verify_rate_limit( pkgs: &[plan::PackageRelease], - index: &crates_index::Index, + index: &mut crate::ops::index::CratesIoIndex, dry_run: bool, level: log::Level, ) -> Result { @@ -227,7 +227,7 @@ pub fn verify_rate_limit( for pkg in pkgs { if pkg.config.registry().is_none() && pkg.config.publish() { let crate_name = pkg.meta.name.as_str(); - if index.crate_(crate_name).is_some() { + if index.has_krate(crate_name)? { existing += 1; } else { new += 1; diff --git a/src/steps/publish.rs b/src/steps/publish.rs index a839e2ed3..c411ab6b6 100644 --- a/src/steps/publish.rs +++ b/src/steps/publish.rs @@ -80,13 +80,16 @@ impl PublishStep { let mut pkgs = plan::plan(pkgs)?; - let mut index = crates_index::Index::new_cargo_default()?; + let mut index = crate::ops::index::CratesIoIndex::open()?; for pkg in pkgs.values_mut() { if pkg.config.registry().is_none() && pkg.config.release() { let crate_name = pkg.meta.name.as_str(); let version = pkg.planned_version.as_ref().unwrap_or(&pkg.initial_version); - if crate::ops::cargo::is_published(&index, crate_name, &version.full_version_string) - { + if crate::ops::cargo::is_published( + &mut index, + crate_name, + &version.full_version_string, + ) { let _ = crate::ops::shell::warn(format!( "disabled due to previous publish ({}), skipping {}", version.full_version_string, crate_name @@ -131,7 +134,8 @@ impl PublishStep { )?; failed |= !super::verify_metadata(&selected_pkgs, dry_run, log::Level::Error)?; - failed |= !super::verify_rate_limit(&selected_pkgs, &index, dry_run, log::Level::Error)?; + failed |= + !super::verify_rate_limit(&selected_pkgs, &mut index, dry_run, log::Level::Error)?; // STEP 1: Release Confirmation super::confirm("Publish", &selected_pkgs, self.no_confirm, dry_run)?; @@ -156,7 +160,7 @@ impl PublishStep { pub fn publish( ws_meta: &cargo_metadata::Metadata, pkgs: &[plan::PackageRelease], - index: &mut crates_index::Index, + index: &mut crate::ops::index::CratesIoIndex, dry_run: bool, ) -> Result<(), CliError> { for pkg in pkgs { diff --git a/src/steps/release.rs b/src/steps/release.rs index ecde41e4b..050c00e42 100644 --- a/src/steps/release.rs +++ b/src/steps/release.rs @@ -46,7 +46,7 @@ pub struct ReleaseStep { impl ReleaseStep { pub fn run(&self) -> Result<(), CliError> { git::git_version()?; - let mut index = crates_index::Index::new_cargo_default()?; + let mut index = crate::ops::index::CratesIoIndex::open()?; if self.dry_run { let _ = @@ -73,7 +73,7 @@ impl ReleaseStep { pkg.bump(level_or_version, self.metadata.as_deref())?; } } - if index.crate_(&pkg.meta.name).is_some() { + if index.has_krate(&pkg.meta.name)? { // Already published, skip it. Use `cargo release owner` for one-time updates pkg.ensure_owners = false; } @@ -101,7 +101,7 @@ impl ReleaseStep { && !explicitly_excluded { let version = &pkg.initial_version; - if !cargo::is_published(&index, crate_name, &version.full_version_string) { + if !cargo::is_published(&mut index, crate_name, &version.full_version_string) { log::debug!( "enabled {}, v{} is unpublished", crate_name, @@ -155,7 +155,7 @@ impl ReleaseStep { if pkg.config.publish() && pkg.config.registry().is_none() { let version = pkg.planned_version.as_ref().unwrap_or(&pkg.initial_version); let crate_name = pkg.meta.name.as_str(); - if !cargo::is_published(&index, crate_name, &version.full_version_string) { + if !cargo::is_published(&mut index, crate_name, &version.full_version_string) { let _ = crate::ops::shell::warn(format!( "disabled by user, skipping {} v{} despite being unpublished", crate_name, version.full_version_string, @@ -198,7 +198,7 @@ impl ReleaseStep { if pkg.config.registry().is_none() { let version = pkg.planned_version.as_ref().unwrap_or(&pkg.initial_version); let crate_name = pkg.meta.name.as_str(); - if cargo::is_published(&index, crate_name, &version.full_version_string) { + if cargo::is_published(&mut index, crate_name, &version.full_version_string) { let _ = crate::ops::shell::error(format!( "{} {} is already published", crate_name, version.full_version_string @@ -231,7 +231,8 @@ impl ReleaseStep { )?; failed |= !super::verify_metadata(&selected_pkgs, dry_run, log::Level::Error)?; - failed |= !super::verify_rate_limit(&selected_pkgs, &index, dry_run, log::Level::Error)?; + failed |= + !super::verify_rate_limit(&selected_pkgs, &mut index, dry_run, log::Level::Error)?; // STEP 1: Release Confirmation super::confirm("Release", &selected_pkgs, self.no_confirm, dry_run)?; diff --git a/src/steps/replace.rs b/src/steps/replace.rs index a91b066c8..d63d27750 100644 --- a/src/steps/replace.rs +++ b/src/steps/replace.rs @@ -43,7 +43,7 @@ pub struct ReplaceStep { impl ReplaceStep { pub fn run(&self) -> Result<(), CliError> { git::git_version()?; - let index = crates_index::Index::new_cargo_default()?; + let mut index = crate::ops::index::CratesIoIndex::open()?; if self.dry_run { let _ = @@ -83,7 +83,7 @@ impl ReplaceStep { { let version = &pkg.initial_version; if !crate::ops::cargo::is_published( - &index, + &mut index, crate_name, &version.full_version_string, ) {