From 2f8a3f02144d4beca42691c2eced9f73571cb2b4 Mon Sep 17 00:00:00 2001 From: Yakiyo Date: Sun, 3 Dec 2023 11:50:13 +0000 Subject: [PATCH] feat: restart everything --- Cargo.lock | 459 +++--------------------------------- Cargo.toml | 7 +- src/alias.rs | 92 -------- src/arch.rs | 106 --------- src/cli.rs | 84 ------- src/commands/alias.rs | 31 --- src/commands/completions.rs | 25 -- src/commands/current.rs | 16 -- src/commands/env.rs | 39 --- src/commands/install.rs | 120 ---------- src/commands/list.rs | 35 --- src/commands/list_remote.rs | 104 -------- src/commands/mod.rs | 34 --- src/commands/self_sub.rs | 49 ---- src/commands/unalias.rs | 24 -- src/commands/uninstall.rs | 58 ----- src/commands/use.rs | 56 ----- src/config.rs | 133 ----------- src/fs.rs | 15 -- src/http.rs | 43 ---- src/main.rs | 63 +---- src/platform.rs | 19 -- src/shell.rs | 173 -------------- src/user_version.rs | 126 ---------- 24 files changed, 33 insertions(+), 1878 deletions(-) delete mode 100644 src/alias.rs delete mode 100644 src/arch.rs delete mode 100644 src/cli.rs delete mode 100644 src/commands/alias.rs delete mode 100644 src/commands/completions.rs delete mode 100644 src/commands/current.rs delete mode 100644 src/commands/env.rs delete mode 100644 src/commands/install.rs delete mode 100644 src/commands/list.rs delete mode 100644 src/commands/list_remote.rs delete mode 100644 src/commands/mod.rs delete mode 100644 src/commands/self_sub.rs delete mode 100644 src/commands/unalias.rs delete mode 100644 src/commands/uninstall.rs delete mode 100644 src/commands/use.rs delete mode 100644 src/config.rs delete mode 100644 src/fs.rs delete mode 100644 src/http.rs delete mode 100644 src/platform.rs delete mode 100644 src/shell.rs delete mode 100644 src/user_version.rs diff --git a/Cargo.lock b/Cargo.lock index 95a222e..deba2d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" -dependencies = [ - "gimli", -] - [[package]] name = "adler" version = "1.0.2" @@ -39,16 +30,15 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] @@ -78,9 +68,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -92,38 +82,6 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" -[[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 = "backtrace" -version = "0.3.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide 0.6.2", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.13.1" @@ -211,51 +169,52 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.25" +version = "4.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272" dependencies = [ - "atty", - "bitflags", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "indexmap", - "once_cell", "strsim", - "termcolor", - "textwrap", ] [[package]] name = "clap_complete" -version = "3.2.5" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8" +checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "3.2.25" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "colorchoice" @@ -263,19 +222,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" -[[package]] -name = "console" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.45.0", -] - [[package]] name = "constant_time_eq" version = "0.1.5" @@ -319,16 +265,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "dart-semver" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71eeee9904f59a829b45672adb51608cdd5eb3db3fb351ea61a268036de249ba" -dependencies = [ - "pest", - "pest_derive", -] - [[package]] name = "digest" version = "0.10.7" @@ -347,11 +283,8 @@ dependencies = [ "anyhow", "clap", "clap_complete", - "dart-semver", "env_logger", "home", - "human-panic", - "indicatif", "junction", "log", "serde_json", @@ -361,12 +294,6 @@ dependencies = [ "zip", ] -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - [[package]] name = "env_logger" version = "0.10.0" @@ -417,7 +344,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", - "miniz_oxide 0.7.1", + "miniz_oxide", ] [[package]] @@ -439,44 +366,12 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[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.3.1" @@ -501,22 +396,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "human-panic" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c16465f6227e18e5a64eba488245d7b2974d4db0c4404ca5a69b550defa18d0a" -dependencies = [ - "anstream", - "anstyle", - "backtrace", - "os_info", - "serde", - "serde_derive", - "toml", - "uuid", -] - [[package]] name = "humantime" version = "2.1.0" @@ -533,29 +412,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "indicatif" -version = "0.17.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" -dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", -] - [[package]] name = "inout" version = "0.1.3" @@ -580,7 +436,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] @@ -591,7 +447,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "io-lifetimes", "rustix", "windows-sys 0.48.0", @@ -631,12 +487,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.144" @@ -661,15 +511,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -679,44 +520,12 @@ dependencies = [ "adler", ] -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "object" -version = "0.30.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" -[[package]] -name = "os_info" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" -dependencies = [ - "log", - "serde", - "winapi", -] - -[[package]] -name = "os_str_bytes" -version = "6.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" - [[package]] name = "password-hash" version = "0.4.2" @@ -746,86 +555,12 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" -[[package]] -name = "pest" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" -dependencies = [ - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.18", -] - -[[package]] -name = "pest_meta" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" -dependencies = [ - "once_cell", - "pest", - "sha2", -] - [[package]] name = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "portable-atomic" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc55135a600d700580e406b4de0d59cb9ad25e344a3a091a97ded2622ec4ec6" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.59" @@ -903,12 +638,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustix" version = "0.37.19" @@ -962,20 +691,6 @@ name = "serde" version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.163" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] [[package]] name = "serde_json" @@ -988,15 +703,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" -dependencies = [ - "serde", -] - [[package]] name = "sha1" version = "0.10.5" @@ -1037,17 +743,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.18" @@ -1081,32 +776,6 @@ dependencies = [ "winapi-util", ] -[[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.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "time" version = "0.3.21" @@ -1138,52 +807,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "toml" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "ucd-trie" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" - [[package]] name = "unicode-bidi" version = "0.3.13" @@ -1205,12 +834,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - [[package]] name = "untrusted" version = "0.7.1" @@ -1250,27 +873,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "uuid" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" -dependencies = [ - "getrandom", -] - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - [[package]] name = "wasm-bindgen" version = "0.2.86" @@ -1292,7 +900,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn", "wasm-bindgen-shared", ] @@ -1314,7 +922,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1517,15 +1125,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winnow" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" -dependencies = [ - "memchr", -] - [[package]] name = "yansi" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index c56dec0..bca4824 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,18 +10,15 @@ homepage = 'https://github.com/Yakiyo/dsm' exclude = ['.devcontainer/**', '.github/**', '.vscode/**', 'tests/**', '.gitignore', 'tools/**', 'site/**', 'pkg/**'] [dependencies] -clap = { version = '3.2.25', features = ['derive', 'env'] } +clap = { version = '4.4.10', features = ['derive', 'env'] } anyhow = '1.0.71' -dart-semver = '0.1.3' -human-panic = '1.1.4' tempfile = '3.5.0' ureq = '2.6.2' yansi = '0.5.1' zip = '0.6.5' serde_json = "1.0.99" -clap_complete = "3.2.5" +clap_complete = "4.4.4" home = "0.5.5" -indicatif = "0.17.5" log = "0.4.19" env_logger = "0.10.0" diff --git a/src/alias.rs b/src/alias.rs deleted file mode 100644 index 8ea5f5c..0000000 --- a/src/alias.rs +++ /dev/null @@ -1,92 +0,0 @@ -use crate::config::EnsurePath; -use crate::fs::symlink_dir; -use anyhow::Context; -use dart_semver::Version; -use std::collections::HashMap; -use std::path; - -/// Represents an alias with name `name` pointing to `version` -#[derive(Debug)] -pub struct Alias { - pub name: String, - pub version: Version, -} - -impl Alias { - /// Inner version's string format - pub fn v_str(&self) -> String { - (self.version).to_string() - } -} - -impl std::convert::TryInto for &std::path::Path { - type Error = anyhow::Error; - - fn try_into(self) -> Result { - let name = &self - .file_name() - .with_context(|| "Unable to read path")? - .to_str() - .with_context(|| "Invalid dir name as alias")?; - let link = std::fs::read_link(self)?; - let link = link - .file_name() - .with_context(|| "Unable to read file name for version directory")? - .to_str() - .with_context(|| "Could not convert file name to string")?; - Ok(Alias { - name: name.to_string(), - version: Version::parse(link).context("Invalid version string")?, - }) - } -} - -/// List all aliases -pub fn list_aliases>(alias_dir: P) -> anyhow::Result> { - let alias_dir = alias_dir.as_ref(); - let aliases: Vec = std::fs::read_dir(alias_dir)? - .filter_map(Result::ok) - .filter_map(|x| TryInto::::try_into(x.path().as_path()).ok()) - .collect(); - Ok(aliases) -} - -/// Create an alias to a version -pub fn create_alias( - alias_dir: path::PathBuf, - version_dir: path::PathBuf, - version: &Version, - name: &str, -) -> anyhow::Result { - alias_dir.ensure_path()?; - let version_dir = version_dir.join(version.to_str()); - if !version_dir.exists() { - return Err(anyhow::anyhow!("Version v{version} is not installed")); - } - let alias_dir = alias_dir.join(name); - - if alias_dir.exists() { - std::fs::remove_dir_all(&alias_dir)?; - } - symlink_dir(version_dir, alias_dir).with_context(|| "Failed to create alias symlink")?; - Ok(Alias { - name: name.to_string(), - version: *version, - }) -} - -/// Generate hashmap of aliases -pub fn create_alias_hash>( - alias_dir: P, -) -> anyhow::Result>> { - let mut aliases = list_aliases(alias_dir.as_ref())?; - let mut hashmap: HashMap> = HashMap::with_capacity(aliases.len()); - for alias in aliases.drain(..) { - if let Some(value) = hashmap.get_mut(&alias.version.to_str()) { - value.push(alias.name); - } else { - hashmap.insert(alias.version.to_str(), vec![alias.name]); - } - } - Ok(hashmap) -} diff --git a/src/arch.rs b/src/arch.rs deleted file mode 100644 index 32e269d..0000000 --- a/src/arch.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Some of the code in this file are taken from Schniz/fnm. All credit goes -// to the contributors of that file -// -// https://github.com/Schniz/fnm/blob/696134ad7cb166c3c54f2e0323ace76b18411bb1/src/system_info.rs - -#[cfg(all( - target_pointer_width = "32", - any(target_arch = "arm", target_arch = "aarch64") -))] -pub fn platform_arch() -> &'static str { - "armv7" -} - -#[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "arm", target_arch = "aarch64")) -))] -pub fn platform_arch() -> &'static str { - "x86" -} - -#[cfg(all( - target_pointer_width = "64", - any(target_arch = "arm", target_arch = "aarch64") -))] -pub fn platform_arch() -> &'static str { - "arm64" -} - -#[cfg(all( - target_pointer_width = "64", - not(any(target_arch = "arm", target_arch = "aarch64")) -))] -pub fn platform_arch() -> &'static str { - "x64" -} - -// I have no idea wether this is even valid or not. This needs fixing. -#[cfg(target_arch = "ia32")] -pub fn platform_arch() -> &'static str { - "ia32" -} - -/// All supported archs. This are the ones dart binaries are built for. -pub const SUPPORTED_ARCHS: &[&str; 4] = &["arm", "arm64", "x64", "ia32"]; - -#[derive(Debug, Clone, PartialEq)] -pub enum Arch { - X64, - Arm64, - Armv7, - Ia32, -} - -impl Arch { - fn to_str(&self) -> &'static str { - match self { - Arch::Armv7 => "arm", - Arch::Arm64 => "arm64", - Arch::X64 => "x64", - Arch::Ia32 => "ia32", - } - } -} - -impl std::str::FromStr for Arch { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - match s.to_lowercase().as_str() { - "armv7" => Ok(Arch::Armv7), - "arm64" => Ok(Arch::Arm64), - "x64" | "x86" => Ok(Arch::X64), - "ia32" => Ok(Arch::Ia32), - unknown => Err(anyhow::anyhow!( - "Unknown arch {unknown}. Must be one of {}", - SUPPORTED_ARCHS.join(", ") - )), - } - } -} -impl std::fmt::Display for Arch { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.to_str()) - } -} - -#[cfg(test)] -mod test { - use super::*; - use std::str::FromStr; - - #[test] - fn test_arch_from_str() { - assert_eq!(Arch::from_str("x64").unwrap(), Arch::X64); - } - - #[test] - fn test_arch_err() { - assert!(Arch::from_str("bjbjka").is_err()); - } - #[test] - fn test_arch_to_str() { - assert_eq!(Arch::X64.to_str(), "x64"); - } -} diff --git a/src/cli.rs b/src/cli.rs deleted file mode 100644 index 4ffbc0d..0000000 --- a/src/cli.rs +++ /dev/null @@ -1,84 +0,0 @@ -use crate::commands::{self, Command}; -use crate::config::Config; -use clap::{Parser, Subcommand}; - -/// A fast and simple version manager for the Dart SDK -#[derive(Parser, Debug)] -#[clap(version, about)] -pub struct Cli { - #[clap(flatten)] - pub config: Config, - - /// Subcommand - #[clap(subcommand)] - pub subcommand: SubCommand, -} - -#[derive(Subcommand, Debug)] -pub enum SubCommand { - /// Install a specific version of the Dart SDK - #[clap(name = "install")] - Install(commands::install::Install), - - /// Uninstall a specific version of the Dart SDK - #[clap(name = "uninstall")] - Uninstall(commands::uninstall::Uninstall), - - /// Change Dart SDK version - #[clap(name = "use")] - Use(commands::r#use::Use), - - /// List all installed versions - #[clap(name = "list", visible_aliases = &["ls"])] - List(commands::list::List), - - /// List all available versions - #[clap(name = "list-remote", visible_aliases = &["ls-remote"])] - ListRemote(commands::list_remote::ListRemote), - - /// Print required environment variables for dsm - #[clap(name = "env")] - Env(commands::env::Env), - - /// Prints the current version in use - #[clap(name = "current")] - Current(commands::current::Current), - - /// Create an alias to an existing version - #[clap(name = "alias")] - Alias(commands::alias::Alias), - - /// Create an alias to an existing version - #[clap(name = "unalias")] - Unlias(commands::unalias::Unalias), - - /// Check for new versions of the app - #[clap(name = "self")] - SelfSub(commands::self_sub::SelfSub), - - /// Generate shell completion scripts - #[clap(name = "completions")] - Completions(commands::completions::Completions), -} - -impl Cli { - pub fn handle_sub(self) { - match self.subcommand { - SubCommand::Install(e) => e.handle(self.config), - SubCommand::Uninstall(e) => e.handle(self.config), - SubCommand::Use(e) => e.handle(self.config), - SubCommand::List(e) => e.handle(self.config), - SubCommand::Env(e) => e.handle(self.config), - SubCommand::Current(e) => e.handle(self.config), - SubCommand::Alias(e) => e.handle(self.config), - SubCommand::Unlias(e) => e.handle(self.config), - SubCommand::SelfSub(e) => e.handle(self.config), - SubCommand::Completions(e) => e.handle(self.config), - SubCommand::ListRemote(e) => e.handle(self.config), - } - } -} - -pub fn parse() -> Cli { - Cli::parse() -} diff --git a/src/commands/alias.rs b/src/commands/alias.rs deleted file mode 100644 index 0cb5ad8..0000000 --- a/src/commands/alias.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::alias; -use crate::config::Config; -use dart_semver::Version; -use yansi::Paint; - -#[derive(clap::Args, Debug, Default)] -pub struct Alias { - version: Version, - name: String, -} - -impl super::Command for Alias { - fn run(self, config: Config) -> anyhow::Result<()> { - let alias_dir = &config.aliases_dir().join(&self.name); - if alias_dir.exists() { - log::warn!("Alias with that name already exists. Overwriting it."); - } - alias::create_alias( - config.aliases_dir(), - config.installation_dir(), - &self.version, - &self.name, - )?; - println!( - "Created alias for {} with name {}", - Paint::blue(format!("v{}", self.version)), - Paint::blue(self.name) - ); - Ok(()) - } -} diff --git a/src/commands/completions.rs b/src/commands/completions.rs deleted file mode 100644 index f5474a7..0000000 --- a/src/commands/completions.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::cli::Cli; -use crate::shell::Shell; -use clap::CommandFactory; -use clap_complete::{generate, Shell as Sh}; - -#[derive(clap::Args, Debug, Default)] -pub struct Completions { - shell: Shell, -} - -impl super::Command for Completions { - fn run(self, _: crate::config::Config) -> anyhow::Result<()> { - let mut app: clap::builder::Command = Cli::command(); - let mut stdio = std::io::stdout(); - let mut gen = move |sh: Sh| generate(sh, &mut app, "dsm", &mut stdio); - match self.shell { - Shell::Bash => gen(Sh::Bash), - Shell::Powershell => gen(Sh::PowerShell), - Shell::Zsh => gen(Sh::Zsh), - Shell::Fish => gen(Sh::Fish), - Shell::Cmd => anyhow::bail!("Shell completion for command prompt is not supported"), - } - Ok(()) - } -} diff --git a/src/commands/current.rs b/src/commands/current.rs deleted file mode 100644 index dbf5eb7..0000000 --- a/src/commands/current.rs +++ /dev/null @@ -1,16 +0,0 @@ -use yansi::Paint; - -#[derive(clap::Args, Debug, Default)] -pub struct Current; - -impl super::Command for Current { - fn run(self, config: crate::config::Config) -> anyhow::Result<()> { - let res = config.current_version()?; - if let Some(version) = res { - println!("{}", Paint::green(version.to_str())); - } else { - println!("{}", Paint::red("No version currently in use")); - } - Ok(()) - } -} diff --git a/src/commands/env.rs b/src/commands/env.rs deleted file mode 100644 index 9683be7..0000000 --- a/src/commands/env.rs +++ /dev/null @@ -1,39 +0,0 @@ -use anyhow::Context; -use std::collections::HashMap; - -use crate::shell::{fix_path, Shell, AVAILABLE_SHELLS}; - -#[derive(clap::Args, Debug, Default)] -pub struct Env { - /// The shell syntax to use - #[clap(possible_values = AVAILABLE_SHELLS)] - shell: Option, - - /// Print as json - #[clap(long, conflicts_with = "shell")] - json: bool, -} - -impl super::Command for Env { - fn run(self, config: crate::config::Config) -> anyhow::Result<()> { - let env_vars = HashMap::from([ - ("DSM_ARCH", config.arch.to_string()), - ("DSM_NO_COLORS", config.disable_colors.to_string()), - ( - "DSM_DIR", - format!("{}", config.root_with_default().display()), - ), - ]); - - if self.json { - println!("{}", serde_json::to_string_pretty(&env_vars).unwrap()); - return Ok(()); - } - - let shell = self.shell.with_context(|| "Missing argument for ")?; - println!("{}", shell.path(&config.bin_dir())?); - let out = shell.env_vars(&env_vars); - println!("{}", fix_path(out.as_str())); - Ok(()) - } -} diff --git a/src/commands/install.rs b/src/commands/install.rs deleted file mode 100644 index 954518d..0000000 --- a/src/commands/install.rs +++ /dev/null @@ -1,120 +0,0 @@ -use crate::arch::Arch; -use crate::config::{Config, EnsurePath}; -use crate::http::fetch_bytes; -use crate::platform::platform_name; -use crate::user_version::UserVersion; -use anyhow::Context; -use dart_semver::Version; -use indicatif::{ProgressBar, ProgressStyle}; -use std::fs::File; -use std::io::Write; -use std::path::Path; -use yansi::Paint; -use zip::read::ZipArchive; - -#[derive(clap::Args, Debug, Default)] -pub struct Install { - /// The version to install. - pub version: UserVersion, -} - -impl super::Command for Install { - fn run(self, config: Config) -> anyhow::Result<()> { - let version = match self.version { - UserVersion::Version(v) => v, - UserVersion::Alias(_) => { - anyhow::bail!("Invalid version string provided. Must be a valid semver") - } - UserVersion::Latest(c) => UserVersion::resolve_latest(&c)?, - }; - - config - .installation_dir() - .ensure_path() - .with_context(|| "Failed to setup dsm dirs")?; - - install_dart_sdk(&version, &config)?; - println!( - "Successfully installed Dart SDK {}", - Paint::green(format!("v{}", version)) - ); - - Ok(()) - } -} - -/// Install dart sdk -fn install_dart_sdk(version: &Version, config: &Config) -> anyhow::Result<()> { - let p = config.installation_dir().join(version.to_str()); - if p.exists() { - return Err(anyhow::anyhow!("Version {version} is already installed. For reinstalling, please uninstall first then install again.")); - } - - println!("Downloading Dart SDK {}", Paint::cyan(version)); - - let archive = fetch_bytes(archive_url(version, &config.arch)) - .with_context(|| "No Dart SDK available with provided arch type or version.")?; - - let mut tmp = tempfile::tempfile().with_context(|| "Failed to create temporary file")?; - let tmp_dir = tempfile::tempdir_in(config.installation_dir()) - .with_context(|| "Could not create tmp dir")?; - - tmp.write_all(&archive) - .with_context(|| "Failed to write contents to temp file")?; - - extract(&tmp, tmp_dir.path())?; - - std::fs::rename(tmp_dir.path().join("dart-sdk"), p) - .with_context(|| "Failed to copy extracted files to installation dir.")?; - - if let Err(e) = tmp_dir.close() { - log::warn!("Could not close temp dir. Please remove it manually\n{e}"); - } - Ok(()) -} - -fn extract(zipfile: &File, dest: &Path) -> anyhow::Result<()> { - let mut zip = ZipArchive::new(zipfile).unwrap(); - if !dest.exists() { - std::fs::create_dir_all(dest) - .with_context(|| "Unable to create temp dir for extracting files")?; - } - let pb = ProgressBar::new(zip.len().try_into().unwrap()); - pb.set_style( - ProgressStyle::with_template("[{bar:60.cyan/blue}] {pos}/{len} ({percent}%)") - .unwrap() - .progress_chars("#>-"), - ); - pb.println("Extracting files"); - - for i in 0..zip.len() { - let mut file = zip.by_index(i).context("Cannot read file in archive")?; - let path = match file.enclosed_name() { - Some(p) => dest.join(p), - None => continue, - }; - if file.name().ends_with('/') { - std::fs::create_dir_all(path).unwrap(); - continue; - } - if let Some(p) = path.parent() { - if !p.exists() { - std::fs::create_dir_all(p).unwrap(); - } - } - let mut outfile = std::fs::File::create(&path) - .context("Failed to create output file while extracting")?; - std::io::copy(&mut file, &mut outfile) - .context("Failed to copy file from archive to disk")?; - pb.inc(1); - } - pb.finish(); - Ok(()) -} - -/// Generate sdk archive url -fn archive_url(version: &Version, arch: &Arch) -> String { - format!( - "https://storage.googleapis.com/dart-archive/channels/{}/release/{}/sdk/dartsdk-{}-{}-release.zip", version.channel, version, platform_name(), arch - ) -} diff --git a/src/commands/list.rs b/src/commands/list.rs deleted file mode 100644 index a3bc864..0000000 --- a/src/commands/list.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::alias; -use crate::config::Config; -use crate::user_version::list_versions; -use yansi::Paint; - -#[derive(clap::Args, Debug, Default)] -pub struct List; - -impl super::Command for List { - fn run(self, config: Config) -> anyhow::Result<()> { - let versions = list_versions(config.installation_dir())?; - if versions.is_empty() { - println!("{}", Paint::yellow("No versions installed")); - return Ok(()); - } - let current = config.current_version().unwrap_or(None); - let alias_hash = alias::create_alias_hash(&config.aliases_dir())?; - for version in versions { - let aliases = match alias_hash.get(&version.to_str()) { - None => String::new(), - Some(v) => { - let v_str = v.iter().map(String::from).collect::>().join(" "); - format!("{}", Paint::new(v_str).dimmed()) - } - }; - let v_str = format!("• v{} {}", version.to_str(), aliases); - if Some(version) == current { - println!("{}", Paint::cyan(v_str)); - } else { - println!("{v_str}"); - } - } - Ok(()) - } -} diff --git a/src/commands/list_remote.rs b/src/commands/list_remote.rs deleted file mode 100644 index e0d7bc5..0000000 --- a/src/commands/list_remote.rs +++ /dev/null @@ -1,104 +0,0 @@ -use crate::config::EnsurePath; -use crate::http; -use anyhow::Context; -use dart_semver::Version; -use std::collections::HashMap; -use std::fs; -use std::io::Write; -use std::path; -use std::time::Duration; - -/// Url to the versions file -const VERSION_URL: &str = "https://github.com/Yakiyo/dinx/raw/main/versions.json"; - -/// Maximum duration for versions file to not be stale -const MAX_VALID_DUR: Duration = Duration::from_secs(7 * 24 * 60 * 60); // 1 week - -#[derive(clap::Args, Debug, Default)] -pub struct ListRemote { - /// Dont manually update index file. Does not apply if index file is missing - #[clap(long = "no-update")] - no_update: bool, -} - -impl super::Command for ListRemote { - fn run(self, config: crate::config::Config) -> anyhow::Result<()> { - let versions = index(config.root_with_default(), self.no_update)?; - let stdout = std::io::stdout(); - let mut lock = stdout.lock(); - versions.iter().for_each(|v| writeln!(lock, "{v}").unwrap()); - Ok(()) - } -} - -fn index(root: path::PathBuf, no_update: bool) -> anyhow::Result> { - let index_file = root.join("index.json"); - let should_fetch = if !index_file.exists() { - log::debug!("Missing index file"); - true - } else if let Ok(Ok(d)) = fs::metadata(&index_file).map(|f| f.modified().map(|f| f.elapsed())) { - let r = match d { - Err(_) => true, - Ok(t) => { - // if file hasnt been updated in more than a week, fetch file - let v = t > MAX_VALID_DUR; - if v { - log::debug!("Index file is stale. Older than 1 week"); - } - v - } - }; - r && !no_update - } else { - false - }; - if should_fetch { - log::debug!("Fetching and writing index file"); - fetch_file(&index_file)?; - } - let file_cont = fs::read_to_string(&index_file)?; - let mut json: HashMap> = - serde_json::from_str(&file_cont).unwrap_or_else(|_| HashMap::new()); - let mut versions: Vec = Vec::new(); - json.iter_mut().for_each(|(_, v)| versions.append(v)); - Ok(versions) -} - -fn fetch_file(file_path: &path::PathBuf) -> anyhow::Result<()> { - let resp = http::fetch(VERSION_URL).context("Failed to fetch versions file")?; - if resp.status() != 200 { - anyhow::bail!( - "Fetching versions file failed. Got status code {}", - resp.status() - ); - } - let rdr = resp.into_reader(); - let resp: HashMap> = - serde_json::from_reader(rdr).context("unable to parse json")?; - let mut map = HashMap::new(); - - // filter out valid versions - for (k, v) in resp { - let vec: Vec = v - .iter() - .filter_map(|f| { - if Version::parse(f).is_ok() { - Some(f.into()) - } else { - None - } - }) - .collect(); - map.insert(k, vec); - } - let json = serde_json::to_string_pretty(&map)?; - if !file_path.exists() { - if let Some(parent) = file_path.parent() { - parent.ensure_path()?; - } - } - let mut file = fs::File::create(file_path)?; - file.write_all(json.as_bytes()) - .context("Unable to write json to file")?; - Ok(()) -} diff --git a/src/commands/mod.rs b/src/commands/mod.rs deleted file mode 100644 index 0eb5118..0000000 --- a/src/commands/mod.rs +++ /dev/null @@ -1,34 +0,0 @@ -use crate::config::Config; -use yansi::Paint; - -pub mod alias; -pub mod completions; -pub mod current; -pub mod env; -pub mod install; -pub mod list; -pub mod list_remote; -pub mod self_sub; -pub mod unalias; -pub mod uninstall; -pub mod r#use; - -pub trait Command: Sized { - fn run(self, config: Config) -> anyhow::Result<()>; - - fn catch(err: anyhow::Error) { - // Print in more details during dev builds - #[cfg(debug_assertions)] - eprintln!("{} {:#?}", Paint::red("[ERROR]"), err); - - #[cfg(not(debug_assertions))] - eprintln!("{} {:?}", Paint::red("[ERROR]"), err); - std::process::exit(1); - } - - fn handle(self, config: Config) { - if let Err(e) = self.run(config) { - Self::catch(e) - } - } -} diff --git a/src/commands/self_sub.rs b/src/commands/self_sub.rs deleted file mode 100644 index 16ce59d..0000000 --- a/src/commands/self_sub.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::http::fetch; -use anyhow::Context; -use yansi::Paint; - -/// Current app version -const PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[derive(clap::Args, Debug, Default)] -pub struct SelfSub; - -impl super::Command for SelfSub { - fn run(self, _: crate::config::Config) -> anyhow::Result<()> { - let latest = fetch_gh_tag()?.to_lowercase(); - let latest = latest.trim_start_matches('v'); - if latest == PKG_VERSION { - println!("App is running latest version v{PKG_VERSION}"); - return Ok(()); - } - println!( - "New version {} available at https://github.com/Yakiyo/dsm/releases", - Paint::blue("v".to_owned() + latest) - ); - #[cfg(windows)] - { - println!("To install the latest version, open up Powershell and run the following:\n"); - println!(" irm https://dsm-vm.vercel.app/install.ps1 | iex\n"); - } - #[cfg(unix)] - { - println!("To install the latest version, run the following command:\n"); - println!(" curl -fsSL https://dsm-vm.vercel.app/install.sh | bash\n"); - } - Ok(()) - } -} - -fn fetch_gh_tag() -> anyhow::Result { - let resp = fetch("https://api.github.com/repos/Yakiyo/dsm/releases/latest") - .with_context(|| "Unable to fetch latest app version from github.")? - .into_string() - .with_context(|| "Response returned invalid text content.".to_string())?; - let json: serde_json::Value = - serde_json::from_str(resp.as_str()).with_context(|| "Invalid json string".to_string())?; - Ok(String::from( - json["tag_name"] - .as_str() - .context("Received non-string tag name {latest}")?, - )) -} diff --git a/src/commands/unalias.rs b/src/commands/unalias.rs deleted file mode 100644 index 3d861c6..0000000 --- a/src/commands/unalias.rs +++ /dev/null @@ -1,24 +0,0 @@ -use anyhow::Context; -use yansi::Paint; - -use crate::config::Config; - -#[derive(clap::Args, Debug, Default)] -pub struct Unalias { - alias: String, -} - -impl super::Command for Unalias { - fn run(self, config: Config) -> anyhow::Result<()> { - let alias_dir = &config.aliases_dir().join(&self.alias); - if !alias_dir.exists() { - return Err(anyhow::anyhow!( - "No alias with the name `{}` exists", - Paint::red(&self.alias).bold() - )); - } - std::fs::remove_dir_all(alias_dir).with_context(|| "Failed to unlink alias directory")?; - println!("Successfully removed alias"); - Ok(()) - } -} diff --git a/src/commands/uninstall.rs b/src/commands/uninstall.rs deleted file mode 100644 index dd6d45e..0000000 --- a/src/commands/uninstall.rs +++ /dev/null @@ -1,58 +0,0 @@ -use crate::alias; -use crate::config::Config; -use crate::user_version::UserVersion; -use anyhow::Context; -use yansi::Paint; - -#[derive(clap::Args, Debug, Default)] -pub struct Uninstall { - /// The version to uninstall - version: UserVersion, -} - -impl super::Command for Uninstall { - fn run(self, config: Config) -> anyhow::Result<()> { - if let UserVersion::Latest(_) = self.version { - anyhow::bail!("Invalid version string. latest-channel is not valid for uninstallation. Provide an alias or full semver."); - } - - let version = self - .version - .to_version(Some(config.aliases_dir())) - .with_context(|| "Unable to resolve version")?; - let p = config.installation_dir().join(version.to_string()); - if !p.exists() { - return Err(anyhow::anyhow!( - "Version {} is not installed. Use the `ls` command to view all installed versions", - Paint::cyan(&self.version) - )); - } - - std::fs::remove_dir_all(p).with_context(|| { - format!( - "Could not delete installation dir for version {}", - Paint::red(&self.version) - ) - })?; - - // Clean up aliases - let aliases = alias::create_alias_hash(config.aliases_dir()) - .with_context(|| "Failed to fetch aliases")? - .remove(&self.version.to_string()) - .unwrap_or(Vec::new()); - - for alias in aliases { - let alias_dir = config.aliases_dir().join(alias); - if !alias_dir.exists() { - continue; - } - std::fs::remove_dir_all(alias_dir)?; - } - - println!( - "Successfully uninstalled Dart SDK version {} from system", - Paint::green(&self.version) - ); - Ok(()) - } -} diff --git a/src/commands/use.rs b/src/commands/use.rs deleted file mode 100644 index e6d1a9d..0000000 --- a/src/commands/use.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::config::Config; -use crate::fs; -use crate::user_version::UserVersion; -use anyhow::Context; -use std::path; -use yansi::Paint; - -#[derive(clap::Args, Debug, Default)] -pub struct Use { - /// The version to use - version: UserVersion, - - /// Remain silent if the current version is the same as the one to be used - #[clap(long, short = 's')] - silent_if_unchanged: bool, -} - -impl super::Command for Use { - fn run(self, config: Config) -> anyhow::Result<()> { - // let dirs = config.root_with_default(); - let version = self.version.to_version(Some(config.installation_dir()))?; - let version_path = config.installation_dir().join(version.to_str()); - if !version_path.exists() { - return Err(anyhow::anyhow!("Version {} is not installed. Cannot use it. View all available versions with the `ls` command.", Paint::cyan(&self.version))); - } - let current = config.current_version().ok(); - if Some(Some(version)) == current { - if !self.silent_if_unchanged { - println!("{} is already in use", &version); - } - return Ok(()); - } - replace_symlink( - config.installation_dir().join(version.to_string()), - config.bin_dir(), - )?; - println!( - "Successfully set {} as current version", - Paint::cyan(&self.version) - ); - - Ok(()) - } -} - -/// Remove prev symlink if it exists and symlink the target versions bin directory -fn replace_symlink(version_dir: path::PathBuf, bin: path::PathBuf) -> anyhow::Result<()> { - let from = version_dir.join("bin"); - let to = bin; - if to.exists() { - log::debug!("Removing previous link"); - std::fs::remove_dir_all(&to).with_context(|| "Failed to remove previous link")?; - } - fs::symlink_dir(from, to).with_context(|| "Failed to hard link executable.")?; - Ok(()) -} diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index afca347..0000000 --- a/src/config.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::arch::{platform_arch, Arch, SUPPORTED_ARCHS}; -use anyhow::Context; -use clap::Parser; -use dart_semver::Version; -use std::{fs, path}; - -#[derive(Parser, Debug)] -pub struct Config { - /// The architecture to use. Defaults to the system arch. - #[clap( - long, - env = "DSM_ARCH", - default_value = platform_arch(), - global = true, - hide_env_values = true, - hide_default_value = true, - possible_values = SUPPORTED_ARCHS - )] - pub arch: Arch, - - /// Dsm directory. Defaults to `~/.dsm` - #[clap( - long = "dsm-dir", - env = "DSM_DIR", - global = true, - value_name = "DSM_DIR", - hide_env_values = true - )] - base_dir: Option, - - /// Bin directory. This is where the current used dart sdk will be symlinked. Defaults to `~/.dsm/bin` - #[clap( - long = "bin-dir", - env = "DSM_BIN", - global = true, - value_name = "DSM_BIN", - hide_env_values = true - )] - bin: Option, - - /// Disable colors in output - #[clap( - long = "no-colors", - env = "DSM_NO_COLORS", - global = true, - hide_env_values = true - )] - pub disable_colors: bool, -} - -impl Config { - /// Get root dir, if provided, else use default - pub fn root_with_default(&self) -> path::PathBuf { - match &self.base_dir { - Some(p) => p.to_path_buf(), - None => { - let h = home::home_dir(); - if h.is_none() { - log::error!("Unable to get user home dir. Consider manually setting value of `DSM_DIR` to passing value to `--dsm-dir` flag."); - std::process::exit(1); - } - h.unwrap().join(".dsm") - } - } - } - - /// aliases dir - pub fn aliases_dir(&self) -> path::PathBuf { - let mut p = self.root_with_default(); - p.push("aliases"); - p - } - - /// installations dir - pub fn installation_dir(&self) -> path::PathBuf { - let mut p = self.root_with_default(); - p.push("installations"); - p - } - - /// bin dir - pub fn bin_dir(&self) -> path::PathBuf { - if let Some(p) = &self.bin { - p.to_path_buf() - } else { - let mut p = self.root_with_default(); - p.push("bin"); - p - } - } - - /// Find current version in use - pub fn current_version(&self) -> anyhow::Result> { - let bin = self.bin_dir(); - if !(bin.exists() && bin.is_symlink()) { - return Ok(None); - } - - let original = std::fs::read_link(bin).with_context(|| "Failed to read symlink")?; - - let dir_name = original - .parent() - .with_context(|| "Installed version seems to be at root. Something seems wrong.")? - .file_name() - .with_context(|| "Unexpected error while trying to read dir name.")? - .to_str() - .with_context(|| "Unexpected error. Directory name isnt valid utf-8")?; - - let version = Version::parse(dir_name).with_context(|| "Invalid version.")?; - Ok(Some(version)) - } -} - -/// utility trait implemented on pathbufs and paths -pub trait EnsurePath { - fn ensure_path(&self) -> anyhow::Result<()>; -} - -impl EnsurePath for path::PathBuf { - fn ensure_path(&self) -> anyhow::Result<()> { - if !self.exists() { - fs::create_dir_all(self) - .with_context(|| format!("Unable to create dir in path {}", self.display()))?; - } - Ok(()) - } -} - -impl EnsurePath for path::Path { - fn ensure_path(&self) -> anyhow::Result<()> { - path::PathBuf::from(self).ensure_path() - } -} diff --git a/src/fs.rs b/src/fs.rs deleted file mode 100644 index 6f1d7dd..0000000 --- a/src/fs.rs +++ /dev/null @@ -1,15 +0,0 @@ -/// This code is taken from Schniz/fnm. View: https://github.com/Schniz/fnm/blob/master/src/fs.rs -/// All credits go to the contributors of that file -use std::path::Path; - -#[cfg(unix)] -pub fn symlink_dir, U: AsRef>(from: P, to: U) -> std::io::Result<()> { - std::os::unix::fs::symlink(from, to)?; - Ok(()) -} - -#[cfg(windows)] -pub fn symlink_dir, U: AsRef>(from: P, to: U) -> std::io::Result<()> { - junction::create(from, to)?; - Ok(()) -} diff --git a/src/http.rs b/src/http.rs deleted file mode 100644 index 9dc5a9b..0000000 --- a/src/http.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! A module for handling http interactivity. A separate module so that -//! when needed, we can easily switch libs - -use anyhow::Context; -use ureq::{get, Response}; - -/// Base fetch method -pub fn fetch>(url: P) -> anyhow::Result { - let url = url.as_ref(); - let resp = get(url) - .call() - .with_context(|| "Failed to make http request".to_string())?; - Ok(resp) -} - -/// Fetch and convert response body to bytes -pub fn fetch_bytes>(url: P) -> anyhow::Result> { - let resp = fetch(url)?; - let mut bytes = Vec::new(); - resp.into_reader() - .read_to_end(&mut bytes) - .with_context(|| "Failed to read bytes from http response.")?; - Ok(bytes) -} - -#[cfg(test)] -mod tests { - use super::*; - #[test] - fn fetch_test() { - let body = fetch("https://nekos.best/api/v2/neko").unwrap(); - assert!(body.into_string().is_ok()); - } - - #[test] - fn fetch_bytes_test() { - use std::fs; - let bytes = - fetch_bytes("https://nekos.best/api/v2/neko/57797897-9d5c-4ad1-8bb8-a3ba8eedbdfa.png") - .unwrap(); - fs::write("image.png", bytes).unwrap(); - } -} diff --git a/src/main.rs b/src/main.rs index e1f2765..9bc5e5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,62 +1,3 @@ -// DSM - Dart SDK Manager -// -// A version manager for the dart sdk, written in rust -// Copyright 2023 Yakiyo. All rights reserved. MIT license. - -#![doc = include_str!("../README.md")] - -mod alias; -mod arch; -mod cli; -mod commands; -mod config; -mod fs; -mod http; -mod platform; -mod shell; -mod user_version; - fn main() { - human_panic::setup_panic!(); - let args = cli::parse(); - - init(args.config.disable_colors); - - args.handle_sub(); -} - -/// initialize some configs and stuffs -fn init(disable_color_flag: bool) { - use env_logger::{Builder, Env}; - use std::env; - - // init panic handler - human_panic::setup_panic!(); - - // init logger - Builder::from_env(Env::new().filter("DSM_LOG").write_style("DSM_LOG_STYLE")) - .format_timestamp(None) - .init(); - - // if DSM_LOG_STYLE is set to "never", disable colors - let disable_color: bool = match env::var("DSM_LOG_STYLE") { - Ok(v) => matches!(v.to_lowercase().as_str(), "never"), - Err(_) => false, - }; - - // if either disable color flag is set or DSM_LOG_STYLE is set to never, disable colors - if disable_color_flag || disable_color { - yansi::Paint::disable(); - } - - #[cfg(windows)] - { - // If ansi escape sequences are not supported, disable colors on windows - if !yansi::Paint::enable_windows_ascii() { - log::debug!( - "Disabling colors in output due to terminal not supporting ascii sequences" - ); - yansi::Paint::disable(); - } - } -} + println!("Hello World"); +} \ No newline at end of file diff --git a/src/platform.rs b/src/platform.rs deleted file mode 100644 index ecbfa7a..0000000 --- a/src/platform.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Some of the code in this file are taken from Schniz/fnm. All credit goes -// to the contributors of that file -// -// https://github.com/Schniz/fnm/blob/696134ad7cb166c3c54f2e0323ace76b18411bb1/src/system_info.rs - -#[cfg(target_os = "windows")] -pub fn platform_name() -> &'static str { - "windows" -} - -#[cfg(target_os = "linux")] -pub fn platform_name() -> &'static str { - "linux" -} - -#[cfg(target_os = "macos")] -pub fn platform_name() -> &'static str { - "darwin" -} diff --git a/src/shell.rs b/src/shell.rs deleted file mode 100644 index b2c745a..0000000 --- a/src/shell.rs +++ /dev/null @@ -1,173 +0,0 @@ -use crate::platform::platform_name; -use anyhow::Context; -use std::collections::HashMap; -use std::path::PathBuf; - -#[cfg(windows)] -pub const AVAILABLE_SHELLS: &[&str; 5] = &["cmd", "powershell", "bash", "zsh", "fish"]; - -#[cfg(unix)] -pub const AVAILABLE_SHELLS: &[&str; 4] = &["bash", "zsh", "fish", "powershell"]; - -/// Enums of Shells -#[derive(Debug)] -pub enum Shell { - Cmd, - Powershell, - Bash, - Zsh, - Fish, -} - -impl Default for Shell { - fn default() -> Self { - match platform_name() { - "linux" | "darwin" => Self::Bash, - "windows" => Self::Powershell, - platform => { - log::error!("Unknown platform {platform} received"); - std::process::exit(1); - } - } - } -} - -impl std::str::FromStr for Shell { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let s = s.to_lowercase(); - let s = s.as_str(); - if !AVAILABLE_SHELLS.contains(&s) { - return Err(anyhow::anyhow!( - "{s} is not a valid shell value. Must be one of ${}", - AVAILABLE_SHELLS.join(", ") - )); - } - let shell = match s { - "cmd" => Shell::Cmd, - "powershell" => Shell::Powershell, - "bash" => Shell::Bash, - "zsh" => Shell::Zsh, - "fish" => Shell::Fish, - _ => unreachable!(), - }; - Ok(shell) - } -} - -impl Shell { - /// Convert to string - fn as_str(&self) -> &'static str { - match self { - Shell::Bash => "bash", - Shell::Cmd => "cmd", - Shell::Fish => "fish", - Shell::Powershell => "powershell", - Shell::Zsh => "zsh", - } - } -} - -impl std::fmt::Display for Shell { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.as_str()) - } -} - -impl Shell { - /// Add current installation dir to path - pub fn path(&self, bin_dir: &PathBuf) -> anyhow::Result { - let bin = bin_dir - .to_str() - .context("Unable to convert bin dir path to str")?; - let s = match self { - Shell::Bash | Shell::Zsh => { - format!("export PATH={bin:?}:$PATH") - } - Shell::Fish => { - format!("set -gx PATH {bin:?} $PATH") - } - Shell::Powershell => { - let current_path = - std::env::var_os("PATH").with_context(|| "Failed to read current path")?; - - let mut split_paths: Vec<_> = std::env::split_paths(¤t_path).collect(); - let bin_path = std::path::PathBuf::from(bin_dir); - split_paths.insert(0, bin_path); - - let new_path = std::env::join_paths(split_paths) - .map_err(|e| anyhow::anyhow!("Can't join paths. Source: {}", e))?; - - format!("$env:PATH = {new_path:?}") - } - Shell::Cmd => { - let current_path = - std::env::var_os("PATH").with_context(|| "Failed to read current path")?; - - let mut split_paths: Vec<_> = std::env::split_paths(¤t_path).collect(); - let bin_path = std::path::PathBuf::from(bin_dir); - split_paths.insert(0, bin_path); - - let new_path = std::env::join_paths(split_paths) - .map_err(|e| anyhow::anyhow!("Can't join paths. Source: {}", e))?; - - format!("set PATH={new_path:?}") - } - }; - Ok(s) - } - - /// Print environment variables - pub fn env_vars(&self, vars: &HashMap<&str, String>) -> String { - let mut res = Vec::new(); - match self { - Shell::Bash | Shell::Zsh => { - for (name, value) in vars { - res.push(format!("export {name}={value:?}")); - } - } - Shell::Fish => { - for (name, value) in vars { - res.push(format!("set -gx {name} {value:?};")); - } - } - Shell::Powershell => { - for (name, value) in vars { - res.push(format!("$env:{name} = \"{value}\"")); - } - } - Shell::Cmd => { - for (name, value) in vars { - res.push(format!("SET {name}={value}")); - } - } - } - res.join("\n") - } -} - -#[cfg(not(windows))] -pub fn fix_path(p: &str) -> String { - p.to_string() -} - -/// Use `cygpath` to convert windows like paths to unix ones -/// As in, convert `C:\\Users\\User\\bin` to `C:/Users/User/bin` -#[cfg(windows)] -pub fn fix_path(p: &str) -> String { - use std::process::Command; - - let out = Command::new("cygpath").args(["-u", p]).output().ok(); - - if out.is_none() { - return p.to_string(); - } - - let out = out.unwrap(); - - if !out.status.success() { - return p.to_string(); - } - return String::from_utf8(out.stdout).unwrap_or(p.to_string()); -} diff --git a/src/user_version.rs b/src/user_version.rs deleted file mode 100644 index 0363077..0000000 --- a/src/user_version.rs +++ /dev/null @@ -1,126 +0,0 @@ -use crate::alias::Alias; -use crate::http; -use anyhow::Context; -use dart_semver::{Channel, Version as DartVersion}; -use std::path; - -/// Represents a user version -#[derive(Debug, PartialEq)] -pub enum UserVersion { - Version(DartVersion), - Alias(String), - Latest(Channel), -} - -impl UserVersion { - /// Parse string to Version - pub fn parse>(s: S) -> anyhow::Result { - let s = s.as_ref(); - let lowercased = s.to_lowercase(); - - if lowercased.starts_with("latest") { - if lowercased == "latest" { - return Ok(Self::Latest(Channel::Stable)); - } - let lowercased: Channel = lowercased - .trim_start_matches("latest-") - .trim_start_matches("latest/") - .into(); - return Ok(Self::Latest(lowercased)); - } else if let Ok(v) = DartVersion::parse(lowercased.trim_start_matches('v')) { - return Ok(Self::Version(v)); - } - Ok(Self::Alias(lowercased)) - } - - /// Version to string - pub fn to_str(&self) -> String { - match self { - UserVersion::Version(v) => format!("v{v}"), - UserVersion::Alias(a) => a.to_string(), - UserVersion::Latest(c) => format!("latest-{c}"), - } - } - - /// Convert an alias to a version - pub fn to_version(&self, dirs: Option) -> anyhow::Result { - match self { - UserVersion::Version(a) => Ok(*a), - UserVersion::Alias(a) => { - let alias: Alias = dirs.unwrap().join(a).as_path().try_into()?; - Ok(alias.version) - } - UserVersion::Latest(c) => UserVersion::resolve_latest(c), - } - } - - /// Resolve to latest version - pub fn resolve_latest(channel: &Channel) -> anyhow::Result { - DartVersion::parse(fetch_latest_version(channel)?).with_context(|| "Invalid version string") - } -} - -impl std::str::FromStr for UserVersion { - type Err = anyhow::Error; - fn from_str(s: &str) -> Result { - UserVersion::parse(s) - } -} - -impl std::fmt::Display for UserVersion { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.to_str()) - } -} - -impl std::default::Default for UserVersion { - fn default() -> Self { - UserVersion::Alias("default".into()) - } -} - -/// Fetch the latest version for the stable dart sdk -pub fn fetch_latest_version(channel: &Channel) -> anyhow::Result { - let resp = http::fetch(format!( - "https://storage.googleapis.com/dart-archive/channels/{channel}/release/latest/VERSION" - )) - .with_context(|| "Failed to fetch latest version of the sdk")?; - let json = resp - .into_string() - .with_context(|| "Invalid string content in response body")?; - let json: serde_json::Value = - serde_json::from_str(json.as_str()).with_context(|| "Invalid json string")?; - - Ok(String::from(json["version"].as_str().with_context( - || "Received non string value for version.", - )?)) -} - -pub fn list_versions>(dir: P) -> anyhow::Result> { - let dir = dir.as_ref(); - if !dir.exists() { - return Ok(vec![]); - } - let vec: Vec = dir - .read_dir()? - .filter_map(Result::ok) - .filter(|f| !f.file_name().to_str().map_or(false, |f| f.starts_with('.'))) - .filter_map(|f| f.file_name().to_str().map(str::to_string)) - .map(DartVersion::parse) - .filter_map(Result::ok) - .collect(); - Ok(vec) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn latest_version_test() { - let latest = fetch_latest_version(&Channel::Stable); - let latest = latest.unwrap(); - let version = DartVersion::parse(latest).unwrap(); - assert!(version.is_stable()); - } -}