diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..d79be99 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,33 @@ +name: Build and Check (w/ Clippy) +on: + - push +jobs: + clippy: + name: Run clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1.3.1 + with: + toolchain: stable + - name: Run clippy + run: cargo clippy -- -D warnings + build: + name: Build on ${{ matrix.target }} + runs-on: ${{ matrix.target }} + strategy: + matrix: + target: [windows-latest, macos-latest, ubuntu-latest] + steps: + - uses: actions/checkout@master + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1.3.1 + with: + toolchain: stable + - name: Compile + run: cargo build -r + - uses: actions/upload-artifact@v3 + with: + name: discloud-cli-${{ matrix.target }} + path: target \ No newline at end of file diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index e0f18da..0000000 --- a/.gitpod.yml +++ /dev/null @@ -1,4 +0,0 @@ -tasks: - - init: cargo build - - diff --git a/Cargo.lock b/Cargo.lock index 958acaa..9669837 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -20,6 +29,15 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -35,7 +53,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -46,17 +64,32 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide 0.5.4", + "object", + "rustc-demangle", +] + [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64ct" -version = "1.0.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" [[package]] name = "bitflags" @@ -75,9 +108,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "byteorder" @@ -87,9 +120,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "bzip2" @@ -114,9 +147,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.73" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" dependencies = [ "jobserver", ] @@ -138,7 +171,7 @@ dependencies = [ "num-integer", "num-traits", "serde", - "time 0.1.44", + "time 0.1.45", "wasm-bindgen", "winapi", ] @@ -160,14 +193,14 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.26" +version = "4.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" +checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" dependencies = [ - "atty", "bitflags", "clap_derive", "clap_lex", + "is-terminal", "once_cell", "strsim", "termcolor", @@ -195,6 +228,16 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "colored" version = "2.0.0" @@ -208,13 +251,13 @@ dependencies = [ [[package]] name = "console" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847" +checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" dependencies = [ "encode_unicode", + "lazy_static", "libc", - "once_cell", "terminal_size", "unicode-width", "winapi", @@ -252,12 +295,11 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -270,6 +312,84 @@ dependencies = [ "typenum", ] +[[package]] +name = "cxx" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "debugid" version = "0.8.0" @@ -293,9 +413,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.3" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer", "crypto-common", @@ -324,7 +444,7 @@ dependencies = [ [[package]] name = "discloud" -version = "0.3.2-alpha" +version = "0.4.1-alpha" dependencies = [ "chrono", "clap", @@ -334,7 +454,10 @@ dependencies = [ "reqwest", "sentry", "serde", + "serde-enum-str", "spinners", + "tracing", + "tracing-subscriber", "walkdir", "zip", ] @@ -354,6 +477,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "1.8.0" @@ -365,12 +509,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.6.2", ] [[package]] @@ -390,42 +534,42 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-io" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-sink" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-core", "futures-io", @@ -448,20 +592,26 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" + [[package]] name = "h2" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", @@ -497,6 +647,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -548,9 +707,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.20" +version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ "bytes", "futures-channel", @@ -572,9 +731,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.0" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ "http", "hyper", @@ -585,18 +744,34 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.47" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c495f162af0bf17656d0014a0eded5f3cd2f365fdd204548c2869db89359dc7" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" dependencies = [ "android_system_properties", "core-foundation-sys", + "iana-time-zone-haiku", "js-sys", - "once_cell", "wasm-bindgen", "winapi", ] +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.3.0" @@ -609,9 +784,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -626,32 +801,54 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "ipnet" -version = "2.5.0" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" + +[[package]] +name = "is-terminal" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys", +] [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jobserver" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -664,9 +861,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.132" +version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "log" @@ -714,11 +926,20 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", @@ -726,6 +947,16 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -747,28 +978,28 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] [[package]] -name = "num_threads" -version = "0.1.6" +name = "object" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ - "libc", + "memchr", ] [[package]] name = "once_cell" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" @@ -778,9 +1009,15 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "os_str_bytes" -version = "6.3.0" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "overload" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "password-hash" @@ -825,15 +1062,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-error" @@ -900,9 +1137,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -927,6 +1164,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -938,9 +1192,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" +checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" dependencies = [ "base64", "bytes", @@ -991,11 +1245,31 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustix" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustls" -version = "0.20.6" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" dependencies = [ "log", "ring", @@ -1033,6 +1307,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + [[package]] name = "sct" version = "0.7.0" @@ -1053,11 +1333,25 @@ dependencies = [ "reqwest", "rustls", "sentry-core", + "sentry-panic", + "sentry-tracing", "tokio", "ureq", "webpki-roots", ] +[[package]] +name = "sentry-backtrace" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afe4800806552aab314129761d5d3b3d422284eca3de2ab59e9fd133636cbd3d" +dependencies = [ + "backtrace", + "once_cell", + "regex", + "sentry-core", +] + [[package]] name = "sentry-core" version = "0.29.1" @@ -1071,6 +1365,27 @@ dependencies = [ "serde_json", ] +[[package]] +name = "sentry-panic" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0af37b8500f273e511ebd6eb0d342ff7937d64ce3f134764b2b4653112d48cb4" +dependencies = [ + "sentry-backtrace", + "sentry-core", +] + +[[package]] +name = "sentry-tracing" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63fc83ec2cf38726bd18cb1943ff11555b07fd5034cb68b10958ab32e2863a1f" +dependencies = [ + "sentry-core", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "sentry-types" version = "0.29.1" @@ -1083,7 +1398,7 @@ dependencies = [ "serde", "serde_json", "thiserror", - "time 0.3.14", + "time 0.3.17", "url", "uuid", ] @@ -1097,6 +1412,36 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-attributes" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3aba2af3c3b9cd6f3a919056dac6005b71fceecc1cdfa65c4df3912f64e07e60" +dependencies = [ + "darling_core", + "serde-rename-rule", + "syn", +] + +[[package]] +name = "serde-enum-str" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a41bf2fc78a58589b9a6948bfc918c9b2dc918732f2ac14eed982ffb876b39" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "serde-attributes", + "syn", +] + +[[package]] +name = "serde-rename-rule" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd2930103714ccef4f1fe5b6a5f2b6fdcfe462a6c802464714bd41e5b5097c33" + [[package]] name = "serde_derive" version = "1.0.150" @@ -1110,9 +1455,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa", "ryu", @@ -1133,9 +1478,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.4" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", @@ -1144,15 +1489,24 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + [[package]] name = "slab" version = "0.4.7" @@ -1162,6 +1516,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + [[package]] name = "socket2" version = "0.4.7" @@ -1269,29 +1629,38 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.34" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1b05ca9d106ba7d2e31a9dab4a64e7be2cce415321966ea3132c49a656e252" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.34" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8f2591983642de85c921015f3f070c665a197ed69e417af436115e3a1407487" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + [[package]] name = "time" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", @@ -1300,21 +1669,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.14" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ "itoa", - "libc", - "num_threads", + "serde", + "time-core", "time-macros", ] +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + [[package]] name = "time-macros" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] [[package]] name = "tinyvec" @@ -1333,9 +1711,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89797afd69d206ccd11fb0ea560a44bbb87731d020670e79416d442919257d42" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ "autocfg", "bytes", @@ -1343,10 +1721,9 @@ dependencies = [ "memchr", "mio", "num_cpus", - "once_cell", "pin-project-lite", "socket2", - "winapi", + "windows-sys", ] [[package]] @@ -1382,22 +1759,60 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", ] [[package]] @@ -1408,9 +1823,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicase" @@ -1429,24 +1844,24 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-normalization" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "untrusted" @@ -1484,14 +1899,20 @@ dependencies = [ [[package]] name = "uuid" -version = "1.1.2" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" dependencies = [ "getrandom", "serde", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.4" @@ -1533,9 +1954,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1543,9 +1964,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", @@ -1558,9 +1979,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -1570,9 +1991,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1580,9 +2001,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -1593,15 +2014,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "web-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -1619,9 +2040,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.5" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ "webpki", ] @@ -1659,46 +2080,60 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ + "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", + "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" [[package]] name = "winreg" @@ -1731,7 +2166,7 @@ dependencies = [ "hmac", "pbkdf2", "sha1", - "time 0.3.14", + "time 0.3.17", "zstd", ] diff --git a/Cargo.toml b/Cargo.toml index d2d3e02..4a0c4b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,11 @@ [package] name = "discloud" -rust-version = "1.63.0" authors = ["coffee-is-power"] repository = "https://github.com/discloud/cli-rust/" -version = "0.3.2-alpha" +version = "0.4.1-alpha" edition = "2021" description = "Blazingly fast Discloud CLI" license = "Apache-2.0" -license-file = "LICENSE" categories = ["command-line-utilities"] keywords = ["discloud", "cli", "bot", "fast", "discord"] readme = "README.md" @@ -19,8 +17,11 @@ colored = "2.0.0" dialoguer = "0.10.2" directories = "4.0.1" reqwest = { version = "0.11.12", features = ["blocking", "json", "multipart", "rustls-tls"], default-features=false } -sentry = {version = "0.29.1", default-features = false, features = ["rustls", "reqwest"]} +sentry = { version = "0.29.1", default-features = false, features = ["rustls", "reqwest", "tracing", "panic"] } serde = { version = "1.0.150", features = ["derive"] } +serde-enum-str = "0.2.5" spinners = "4.1.0" +tracing = "0.1.36" +tracing-subscriber = { version = "0.3.15" } walkdir = "2.3.2" zip = "0.6.3" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 6a423bf..979fd85 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,3 @@ [toolchain] -channel = "1.63.0" +channel = "stable" +components = [ "clippy", "rustfmt" ] \ No newline at end of file diff --git a/src/auth.rs b/src/auth.rs index e08909f..007b5ed 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,14 +1,17 @@ use crate::api_url; +#[tracing::instrument] pub fn login(token: String) -> std::io::Result<()> { let token_file = crate::config_dir::get_path(".discloud_token").unwrap(); std::fs::write(token_file, token)?; Ok(()) } +#[tracing::instrument] pub fn get_token() -> std::io::Result { let token_file = crate::config_dir::get_path(".discloud_token").unwrap(); std::fs::read_to_string(token_file) } +#[tracing::instrument] pub fn validate_token() -> bool { match get_token() { Ok(token) => { diff --git a/src/commands/mod.rs b/src/commands.rs similarity index 51% rename from src/commands/mod.rs rename to src/commands.rs index 7c0cf38..ceb9d30 100644 --- a/src/commands/mod.rs +++ b/src/commands.rs @@ -1,24 +1,47 @@ pub mod aboutme; -pub mod logs; -pub mod stop; -pub mod start; -pub mod restart; pub mod apps; pub mod authstatus; pub mod commit; +pub mod status; pub mod init; pub mod login; -pub mod upload; +pub mod logs; +pub mod mods; pub mod remove; +pub mod restart; +pub mod start; +pub mod stop; +pub mod upload; use colored::Colorize; use dialoguer::{theme::ColorfulTheme, Select}; use spinners::*; - -use crate::entities::FetchError; +#[macro_export] +macro_rules! handle_result { + ($v:expr) => { + match $v { + Ok(v) => v, + Err(err) => { + super::err(&err.to_string()); + std::process::exit(1); + } + } + }; + ($v:expr, $spinner:ident) => { + match $v { + Ok(v) => v, + Err(err) => { + $spinner.stop_with_message(super::format_err(&err.to_string())); + std::process::exit(1); + } + } + }; +} +use crate::entities::{FetchError, app::App}; +#[tracing::instrument] pub fn expect_token() -> String { if crate::auth::validate_token() { log("Your token is valid!"); - return crate::auth::get_token().unwrap(); + crate::auth::get_token().unwrap() } else { err("Your token is invalid!"); std::process::exit(1); @@ -58,35 +81,66 @@ mod tests { #[test] fn log() { - let mut out = String::from("✔".green().bold().to_string()); + let mut out = "✔".green().bold().to_string(); out.push_str(" Some logs"); assert_eq!(super::format_log("Some logs"), out) } #[test] fn err() { - let mut out = String::from("✘".red().bold().to_string()); + let mut out = "X".red().bold().to_string(); out.push_str(" Some errors"); assert_eq!(super::format_err("Some errors"), out) } #[test] fn warn() { - let mut out = String::from("!".yellow().bold().to_string()); + let mut out = "!".yellow().bold().to_string(); out.push_str(" Some warnings"); assert_eq!(super::format_warn("Some warnings"), out) } } -pub fn ask_for_app(token: String, action: &str) -> Result { - let user = crate::entities::user::fetch_user(token.clone())?; - match user.apps.len() { + +pub fn ask_for_app(token: String, action: &str, teams: bool) -> Result { + let mut apps = if teams { + crate::entities::app::App::fetch_foreign_apps(token) + } else { + crate::entities::app::App::fetch_all(token) + }?; + match apps.len() { 0 => { - err("You don't have any apps. Use `discloud up` to upload one."); - std::process::exit(1) + err("You don't have any apps!"); + std::process::exit(1); + }, + 1 => Ok(apps.remove(0)), + _ => { + let options = apps + .iter() + .map(|app| format!("{}: ({}) {}", app.name, app.lang, app.id)) + .collect::>(); + let chosen_opt = Select::with_theme(&ColorfulTheme::default()) + .items(&options) + .with_prompt(format!("Which app you want to {}?", action)) + .interact() + .unwrap(); + Ok(apps.remove(chosen_opt)) } - 1 => Ok(user.apps[0].parse().unwrap()), + } +} + +pub fn ask_for_app_id(token: String, action: &str, teams: bool) -> Result { + let apps = if teams { + crate::entities::app::App::fetch_foreign_apps(token) + } else { + crate::entities::app::App::fetch_all(token) + }?; + match apps.len() { + 0 => { + err("You don't have any apps!"); + std::process::exit(1); + }, + 1 => Ok(apps[0].id.parse().unwrap()), _ => { - let apps = crate::entities::app::App::fetch_all(token)?; let options = apps .iter() .map(|app| format!("{}: ({}) {}", app.name, app.lang, app.id)) diff --git a/src/commands/aboutme.rs b/src/commands/aboutme.rs index 97785e6..b7446eb 100644 --- a/src/commands/aboutme.rs +++ b/src/commands/aboutme.rs @@ -1,53 +1,65 @@ use chrono::{Datelike, Timelike}; use colored::Colorize; -pub fn aboutme(){ +#[tracing::instrument] +pub fn aboutme() { let token = super::expect_token(); - match crate::entities::user::fetch_user(token.clone()) { + match crate::entities::user::fetch_user(token) { Ok(user) => { println!("ID: {}", user.user_id.bright_black()); println!("Plan: {}", color_plan(user.plan)); - let end_date = user.plan_data_end; - println!("Your plan ends at: {}/{}/{} {}:{}", end_date.day(), end_date.month(), end_date.year(), end_date.hour(), end_date.minute()); - println!(" Which means you have {} days left!", user.last_data_left.days.to_string().green().bold()); + if let Some(end_date) = user.plan_data_end { + println!( + "Your plan ends at: {}/{}/{} {}:{}", + end_date.day(), + end_date.month(), + end_date.year(), + end_date.hour(), + end_date.minute() + ); + } + if let Some(time_left) = user.last_data_left{ + println!( + " Which means you have {} days left!", + time_left.days.to_string().green().bold() + ); + } println!("Memory:"); - println!(" Total: {}{}", user.total_ram_mb.to_string().green().bold(), "MB".green().bold()); - println!(" Used: {}{}", user.ram_used_mb.to_string().green().bold(), "MB".green().bold()); - println!(" Available: {}{}", (user.total_ram_mb - user.ram_used_mb).to_string().green().bold(), "MB".green().bold()); + println!( + " Total: {}{}", + user.total_ram_mb.to_string().green().bold(), + "MB".green().bold() + ); + println!( + " Used: {}{}", + user.ram_used_mb.to_string().green().bold(), + "MB".green().bold() + ); + println!( + " Available: {}{}", + (user.total_ram_mb - user.ram_used_mb) + .to_string() + .green() + .bold(), + "MB".green().bold() + ); println!("Locale: {}", user.locale.blue()); } - Err(err) => super::err(&err.to_string()) - } + Err(err) => super::err(&err.to_string()), + } } +#[tracing::instrument] fn color_plan(plan: String) -> String { - match plan.as_str() { - "Free" => { - plan.bright_black().to_string() - } - "Carbon" => { - plan.bright_black().bold().to_string() - } - "Gold" => { - plan.yellow().bold().to_string() - } - "Platinum" => { - plan.blue().bold().to_string() - } - "Diamond" => { - plan.cyan().bold().to_string() - } - "Ruby" => { - plan.red().bold().to_string() - } - "Sapphire" => { - plan.bright_red().bold().to_string() - } - "Krypton" => { - plan.bright_green().bold().to_string() - } - "Special" => { - plan.bright_cyan().bold().to_string() - } - _ => unreachable!() - } + match plan.as_str() { + "Free" => plan.bright_black().to_string(), + "Carbon" => plan.bright_black().bold().to_string(), + "Gold" => plan.yellow().bold().to_string(), + "Platinum" => plan.blue().bold().to_string(), + "Diamond" => plan.cyan().bold().to_string(), + "Ruby" => plan.red().bold().to_string(), + "Sapphire" => plan.bright_red().bold().to_string(), + "Krypton" => plan.bright_green().bold().to_string(), + "Special" => plan.bright_cyan().bold().to_string(), + _ => unreachable!(), + } } diff --git a/src/commands/apps.rs b/src/commands/apps.rs index a4a7d05..892cf46 100644 --- a/src/commands/apps.rs +++ b/src/commands/apps.rs @@ -1,31 +1,31 @@ use colored::Colorize; use crate::entities::FetchError; -pub fn apps() { +#[tracing::instrument] +pub fn apps(teams: bool) { let token = super::expect_token(); - match crate::entities::app::App::fetch_all(token.clone()) { + match if !teams {crate::entities::app::App::fetch_all(token)} else {crate::entities::app::App::fetch_foreign_apps(token)} { Ok(apps) => { - println!("Your apps:"); + println!("{}Your apps:", if teams{"(Not) "} else {""}); for app in apps { - println!("- {}: ({}) {}", app.name.green(), app.lang.yellow(), app.id.to_string().bright_black()); + println!( + "- {}: ({}) {}", + app.name.green(), + app.lang.yellow(), + app.id.to_string().bright_black() + ); } } - Err(err) => { - match err { - FetchError::APIReturnedError(code) =>{ - match code { - 404 => { - super::err("You don't have any apps. Use `discloud up` to upload one.") - } - _ => { - super::err(&err.to_string()); - } - } - } - err => { + Err(err) => match err { + FetchError::APIReturnedError(code) => match code { + 404 => super::err("You don't have any apps. Use `discloud up` to upload one."), + _ => { super::err(&err.to_string()); } + }, + err => { + super::err(&err.to_string()); } - } + }, } -} \ No newline at end of file +} diff --git a/src/commands/authstatus.rs b/src/commands/authstatus.rs index 09e8192..82061c0 100644 --- a/src/commands/authstatus.rs +++ b/src/commands/authstatus.rs @@ -1,13 +1,12 @@ use crate::auth; use std::io::ErrorKind; +#[tracing::instrument] pub fn authstatus() -> std::io::Result<()> { match auth::get_token() { Ok(token) => { super::log("You're already logged in!\n"); let mut stars = String::new(); - for _ in 0..token.len() - 5 { - stars.push('*'); - } + stars.push_str(&"*".repeat(token.len() - 5)); super::log(&format!("Token: {}{}", &token[..5], stars)); super::check_token(); } diff --git a/src/commands/commit.rs b/src/commands/commit.rs index 2464ca0..eee3b07 100644 --- a/src/commands/commit.rs +++ b/src/commands/commit.rs @@ -9,14 +9,16 @@ use zip::write::FileOptions; use std::fs::File; use std::path::{Path, PathBuf}; use walkdir::{DirEntry, WalkDir}; +#[tracing::instrument] fn get_zip_file_path() -> PathBuf { let mut dst_file = std::env::temp_dir(); dst_file.push("discloud.zip"); dst_file } -pub fn commit() { +#[tracing::instrument] +pub fn commit(teams: bool) { let token = super::expect_token(); - let app_id = match super::ask_for_app(token.clone(), "commit") { + let app_id = match super::ask_for_app_id(token.clone(), "commit", teams) { Ok(app_id) => app_id, Err(error) => { super::err(&format!("Couldn't fetch apps: {}", error)); @@ -31,8 +33,8 @@ pub fn commit() { Err(e) => super::err(&format!("Failed to zip: {:?}", e)), } let mut spinner = Spinner::new(spinners::Spinners::Earth, "Committing app...".to_string()); - let msg = match upload_zip(token, app_id) { - Ok(()) => super::format_log("Your app was successfully commited!"), + let msg = match upload_zip(token, app_id, teams) { + Ok(()) => if !teams {super::format_log("Your app was updated successfully!")} else {super::format_log("Your buddy's app was updated!")}, Err(err) => super::format_err(&err), }; spinner.stop_with_message(msg); @@ -64,10 +66,10 @@ where let mut f = File::open(path)?; f.read_to_end(&mut buffer)?; - zip.write_all(&*buffer)?; + zip.write_all(&buffer)?; buffer.clear(); println!("{}", "✔".green().bold()); - } else if name.as_os_str().len() != 0 { + } else if !name.as_os_str().is_empty() { zip.add_directory(name.to_str().unwrap(), options)?; } } @@ -75,6 +77,7 @@ where Result::Ok(()) } +#[tracing::instrument] fn zip_dir_to_file( src_dir: &str, dst_file: &str, @@ -85,7 +88,7 @@ fn zip_dir_to_file( } let writer = File::create(dst_file).unwrap(); - let walkdir = WalkDir::new(src_dir.to_string()); + let walkdir = WalkDir::new(src_dir); let it = walkdir.into_iter(); zip_dir( @@ -111,16 +114,20 @@ fn zip_dir_to_file( Ok(()) } -fn upload_zip(token: String, app_id: u128) -> Result<(), String> { +#[tracing::instrument] +fn upload_zip(token: String, app_id: u128, teams: bool) -> Result<(), String> { let file_path = get_zip_file_path(); let file_path = file_path.to_str().unwrap(); - let client = reqwest::blocking::Client::builder().timeout(None).build().unwrap(); + let client = reqwest::blocking::Client::builder() + .timeout(None) + .build() + .unwrap(); let form = reqwest::blocking::multipart::Form::new().file("file", file_path); match form { Err(err) => Err(format!("Couldn't open zip file: {}", err)), Ok(form) => { let req = client - .put(crate::api_url!(format!("/app/{}/commit", app_id))) + .put(crate::api_url!(format!("/{}/{}/commit", if teams {"team"} else {"app"}, app_id))) .multipart(form) .header("api-token", token); let res = req.send(); diff --git a/src/commands/init.rs b/src/commands/init.rs index 9c2d312..8bb8521 100644 --- a/src/commands/init.rs +++ b/src/commands/init.rs @@ -1,7 +1,7 @@ use dialoguer::{theme::ColorfulTheme, Select}; fn vec_from_str(s: String) -> Vec { - s.split(",").map(|s| s.trim().into()).collect() + s.split(',').map(|s| s.trim().into()).collect() } #[derive(Default)] @@ -25,7 +25,7 @@ impl App { fn get_config(&self) -> String { match &self.typ { AppTyp::Site => { - if self.apt.len() > 0 { + if !self.apt.is_empty() { format!( "ID={}\nMAIN={}\nAUTORESTART={}\nRAM={}\nAPT={}\nTYPE=site\nVERSION=latest", self.subdomain, @@ -42,7 +42,7 @@ impl App { } } AppTyp::Bot => { - if self.apt.len() > 0 { + if !self.apt.is_empty() { format!("NAME={}\nAVATAR={}\nMAIN={}\nAUTORESTART={}\nRAM={}\nAPT={}\nTYPE=bot\nVERSION=latest", self.name, self.avatar, self.main, self.autorestart, self.ram, self.apt.join(",")) } else { format!("NAME={}\nAVATAR={}\nMAIN={}\nAUTORESTART={}\nRAM={}\nTYPE=bot\nVERSION=latest", self.name,self.avatar, self.main, self.autorestart, self.ram) @@ -51,6 +51,7 @@ impl App { } } } +#[tracing::instrument] pub fn init() -> std::io::Result<()> { use dialoguer::Input; if std::path::Path::new("discloud.config").exists() { @@ -59,7 +60,7 @@ pub fn init() -> std::io::Result<()> { let typ = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Type") .default(0) - .items(&vec!["Bot", "Site"]) + .items(&["Bot", "Site"]) .interact()?; let mut app: App = Default::default(); match typ { @@ -95,7 +96,7 @@ pub fn init() -> std::io::Result<()> { .with_prompt("APT Packages") .allow_empty(true) .interact_text()?; - if apt.len() > 0 { + if !apt.is_empty() { app.apt = vec_from_str(apt); } std::fs::write("discloud.config", app.get_config())?; diff --git a/src/commands/login.rs b/src/commands/login.rs index 53e8f21..f024b97 100644 --- a/src/commands/login.rs +++ b/src/commands/login.rs @@ -1,8 +1,9 @@ use clap::*; +#[tracing::instrument] pub fn login(matches: &ArgMatches) -> std::io::Result<()> { let token = matches.get_one::("token").unwrap().clone(); if let Err(err) = crate::auth::login(token) { - super::err(format!("Couldn't save the token: {}", err.kind().to_string()).as_str()); + super::err(format!("Couldn't save the token: {}", err.kind()).as_str()); Err(err) } else { super::log("Token saved successfully"); diff --git a/src/commands/logs.rs b/src/commands/logs.rs index 3ac5f76..eda74ee 100644 --- a/src/commands/logs.rs +++ b/src/commands/logs.rs @@ -1,11 +1,12 @@ use spinners::{Spinner, Spinners}; -pub fn logs(){ +#[tracing::instrument] +pub fn logs(teams: bool) { let token = super::expect_token(); - match super::ask_for_app(token.clone(), "show the logs") { + match super::ask_for_app_id(token.clone(), "show the logs", teams) { Ok(app_id) => { let mut spinner = Spinner::new(Spinners::Bounce, "Downloading the logs".into()); - match crate::entities::app::App::get_logs(token.clone(), app_id) { + match crate::entities::app::App::get_logs(token, app_id, teams) { Ok(logs) => { spinner.stop_with_message(logs); } @@ -14,11 +15,10 @@ pub fn logs(){ std::process::exit(1); } } - } Err(err) => { super::err(&format!("Couldn't fetch apps from api: {}", err)); std::process::exit(1); } } -} \ No newline at end of file +} diff --git a/src/commands/mods.rs b/src/commands/mods.rs new file mode 100644 index 0000000..8de5e15 --- /dev/null +++ b/src/commands/mods.rs @@ -0,0 +1,5 @@ +pub mod add; +pub mod allow; +pub mod deny; +pub mod remove; +use super::*; diff --git a/src/commands/mods/add.rs b/src/commands/mods/add.rs new file mode 100644 index 0000000..8b7b39e --- /dev/null +++ b/src/commands/mods/add.rs @@ -0,0 +1,31 @@ +use spinners::Spinner; + +use crate::{ + commands::{ask_for_app_id, expect_token}, + entities::moderator::{Feature, Mod}, +}; + +#[tracing::instrument] +pub fn add(id: u128) { + let token = expect_token(); + let app_id = crate::handle_result!(ask_for_app_id(token.clone(), "add a moderator", false)); + let mut spinner = Spinner::new( + spinners::Spinners::Bounce, + format!("Adding {} as a moderator", id), + ); + + let moderator = crate::handle_result!( + Mod::new( + token, + id, + app_id, + vec![Feature::SeeLogs, Feature::Status] + ), + spinner + ); + spinner.stop_with_message(super::format_log(&format!( + "Permissions {:?} have been given to {}", + moderator.get_features(), + id + ))); +} diff --git a/src/commands/mods/allow.rs b/src/commands/mods/allow.rs new file mode 100644 index 0000000..aafcca8 --- /dev/null +++ b/src/commands/mods/allow.rs @@ -0,0 +1,30 @@ +use crate::entities::moderator::Feature; +use spinners::*; +pub fn allow(id: u128, features: Vec) { + let token = super::expect_token(); + let app_id = crate::handle_result!(super::ask_for_app_id( + token.clone(), + "modify the mod's permissions", + false + )); + let mut spinner = Spinner::new(Spinners::Pong, "Adding the permissions...".into()); + let moderator = crate::handle_result!(crate::entities::moderator::Mod::fetch_mod( + token.clone(), + id, + app_id + )); + match moderator { + Some(mut moderator) => { + let mut feats = moderator.get_features(); + feats.append(&mut features.clone()); + crate::handle_result!(moderator.set_features(feats, token), spinner); + spinner.stop_with_message(super::format_log(&format!( + "{:?} were added successfully!", + features + ))); + } + None => { + spinner.stop_with_message(super::format_err("That moderator doesn't exist!")); + } + } +} diff --git a/src/commands/mods/deny.rs b/src/commands/mods/deny.rs new file mode 100644 index 0000000..755dcb5 --- /dev/null +++ b/src/commands/mods/deny.rs @@ -0,0 +1,40 @@ +use crate::entities::moderator::Feature; +use spinners::*; +fn subtract_vecs(v1: &[T], v2: &[T]) -> Vec +where + T: Eq + Clone, +{ + v1.iter().filter(|&x| !v2.contains(x)).cloned().collect() +} +pub fn deny(id: u128, features: Vec) { + let token = super::expect_token(); + let app_id = crate::handle_result!(super::ask_for_app_id( + token.clone(), + "modify the mod's permissions", + false + )); + let mut spinner = Spinner::new(Spinners::Toggle2, "Removing the permissions...".into()); + let moderator = crate::handle_result!(crate::entities::moderator::Mod::fetch_mod( + token.clone(), + id, + app_id + )); + match moderator { + Some(mut moderator) => { + crate::handle_result!( + moderator.set_features( + subtract_vecs(&moderator.get_features(), &features), + token + ), + spinner + ); + spinner.stop_with_message(super::format_log(&format!( + "{:?} were removed successfully!", + features + ))); + } + None => { + spinner.stop_with_message(super::format_err("That moderator doesn't exist!")); + } + } +} diff --git a/src/commands/mods/remove.rs b/src/commands/mods/remove.rs new file mode 100644 index 0000000..1bb58c8 --- /dev/null +++ b/src/commands/mods/remove.rs @@ -0,0 +1,31 @@ +use spinners::Spinner; + +use crate::handle_result; +use crate::{ + commands::{ask_for_app_id, expect_token}, + entities::{app::App, moderator::Mod}, +}; +#[tracing::instrument] +pub fn remove(id: u128) { + let token = expect_token(); + let app_id = handle_result!(ask_for_app_id(token.clone(), "remove the moderator", false)); + let mut spinner = Spinner::new( + spinners::Spinners::Moon, + format!("Sending {} to the moon", id), + ); + let app = handle_result!(App::fetch(token.clone(), app_id), spinner); + let moderator = handle_result!(Mod::fetch_mod(token.clone(), id, app_id), spinner); + if let Some(moderator) = moderator { + handle_result!(moderator.remove(token), spinner); + spinner.stop_with_message(super::format_log(&format!( + "{} was removed from your app!", + id + ))); + } else { + spinner.stop_with_message(super::format_err(&format!( + "{} isn't a moderator on {} ({})", + id, app.name, app.id + ))); + std::process::exit(1); + } +} diff --git a/src/commands/remove.rs b/src/commands/remove.rs index 80fc6ee..2b0ae93 100644 --- a/src/commands/remove.rs +++ b/src/commands/remove.rs @@ -1,24 +1,24 @@ use spinners::*; +#[tracing::instrument] pub fn remove() { let token = super::expect_token(); - match super::ask_for_app(token.clone(), "delete") { + match super::ask_for_app_id(token.clone(), "delete", false) { Ok(app_id) => { let mut spinner = Spinner::new(Spinners::Flip, "Deleting your app".into()); - match crate::entities::app::App::delete(token.clone(), app_id) { + match crate::entities::app::App::delete(token, app_id) { Ok(()) => { - spinner.stop_with_message(super::format_log("Your app was successfully nuked!")); + spinner + .stop_with_message(super::format_log("Your app was successfully nuked!")); } Err(err) => { super::err(&format!("Couldn't delete your app: {}", err)); std::process::exit(1); } } - } Err(err) => { super::err(&format!("Couldn't fetch apps from api: {}", err)); std::process::exit(1); } } - -} \ No newline at end of file +} diff --git a/src/commands/restart.rs b/src/commands/restart.rs index 9263b40..77cf943 100644 --- a/src/commands/restart.rs +++ b/src/commands/restart.rs @@ -1,10 +1,11 @@ use spinners::*; -pub fn restart() { +#[tracing::instrument] +pub fn restart(teams: bool) { let token = super::expect_token(); - match super::ask_for_app(token.clone(), "restart") { + match super::ask_for_app_id(token.clone(), "restart", teams) { Ok(app_id) => { let mut spinner = Spinner::new(Spinners::Earth, "Restarting your app".into()); - match crate::entities::app::App::restart(token.clone(), app_id) { + match crate::entities::app::App::restart(token, app_id, teams) { Ok(()) => { spinner.stop_with_message(super::format_log("Your app is up!")); } @@ -13,12 +14,10 @@ pub fn restart() { std::process::exit(1); } } - } Err(err) => { super::err(&format!("Couldn't fetch apps from api: {}", err)); std::process::exit(1); } } - } diff --git a/src/commands/start.rs b/src/commands/start.rs index 91e40bb..ee42321 100644 --- a/src/commands/start.rs +++ b/src/commands/start.rs @@ -1,10 +1,11 @@ use spinners::*; -pub fn start() { +#[tracing::instrument] +pub fn start(teams: bool) { let token = super::expect_token(); - match super::ask_for_app(token.clone(), "start") { + match super::ask_for_app_id(token.clone(), "start", teams) { Ok(app_id) => { let mut spinner = Spinner::new(Spinners::Earth, "Starting your app".into()); - match crate::entities::app::App::start(token.clone(), app_id) { + match crate::entities::app::App::start(token, app_id, teams) { Ok(()) => { spinner.stop_with_message(super::format_log("Your app is up!")); } @@ -13,12 +14,10 @@ pub fn start() { std::process::exit(1); } } - } Err(err) => { super::err(&format!("Couldn't fetch apps from api: {}", err)); std::process::exit(1); } } - } diff --git a/src/commands/status.rs b/src/commands/status.rs new file mode 100644 index 0000000..9c3fbe2 --- /dev/null +++ b/src/commands/status.rs @@ -0,0 +1,18 @@ +use colored::Colorize; +#[tracing::instrument] +pub fn status(teams: bool) { + let token = super::expect_token(); + match super::ask_for_app(token, "show the status", teams) { + Ok(app) => { + println!("Your app is {}", if app.online { + "on".green() + } else { + "off".red() + }); + } + Err(err) => { + super::err(&format!("Couldn't fetch apps from api: {}", err)); + std::process::exit(1); + } + } +} diff --git a/src/commands/stop.rs b/src/commands/stop.rs index a658442..e45daa0 100644 --- a/src/commands/stop.rs +++ b/src/commands/stop.rs @@ -1,10 +1,11 @@ use spinners::*; -pub fn stop() { +#[tracing::instrument] +pub fn stop(teams: bool) { let token = super::expect_token(); - match super::ask_for_app(token.clone(), "shutdown") { + match super::ask_for_app_id(token.clone(), "shutdown", teams) { Ok(app_id) => { let mut spinner = Spinner::new(Spinners::Pong, "Shutting down your app".into()); - match crate::entities::app::App::stop(token.clone(), app_id) { + match crate::entities::app::App::stop(token, app_id, teams) { Ok(()) => { spinner.stop_with_message(super::format_log("Your app is down!")); } @@ -13,12 +14,10 @@ pub fn stop() { std::process::exit(1); } } - } Err(err) => { super::err(&format!("Couldn't fetch apps from api: {}", err)); std::process::exit(1); } } - -} \ No newline at end of file +} diff --git a/src/commands/upload.rs b/src/commands/upload.rs index aea684c..471108b 100644 --- a/src/commands/upload.rs +++ b/src/commands/upload.rs @@ -15,6 +15,7 @@ fn get_zip_file_path() -> PathBuf { dst_file.push("discloud.zip"); dst_file } +#[tracing::instrument] pub fn upload() { let token = super::expect_token(); let src_dir = "."; @@ -57,10 +58,10 @@ where let mut f = File::open(path)?; f.read_to_end(&mut buffer)?; - zip.write_all(&*buffer)?; + zip.write_all(&buffer)?; buffer.clear(); println!("{}", "✔".green().bold()); - } else if name.as_os_str().len() != 0 { + } else if !name.as_os_str().is_empty() { zip.add_directory(name.to_str().unwrap(), options)?; } } @@ -78,7 +79,7 @@ fn zip_dir_to_file( } let writer = File::create(dst_file).unwrap(); - let walkdir = WalkDir::new(src_dir.to_string()); + let walkdir = WalkDir::new(src_dir); let it = walkdir.into_iter(); zip_dir( @@ -109,11 +110,14 @@ fn upload_zip(token: String) -> Result<(), String> { struct UploadResponse { status: String, message: Option, - logs: Option + logs: Option, } let file_path = get_zip_file_path(); let file_path = file_path.to_str().unwrap(); - let client = reqwest::blocking::Client::builder().timeout(None).build().unwrap(); + let client = reqwest::blocking::Client::builder() + .timeout(None) + .build() + .unwrap(); let form = reqwest::blocking::multipart::Form::new().file("file", file_path); match form { Err(err) => Err(format!("Couldn't open zip file: {}", err)), @@ -130,14 +134,22 @@ fn upload_zip(token: String) -> Result<(), String> { let res: UploadResponse = res.json().unwrap(); if res.status == "error" { if let Some(logs) = res.logs { - Err(format!("Upload failed: API Returned {}: {}\nLogs:\n{}", status.as_u16(), res.message.unwrap(), logs)) + Err(format!( + "Upload failed: API Returned {}: {}\nLogs:\n{}", + status.as_u16(), + res.message.unwrap(), + logs + )) } else { - Err(format!("Upload failed: API Returned {}: {}", status.as_u16(), res.message.unwrap())) + Err(format!( + "Upload failed: API Returned {}: {}", + status.as_u16(), + res.message.unwrap() + )) } } else { Ok(()) } - } } } diff --git a/src/config_dir.rs b/src/config_dir.rs index 6ecd0d3..caf3c32 100644 --- a/src/config_dir.rs +++ b/src/config_dir.rs @@ -1,15 +1,13 @@ use directories::ProjectDirs; /// Returns config base paths according to the conventions of the OS +#[tracing::instrument] pub fn get_proj_dir() -> Option { - if let Some(proj_dirs) = ProjectDirs::from("com", "Discloud", "Discloud Cli") { - Some(proj_dirs.config_dir().to_path_buf()) - } else { - None - } + ProjectDirs::from("com", "Discloud", "Discloud Cli").map(|p| p.config_dir().to_path_buf()) } +#[tracing::instrument] /// Pushes file to the path returned by get_proj_dir() pub fn get_path(file: &str) -> Option { let mut result = get_proj_dir()?; - result.push(file.to_string()); + result.push(file); Some(result) } diff --git a/src/entities/mod.rs b/src/entities.rs similarity index 65% rename from src/entities/mod.rs rename to src/entities.rs index 0c81630..03a5736 100644 --- a/src/entities/mod.rs +++ b/src/entities.rs @@ -1,3 +1,4 @@ +pub mod moderator; use std::fmt::Display; pub mod app; @@ -7,15 +8,17 @@ pub enum FetchError { NotLoggedIn, FailedToConnect(reqwest::Error), APIReturnedError(u16), - FailedWithMessage(String) + FailedWithMessage(String), } impl Display for FetchError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::NotLoggedIn => f.write_str("not logged in"), Self::FailedToConnect(err) => f.write_str(&format!("failed to connect: {}", err)), - Self::APIReturnedError(status) => f.write_str(&format!("api returned code: {}", status)), - Self::FailedWithMessage(msg) => f.write_str(&msg), + Self::APIReturnedError(status) => { + f.write_str(&format!("api returned code: {}", status)) + } + Self::FailedWithMessage(msg) => f.write_str(msg), } } } diff --git a/src/entities/app.rs b/src/entities/app.rs index f1ae766..98f789c 100644 --- a/src/entities/app.rs +++ b/src/entities/app.rs @@ -1,19 +1,29 @@ use super::*; use serde::Deserialize; -#[derive(Deserialize)] +#[derive(Deserialize, Debug, Clone)] pub struct App { pub name: String, pub id: String, pub online: bool, - #[serde(rename = "ramKilled")] - pub ram_killed: bool, - pub ram: u64, - #[serde(rename = "mainFile")] - pub main_file: String, pub lang: String, } impl App { + // Fetches apps from /team instead of /app/all + pub fn fetch_foreign_apps(token: String) -> Result, FetchError> { + #[derive(Deserialize)] + struct AppsResponse { + pub apps: Vec, + } + let client = reqwest::blocking::Client::new(); + let req = client + .get(crate::api_url!("/team")) + .header("api-token", token); + match req.send() { + Ok(res) => Ok(res.json::().unwrap().apps), + Err(err) => Err(FetchError::FailedToConnect(err)), + } + } pub fn fetch_all(token: String) -> Result, FetchError> { #[derive(Deserialize)] struct AppsResponse { @@ -34,7 +44,6 @@ impl App { Err(err) => Err(FetchError::FailedToConnect(err)), } } - pub fn fetch(token: String, id: u128) -> Result { #[derive(Deserialize)] struct AppResponse { @@ -55,27 +64,33 @@ impl App { Err(err) => Err(FetchError::FailedToConnect(err)), } } - pub fn get_logs(token: String, id: u128) -> Result { + pub fn get_logs(token: String, id: u128, team: bool) -> Result { #[derive(Deserialize)] struct Terminal { - big: String + big: String, } #[derive(Deserialize)] struct AppLogs { - terminal: Terminal + terminal: Terminal, } #[derive(Deserialize)] struct LogsResponse { - apps: Option + apps: Option, } let client = reqwest::blocking::Client::new(); let req = client - .get(crate::api_url!(format!("/app/{}/logs", id))) + .get(crate::api_url!(format!("/{}/{}/logs", if team {"team"} else {"app"}, id))) .header("api-token", token); - match req.send() { + match req.send() { Ok(res) => { if res.status().is_success() { - Ok(res.json::().unwrap().apps.unwrap().terminal.big) + Ok(res + .json::() + .unwrap() + .apps + .unwrap() + .terminal + .big) } else { Err(FetchError::APIReturnedError(res.status().as_u16())) } @@ -83,12 +98,12 @@ impl App { Err(err) => Err(FetchError::FailedToConnect(err)), } } - pub fn restart(token: String, id: u128) -> Result<(), FetchError> { + pub fn restart(token: String, id: u128, team: bool) -> Result<(), FetchError> { let client = reqwest::blocking::Client::new(); let req = client - .put(crate::api_url!(format!("/app/{}/restart", id))) + .put(crate::api_url!(format!("/{}/{}/restart", if team {"team"} else {"app"}, id))) .header("api-token", token); - match req.send() { + match req.send() { Ok(res) => { if res.status().is_success() { Ok(()) @@ -99,12 +114,12 @@ impl App { Err(err) => Err(FetchError::FailedToConnect(err)), } } - pub fn start(token: String, id: u128) -> Result<(), FetchError> { + pub fn start(token: String, id: u128, team: bool) -> Result<(), FetchError> { let client = reqwest::blocking::Client::new(); let req = client - .put(crate::api_url!(format!("/app/{}/start", id))) + .put(crate::api_url!(format!("/{}/{}/start", if team {"team"} else {"app"}, id))) .header("api-token", token); - match req.send() { + match req.send() { Ok(res) => { if res.status().is_success() { Ok(()) @@ -115,12 +130,12 @@ impl App { Err(err) => Err(FetchError::FailedToConnect(err)), } } - pub fn stop(token: String, id: u128) -> Result<(), FetchError> { + pub fn stop(token: String, id: u128, team: bool) -> Result<(), FetchError> { let client = reqwest::blocking::Client::new(); let req = client - .put(crate::api_url!(format!("/app/{}/stop", id))) + .put(crate::api_url!(format!("/{}/{}/stop", if team {"team"} else {"app"}, id))) .header("api-token", token); - match req.send() { + match req.send() { Ok(res) => { if res.status().is_success() { Ok(()) @@ -136,7 +151,7 @@ impl App { let req = client .delete(crate::api_url!(format!("/app/{}/delete", id))) .header("api-token", token); - match req.send() { + match req.send() { Ok(res) => { if res.status().is_success() { Ok(()) diff --git a/src/entities/moderator.rs b/src/entities/moderator.rs new file mode 100644 index 0000000..dfd1894 --- /dev/null +++ b/src/entities/moderator.rs @@ -0,0 +1,193 @@ +use super::FetchError; +use serde::{Deserialize, Serialize}; +use serde_enum_str::*; +use std::fmt::Debug; + +#[derive(Deserialize_enum_str, Serialize_enum_str, Clone, Eq, PartialEq)] +pub enum Feature { + #[serde(rename = "start_app")] + Start, + #[serde(rename = "stop_app")] + Stop, + #[serde(rename = "restart_app")] + Restart, + #[serde(rename = "logs_app")] + SeeLogs, + #[serde(rename = "commit_app")] + Commit, + #[serde(rename = "status_app")] + Status, + #[serde(rename = "edit_ram")] + SetRam, + #[serde(rename = "backup_app")] + Backup, +} +impl Debug for Feature { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + Self::Backup => "backup", + Self::Commit => "commit", + Self::Restart => "restart", + Self::SeeLogs => "logs", + Self::SetRam => "ram", + Self::Start => "start", + Self::Status => "status", + Self::Stop => "stop", + }) + } +} +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct Mod { + #[serde(rename = "modID")] + user_id: String, + #[serde(rename = "perms")] + features: Vec, + #[serde(skip)] + app_id: u128, +} +impl Mod { + pub fn new( + token: String, + user_id: u128, + app_id: u128, + features: Vec, + ) -> Result { + let moderator = Self { + user_id: user_id.to_string(), + features, + app_id, + }; + moderator.add(token)?; + Ok(moderator) + } + + pub fn id(&self) -> u128 { + self.user_id.parse().unwrap() + } + pub fn set_features( + &mut self, + permissions: Vec, + token: String, + ) -> Result<(), FetchError> { + self.features = permissions; + #[derive(Deserialize)] + struct Response { + status: String, + message: Option, + } + let client = reqwest::blocking::Client::new(); + let req = client + .put(crate::api_url!(format!("/app/{}/team", self.app_id))) + .header("api-token", token) + .json(self); + match req.send() { + Ok(res) => match res.json::() { + Err(err) => Err(FetchError::FailedWithMessage(err.to_string())), + Ok(response) => { + if response.status == "ok" { + Ok(()) + } else { + Err(FetchError::FailedWithMessage(response.message.unwrap())) + } + } + }, + Err(err) => Err(FetchError::FailedToConnect(err)), + } + } + pub fn fetch_mod( + token: String, + user_id: u128, + app_id: u128, + ) -> Result, FetchError> { + #[derive(Deserialize)] + struct Response { + status: String, + message: Option, + team: Option>, + } + let client = reqwest::blocking::Client::new(); + let req = client + .get(crate::api_url!(format!("/app/{}/team", app_id))) + .header("api-token", token); + match req.send() { + Ok(res) => match res.json::() { + Err(err) => Err(FetchError::FailedWithMessage(err.to_string())), + Ok(response) => { + if response.status == "ok" { + let moderator = response + .team + .unwrap() + .iter() + .find(|m| m.user_id == user_id.to_string()) + .map(|m| Self { + app_id, + ..m.clone() + }); + Ok(moderator) + } else { + Err(FetchError::FailedWithMessage(response.message.unwrap())) + } + } + }, + Err(err) => Err(FetchError::FailedToConnect(err)), + } + } + #[tracing::instrument] + pub fn get_features(&self) -> Vec { + self.features.clone() + } + /// Adds this moderator to the app + pub fn add(&self, token: String) -> Result<(), FetchError> { + #[derive(Deserialize)] + struct Response { + status: String, + message: Option, + } + let client = reqwest::blocking::Client::new(); + let req = client + .post(crate::api_url!(format!("/app/{}/team", self.app_id))) + .header("api-token", token) + .json(self); + match req.send() { + Ok(res) => match res.json::() { + Err(err) => Err(FetchError::FailedWithMessage(err.to_string())), + Ok(response) => { + if response.status == "ok" { + Ok(()) + } else { + Err(FetchError::FailedWithMessage(response.message.unwrap())) + } + } + }, + Err(err) => Err(FetchError::FailedToConnect(err)), + } + } + + pub fn remove(self, token: String) -> Result<(), FetchError> { + #[derive(Deserialize)] + struct Response { + status: String, + message: Option, + } + let client = reqwest::blocking::Client::new(); + let req = client + .delete(crate::api_url!(format!( + "/app/{}/team/{}", + self.app_id, self.user_id + ))) + .header("api-token", token); + match req.send() { + Ok(res) => match res.json::() { + Err(err) => Err(FetchError::FailedWithMessage(err.to_string())), + Ok(response) => { + if response.status == "ok" { + Ok(()) + } else { + Err(FetchError::FailedWithMessage(response.message.unwrap())) + } + } + }, + Err(err) => Err(FetchError::FailedToConnect(err)), + } + } +} diff --git a/src/entities/user.rs b/src/entities/user.rs index fc97939..95c1811 100644 --- a/src/entities/user.rs +++ b/src/entities/user.rs @@ -2,14 +2,14 @@ use serde::Deserialize; use super::FetchError; -#[derive(Deserialize)] -pub struct UserDate { +#[derive(Deserialize, Debug)] +pub struct TimeLeft { pub days: u32, pub hours: u32, pub minutes: u32, pub seconds: u32, } -#[derive(Deserialize)] +#[derive(Deserialize, Debug)] pub struct User { #[serde(rename = "userID")] pub user_id: String, @@ -25,16 +25,17 @@ pub struct User { pub plan: String, pub locale: String, #[serde(rename = "planDataEnd")] - pub plan_data_end: chrono::DateTime, + pub plan_data_end: Option>, #[serde(rename = "lastDataLeft")] - pub last_data_left: UserDate + pub last_data_left: Option, } +#[tracing::instrument] pub fn fetch_user(token: String) -> Result { #[derive(Deserialize)] struct UserResponse { user: User, status: String, - message: String + message: String, } let client = reqwest::blocking::Client::new(); let req = client @@ -45,13 +46,9 @@ pub fn fetch_user(token: String) -> Result { if res.status().is_success() { let res = res.json::().unwrap(); match res.status.as_str() { - "ok" => { - Ok(res.user) - } - "error" => { - Err(FetchError::FailedWithMessage(res.message)) - } - _ => unreachable!() + "ok" => Ok(res.user), + "error" => Err(FetchError::FailedWithMessage(res.message)), + _ => unreachable!(), } } else { Err(FetchError::APIReturnedError(res.status().as_u16())) diff --git a/src/main.rs b/src/main.rs index c3b035e..2b53d25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ mod commands; pub mod config_dir; pub mod entities; use clap::*; +use entities::moderator::Feature; +use tracing_subscriber::prelude::*; #[macro_export] macro_rules! api_url { () => { @@ -16,19 +18,36 @@ macro_rules! api_url { }; } fn main() -> std::io::Result<()> { - if let Some(dir) = config_dir::get_proj_dir() { - std::fs::create_dir_all(dir)?; - } else { - eprintln!("ERROR: Couldn't find a directory for config files."); - return Ok(()); + tracing_subscriber::Registry::default() + .with(sentry::integrations::tracing::layer()) + .init(); + fn parse_feature(feature: &str) -> Result { + match feature { + "start" => Ok(Feature::Start), + "stop" => Ok(Feature::Stop), + "restart" => Ok(Feature::Restart), + "logs" => Ok(Feature::SeeLogs), + "commit" => Ok(Feature::Commit), + "status" => Ok(Feature::Status), + "setram" => Ok(Feature::SetRam), + "backup" => Ok(Feature::Backup), + _ => Err(format!("Invalid permission: {}", feature)), + } } let _guard = sentry::init(( "https://0512a7bb28624cfc848cdad08f2186a7@sentry.discloudbot.com/3", sentry::ClientOptions { release: sentry::release_name!(), + traces_sample_rate: if cfg!(debug_assertions) { 1.0 } else { 0.2 }, ..Default::default() }, )); + if let Some(dir) = config_dir::get_proj_dir() { + std::fs::create_dir_all(dir)?; + } else { + eprintln!("ERROR: Couldn't find a directory for config files."); + return Ok(()); + } let cmd = Command::new("discloud") .about("Blazingly Fast CLI for discloud") .subcommand_required(true) @@ -63,6 +82,12 @@ fn main() -> std::io::Result<()> { .about("Commits to an app on discloud. If you have more than one app, it will ask which app you want to commit to.") .alias("c") ) + + .subcommand( + Command::new("status") + .about("Says if a app is on or off") + .alias("s") + ) .subcommand( Command::new("remove") .about("Removes an app. If you have more than one app, it will ask which app you want to delete.") @@ -101,18 +126,112 @@ fn main() -> std::io::Result<()> { Command::new("aboutme") .about("Shows information about you.") .alias("user") + ) + .subcommand( + Command::new("teams") + .about("Allows to interact with other people's bots, you can use this once someone adds you as a moderator.") + .subcommand_required(true) + .arg_required_else_help(true) + .subcommand( + Command::new("status") + .about("Says if a app is on or off") + .alias("s") + ) + .subcommand( + Command::new("apps") + .about("Shows all bots you have access to.") + .alias("ls") + .alias("list") + ) + .subcommand( + Command::new("start") + .about("Starts a stopped app.") + ) + .subcommand( + Command::new("restart") + .about("Restarts an app.") + .alias("reboot") + .alias("r") + ) + .subcommand( + Command::new("logs") + .about("Prints logs of an app.") + .alias("terminal") + .alias("t") + ) + + .subcommand( + Command::new("stop") + .about("Stops an app.") + .alias("shutdown") + .alias("down") + ) + + .subcommand( + Command::new("commit") + .about("Commits to an app on discloud. If you have more than one shared app, it will ask which app you want to commit to.") + .alias("c") + ) + ) + .subcommand( + Command::new("mods") + .about("Manages your apps' mods") + .subcommand_required(true) + .arg_required_else_help(true) + .alias("m") + .subcommand( + Command::new("add") + .about("Adds a mod to an app, by default, the mod can only see the logs and status, use `discloud mods allow` to allow more actions.") + .arg(Arg::new("id").value_parser(value_parser!(u128)).action(clap::ArgAction::Set).required(true)) + ) + .subcommand( + Command::new("remove") + .alias("rm") + .about("Removes a moderator from your app.") + .arg(Arg::new("id").value_parser(value_parser!(u128)).action(clap::ArgAction::Set).required(true)) + ) + .subcommand( + Command::new("allow") + .about("Gives permissions to a moderator") + .arg(Arg::new("id").value_parser(value_parser!(u128)).action(clap::ArgAction::Set) + .required(true)) + .arg( + Arg::new("perm") + .value_parser(parse_feature) + .action(clap::ArgAction::Append) + .required(true) + ) + ) + .subcommand( + Command::new("deny") + .about("Removes permissions from a moderator") + .arg(Arg::new("id").value_parser(value_parser!(u128)).action(clap::ArgAction::Set) + .required(true)) + .arg( + Arg::new("perm") + .value_parser(parse_feature) + .action(clap::ArgAction::Append) + .required(true) + ) + ) + .after_help("Be careful with what people you add and what permissions you give: With Great Power comes Great Responsability.") ); let matches = cmd.get_matches(); match matches.subcommand() { Some(("login", login_matches)) => commands::login::login(login_matches), Some(("authstatus", _)) => commands::authstatus::authstatus(), Some(("init", _)) => commands::init::init(), + + Some(("status", _)) => { + commands::status::status(false); + Ok(()) + } Some(("upload", _)) => { commands::upload::upload(); Ok(()) } Some(("commit", _)) => { - commands::commit::commit(); + commands::commit::commit(false); Ok(()) } Some(("remove", _)) => { @@ -120,30 +239,97 @@ fn main() -> std::io::Result<()> { Ok(()) } Some(("apps", _)) => { - commands::apps::apps(); + commands::apps::apps(false); Ok(()) } Some(("stop", _)) => { - commands::stop::stop(); + commands::stop::stop(false); Ok(()) } Some(("start", _)) => { - commands::start::start(); + commands::start::start(false); Ok(()) } Some(("restart", _)) => { - commands::restart::restart(); + commands::restart::restart(false); Ok(()) } Some(("logs", _)) => { - commands::logs::logs(); + commands::logs::logs(false); Ok(()) } Some(("aboutme", _)) => { commands::aboutme::aboutme(); Ok(()) } - _ => unreachable!(), + Some(("mods", matches)) => match matches.subcommand() { + Some(("add", matches)) => { + let id: u128 = *matches.get_one("id").unwrap(); + commands::mods::add::add(id); + Ok(()) + } + Some(("remove", matches)) => { + let id: u128 = *matches.get_one("id").unwrap(); + commands::mods::remove::remove(id); + Ok(()) + } + Some(("deny", matches)) => { + let id: u128 = *matches.get_one("id").unwrap(); + let features: Vec = matches.get_many("perm").unwrap().cloned().collect(); + commands::mods::deny::deny(id, features); + Ok(()) + } + Some(("allow", matches)) => { + let id: u128 = *matches.get_one("id").unwrap(); + let features: Vec = matches.get_many("perm").unwrap().cloned().collect(); + commands::mods::allow::allow(id, features); + Ok(()) + } + cmd => { + eprintln!("{:#?} command is not implemented yet.", cmd.unwrap().0); + Ok(()) + } + }, + Some(("teams", matches)) => match matches.subcommand() { + Some(("status", _)) => { + commands::status::status(true); + Ok(()) + } + Some(("commit", _)) => { + commands::commit::commit(true); + Ok(()) + } + Some(("apps", _)) => { + commands::apps::apps(true); + Ok(()) + } + + Some(("stop", _)) => { + commands::stop::stop(true); + Ok(()) + } + + Some(("start", _)) => { + commands::start::start(true); + Ok(()) + } + Some(("restart", _)) => { + commands::restart::restart(true); + Ok(()) + } + Some(("logs", _)) => { + commands::logs::logs(true); + Ok(()) + } + cmd => { + eprintln!("{:#?} command is not implemented yet.", cmd.unwrap().0); + Ok(()) + } + }, + cmd => { + eprintln!("{:#?} command is not implemented yet.", cmd.unwrap().0); + Ok(()) + } } }