From 1fa0106ca3b7f5671c1677e224db388a7323dcee Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 10 Dec 2023 10:48:21 +0800 Subject: [PATCH] feat: fork aim-downloader into crates/aim-downloader to make it compatible with windows (#996) * feat: support build on windows * revert change * feat: migrate aim source code * revert change * [autofix.ci] apply automated fixes * fix test * remove test dir, skip test * fix test --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- Cargo.lock | 1513 ++---------------------- Cargo.toml | 1 + crates/aim-downloader/Cargo.toml | 26 + crates/aim-downloader/LICENCE.md | 21 + crates/aim-downloader/README.md | 3 + crates/aim-downloader/src/address.rs | 248 ++++ crates/aim-downloader/src/bar.rs | 165 +++ crates/aim-downloader/src/consts.rs | 7 + crates/aim-downloader/src/error.rs | 29 + crates/aim-downloader/src/hash.rs | 77 ++ crates/aim-downloader/src/https.rs | 268 +++++ crates/aim-downloader/src/io.rs | 94 ++ crates/aim-downloader/src/lib.rs | 10 + crates/aim-downloader/src/netrc.rs | 64 + crates/aim-downloader/src/untildify.rs | 80 ++ crates/tabby-download/Cargo.toml | 2 +- crates/tabby-download/src/lib.rs | 4 +- 17 files changed, 1195 insertions(+), 1417 deletions(-) create mode 100644 crates/aim-downloader/Cargo.toml create mode 100644 crates/aim-downloader/LICENCE.md create mode 100644 crates/aim-downloader/README.md create mode 100644 crates/aim-downloader/src/address.rs create mode 100644 crates/aim-downloader/src/bar.rs create mode 100644 crates/aim-downloader/src/consts.rs create mode 100644 crates/aim-downloader/src/error.rs create mode 100644 crates/aim-downloader/src/hash.rs create mode 100644 crates/aim-downloader/src/https.rs create mode 100644 crates/aim-downloader/src/io.rs create mode 100644 crates/aim-downloader/src/lib.rs create mode 100644 crates/aim-downloader/src/netrc.rs create mode 100644 crates/aim-downloader/src/untildify.rs diff --git a/Cargo.lock b/Cargo.lock index 7f452da..c7c2184 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,17 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" -dependencies = [ - "getrandom 0.2.11", - "once_cell", - "version_check", -] - [[package]] name = "ahash" version = "0.8.3" @@ -49,45 +38,25 @@ dependencies = [ ] [[package]] -name = "aim" -version = "1.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "834394bdcdfd397e1f178c47fa67285e4e2581557806dadccaaf8c83259a4c7b" +name = "aim-downloader" +version = "0.7.0-dev" dependencies = [ - "async-ssh2-lite", - "async-std", "async-stream", - "async_ftp", - "autoclap", - "clap 4.4.7", - "crossbeam-utils", + "clap", "custom_error", "dotenvy", - "futures", "futures-util", - "http", + "home", "indicatif", - "lazy_static", - "log", - "melt", - "native-tls", "netrc", - "openssl", - "question", "regex", "reqwest", - "rust-s3", - "self_update", + "serial_test", "sha2", - "skim-navi", - "ssh2", "strfmt", "tokio", "tokio-util", - "untildify", "url-parse", - "uuid 1.4.1", - "warpy", ] [[package]] @@ -192,12 +161,6 @@ dependencies = [ "password-hash", ] -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "ascii" version = "0.9.3" @@ -220,114 +183,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0" -dependencies = [ - "async-lock", - "async-task", - "concurrent-queue", - "fastrand 2.0.1", - "futures-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite", - "log", - "parking", - "polling", - "rustix 0.37.19", - "slab", - "socket2 0.4.9", - "waker-fn", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-ssh2-lite" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb43eaa75050ebe27dfd16e6de7078d9796a251f03c77d7a24c05aa9037c29b" -dependencies = [ - "async-trait", - "futures-util", - "libssh2-sys", - "ssh2", - "tokio", -] - -[[package]] -name = "async-std" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" -dependencies = [ - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - [[package]] name = "async-stream" version = "0.3.5" @@ -350,12 +205,6 @@ dependencies = [ "syn 2.0.28", ] -[[package]] -name = "async-task" -version = "4.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" - [[package]] name = "async-trait" version = "0.1.74" @@ -367,91 +216,12 @@ dependencies = [ "syn 2.0.28", ] -[[package]] -name = "async_ftp" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d101b45e744a5893bba920ed28f0b0f3d7a9c929e97f9cf2117bba5accadb76b" -dependencies = [ - "chrono", - "lazy_static", - "pin-project", - "regex", - "tokio", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "attohttpc" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" -dependencies = [ - "http", - "log", - "native-tls", - "serde", - "serde_json", - "url", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "autoclap" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ef6366b4905691d83749db7d2d14d554b1a15863064ba138ca63a4e3f6130d" -dependencies = [ - "clap 4.4.7", -] - -[[package]] -name = "aws-creds" -version = "0.34.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3776743bb68d4ad02ba30ba8f64373f1be4e082fe47651767171ce75bb2f6cf5" -dependencies = [ - "attohttpc", - "dirs", - "log", - "quick-xml 0.26.0", - "rust-ini", - "serde", - "thiserror", - "time", - "url", -] - -[[package]] -name = "aws-region" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42fed2b9fca70f2908268d057a607f2a906f47edbf856ea8587de9038d264e22" -dependencies = [ - "thiserror", -] - [[package]] name = "axum" version = "0.6.20" @@ -596,12 +366,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "beef" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" - [[package]] name = "bincode" version = "1.3.3" @@ -650,32 +414,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block_on_proc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b872f3528eeeb4370ee73b51194dc1cd93680c2d0eb6c7a223889038d2c1a167" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "blocking" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" -dependencies = [ - "async-channel", - "async-lock", - "async-task", - "fastrand 2.0.1", - "futures-io", - "futures-lite", - "piper", - "tracing", -] - [[package]] name = "bson" version = "1.2.4" @@ -703,12 +441,6 @@ dependencies = [ "serde", ] -[[package]] -name = "build_html" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3108fe6fe7ac796fb7625bdde8fa2b67b5a7731496251ca57c7b8cadd78a16a1" - [[package]] name = "bumpalo" version = "3.13.0" @@ -768,12 +500,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "checked_int_cast" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" - [[package]] name = "chrono" version = "0.4.31" @@ -790,92 +516,38 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap 0.11.0", - "unicode-width", - "vec_map", -] - -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_derive 3.2.25", - "clap_lex 0.2.4", - "indexmap 1.9.3", - "once_cell", - "strsim 0.10.0", - "termcolor", - "textwrap 0.16.0", -] - -[[package]] -name = "clap" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", - "clap_derive 4.4.7", + "clap_derive", ] [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstream", "anstyle", - "clap_lex 0.6.0", + "clap_lex", "strsim 0.10.0", ] -[[package]] -name = "clap_derive" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "clap_derive" version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "syn 2.0.28", ] -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "clap_lex" version = "0.6.0" @@ -920,15 +592,6 @@ dependencies = [ "unreachable", ] -[[package]] -name = "concurrent-queue" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "console" version = "0.15.7" @@ -998,20 +661,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "crossbeam" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" -dependencies = [ - "cfg-if", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - [[package]] name = "crossbeam-channel" version = "0.5.8" @@ -1042,20 +691,10 @@ dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset", "scopeguard", ] -[[package]] -name = "crossbeam-queue" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.16" @@ -1065,31 +704,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossterm" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" -dependencies = [ - "bitflags 1.3.2", - "crossterm_winapi", - "libc", - "mio", - "parking_lot 0.12.1", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" -dependencies = [ - "winapi", -] - [[package]] name = "crunchy" version = "0.2.2" @@ -1236,7 +850,7 @@ dependencies = [ "hashbrown 0.14.0", "lock_api", "once_cell", - "parking_lot_core 0.9.8", + "parking_lot_core", ] [[package]] @@ -1245,16 +859,6 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" -[[package]] -name = "defer-drop" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f613ec9fa66a6b28cdb1842b27f9adf24f39f9afc4dcdd9fdecee4aca7945c57" -dependencies = [ - "crossbeam-channel", - "once_cell", -] - [[package]] name = "deranged" version = "0.3.8" @@ -1264,34 +868,13 @@ dependencies = [ "serde", ] -[[package]] -name = "derive_builder" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" -dependencies = [ - "derive_builder_macro 0.11.2", -] - [[package]] name = "derive_builder" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" dependencies = [ - "derive_builder_macro 0.12.0", -] - -[[package]] -name = "derive_builder_core" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" -dependencies = [ - "darling 0.14.4", - "proc-macro2", - "quote", - "syn 1.0.109", + "derive_builder_macro", ] [[package]] @@ -1306,23 +889,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_builder_macro" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" -dependencies = [ - "derive_builder_core 0.11.2", - "syn 1.0.109", -] - [[package]] name = "derive_builder_macro" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" dependencies = [ - "derive_builder_core 0.12.0", + "derive_builder_core", "syn 1.0.109", ] @@ -1357,16 +930,6 @@ dependencies = [ "dirs-sys", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.3.7" @@ -1378,23 +941,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - [[package]] name = "dotenvy" version = "0.15.7" @@ -1428,32 +974,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "env_logger" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1490,12 +1010,6 @@ dependencies = [ "backtrace", ] -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -1523,12 +1037,6 @@ dependencies = [ "instant", ] -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - [[package]] name = "file-rotate" version = "0.7.5" @@ -1548,18 +1056,6 @@ dependencies = [ "regex", ] -[[package]] -name = "filetime" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", -] - [[package]] name = "fixedbitset" version = "0.4.2" @@ -1633,9 +1129,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -1643,9 +1139,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-enum" @@ -1671,30 +1167,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", @@ -1703,21 +1184,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -1731,15 +1212,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fuzzy-matcher" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" -dependencies = [ - "thread_local", -] - [[package]] name = "generator" version = "0.7.4" @@ -1820,18 +1292,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "graphql-parser" version = "0.3.0" @@ -1866,9 +1326,6 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.7", -] [[package]] name = "hashbrown" @@ -1876,7 +1333,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" dependencies = [ - "ahash 0.8.3", + "ahash", ] [[package]] @@ -1885,7 +1342,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" dependencies = [ - "ahash 0.8.3", + "ahash", "allocator-api2", ] @@ -1898,55 +1355,12 @@ dependencies = [ "hashbrown 0.14.0", ] -[[package]] -name = "headers" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" -dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.2.6" @@ -1969,12 +1383,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "hmac" -version = "0.12.1" +name = "home" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "digest", + "windows-sys 0.48.0", ] [[package]] @@ -1985,9 +1399,9 @@ checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -2226,18 +1640,6 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix 0.37.19", - "windows-sys 0.48.0", -] - [[package]] name = "itertools" version = "0.10.5" @@ -2299,7 +1701,7 @@ checksum = "155c4d7e39ad04c172c5e3a99c434ea3b4a7ba7960b38ecd562b270b097cce09" dependencies = [ "base64 0.21.2", "pem", - "ring 0.17.5", + "ring", "serde", "serde_json", "simple_asn1", @@ -2382,15 +1784,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -2430,32 +1823,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "libssh2-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" -dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "libz-sys" -version = "1.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "link-cplusplus" version = "1.0.8" @@ -2492,19 +1859,13 @@ dependencies = [ "cmake", "cxx", "cxx-build", - "derive_builder 0.12.0", + "derive_builder", "futures", "tabby-inference", "tokio", "tracing", ] -[[package]] -name = "local_ipaddress" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6a104730949fbc4c78e4fa98ed769ca0faa02e9818936b61032d2d77526afa9" - [[package]] name = "lock_api" version = "0.4.10" @@ -2520,9 +1881,6 @@ name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -dependencies = [ - "value-bag", -] [[package]] name = "loom" @@ -2586,23 +1944,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" -[[package]] -name = "maybe-async" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" - [[package]] name = "measure_time" version = "0.8.2" @@ -2613,17 +1954,6 @@ dependencies = [ "log", ] -[[package]] -name = "melt" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84430eac06413c4a10503a074afa33850fa18695ec48e3f1aca16a634488490b" -dependencies = [ - "anyhow", - "clap 3.2.25", - "once_cell", -] - [[package]] name = "memchr" version = "2.6.2" @@ -2645,15 +1975,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "374c335b2df19e62d4cb323103473cbc6510980253119180de862d89184f6a83" -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.8.0" @@ -2669,7 +1990,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" dependencies = [ - "ahash 0.8.3", + "ahash", "metrics-macros", "portable-atomic", ] @@ -2734,15 +2055,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "minidom" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f45614075738ce1b77a1768912a60c0227525971b03e09122a05b8a34a2a6278" -dependencies = [ - "rxml", -] - [[package]] name = "minijinja" version = "1.0.8" @@ -2780,32 +2092,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.6" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", -] - -[[package]] -name = "multer" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "log", - "memchr", - "mime", - "spin 0.9.8", - "version_check", + "windows-sys 0.48.0", ] [[package]] @@ -2844,31 +2137,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9a91b326434fca226707ed8ec1fd22d4e1c96801abdf10c412afdc7d97116e0" -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", -] - -[[package]] -name = "nix" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.6.5", - "pin-utils", -] - [[package]] name = "nom" version = "4.1.1" @@ -3022,9 +2290,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.59" +version = "0.10.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" dependencies = [ "bitflags 2.4.0", "cfg-if", @@ -3052,24 +2320,14 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "300.1.6+3.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439fac53e092cd7442a3660c85dde4643ab3b5bd39040912388dcdabf6b88085" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" -version = "0.9.95" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -3154,22 +2412,6 @@ dependencies = [ "tokio-stream", ] -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown 0.12.3", -] - -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - [[package]] name = "overload" version = "0.1.1" @@ -3185,23 +2427,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "parking" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -3209,21 +2434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -3359,39 +2570,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" -dependencies = [ - "atomic-waker", - "fastrand 2.0.1", - "futures-io", -] - [[package]] name = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.48.0", -] - [[package]] name = "portable-atomic" version = "1.3.2" @@ -3464,7 +2648,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", - "heck 0.4.1", + "heck", "itertools 0.10.5", "lazy_static", "log", @@ -3501,25 +2685,6 @@ dependencies = [ "prost", ] -[[package]] -name = "qr2term" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2a1e77b5cd714b04247ad912b7c8fe9a1fe1d58425048249def91bcf690e4c" -dependencies = [ - "crossterm", - "qrcode", -] - -[[package]] -name = "qrcode" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d2f1455f3630c6e5107b4f2b94e74d76dea80736de0981fd27644216cff57f" -dependencies = [ - "checked_int_cast", -] - [[package]] name = "quanta" version = "0.11.1" @@ -3536,31 +2701,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "question" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbb3ede7a8f9a8ab89e714637f2cf40001b58f21340d4242b2f11533e65fa8d" - -[[package]] -name = "quick-xml" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea" -dependencies = [ - "memchr", -] - -[[package]] -name = "quick-xml" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "quote" version = "1.0.32" @@ -3672,18 +2812,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "rcgen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" -dependencies = [ - "pem", - "ring 0.16.20", - "time", - "yasna", -] - [[package]] name = "redox_syscall" version = "0.2.16" @@ -3810,21 +2938,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.5" @@ -3834,8 +2947,8 @@ dependencies = [ "cc", "getrandom 0.2.11", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.48.0", ] @@ -3957,50 +3070,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", -] - -[[package]] -name = "rust-s3" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b2ac5ff6acfbe74226fa701b5ef793aaa054055c13ebb7060ad36942956e027" -dependencies = [ - "async-trait", - "aws-creds", - "aws-region", - "base64 0.13.1", - "block_on_proc", - "bytes", - "cfg-if", - "futures", - "hex", - "hmac", - "http", - "log", - "maybe-async", - "md5", - "minidom", - "percent-encoding", - "quick-xml 0.26.0", - "reqwest", - "serde", - "serde_derive", - "sha2", - "thiserror", - "time", - "tokio", - "tokio-stream", - "url", -] - [[package]] name = "rust-stemmers" version = "1.2.0" @@ -4050,60 +3119,12 @@ 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 0.17.5", - "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 0.21.2", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring 0.17.5", - "untrusted 0.9.0", -] - [[package]] name = "rustversion" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" -[[package]] -name = "rxml" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98f186c7a2f3abbffb802984b7f1dfd65dac8be1aafdaabbca4137f53f0dff7" -dependencies = [ - "bytes", - "rxml_validation", - "smartstring", -] - -[[package]] -name = "rxml_validation" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" - [[package]] name = "ryu" version = "1.0.13" @@ -4146,16 +3167,6 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.5", - "untrusted 0.9.0", -] - [[package]] name = "security-framework" version = "2.9.2" @@ -4179,45 +3190,12 @@ dependencies = [ "libc", ] -[[package]] -name = "self-replace" -version = "1.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56335359191626938ef6fdeb478f9f6a7c6020254d7f4641c7d810369fa0ec1" -dependencies = [ - "fastrand 1.9.0", - "tempfile", - "windows-sys 0.48.0", -] - [[package]] name = "self_cell" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c309e515543e67811222dbc9e3dd7e1056279b782e1dacffe4242b718734fb6" -[[package]] -name = "self_update" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b3c585a1ced6b97ac13bd5e56f66559e5a75f477da5913f70df98e114518446" -dependencies = [ - "either", - "flate2", - "hyper", - "indicatif", - "log", - "quick-xml 0.23.1", - "regex", - "reqwest", - "self-replace", - "semver", - "serde_json", - "tar", - "tempfile", - "urlencoding", -] - [[package]] name = "semver" version = "1.0.20" @@ -4322,6 +3300,31 @@ dependencies = [ "trackable", ] +[[package]] +name = "serial_test" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" +dependencies = [ + "dashmap", + "futures", + "lazy_static", + "log", + "parking_lot", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + [[package]] name = "sha1" version = "0.10.6" @@ -4375,33 +3378,6 @@ dependencies = [ "dirs", ] -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" -dependencies = [ - "libc", - "mio", - "signal-hook", -] - [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -4432,45 +3408,6 @@ dependencies = [ "serde", ] -[[package]] -name = "skim" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d28de0a6cb2cdd83a076f1de9d965b973ae08b244df1aa70b432946dda0f32" -dependencies = [ - "atty", - "beef", - "bitflags 1.3.2", - "chrono", - "clap 3.2.25", - "crossbeam", - "defer-drop", - "derive_builder 0.11.2", - "env_logger 0.9.3", - "fuzzy-matcher", - "lazy_static", - "log", - "nix 0.25.1", - "rayon", - "regex", - "shlex", - "time", - "timer", - "tuikit", - "unicode-width", - "vte", -] - -[[package]] -name = "skim-navi" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a7f93531ccb9a93c32997e271b372cb0a700de5663318b64ae04cf20cb8b7ae" -dependencies = [ - "log", - "skim", -] - [[package]] name = "slab" version = "0.4.8" @@ -4517,30 +3454,12 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -[[package]] -name = "ssh2" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7fe461910559f6d5604c3731d00d2aafc4a83d1665922e280f42f9a168d5455" -dependencies = [ - "bitflags 1.3.2", - "libc", - "libssh2-sys", - "parking_lot 0.11.2", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -4559,12 +3478,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65" -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.9.3" @@ -4577,30 +3490,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap 2.34.0", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "strum" version = "0.24.1" @@ -4616,7 +3505,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "rustversion", @@ -4706,7 +3595,7 @@ dependencies = [ "axum-streams", "axum-tracing-opentelemetry", "chrono", - "clap 4.4.7", + "clap", "futures", "http-api-bindings", "hyper", @@ -4740,7 +3629,7 @@ dependencies = [ "tracing-subscriber 0.3.17", "utoipa", "utoipa-swagger-ui", - "uuid 1.4.1", + "uuid 1.6.1", "vergen", ] @@ -4761,14 +3650,14 @@ dependencies = [ "tantivy", "thiserror", "utoipa", - "uuid 1.4.1", + "uuid 1.6.1", ] [[package]] name = "tabby-download" version = "0.7.0-dev" dependencies = [ - "aim", + "aim-downloader", "anyhow", "sha256", "tabby-common", @@ -4783,7 +3672,7 @@ dependencies = [ "async-stream", "async-trait", "dashmap", - "derive_builder 0.12.0", + "derive_builder", "futures", "regex", "tabby-common", @@ -4854,7 +3743,7 @@ dependencies = [ "tower-http 0.4.0", "tracing", "unicase", - "uuid 1.4.1", + "uuid 1.6.1", "validator", ] @@ -4906,7 +3795,7 @@ dependencies = [ "tempfile", "thiserror", "time", - "uuid 1.4.1", + "uuid 1.6.1", "winapi", ] @@ -4998,17 +3887,6 @@ dependencies = [ "serde", ] -[[package]] -name = "tar" -version = "0.4.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" -dependencies = [ - "filetime", - "libc", - "xattr", -] - [[package]] name = "tarpc" version = "0.33.0" @@ -5057,23 +3935,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", - "fastrand 1.9.0", + "fastrand", "redox_syscall 0.3.5", "rustix 0.37.19", "windows-sys 0.45.0", ] -[[package]] -name = "term" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" -dependencies = [ - "dirs-next", - "rustversion", - "winapi", -] - [[package]] name = "termcolor" version = "1.2.0" @@ -5099,21 +3966,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d321c8576c2b47e43953e9cce236550d4cd6af0a6ce518fe084340082ca6037b" -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" version = "1.0.49" @@ -5174,15 +4026,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "timer" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31d42176308937165701f50638db1c31586f183f1aab416268216577aec7306b" -dependencies = [ - "chrono", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -5200,16 +4043,16 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.5", @@ -5229,7 +4072,7 @@ dependencies = [ "num-traits", "tokio", "tracing", - "uuid 1.4.1", + "uuid 1.6.1", ] [[package]] @@ -5244,9 +4087,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", @@ -5285,16 +4128,6 @@ dependencies = [ "tokio", ] -[[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-serde" version = "0.8.0" @@ -5332,16 +4165,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", "futures-io", "futures-sink", "futures-util", - "hashbrown 0.12.3", + "hashbrown 0.14.0", "pin-project-lite", "slab", "tokio", @@ -5762,20 +4595,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "tuikit" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e19c6ab038babee3d50c8c12ff8b910bdb2196f62278776422f50390d8e53d8" -dependencies = [ - "bitflags 1.3.2", - "lazy_static", - "log", - "nix 0.24.3", - "term", - "unicode-width", -] - [[package]] name = "tungstenite" version = "0.20.1" @@ -5837,12 +4656,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - [[package]] name = "unicode-width" version = "0.1.10" @@ -5858,21 +4671,6 @@ dependencies = [ "void", ] -[[package]] -name = "untildify" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992d9e1100cf171942054a07eef9a04986cc8acdb1f771be47accaa301a46bb7" -dependencies = [ - "regex", -] - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -5899,12 +4697,6 @@ dependencies = [ "regex", ] -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - [[package]] name = "utf-8" version = "0.7.6" @@ -5974,9 +4766,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.4.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "getrandom 0.2.11", "rand 0.8.5", @@ -5986,9 +4778,9 @@ dependencies = [ [[package]] name = "uuid-macro-internal" -version = "1.4.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e1ba1f333bd65ce3c9f27de592fcbc256dafe3af2717f56d7c87761fbaccf4" +checksum = "f49e7f3f3db8040a100710a11932239fd30697115e2ba4107080d8252939845e" dependencies = [ "proc-macro2", "quote", @@ -6043,24 +4835,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "value-bag" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" - [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "vergen" version = "8.2.4" @@ -6084,33 +4864,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -[[package]] -name = "vte" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" -dependencies = [ - "arrayvec", - "utf8parse", - "vte_generate_state_changes", -] - -[[package]] -name = "vte_generate_state_changes" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "waker-fn" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" - [[package]] name = "walkdir" version = "2.3.3" @@ -6131,56 +4884,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "warp" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e92e22e03ff1230c03a1a8ee37d2f89cd489e2e541b7550d6afad96faed169" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "headers", - "http", - "hyper", - "log", - "mime", - "mime_guess", - "multer", - "percent-encoding", - "pin-project", - "rustls-pemfile", - "scoped-tls", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-rustls", - "tokio-stream", - "tokio-tungstenite", - "tokio-util", - "tower-service", - "tracing", -] - -[[package]] -name = "warpy" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df67bc1a6a0058a4669ea9490039bce754d5cad4af590334ccb3b4579cfedf1" -dependencies = [ - "build_html", - "chrono", - "env_logger 0.10.0", - "local_ipaddress", - "log", - "qr2term", - "rcgen", - "structopt", - "tokio", - "warp", -] - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -6511,24 +5214,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "xattr" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" -dependencies = [ - "libc", -] - -[[package]] -name = "yasna" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" -dependencies = [ - "time", -] - [[package]] name = "zip" version = "0.6.6" diff --git a/Cargo.toml b/Cargo.toml index 5e4c1fb..28fcc1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "crates/tabby-inference", "crates/llama-cpp-bindings", "crates/http-api-bindings", + "crates/aim-downloader", "crates/juniper-axum", "ee/tabby-webserver", ] diff --git a/crates/aim-downloader/Cargo.toml b/crates/aim-downloader/Cargo.toml new file mode 100644 index 0000000..a3efba3 --- /dev/null +++ b/crates/aim-downloader/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "aim-downloader" +version.workspace = true +edition.workspace = true +authors.workspace = true +homepage.workspace = true + +[dependencies] +async-stream = "0.3.5" +clap = { version = "4.4.11", features = ["cargo", "string"] } +custom_error = "1.9.2" +dotenvy = "0.15.7" +futures-util = "0.3.29" +home = "0.5.5" +indicatif = "0.17.7" +netrc = "0.4.1" +regex.workspace = true +reqwest = { workspace = true, features = ["stream"] } +sha2 = "0.10.8" +strfmt = "0.2.4" +tokio = { workspace = true, features = ["full"] } +tokio-util = { version="0.7.10", features = ["full"] } +url-parse = "1.0.7" + +[dev-dependencies] +serial_test = "2.0.0" diff --git a/crates/aim-downloader/LICENCE.md b/crates/aim-downloader/LICENCE.md new file mode 100644 index 0000000..2f01378 --- /dev/null +++ b/crates/aim-downloader/LICENCE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-3021 Mihai Galos + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/aim-downloader/README.md b/crates/aim-downloader/README.md new file mode 100644 index 0000000..8a3da43 --- /dev/null +++ b/crates/aim-downloader/README.md @@ -0,0 +1,3 @@ +# http_downloader + +Adopted from https://github.com/mihaigalos/aim \ No newline at end of file diff --git a/crates/aim-downloader/src/address.rs b/crates/aim-downloader/src/address.rs new file mode 100644 index 0000000..f336ac0 --- /dev/null +++ b/crates/aim-downloader/src/address.rs @@ -0,0 +1,248 @@ +use url_parse::core::Parser; + +use crate::netrc::netrc; + +#[derive(Debug)] +pub struct ParsedAddress { + pub server: String, + pub username: String, + pub password: String, + pub path_segments: Vec, + pub file: String, +} + +impl PartialEq for ParsedAddress { + fn eq(&self, other: &Self) -> bool { + let result = self.server == other.server + && self.username == other.username + && self.password == other.password + && self.file == other.file; + + let mut paths_equal = true; + for it in self.path_segments.iter().zip(self.path_segments.iter()) { + let (left, right) = it; + paths_equal = paths_equal && (left == right); + } + + result && paths_equal + } +} + +impl ParsedAddress { + pub fn parse_address(address: &str, silent: bool) -> ParsedAddress { + let netrc = netrc(silent); + let url = Parser::new(None).parse(address).unwrap(); + let server = format!( + "{}:{}", + url.host_str() + .ok_or_else(|| panic!("failed to parse hostname from url: {url}")) + .unwrap(), + url.port_or_known_default() + .ok_or_else(|| panic!("failed to parse port from url: {url}")) + .unwrap(), + ); + + let url_username = url.username(); + let username = if url_username.is_none() { + "anonymous".to_string() + } else { + url.username().unwrap() + }; + + let password = url.password().unwrap_or_else(|| "anonymous".to_string()); + if !silent && username != "anonymous" && password != "anonymous" { + println!("🔑 Parsed credentials from URL."); + } + + let (username, password) = ParsedAddress::mixin_netrc(&netrc, &server, username, password); + + let mut path_segments: Vec = url + .path_segments() + .ok_or_else(|| panic!("failed to get url path segments: {url}")) + .unwrap(); + + let file = path_segments + .pop() + .ok_or_else(|| panic!("got empty path segments from url: {url}")) + .unwrap(); + + ParsedAddress { + server, + username, + password, + path_segments, + file, + } + } + + fn mixin_netrc( + netrc: &Option, + server: &str, + username: String, + password: String, + ) -> (String, String) { + let mut user = username.clone(); + let mut pass = password.clone(); + if !netrc.is_none() && username == "anonymous" && password == "anonymous" { + for host in netrc.as_ref().unwrap().hosts.iter().enumerate() { + let (_i, (netrc_name, machine)) = host; + + let mut name = netrc_name.to_string(); + if let Some(port) = machine.port { + name = name + ":" + &port.to_string()[..]; + } + if server == name { + user = machine.login.clone(); + pass = machine.password.clone().unwrap(); + break; + } + } + } + (user, pass) + } +} + +#[tokio::test] +async fn parseaddress_operator_equals_works_when_typical() { + let left = ParsedAddress { + server: "do.main".to_string(), + username: "user".to_string(), + password: "pass".to_string(), + path_segments: vec!["my".to_string(), "path".to_string()], + file: "pass".to_string(), + }; + let right = ParsedAddress { + server: "do.main".to_string(), + username: "user".to_string(), + password: "pass".to_string(), + path_segments: vec!["my".to_string(), "path".to_string()], + file: "pass".to_string(), + }; + + assert!(left == right); +} + +#[tokio::test] +async fn parseaddress_operator_equals_fails_when_not_equal() { + let left = ParsedAddress { + server: "do.main".to_string(), + username: "user".to_string(), + password: "pass".to_string(), + path_segments: vec!["my".to_string(), "path".to_string()], + file: "pass".to_string(), + }; + let right = ParsedAddress { + server: "do".to_string(), + username: "user".to_string(), + password: "pass".to_string(), + path_segments: vec!["my".to_string(), "path".to_string()], + file: "pass".to_string(), + }; + + assert!(left != right); +} + +#[tokio::test] +async fn parse_works() { + let expected = ParsedAddress { + server: "do.main:21".to_string(), + username: "user".to_string(), + password: "pass".to_string(), + path_segments: vec!["index".to_string()], + file: "file".to_string(), + }; + + let actual = ParsedAddress::parse_address("ftp://user:pass@do.main:21/index/file", true); + + assert_eq!(actual, expected); +} + +#[tokio::test] +async fn mixin_works() { + let expected_username = "test"; + let expected_password = "p@ssw0rd"; + let input = "machine example.com login test password p@ssw0rd"; + let input = std::io::BufReader::new(input.as_bytes()); + let netrc = netrc::Netrc::parse(input).unwrap(); + let username_decoded_from_url = "anonymous".to_string(); + let password_decoded_from_url = "anonymous".to_string(); + + let (actual_username, actual_password) = ParsedAddress::mixin_netrc( + &Some(netrc), + "example.com", + username_decoded_from_url, + password_decoded_from_url, + ); + + assert_eq!(actual_username, expected_username); + assert_eq!(actual_password, expected_password); +} + +#[tokio::test] +async fn mixin_works_with_port() { + let expected_username = "test"; + let expected_password = "p@ssw0rd"; + let input = "machine example.com login test password p@ssw0rd port 443"; + let input = std::io::BufReader::new(input.as_bytes()); + let netrc = netrc::Netrc::parse(input).unwrap(); + let username_decoded_from_url = "anonymous".to_string(); + let password_decoded_from_url = "anonymous".to_string(); + + let (actual_username, actual_password) = ParsedAddress::mixin_netrc( + &Some(netrc), + "example.com:443", + username_decoded_from_url, + password_decoded_from_url, + ); + + assert_eq!(actual_username, expected_username); + assert_eq!(actual_password, expected_password); +} + +#[tokio::test] +async fn parse_works_with_netrc_mixin() { + let expected = ParsedAddress { + server: "do.main:21".to_string(), + username: "test".to_string(), + password: "p@ssw0rd".to_string(), + path_segments: vec!["index".to_string()], + file: "file".to_string(), + }; + let data = "machine do.main login test password p@ssw0rd port 21"; + + std::fs::write(".netrc.test", data).expect("Unable to write file"); + let actual = ParsedAddress::parse_address("ftp://do.main/index/file", true); + + assert_eq!(actual, expected); + std::fs::remove_file(".netrc.test").unwrap(); +} + +#[tokio::test] +async fn parse_works_when_ssh_user() { + let expected = ParsedAddress { + server: "localhost:2223".to_string(), + username: "user".to_string(), + password: "anonymous".to_string(), + path_segments: vec!["".to_string()], + file: "file".to_string(), + }; + + let actual = ParsedAddress::parse_address("ssh://user@localhost:2223/file", true); + + assert_eq!(actual, expected); +} + +#[tokio::test] +async fn parse_works_when_not_silent() { + let expected = ParsedAddress { + server: "localhost:2223".to_string(), + username: "user".to_string(), + password: "pass".to_string(), + path_segments: vec!["".to_string()], + file: "file".to_string(), + }; + + let actual = ParsedAddress::parse_address("ssh://user:pass@localhost:2223/file", false); + + assert_eq!(actual, expected); +} diff --git a/crates/aim-downloader/src/bar.rs b/crates/aim-downloader/src/bar.rs new file mode 100644 index 0000000..45e89c3 --- /dev/null +++ b/crates/aim-downloader/src/bar.rs @@ -0,0 +1,165 @@ +use std::{collections::HashMap, env}; + +use dotenvy::dotenv; +use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle}; +use strfmt::strfmt; + +const DEFAULT_AIM_PROGRESSBAR_DOWNLOADED_MESSAGE: &str = "🎯 Downloaded {input} to {output}"; +const DEFAULT_AIM_PROGRESSBAR_MESSAGE_FORMAT: &str = "🎯 Transferring {url}"; +const DEFAULT_AIM_PROGRESSBAR_PROGRESS_CHARS: &str = "█▉▊▋▌▍▎▏ "; +const DEFAULT_AIM_PROGRESSBAR_TEMPLATE: &str = "{msg}\n{spinner:.cyan} {elapsed_precise} ▕{bar:.white}▏ {bytes}/{total_bytes} {bytes_per_sec} ETA {eta}."; +const DEFAULT_AIM_PROGRESSBAR_UPLOADED_MESSAGE: &str = "🎯 Uploaded {input} to {output}"; + +const THRESHOLD_IF_TOTALBYTES_BELOW_THEN_AUTO_SILENT_MODE: u64 = 1024 * 1024; + +fn construct_progress_bar( + total_size: u64, + url: &str, + message_format: &str, + progress_chars: &str, + template: &str, +) -> indicatif::ProgressBar { + let pb = ProgressBar::new(total_size); + pb.set_draw_target(ProgressDrawTarget::hidden()); + let mut vars: HashMap = HashMap::new(); + + if message_format.contains("{url}") { + vars.insert("url".to_string(), url.to_string()); + } + + pb.set_message(strfmt(message_format, &vars).unwrap()); + pb.set_style( + ProgressStyle::default_bar() + .template(template) + .unwrap() + .progress_chars(progress_chars), + ); + pb +} + +pub struct WrappedBar { + pub silent: bool, + pub output: Option, + downloaded_message: String, + uploaded_message: String, +} + +impl WrappedBar { + pub fn new_empty() -> Self { + WrappedBar { + silent: true, + output: None, + downloaded_message: "".to_string(), + uploaded_message: "".to_string(), + } + } + pub fn new_empty_verbose() -> Self { + WrappedBar { + silent: false, + output: None, + downloaded_message: "".to_string(), + uploaded_message: "".to_string(), + } + } + pub fn new(total_size: u64, url: &str, silent: bool) -> Self { + dotenv().ok(); + let message_format = &env::var("AIM_PROGRESSBAR_MESSAGE_FORMAT") + .unwrap_or_else(|_| DEFAULT_AIM_PROGRESSBAR_MESSAGE_FORMAT.to_string()); + let progress_chars = &env::var("AIM_PROGRESSBAR_PROGRESS_CHARS") + .unwrap_or_else(|_| DEFAULT_AIM_PROGRESSBAR_PROGRESS_CHARS.to_string()); + let template = &env::var("AIM_PROGRESSBAR_TEMPLATE") + .unwrap_or_else(|_| DEFAULT_AIM_PROGRESSBAR_TEMPLATE.to_string()); + let downloaded_message = &env::var("AIM_PROGRESSBAR_DOWNLOADED_MESSAGE") + .unwrap_or_else(|_| DEFAULT_AIM_PROGRESSBAR_DOWNLOADED_MESSAGE.to_string()); + let uploaded_message = &env::var("AIM_PROGRESSBAR_UPLOADED_MESSAGE") + .unwrap_or_else(|_| DEFAULT_AIM_PROGRESSBAR_UPLOADED_MESSAGE.to_string()); + let output = match silent { + false => Some(construct_progress_bar( + total_size, + url, + message_format, + progress_chars, + template, + )), + true => None, + }; + WrappedBar { + silent, + output, + downloaded_message: downloaded_message.to_string(), + uploaded_message: uploaded_message.to_string(), + } + } + + pub fn set_length(&mut self, len: u64) { + if len < THRESHOLD_IF_TOTALBYTES_BELOW_THEN_AUTO_SILENT_MODE { + self.silent = true; + } + if !self.silent { + self.output + .as_ref() + .unwrap() + .set_draw_target(ProgressDrawTarget::stderr()); + self.output.as_ref().unwrap().set_length(len); + } + } + + pub fn set_position(&self, pos: u64) { + if !self.silent { + self.output.as_ref().unwrap().set_position(pos); + } + } + + pub fn finish_download(&self, input: &str, output: &str) { + if !self.silent { + let mut vars: HashMap = HashMap::new(); + + if self.downloaded_message.contains("{input}") { + vars.insert("input".to_string(), input.to_string()); + } + + if self.downloaded_message.contains("{output}") { + vars.insert("output".to_string(), output.to_string()); + } + self.output + .as_ref() + .unwrap() + .finish_with_message(strfmt(&self.downloaded_message, &vars).unwrap()); + } + } + pub fn finish_upload(&self, input: &str, output: &str) { + if !self.silent { + let mut vars: HashMap = HashMap::new(); + + if self.uploaded_message.contains("{input}") { + vars.insert("input".to_string(), input.to_string()); + } + + if self.uploaded_message.contains("{output}") { + vars.insert("output".to_string(), output.to_string()); + } + self.output + .as_ref() + .unwrap() + .finish_with_message(strfmt(&self.uploaded_message, &vars).unwrap()); + } + } +} + +#[test] +fn test_bar_finish_download_works_when_typical() { + let bar = WrappedBar::new(42, "url", false); + bar.finish_download("", ""); +} + +#[test] +fn test_bar_finish_upload_works_when_typical() { + let bar = WrappedBar::new(42, "url", false); + bar.finish_upload("", ""); +} + +#[test] +fn test_bar_set_length_works_when_typical() { + let mut bar = WrappedBar::new(42, "url", false); + bar.set_length(42); +} diff --git a/crates/aim-downloader/src/consts.rs b/crates/aim-downloader/src/consts.rs new file mode 100644 index 0000000..78cfc0f --- /dev/null +++ b/crates/aim-downloader/src/consts.rs @@ -0,0 +1,7 @@ +use clap::crate_version; + +pub const CLIENT_ID: &str = concat!( + env!("CARGO_PKG_REPOSITORY"), + "/releases/tag/", + crate_version!() +); diff --git a/crates/aim-downloader/src/error.rs b/crates/aim-downloader/src/error.rs new file mode 100644 index 0000000..03150c9 --- /dev/null +++ b/crates/aim-downloader/src/error.rs @@ -0,0 +1,29 @@ +extern crate custom_error; +use custom_error::custom_error; + +custom_error! { + pub ValidateError + Sha256Mismatch = "Invalid sha256.", +} + +custom_error! { + pub HTTPHeaderError + NotPresent = "Cannot find requested header.", +} + +impl From for std::io::Error { + fn from(cause: ValidateError) -> std::io::Error { + std::io::Error::new(std::io::ErrorKind::Other, cause.to_string()) + } +} + +#[test] +fn test_from_validate_error_to_std_io_error_works_when_typical() { + let _ = match Err(ValidateError::Sha256Mismatch) { + Ok(v) => v, + Err(e) => { + let error: std::io::Error = e.into(); + error + } + }; +} diff --git a/crates/aim-downloader/src/hash.rs b/crates/aim-downloader/src/hash.rs new file mode 100644 index 0000000..d754470 --- /dev/null +++ b/crates/aim-downloader/src/hash.rs @@ -0,0 +1,77 @@ +use std::{fs, io, str}; + +use sha2::{Digest, Sha256}; + +use crate::error::ValidateError; + +pub struct HashChecker; +impl HashChecker { + pub fn check(filename: &str, expected_hash: &str) -> Result<(), ValidateError> { + let mut result = Ok(()); + if filename != "stdout" && (!expected_hash.is_empty()) { + let actual_hash = HashChecker::sha256sum(filename); + if actual_hash != expected_hash { + result = Err(ValidateError::Sha256Mismatch); + } + match result { + Ok(()) => println!("✅ Checksum OK."), + Err(ValidateError::Sha256Mismatch) => println!( + "❌ Checksum verification failed for {filename}:\n expected: {expected_hash}\n got: {actual_hash}"), + } + } + result + } + + fn sha256sum(filename: &str) -> String { + let mut hasher = Sha256::new(); + let mut file = fs::File::open(filename).unwrap(); + + io::copy(&mut file, &mut hasher).unwrap(); + let computed_hash = hasher.finalize(); + drop(file); + + format!("{computed_hash:x}") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! assert_err { + ($expression:expr, $($pattern:tt)+) => { + match $expression { + $($pattern)+ => (), + ref e => panic!("expected `{}` but got `{:?}`", stringify!($($pattern)+), e), + } + } + } + + #[test] + fn test_check_api_fails_when_checksum_mismatch() { + let expected = "AAAA847124bfb9d9a9d44af6f00d8003006c44b9ef9ba458b5d4d3fc5f81bde5"; + + assert_err!( + HashChecker::check("LICENCE.md", expected), + Err(ValidateError::Sha256Mismatch) + ); + } + + #[test] + fn test_sha256sum_api() { + let expected = "21d7847124bfb9d9a9d44af6f00d8003006c44b9ef9ba458b5d4d3fc5f81bde5"; + + let actual = HashChecker::sha256sum("LICENCE.md"); + + assert_eq!(actual, expected); + } + + #[test] + fn test_check_api_works_when_typical() { + let expected = "21d7847124bfb9d9a9d44af6f00d8003006c44b9ef9ba458b5d4d3fc5f81bde5"; + + let is_match = HashChecker::check("LICENCE.md", expected).is_ok(); + + assert!(is_match); + } +} diff --git a/crates/aim-downloader/src/https.rs b/crates/aim-downloader/src/https.rs new file mode 100644 index 0000000..399535b --- /dev/null +++ b/crates/aim-downloader/src/https.rs @@ -0,0 +1,268 @@ +use std::{cmp::min, io::Error}; + +use futures_util::StreamExt; +use regex::Regex; +use reqwest::Client; +use tokio_util::io::ReaderStream; + +use crate::{ + address::ParsedAddress, bar::WrappedBar, consts::*, error::ValidateError, hash::HashChecker, io, +}; + +pub struct HTTPSHandler; +impl HTTPSHandler { + pub async fn get( + input: &str, + output: &str, + bar: &mut WrappedBar, + expected_sha256: &str, + ) -> Result<(), ValidateError> { + HTTPSHandler::_get(input, output, bar).await?; + HashChecker::check(output, expected_sha256) + } + + pub async fn put(input: &str, output: &str, mut bar: WrappedBar) -> Result<(), ValidateError> { + let parsed_address = ParsedAddress::parse_address(output, bar.silent); + let file = tokio::fs::File::open(&input) + .await + .expect("Cannot open input file for HTTPS read"); + let total_size = file + .metadata() + .await + .expect("Cannot determine input file size for HTTPS read") + .len(); + let input_ = input.to_string(); + let output_ = output.to_string(); + let mut reader_stream = ReaderStream::new(file); + + let mut uploaded = HTTPSHandler::get_already_uploaded(output, bar.silent).await; + bar.set_length(total_size); + + let async_stream = async_stream::stream! { + while let Some(chunk) = reader_stream.next().await { + if let Ok(chunk) = &chunk { + let new = min(uploaded + (chunk.len() as u64), total_size); + uploaded = new; + bar.set_position(new); + if uploaded >= total_size { + bar.finish_upload(&input_, &output_); + } + } + yield chunk; + } + }; + + let response = reqwest::Client::new() + .put(output) + .header("content-type", "application/octet-stream") + .header( + "Range", + "bytes=".to_owned() + &uploaded.to_string()[..] + "-", + ) + .header( + reqwest::header::USER_AGENT, + reqwest::header::HeaderValue::from_static(CLIENT_ID), + ) + .basic_auth(parsed_address.username, Some(parsed_address.password)) + .body(reqwest::Body::wrap_stream(async_stream)) + .send() + .await + .unwrap(); + println!("{:?}", response.text().await.unwrap()); + Ok(()) + } + + pub async fn get_links(input: String) -> Result, Error> { + let mut result = Vec::new(); + let res = HTTPSHandler::list(&input).await.unwrap(); + let lines: Vec<&str> = res.split('\n').collect(); + + for line in lines { + let re = Regex::new(r#".*href="/(.+?)".*"#).unwrap(); + let caps = re.captures(line); + if let Some(e) = caps { + result.push(e.get(1).unwrap().as_str().to_string()) + } + } + result.push("..".to_string()); + + result.sort(); + + Ok(result) + } + + async fn list(input: &str) -> Result { + let is_silent = true; + let parsed_address = ParsedAddress::parse_address(input, is_silent); + + let res = Client::new() + .get(input) + .header( + reqwest::header::USER_AGENT, + reqwest::header::HeaderValue::from_static(CLIENT_ID), + ) + .basic_auth(parsed_address.username, Some(parsed_address.password)) + .send() + .await + .map_err(|_| format!("Failed to GET from {}", &input)) + .unwrap() + .text() + .await + .unwrap(); + + Ok(res) + } + + async fn _get(input: &str, output: &str, bar: &mut WrappedBar) -> Result<(), ValidateError> { + let parsed_address = ParsedAddress::parse_address(input, bar.silent); + let (mut out, mut downloaded) = io::get_output(output, bar.silent); + + let res = Client::new() + .get(input) + .header( + "Range", + "bytes=".to_owned() + &downloaded.to_string()[..] + "-", + ) + .header( + reqwest::header::USER_AGENT, + reqwest::header::HeaderValue::from_static(CLIENT_ID), + ) + .basic_auth(parsed_address.username, Some(parsed_address.password)) + .send() + .await + .map_err(|_| format!("Failed to GET from {} to {}", &input, &output)) + .unwrap(); + let total_size = downloaded + res.content_length().unwrap_or(0); + + bar.set_length(total_size); + + let mut stream = res.bytes_stream(); + while let Some(item) = stream.next().await { + let chunk = item.map_err(|_| "Error while downloading.").unwrap(); + out.write_all(&chunk) + .map_err(|_| "Error while writing to output.") + .unwrap(); + let new = min(downloaded + (chunk.len() as u64), total_size); + downloaded = new; + bar.set_position(new); + } + + bar.finish_download(input, output); + Ok(()) + } + + async fn get_already_uploaded(output: &str, silent: bool) -> u64 { + let parsed_address = ParsedAddress::parse_address(output, silent); + let res = Client::new() + .get(output) + .header( + reqwest::header::USER_AGENT, + reqwest::header::HeaderValue::from_static(CLIENT_ID), + ) + .basic_auth(parsed_address.username, Some(parsed_address.password)) + .send() + .await + .map_err(|_| format!("Failed to GET already uploaded size from {}", &output)) + .unwrap(); + res.content_length().unwrap_or(0) + } +} + +#[ignore] +#[tokio::test] +async fn get_https_works() { + let expected_hash = "0e0f0d7139c8c7e3ff20cb243e94bc5993517d88e8be8d59129730607d5c631b"; + let out_file = "tokei-x86_64-unknown-linux-gnu.tar.gz"; + + let result = HTTPSHandler::get("https://github.com/XAMPPRocky/tokei/releases/download/v12.0.4/tokei-x86_64-unknown-linux-gnu.tar.gz", out_file, &mut WrappedBar::new_empty(), expected_hash).await; + + assert!(result.is_ok()); + std::fs::remove_file(out_file).unwrap(); +} + +#[ignore] +#[tokio::test] +async fn get_resume_works() { + let expected_size = 561553; + let out_file = "test/dua-v2.10.2-x86_64-unknown-linux-musl.tar.gz"; + std::fs::copy( + "test/incomplete_dua-v2.10.2-x86_64-unknown-linux-musl.tar.gz", + out_file, + ) + .unwrap(); + + let _ = HTTPSHandler::get("https://github.com/Byron/dua-cli/releases/download/v2.10.2/dua-v2.10.2-x86_64-unknown-linux-musl.tar.gz", out_file, &mut WrappedBar::new_empty_verbose(), "").await; + + let actual_size = std::fs::metadata(out_file).unwrap().len(); + assert_eq!(actual_size, expected_size); + std::fs::remove_file(out_file).unwrap(); +} + +#[ignore] +#[tokio::test] +async fn list_works_when_typical() { + let expected = r#" + + + Example Domain + + + + + + + + +
+

Example Domain

+

This domain is for use in illustrative examples in documents. You may use this + domain in literature without prior coordination or asking for permission.

+

More information...

+
+ + +"#; + + let result = HTTPSHandler::list("https://example.com").await.unwrap(); + let result = str::replace(&result, " \n ", ""); + let result = str::replace(&result, " \n", "\n"); + + assert_eq!(result, expected); +} + +#[ignore] +#[tokio::test] +async fn get_links_works_when_typical() { + let expected = ".."; + + let result = HTTPSHandler::get_links("https://github.com/mihaigalos/aim/releases".to_string()) + .await + .unwrap(); + + assert_eq!(result[0], expected); +} diff --git a/crates/aim-downloader/src/io.rs b/crates/aim-downloader/src/io.rs new file mode 100644 index 0000000..90980df --- /dev/null +++ b/crates/aim-downloader/src/io.rs @@ -0,0 +1,94 @@ +use std::{fs::File, io::Write}; + +fn get_output_file(path: &str, silent: bool) -> (Option, u64) { + let mut transferred: u64 = 0; + let mut file = None; + if path != "stdout" { + if std::path::Path::new(path).exists() { + if !silent { + println!("File exists. Resuming."); + } + file = Some( + std::fs::OpenOptions::new() + .write(true) + .append(true) + .open(path) + .unwrap(), + ); + + let file_size = std::fs::metadata(path).unwrap().len(); + transferred = file_size; + } else { + if !silent { + println!("Writing to new file."); + } + file = Some( + File::create(path) + .map_err(|_| format!("Failed to create file '{path}'")) + .unwrap(), + ); + } + } + (file, transferred) +} + +pub fn get_output(path: &str, silent: bool) -> (Box, u64) { + let (file, transferred) = get_output_file(path, silent); + let output: Box = Box::new(std::io::BufWriter::new(match path { + "stdout" => Box::new(std::io::stdout()) as Box, + _ => Box::new(file.unwrap()) as Box, + })); + + (output, transferred) +} + +#[test] +fn test_get_output_file_file_is_none_when_stdout() { + let is_silet = true; + let (file, _) = get_output_file("stdout", is_silet); + assert!(file.is_none()); +} + +#[test] +fn test_get_output_file_pos_is_zero_when_stdout() { + let is_silet = true; + let (_, position) = get_output_file("stdout", is_silet); + assert_eq!(position, 0); +} + +#[test] +fn test_get_output_file_file_is_none_when_newfile() { + let is_silet = true; + let filename = "test_get_output_file_file_is_none_when_newfile"; + + let (file, _) = get_output_file(filename, is_silet); + + assert!(file.is_some()); + std::fs::remove_file(filename).unwrap(); +} + +#[test] +fn test_get_output_file_file_is_none_when_newfile_and_not_silent() { + let is_silet = false; + let filename = "test_get_output_file_file_is_none_when_newfile_and_not_silent"; + + let (file, _) = get_output_file(filename, is_silet); + + assert!(file.is_some()); + std::fs::remove_file(filename).unwrap(); +} + +#[test] +fn test_get_output_file_file_is_none_when_existingfile_and_not_silent() { + use std::io::Write; + let is_silet = false; + let filename = "test_get_output_file_file_is_none_when_existingfile_and_not_silent"; + let expected_position_byte = 4; + let mut file = File::create(filename).unwrap(); + file.write_all(b"1234").unwrap(); + + let (_, position) = get_output_file(filename, is_silet); + + assert_eq!(position, expected_position_byte); + std::fs::remove_file(filename).unwrap(); +} diff --git a/crates/aim-downloader/src/lib.rs b/crates/aim-downloader/src/lib.rs new file mode 100644 index 0000000..2928603 --- /dev/null +++ b/crates/aim-downloader/src/lib.rs @@ -0,0 +1,10 @@ +pub mod bar; +pub mod https; + +mod address; +mod consts; +mod error; +mod hash; +mod io; +mod netrc; +mod untildify; diff --git a/crates/aim-downloader/src/netrc.rs b/crates/aim-downloader/src/netrc.rs new file mode 100644 index 0000000..9056bcc --- /dev/null +++ b/crates/aim-downloader/src/netrc.rs @@ -0,0 +1,64 @@ +use std::{io::BufReader, path::Path}; + +use netrc::Netrc; + +use crate::untildify::untildify; + +fn get_possible_netrc_path(silent: bool) -> String { + let candidates = vec![ + ".netrc", + ".netrc.test", + ".netrc.test_https", + ".netrc.test_ftp", + ".netrc.test_unit", + "~/.netrc", + ]; + for candidate in candidates { + let candidate = untildify(candidate); + if Path::new(&candidate).exists() { + if !silent { + println!("🔑 Parsed .netrc from: {candidate}"); + } + return candidate; + } + } + "".to_string() +} + +pub fn netrc(silent: bool) -> Option { + let mut result = None; + let path = get_possible_netrc_path(silent); + if !path.is_empty() { + let file = std::fs::File::open(path).unwrap(); + let parsed = Netrc::parse(BufReader::new(file)); + result = Some(parsed.unwrap()); + } + result +} + +#[test] +fn test_netrc_with_file_works_when_typical() { + use std::io::Write; + let mut file = std::fs::File::create(".netrc.test_unit").unwrap(); + file.write_all(b"machine mydomain.com login myuser password mypass port 1234") + .unwrap(); + + assert!(netrc(true).is_some()); + assert!(netrc(false).is_some()); + + std::fs::remove_file(".netrc.test_unit").unwrap(); +} + +#[ignore] +#[test] +fn test_netrc_with_file_works_when_typical_and_not_silent() { + use std::io::Write; + let mut file = std::fs::File::create(".netrc.test_unit").unwrap(); + file.write_all(b"machine mydomain.com login myuser password mypass port 1234") + .unwrap(); + + let netrc = netrc(false); + + assert!(netrc.is_some()); + std::fs::remove_file(".netrc.test_unit").unwrap(); +} diff --git a/crates/aim-downloader/src/untildify.rs b/crates/aim-downloader/src/untildify.rs new file mode 100644 index 0000000..4c79bd9 --- /dev/null +++ b/crates/aim-downloader/src/untildify.rs @@ -0,0 +1,80 @@ +//! Replace `~` with user home directory across all platforms +//! +//! Unit tests come from https://github.com/sathishsoundharajan/untildify (MIT LICENSE) + +pub fn untildify(input_path: &str) -> String { + if input_path.is_empty() { + return String::from(input_path); + } + if let Some(home) = home::home_dir() { + if input_path == r"~" { + return home.into_os_string().into_string().unwrap(); + } + if input_path.starts_with(r"~/") || input_path.starts_with(r"~\") { + if let Ok(path) = home.join(&input_path[2..]).into_os_string().into_string() { + return path; + } + } + } + String::from(input_path) +} + +#[cfg(any(unix, target_os = "redox"))] +#[cfg(test)] +mod tests { + use std::{env, path::Path}; + + use super::*; + + #[test] + fn test_returns_untildfyed_string() { + env::remove_var("HOME"); + + let home = Path::new("/User/Untildify"); + env::set_var("HOME", home.as_os_str()); + + assert_eq!(untildify("~/Desktop"), "/User/Untildify/Desktop"); + assert_eq!(untildify("~/a/b/c/d/e"), "/User/Untildify/a/b/c/d/e"); + assert_eq!(untildify("~/"), "/User/Untildify/"); + } + + #[test] + fn test_returns_empty_string() { + env::remove_var("HOME"); + + let home = Path::new("/User/Untildify"); + env::set_var("HOME", home.as_os_str()); + + assert_eq!(untildify("Desktop"), "Desktop"); + assert_eq!(untildify(""), ""); + assert_eq!(untildify("/"), "/"); + // assert_eq!(untildify("~/Desktop/~/Code"), "/User/Untildify/Desktop/"); + } + + #[test] + fn test_with_dot_folders() { + env::remove_var("HOME"); + + let home = Path::new("/User/Untildify"); + env::set_var("HOME", home.as_os_str()); + + assert_eq!(untildify("~/.ssh/id_rsa"), "/User/Untildify/.ssh/id_rsa"); + } +} + +#[cfg(target_os = "windows")] +#[cfg(test)] +mod tests { + use std::env; + + use super::*; + + #[test] + fn test_returns_untildfyed_string() { + env::set_var("USERPROFILE", r"C:\Users\Admin"); + + assert_eq!(untildify(r"~\Desktop"), r"C:\Users\Admin\Desktop"); + assert_eq!(untildify(r"~\a\b\c\d\e"), r"C:\Users\Admin\a\b\c\d\e"); + assert_eq!(untildify(r"~\"), r"C:\Users\Admin\"); + } +} diff --git a/crates/tabby-download/Cargo.toml b/crates/tabby-download/Cargo.toml index 5ef22b2..623a479 100644 --- a/crates/tabby-download/Cargo.toml +++ b/crates/tabby-download/Cargo.toml @@ -4,9 +4,9 @@ version = "0.7.0-dev" edition = "2021" [dependencies] +aim-downloader = { path = "../aim-downloader" } tabby-common = { path = "../tabby-common" } anyhow = { workspace = true } tracing = { workspace = true } tokio-retry = "0.3.0" sha256 = "1.4.0" -aim = "1.8.5" diff --git a/crates/tabby-download/src/lib.rs b/crates/tabby-download/src/lib.rs index 4167fd7..5ec3a04 100644 --- a/crates/tabby-download/src/lib.rs +++ b/crates/tabby-download/src/lib.rs @@ -1,6 +1,6 @@ use std::{fs, path::Path}; -use aim::bar::WrappedBar; +use aim_downloader::{bar::WrappedBar, https}; use anyhow::{anyhow, Result}; use tabby_common::registry::{parse_model_id, ModelRegistry}; use tokio_retry::{ @@ -60,7 +60,7 @@ async fn download_file(url: &str, path: &Path) -> Result<()> { let mut bar = WrappedBar::new(0, url, false); - aim::https::HTTPSHandler::get(url, &intermediate_filename, &mut bar, "").await?; + https::HTTPSHandler::get(url, &intermediate_filename, &mut bar, "").await?; fs::rename(intermediate_filename, filename)?; Ok(())