Compare commits
13 Commits
fa65b6b071
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4533b9a72d | ||
|
|
980d2d9a5d | ||
|
|
939b6f2fe3 | ||
|
|
4504b98112 | ||
|
|
e8c8ab9dfe | ||
|
|
3420634bea | ||
|
|
1aa02a24af | ||
|
|
5e43800d6c | ||
|
|
dc7df00ac9 | ||
|
|
a1b9cde71a | ||
|
|
7180647d26 | ||
|
|
d5891a1a93 | ||
|
|
3207391fdb |
534
Cargo.lock
generated
534
Cargo.lock
generated
@@ -2,6 +2,21 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@@ -27,23 +42,51 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ansi_term"
|
name = "anstream"
|
||||||
version = "0.12.1"
|
version = "0.6.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"utf8parse",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "anstyle"
|
||||||
version = "0.2.14"
|
version = "1.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.1.19",
|
"utf8parse",
|
||||||
"libc",
|
]
|
||||||
"winapi",
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -52,6 +95,21 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.71"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.2"
|
version = "0.21.2"
|
||||||
@@ -84,9 +142,9 @@ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.79"
|
version = "1.0.90"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@@ -96,43 +154,59 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.26"
|
version = "0.4.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
|
checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"time",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"winapi",
|
"windows-targets 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.34.0"
|
version = "4.5.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"clap_builder",
|
||||||
"atty",
|
|
||||||
"bitflags 1.3.2",
|
|
||||||
"strsim",
|
|
||||||
"textwrap 0.11.0",
|
|
||||||
"unicode-width",
|
|
||||||
"vec_map",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colored"
|
name = "clap_builder"
|
||||||
version = "2.0.0"
|
version = "4.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colored"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"winapi",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -185,6 +259,12 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
@@ -248,21 +328,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -271,21 +351,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
|
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
@@ -315,6 +395,12 @@ dependencies = [
|
|||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.28.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glob"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -323,9 +409,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.19"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782"
|
checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fnv",
|
"fnv",
|
||||||
@@ -342,18 +428,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.14.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hermit-abi"
|
|
||||||
version = "0.1.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
@@ -366,9 +443,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.9"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
|
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fnv",
|
"fnv",
|
||||||
@@ -377,12 +454,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http-body"
|
name = "http-body"
|
||||||
version = "0.4.5"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-body-util"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -392,47 +481,60 @@ version = "1.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "httpdate"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.14.26"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
|
checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
"httpdate",
|
|
||||||
"itoa",
|
"itoa",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"smallvec",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-service",
|
|
||||||
"tracing",
|
|
||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-tls"
|
name = "hyper-tls"
|
||||||
version = "0.5.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"hyper-util",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-util"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"hyper",
|
||||||
|
"pin-project-lite",
|
||||||
|
"socket2",
|
||||||
|
"tokio",
|
||||||
|
"tower",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -470,19 +572,19 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.3"
|
version = "2.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indicatif"
|
name = "indicatif"
|
||||||
version = "0.17.5"
|
version = "0.17.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057"
|
checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console",
|
"console",
|
||||||
"instant",
|
"instant",
|
||||||
@@ -514,9 +616,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.63"
|
version = "0.3.69"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790"
|
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
@@ -563,9 +665,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
@@ -584,10 +686,19 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "miniz_oxide"
|
||||||
version = "0.8.7"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eebffdb73fe72e917997fad08bdbf31ac50b0fa91cec93e69a0662e4264d454c"
|
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
@@ -630,8 +741,9 @@ dependencies = [
|
|||||||
"reqwest",
|
"reqwest",
|
||||||
"rpassword",
|
"rpassword",
|
||||||
"rust-crypto",
|
"rust-crypto",
|
||||||
|
"rustc-serialize",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"textwrap 0.13.4",
|
"textwrap",
|
||||||
"tokio",
|
"tokio",
|
||||||
"xml-rs",
|
"xml-rs",
|
||||||
]
|
]
|
||||||
@@ -651,7 +763,7 @@ version = "1.15.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.2.6",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -661,6 +773,15 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.32.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.17.2"
|
version = "1.17.2"
|
||||||
@@ -741,10 +862,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project"
|
||||||
version = "0.2.9"
|
version = "1.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-internal",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-internal"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-utils"
|
name = "pin-utils"
|
||||||
@@ -876,9 +1017,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.8.3"
|
version = "1.10.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390"
|
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -887,15 +1040,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.7.2"
|
version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.11.18"
|
version = "0.12.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
|
checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -905,8 +1058,10 @@ dependencies = [
|
|||||||
"h2",
|
"h2",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-tls",
|
"hyper-tls",
|
||||||
|
"hyper-util",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
@@ -916,9 +1071,12 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"rustls-pemfile",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
|
"sync_wrapper",
|
||||||
|
"system-configuration",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
@@ -933,13 +1091,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rpassword"
|
name = "rpassword"
|
||||||
version = "7.2.0"
|
version = "7.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322"
|
checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rtoolbox",
|
"rtoolbox",
|
||||||
"winapi",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -966,10 +1124,16 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-serialize"
|
name = "rustc-demangle"
|
||||||
version = "0.3.24"
|
version = "0.1.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-serialize"
|
||||||
|
version = "0.3.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
@@ -984,6 +1148,15 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.13"
|
version = "1.0.13"
|
||||||
@@ -1077,9 +1250,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.10.0"
|
version = "1.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smawk"
|
name = "smawk"
|
||||||
@@ -1089,19 +1262,19 @@ checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.4.9"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"winapi",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.8.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
@@ -1115,10 +1288,37 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "sync_wrapper"
|
||||||
version = "3.10.0"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
|
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "system-configuration"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"core-foundation",
|
||||||
|
"system-configuration-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "system-configuration-sys"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
@@ -1128,20 +1328,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.11.0"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
|
||||||
dependencies = [
|
|
||||||
"unicode-width",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "textwrap"
|
|
||||||
version = "0.13.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cd05616119e612a8041ef58f2b578906cc2531a6069047ae092cfb86a325d835"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smawk",
|
"smawk",
|
||||||
|
"unicode-linebreak",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1173,11 +1365,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.28.2"
|
version = "1.37.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
|
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
@@ -1192,9 +1384,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.1.0"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1225,6 +1417,28 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower"
|
||||||
|
version = "0.4.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"pin-project",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-layer"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@@ -1238,6 +1452,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
@@ -1278,6 +1493,12 @@ version = "1.0.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-linebreak"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
version = "0.1.22"
|
version = "0.1.22"
|
||||||
@@ -1304,18 +1525,18 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vec_map"
|
|
||||||
version = "0.8.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
@@ -1346,9 +1567,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.86"
|
version = "0.2.92"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73"
|
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
@@ -1356,9 +1577,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.86"
|
version = "0.2.92"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb"
|
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"log",
|
"log",
|
||||||
@@ -1371,9 +1592,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-futures"
|
name = "wasm-bindgen-futures"
|
||||||
version = "0.4.36"
|
version = "0.4.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e"
|
checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@@ -1383,9 +1604,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.86"
|
version = "0.2.92"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258"
|
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
@@ -1393,9 +1614,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.86"
|
version = "0.2.92"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
|
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1406,15 +1627,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.86"
|
version = "0.2.92"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93"
|
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-streams"
|
name = "wasm-streams"
|
||||||
version = "0.2.3"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078"
|
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@@ -1425,9 +1646,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.63"
|
version = "0.3.69"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2"
|
checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@@ -1679,15 +1900,16 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.10.1"
|
version = "0.50.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"cfg-if",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xml-rs"
|
name = "xml-rs"
|
||||||
version = "0.8.14"
|
version = "0.8.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52839dc911083a8ef63efa4d039d1f58b5e409f923e44c80828f206f66e5541c"
|
checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
|
||||||
|
|||||||
27
Cargo.toml
27
Cargo.toml
@@ -6,24 +6,25 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = { version = "0.11", features = ["stream", "json", "multipart"] }
|
rustc-serialize="0.3.25"
|
||||||
tokio = { version = "1", features = ["full"] }
|
reqwest = { version = "0.12", features = ["stream", "json", "multipart"] }
|
||||||
|
tokio = { version = "1.37", features = ["full"] }
|
||||||
dotenv ="0.15.0"
|
dotenv ="0.15.0"
|
||||||
clap = "2.33"
|
clap = "4.5.4"
|
||||||
rust-crypto = "0.2.36"
|
rust-crypto = "0.2.36"
|
||||||
colored = "2.0.0"
|
colored = "2.1.0"
|
||||||
xml-rs = "0.8.0"
|
xml-rs = "0.8.19"
|
||||||
regex = "1.8.3"
|
regex = "1.10.4"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
glob = "0.3.1"
|
glob = "0.3.1"
|
||||||
textwrap = "0.13"
|
textwrap = "0.16.1"
|
||||||
chrono = "0.4.26"
|
chrono = "0.4.37"
|
||||||
indicatif = "0.17.5"
|
indicatif = "0.17.8"
|
||||||
md5 = "0.7.0"
|
md5 = "0.7.0"
|
||||||
futures-util = "0.3.28"
|
futures-util = "0.3.30"
|
||||||
rpassword = "7.2"
|
rpassword = "7.3.1"
|
||||||
rand = "0.8"
|
rand = "0.8.5"
|
||||||
tempfile = "3.10.0"
|
tempfile = "3.10.1"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use clap::Values;
|
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use crate::store::{self, object::Object};
|
use crate::store::{self, object::Object};
|
||||||
use crate::utils::{self, path};
|
use crate::utils::{self, path};
|
||||||
@@ -8,8 +7,8 @@ use crate::store::object::object::{Obj, ObjMethods};
|
|||||||
use crate::utils::nextsyncignore::{self, ignore_file};
|
use crate::utils::nextsyncignore::{self, ignore_file};
|
||||||
use crate::utils::path::{normalize_relative, repo_root, path_buf_to_string};
|
use crate::utils::path::{normalize_relative, repo_root, path_buf_to_string};
|
||||||
|
|
||||||
pub struct AddArgs<'a> {
|
pub struct AddArgs {
|
||||||
pub files: Option<Values<'a>>,
|
pub files: Vec<String>,
|
||||||
pub force: bool,
|
pub force: bool,
|
||||||
pub all: bool,
|
pub all: bool,
|
||||||
}
|
}
|
||||||
@@ -18,13 +17,13 @@ pub struct AddArgs<'a> {
|
|||||||
pub fn add(args: AddArgs) {
|
pub fn add(args: AddArgs) {
|
||||||
|
|
||||||
let mut pattern: String;
|
let mut pattern: String;
|
||||||
let file_vec: Vec<&str> = match args.all {
|
let file_vec: Vec<String> = match args.all {
|
||||||
true => {
|
true => {
|
||||||
pattern = path_buf_to_string(repo_root());
|
pattern = path_buf_to_string(repo_root());
|
||||||
pattern.push_str("/*");
|
pattern.push_str("/*");
|
||||||
vec![&pattern]
|
vec![pattern]
|
||||||
},
|
},
|
||||||
false => args.files.unwrap().collect(),
|
false => args.files,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut added_files: Vec<String> = vec![];
|
let mut added_files: Vec<String> = vec![];
|
||||||
@@ -32,7 +31,7 @@ pub fn add(args: AddArgs) {
|
|||||||
let rules = nextsyncignore::get_rules();
|
let rules = nextsyncignore::get_rules();
|
||||||
|
|
||||||
for file in file_vec {
|
for file in file_vec {
|
||||||
let f = match normalize_relative(file) {
|
let f = match normalize_relative(&file) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("err: {} {}", file, err);
|
eprintln!("err: {} {}", file, err);
|
||||||
@@ -43,10 +42,13 @@ pub fn add(args: AddArgs) {
|
|||||||
let path = repo_root().join(Path::new(&f));
|
let path = repo_root().join(Path::new(&f));
|
||||||
match path.exists() {
|
match path.exists() {
|
||||||
true => {
|
true => {
|
||||||
add_entry(path, args.force, &mut added_files, rules.clone(), &mut ignored_f);
|
let mut obj = Obj::from_path(f.clone());
|
||||||
|
if obj.has_changes() {
|
||||||
|
add_entry(path, args.force, &mut added_files, rules.clone(), &mut ignored_f);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
false => {
|
false => {
|
||||||
if Object::new(path.to_str().unwrap()).exists() {
|
if Obj::from_path(file.clone()).exists_on_remote() {
|
||||||
// object is deleted so not present but can still be added for deletion
|
// object is deleted so not present but can still be added for deletion
|
||||||
added_files.push(String::from(f));
|
added_files.push(String::from(f));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use std::io;
|
|||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::fs::DirBuilder;
|
use std::fs::DirBuilder;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use clap::Values;
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use crate::services::downloader::Downloader;
|
use crate::services::downloader::Downloader;
|
||||||
use crate::utils::api::ApiProps;
|
use crate::utils::api::ApiProps;
|
||||||
@@ -18,16 +17,16 @@ use crate::commands::init;
|
|||||||
|
|
||||||
pub const DEPTH: &str = "3";
|
pub const DEPTH: &str = "3";
|
||||||
|
|
||||||
pub struct CloneArgs<'a> {
|
pub struct CloneArgs {
|
||||||
pub remote: Values<'a>,
|
pub remote: String,
|
||||||
pub depth: Option<String>,
|
pub depth: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone(args: CloneArgs) {
|
pub fn clone(args: CloneArgs) {
|
||||||
let d = DIR_PATH.lock().unwrap().clone();
|
let d = DIR_PATH.lock().unwrap().clone();
|
||||||
|
|
||||||
let url = args.remote.clone().next().unwrap();
|
let url = args.remote.clone();
|
||||||
let (host, tmp_user, dist_path_str) = get_url_props(url);
|
let (host, tmp_user, dist_path_str) = get_url_props(&url);
|
||||||
let username = match tmp_user {
|
let username = match tmp_user {
|
||||||
Some(u) => u.to_string(),
|
Some(u) => u.to_string(),
|
||||||
None => {
|
None => {
|
||||||
@@ -178,7 +177,7 @@ mod tests {
|
|||||||
fn test_get_url_props() {
|
fn test_get_url_props() {
|
||||||
let p = "/foo/bar";
|
let p = "/foo/bar";
|
||||||
let u = Some("user");
|
let u = Some("user");
|
||||||
let d = String::from("http://nextcloud.com");
|
// let d = String::from("http://nextcloud.com");
|
||||||
let sd = String::from("https://nextcloud.com");
|
let sd = String::from("https://nextcloud.com");
|
||||||
let sld = String::from("https://nextcloud.example.com");
|
let sld = String::from("https://nextcloud.example.com");
|
||||||
let ld = String::from("http://nextcloud.example.com");
|
let ld = String::from("http://nextcloud.example.com");
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use clap::Values;
|
|
||||||
use std::io::{self, Write, BufRead, Seek, SeekFrom};
|
use std::io::{self, Write, BufRead, Seek, SeekFrom};
|
||||||
use crate::utils::{path, read};
|
use crate::utils::{path, read};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub struct ConfigSetArgs<'a> {
|
pub struct ConfigSetArgs {
|
||||||
pub name: Option<Values<'a>>,
|
pub name: String,
|
||||||
pub value: Option<Values<'a>>,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn config_set(args: ConfigSetArgs) {
|
pub fn config_set(args: ConfigSetArgs) {
|
||||||
@@ -15,17 +14,14 @@ pub fn config_set(args: ConfigSetArgs) {
|
|||||||
option_categories.insert("force_insecure", "core");
|
option_categories.insert("force_insecure", "core");
|
||||||
option_categories.insert("token", "core");
|
option_categories.insert("token", "core");
|
||||||
|
|
||||||
let name = args.name.unwrap().next().unwrap();
|
|
||||||
let value = args.value.unwrap().next().unwrap();
|
|
||||||
|
|
||||||
// get category of option
|
// get category of option
|
||||||
let category = option_categories.get(name);
|
let category = option_categories.get(args.name.as_str());
|
||||||
if category.is_none() {
|
if category.is_none() {
|
||||||
eprintln!("fatal: '{}' is not a valid option.", name);
|
eprintln!("fatal: '{}' is not a valid option.", args.name.clone());
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_option_in_cat(category.unwrap(), name, value);
|
let _ = write_option_in_cat(category.unwrap(), &args.name, &args.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -34,7 +30,7 @@ pub fn find_option_in_cat(category: &str, option: &str) -> Option<String> {
|
|||||||
config.push("config");
|
config.push("config");
|
||||||
|
|
||||||
let mut in_target_category = false;
|
let mut in_target_category = false;
|
||||||
if let Ok(mut lines) = read::read_lines(config) {
|
if let Ok(lines) = read::read_lines(config) {
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
if let Ok(line) = line {
|
if let Ok(line) = line {
|
||||||
@@ -128,7 +124,7 @@ pub fn write_option_in_cat(category: &str, option: &str, value: &str) -> io::Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_remote(name: &str, url: &str) -> io::Result<()> {
|
pub fn add_remote(name: &str, url: &str) -> io::Result<()> {
|
||||||
let mut config = path::config();
|
let config = path::config();
|
||||||
|
|
||||||
// check if there is already a remote with this name
|
// check if there is already a remote with this name
|
||||||
if get_remote(name).is_some()
|
if get_remote(name).is_some()
|
||||||
@@ -192,38 +188,3 @@ pub fn get_all_remote() -> Vec<(String, String)> {
|
|||||||
pub fn get_core(name: &str) -> Option<String> {
|
pub fn get_core(name: &str) -> Option<String> {
|
||||||
find_option_in_cat("core", name)
|
find_option_in_cat("core", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_core(name: &str, value: &str) -> io::Result<()> {
|
|
||||||
let mut config = path::nextsync();
|
|
||||||
config.push("config");
|
|
||||||
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.read(true)
|
|
||||||
.write(true)
|
|
||||||
.create(true)
|
|
||||||
.append(true)
|
|
||||||
.open(config)?;
|
|
||||||
|
|
||||||
writeln!(file, "[core]")?;
|
|
||||||
writeln!(file, "\t{} = {}", name, value)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(var: &str) -> Option<String> {
|
|
||||||
let mut config = path::config();
|
|
||||||
|
|
||||||
if let Ok(lines) = read::read_lines(config) {
|
|
||||||
for line in lines {
|
|
||||||
if let Ok(l) = line {
|
|
||||||
if l.starts_with(var) {
|
|
||||||
let (_, val) = l.split_once(" ").unwrap();
|
|
||||||
return Some(val.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use clap::Values;
|
|
||||||
use crate::commands::clone::get_url_props;
|
use crate::commands::clone::get_url_props;
|
||||||
use crate::services::api::ApiError::RequestError;
|
use crate::services::api::ApiError::RequestError;
|
||||||
|
|
||||||
@@ -6,9 +5,9 @@ use crate::services::login::Login;
|
|||||||
use crate::services::api_call::ApiCall;
|
use crate::services::api_call::ApiCall;
|
||||||
use crate::commands::config;
|
use crate::commands::config;
|
||||||
|
|
||||||
pub struct CredentialArgs<'a> {
|
pub struct CredentialArgs {
|
||||||
pub username: Option<Values<'a>>,
|
pub username: String,
|
||||||
pub password: Option<Values<'a>>,
|
pub password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn credential_add(args: CredentialArgs) {
|
pub fn credential_add(args: CredentialArgs) {
|
||||||
@@ -23,9 +22,9 @@ pub fn credential_add(args: CredentialArgs) {
|
|||||||
let (host, _, _) = get_url_props(&remote);
|
let (host, _, _) = get_url_props(&remote);
|
||||||
|
|
||||||
// get username and password
|
// get username and password
|
||||||
let username = args.username.unwrap().next().unwrap();
|
let username = args.username.to_owned();
|
||||||
let password = match args.password {
|
let password = match args.password {
|
||||||
Some(mut pwd) => pwd.next().unwrap().to_owned(),
|
Some(mut pwd) => pwd.to_owned(),
|
||||||
None => {
|
None => {
|
||||||
println!("Please enter the password for {}: ", username);
|
println!("Please enter the password for {}: ", username);
|
||||||
rpassword::read_password().unwrap()
|
rpassword::read_password().unwrap()
|
||||||
@@ -34,7 +33,7 @@ pub fn credential_add(args: CredentialArgs) {
|
|||||||
|
|
||||||
// get token
|
// get token
|
||||||
let get_token = Login::new()
|
let get_token = Login::new()
|
||||||
.set_auth(username, &password)
|
.set_auth(&username, &password)
|
||||||
.set_host(Some(host))
|
.set_host(Some(host))
|
||||||
.send_login();
|
.send_login();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{DirBuilder, File};
|
use std::fs::{DirBuilder, File};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use crate::utils::read::read_folder;
|
|
||||||
use crate::global::global::DIR_PATH;
|
use crate::global::global::DIR_PATH;
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
@@ -12,23 +11,24 @@ pub fn init() {
|
|||||||
None => env::current_dir().unwrap(),
|
None => env::current_dir().unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// todo
|
||||||
// check if dir is empty
|
// check if dir is empty
|
||||||
if let Ok(entries) = read_folder(path.clone()) {
|
// if let Ok(entries) = read_folder(path.clone()) {
|
||||||
if entries.len() != 0 {
|
// if entries.len() != 0 {
|
||||||
eprintln!("fatal: destination path '{}' already exists and is not an empty directory.", path.display());
|
// eprintln!("fatal: destination path '{}' already exists and is not an empty directory.", path.display());
|
||||||
std::process::exit(1);
|
// std::process::exit(1);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
eprintln!("fatal: cannot open the destination directory");
|
// eprintln!("fatal: cannot open the destination directory");
|
||||||
std::process::exit(1);
|
// std::process::exit(1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
let builder = DirBuilder::new();
|
let builder = DirBuilder::new();
|
||||||
|
|
||||||
path.push(".nextsync");
|
path.push(".nextsync");
|
||||||
match builder.create(path.clone()) {
|
match builder.create(path.clone()) {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(_) => println!("Error: cannot create .nextsync"),
|
Err(err) => println!("Error: cannot create .nextsync ({})", err),
|
||||||
};
|
};
|
||||||
|
|
||||||
path.push("objects");
|
path.push("objects");
|
||||||
@@ -58,12 +58,13 @@ pub fn init() {
|
|||||||
Err(_) => println!("Error: cannot create index"),
|
Err(_) => println!("Error: cannot create index"),
|
||||||
}
|
}
|
||||||
|
|
||||||
path.pop();
|
// todo
|
||||||
path.pop();
|
// path.pop();
|
||||||
path.push(".nextsyncignore");
|
// path.pop();
|
||||||
|
// path.push(".nextsyncignore");
|
||||||
match File::create(path) {
|
//
|
||||||
Ok(_) => (),
|
// match File::create(path) {
|
||||||
Err(_) => println!("Error: cannot create .nextsyncignore"),
|
// Ok(_) => (),
|
||||||
}
|
// Err(_) => println!("Error: cannot create .nextsyncignore"),
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ pub fn pull() {
|
|||||||
.strip_prefix(path::repo_root()).unwrap().to_path_buf();
|
.strip_prefix(path::repo_root()).unwrap().to_path_buf();
|
||||||
let (folders, files) = get_diff(relative_p);
|
let (folders, files) = get_diff(relative_p);
|
||||||
|
|
||||||
let ref_p = path::nextsync();
|
let root = path::repo_root();
|
||||||
|
|
||||||
for folder in folders {
|
for folder in folders {
|
||||||
let p = ref_p.clone().join(PathBuf::from(folder.relative_s.unwrap()));
|
let p = root.clone().join(PathBuf::from(folder.relative_s.unwrap()));
|
||||||
if !p.exists() {
|
if !p.exists() {
|
||||||
// create folder
|
// create folder
|
||||||
if let Err(err) = DirBuilder::new().recursive(true).create(p.clone()) {
|
if let Err(err) = DirBuilder::new().recursive(true).create(p.clone()) {
|
||||||
@@ -27,9 +27,9 @@ pub fn pull() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add tree
|
// add tree
|
||||||
let path_folder = p.strip_prefix(ref_p.clone()).unwrap();
|
let path_folder = p.strip_prefix(root.clone()).unwrap();
|
||||||
let lastmodified = folder.lastmodified.unwrap().timestamp_millis();
|
let lastmodified = folder.lastmodified.unwrap().timestamp_millis();
|
||||||
if let Err(err) = Tree::from_path(path_folder.clone()).create(&lastmodified.to_string(), false) {
|
if let Err(err) = Tree::from_path(path_folder).create(&lastmodified.to_string(), false) {
|
||||||
eprintln!("err: saving ref of {} ({})", path_folder.display(), err);
|
eprintln!("err: saving ref of {} ({})", path_folder.display(), err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,13 +39,11 @@ pub fn pull() {
|
|||||||
.set_api_props(get_api_props())
|
.set_api_props(get_api_props())
|
||||||
.set_files(files)
|
.set_files(files)
|
||||||
.should_log()
|
.should_log()
|
||||||
.download(ref_p.clone(), Some(&update_blob));
|
.download(root, Some(&update_blob));
|
||||||
// todo look if need to download or update
|
// todo look if need to download or update
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_blob(obj: ObjProps) {
|
fn update_blob(obj: ObjProps) {
|
||||||
// todo update blob
|
|
||||||
return;
|
|
||||||
let relative_s = &obj.clone().relative_s.unwrap();
|
let relative_s = &obj.clone().relative_s.unwrap();
|
||||||
let relative_p = PathBuf::from(&relative_s);
|
let relative_p = PathBuf::from(&relative_s);
|
||||||
let lastmodified = obj.clone().lastmodified.unwrap().timestamp_millis();
|
let lastmodified = obj.clone().lastmodified.unwrap().timestamp_millis();
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ pub mod moved;
|
|||||||
pub mod copied;
|
pub mod copied;
|
||||||
|
|
||||||
pub fn push() {
|
pub fn push() {
|
||||||
// todo err when pushing new folder
|
|
||||||
let _remote = match config::get_remote("origin") {
|
let _remote = match config::get_remote("origin") {
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
None => {
|
None => {
|
||||||
@@ -40,11 +39,9 @@ pub fn push() {
|
|||||||
let mut whitelist: Option<PathBuf> = None;
|
let mut whitelist: Option<PathBuf> = None;
|
||||||
|
|
||||||
for obj in staged_objs {
|
for obj in staged_objs {
|
||||||
dbg!(obj.clone());
|
|
||||||
if obj.otype == String::from("tree") {
|
if obj.otype == String::from("tree") {
|
||||||
let push_factory = PushFactory.new_dir(obj.clone());
|
let push_factory = PushFactory.new_dir(obj.clone());
|
||||||
let res = push_factory.can_push(&mut whitelist);
|
let res = push_factory.can_push(&mut whitelist);
|
||||||
dbg!(&res);
|
|
||||||
match res {
|
match res {
|
||||||
PushState::Valid => {
|
PushState::Valid => {
|
||||||
match push_factory.push() {
|
match push_factory.push() {
|
||||||
@@ -74,9 +71,10 @@ pub fn push() {
|
|||||||
},
|
},
|
||||||
PushState::Done => remove_obj_from_index(obj.clone()),
|
PushState::Done => remove_obj_from_index(obj.clone()),
|
||||||
PushState::Conflict => {
|
PushState::Conflict => {
|
||||||
|
eprintln!("conflict when pushing blob");
|
||||||
// download file
|
// download file
|
||||||
}
|
}
|
||||||
PushState::Error => (),
|
PushState::Error => (eprintln!("error when pushing changes blob")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ impl PushChange for Deleted {
|
|||||||
|
|
||||||
// update tree
|
// update tree
|
||||||
// todo date
|
// todo date
|
||||||
Blob::from_path(obj.path.clone()).rm()?;
|
Blob::from_path(obj.path.clone()).rm_node()?;
|
||||||
|
|
||||||
// remove index
|
// remove index
|
||||||
index::rm_line(obj.path.to_str().unwrap())?;
|
index::rm_line(obj.path.to_str().unwrap())?;
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ impl PushChange for NewDir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn push(&self) -> io::Result<()> {
|
fn push(&self) -> io::Result<()> {
|
||||||
dbg!("pushing new dir");
|
|
||||||
let obj = &self.obj;
|
let obj = &self.obj;
|
||||||
let res = CreateFolder::new()
|
let res = CreateFolder::new()
|
||||||
.set_url(obj.path.to_str().unwrap())
|
.set_url(obj.path.to_str().unwrap())
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use std::error::Error;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::io;
|
use std::io;
|
||||||
use crate::commands::status::{State, LocalObj};
|
use crate::commands::status::{State, LocalObj};
|
||||||
@@ -74,9 +73,16 @@ pub trait PushChange {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// check if remote is newest
|
// check if remote is newest
|
||||||
let last_sync_ts = Blob::from_path(obj.path.clone())
|
let last_sync_ts = {
|
||||||
.saved_remote_ts()
|
if obj.otype == String::from("blob") {
|
||||||
.parse::<i64>().unwrap();
|
Blob::from_path(obj.path.clone())
|
||||||
|
.saved_remote_ts()
|
||||||
|
.parse::<i64>().unwrap()
|
||||||
|
} else {
|
||||||
|
// todo timestamp on tree
|
||||||
|
99999999999999
|
||||||
|
}
|
||||||
|
};
|
||||||
let remote_ts = obj_data.lastmodified.unwrap().timestamp_millis();
|
let remote_ts = obj_data.lastmodified.unwrap().timestamp_millis();
|
||||||
|
|
||||||
if last_sync_ts < remote_ts {
|
if last_sync_ts < remote_ts {
|
||||||
|
|||||||
@@ -1,24 +1,14 @@
|
|||||||
use clap::Values;
|
|
||||||
|
|
||||||
use crate::commands::config;
|
use crate::commands::config;
|
||||||
|
|
||||||
use super::config::get_all_remote;
|
use super::config::get_all_remote;
|
||||||
|
|
||||||
pub struct RemoteArgs<'a> {
|
pub struct RemoteArgs {
|
||||||
pub name: Option<Values<'a>>,
|
pub name: String,
|
||||||
pub url: Option<Values<'a>>,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remote_add(args: RemoteArgs) {
|
pub fn remote_add(args: RemoteArgs) {
|
||||||
if args.name.is_none() || args.url.is_none() {
|
let _ = config::add_remote(&args.name, &args.url);
|
||||||
eprintln!("Missing argument: remote add command need a name and an url");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = args.name.unwrap().next().unwrap();
|
|
||||||
let url = args.url.unwrap().next().unwrap();
|
|
||||||
|
|
||||||
let _ = config::add_remote(name, url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remote_list(verbose: bool) {
|
pub fn remote_list(verbose: bool) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub fn remote_diff() {
|
|||||||
|
|
||||||
pub fn get_diff(path: PathBuf) -> (Vec<ObjProps>, Vec<ObjProps>) {
|
pub fn get_diff(path: PathBuf) -> (Vec<ObjProps>, Vec<ObjProps>) {
|
||||||
|
|
||||||
let depth = "2"; // todo opti
|
let depth = "6"; // todo opti
|
||||||
let api_props = get_api_props();
|
let api_props = get_api_props();
|
||||||
|
|
||||||
enumerate_remote(
|
enumerate_remote(
|
||||||
@@ -55,6 +55,7 @@ fn req(api_props: &ApiProps, depth: &str, relative_s: &str) -> Result<Vec<ObjPro
|
|||||||
.set_request(relative_s, &api_props)
|
.set_request(relative_s, &api_props)
|
||||||
.set_depth(depth)
|
.set_depth(depth)
|
||||||
.gethref()
|
.gethref()
|
||||||
|
.getcontentlength() // todo opti
|
||||||
.getlastmodified()
|
.getlastmodified()
|
||||||
.send_req_multiple()
|
.send_req_multiple()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,19 +160,8 @@ pub struct LocalObj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_staged() -> Vec<LocalObj> {
|
pub fn get_all_staged() -> Vec<LocalObj> {
|
||||||
let mut staged_objs = vec![];
|
let mut all_hashes = get_all_objs_hashes();
|
||||||
|
get_staged(&mut all_hashes)
|
||||||
if let Ok(entries) = index::read_line() {
|
|
||||||
for line in entries {
|
|
||||||
|
|
||||||
let obj = Obj::from_path(line.unwrap()).get_local_obj();
|
|
||||||
if obj.state != State::Default {
|
|
||||||
staged_objs.push(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
staged_objs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_staged(hashes: &mut HashMap<String, LocalObj>) -> Vec<LocalObj> {
|
fn get_staged(hashes: &mut HashMap<String, LocalObj>) -> Vec<LocalObj> {
|
||||||
@@ -361,7 +350,7 @@ fn print_status(staged_objs: Vec<LocalObj>, objs: Vec<LocalObj>) {
|
|||||||
// not staged files
|
// not staged files
|
||||||
if objs.len() != 0 {
|
if objs.len() != 0 {
|
||||||
println!("Changes not staged for push:");
|
println!("Changes not staged for push:");
|
||||||
println!(" (Use\"nextsync add <file>...\" to update what will be pushed)");
|
println!(" (Use \"nextsync add <file>...\" to update what will be pushed)");
|
||||||
|
|
||||||
for object in objs {
|
for object in objs {
|
||||||
print_object(object);
|
print_object(object);
|
||||||
|
|||||||
59
src/main.rs
59
src/main.rs
@@ -1,4 +1,4 @@
|
|||||||
use clap::{App, SubCommand};
|
use clap::Command;
|
||||||
|
|
||||||
mod subcommands;
|
mod subcommands;
|
||||||
|
|
||||||
@@ -9,42 +9,41 @@ mod global;
|
|||||||
mod store;
|
mod store;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let app = App::new("Nextsync")
|
let app = Command::new("Nextsync")
|
||||||
.version("1.0")
|
.version("1.0")
|
||||||
.author("grimhilt")
|
.author("grimhilt")
|
||||||
.about("A git-line command line tool to interact with nextcloud")
|
.about("A git-line command line tool to interact with nextcloud")
|
||||||
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
|
.subcommands([
|
||||||
.subcommand(subcommands::clone::create())
|
subcommands::clone::create(),
|
||||||
.subcommand(subcommands::init::create())
|
subcommands::init::create(),
|
||||||
.subcommand(subcommands::status::create())
|
subcommands::status::create(),
|
||||||
.subcommand(subcommands::add::create())
|
subcommands::add::create(),
|
||||||
.subcommand(subcommands::push::create())
|
subcommands::push::create(),
|
||||||
.subcommand(subcommands::reset::create())
|
subcommands::reset::create(),
|
||||||
.subcommand(subcommands::remote::create())
|
subcommands::remote::create(),
|
||||||
.subcommand(subcommands::config::create())
|
subcommands::config::create(),
|
||||||
.subcommand(subcommands::remote_diff::create())
|
subcommands::remote_diff::create(),
|
||||||
.subcommand(subcommands::pull::create())
|
subcommands::pull::create(),
|
||||||
.subcommand(subcommands::credential::create())
|
subcommands::credential::create(),
|
||||||
.subcommand(
|
]);
|
||||||
SubCommand::with_name("test")
|
// .setting(clap::AppSettings::SubcommandRequiredElseHelp);
|
||||||
);
|
|
||||||
|
|
||||||
let matches = app.get_matches();
|
let matches = app.get_matches();
|
||||||
|
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
("init", Some(args)) => subcommands::init::handler(args),
|
Some(("init", args)) => subcommands::init::handler(args),
|
||||||
("status", Some(args)) => subcommands::status::handler(args),
|
Some(("status", args)) => subcommands::status::handler(args),
|
||||||
("add", Some(args)) => subcommands::add::handler(args),
|
Some(("add", args)) => subcommands::add::handler(args),
|
||||||
("reset", Some(_)) => commands::reset::reset(),
|
Some(("reset", _)) => commands::reset::reset(),
|
||||||
("clone", Some(args)) => subcommands::clone::handler(args),
|
Some(("clone", args)) => subcommands::clone::handler(args),
|
||||||
("push", Some(_)) => commands::push::push(),
|
Some(("push", _)) => commands::push::push(),
|
||||||
("config", Some(args)) => subcommands::config::handler(args),
|
Some(("config", args)) => subcommands::config::handler(args),
|
||||||
("remote-diff", Some(args)) => subcommands::remote_diff::handler(args),
|
Some(("remote-diff", args)) => subcommands::remote_diff::handler(args),
|
||||||
("pull", Some(args)) => subcommands::pull::handler(args),
|
Some(("pull", args)) => subcommands::pull::handler(args),
|
||||||
("remote", Some(args)) => subcommands::remote::handler(args),
|
Some(("remote", args)) => subcommands::remote::handler(args),
|
||||||
("credential", Some(args)) => subcommands::credential::handler(args),
|
Some(("credential", args)) => subcommands::credential::handler(args),
|
||||||
|
Some((_, _)) => {},
|
||||||
(_, _) => {},
|
None => {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ impl Downloader {
|
|||||||
let mut total_size = 0;
|
let mut total_size = 0;
|
||||||
let nb_objs = self.files.len();
|
let nb_objs = self.files.len();
|
||||||
|
|
||||||
|
// set the full size of the download
|
||||||
self.files
|
self.files
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|f|
|
.for_each(|f|
|
||||||
@@ -111,11 +112,7 @@ impl Downloader {
|
|||||||
|
|
||||||
let should_use_stream = {
|
let should_use_stream = {
|
||||||
if let Some(size) = file.contentlength {
|
if let Some(size) = file.contentlength {
|
||||||
if size > SIZE_TO_STREAM {
|
size > SIZE_TO_STREAM
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ use std::io::Write;
|
|||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use crate::commands::status::{State};
|
use crate::commands::status::State;
|
||||||
use crate::utils::into::IntoPathBuf;
|
use crate::utils::into::IntoPathBuf;
|
||||||
use crate::utils::{path, read};
|
use crate::utils::{path, read};
|
||||||
use crate::store::head;
|
use crate::store::object::update_dates;
|
||||||
use crate::store::object::{update_dates, add_node, rm_node};
|
|
||||||
|
|
||||||
use crate::store::object::object::ObjMethods;
|
use crate::store::object::object::ObjMethods;
|
||||||
use crate::store::object::object::Obj;
|
use crate::store::object::object::Obj;
|
||||||
@@ -265,7 +264,7 @@ impl Blob {
|
|||||||
pub fn create(&mut self, ts_remote: &str, up_parent: bool) -> io::Result<()> {
|
pub fn create(&mut self, ts_remote: &str, up_parent: bool) -> io::Result<()> {
|
||||||
|
|
||||||
// add blob reference to parent
|
// add blob reference to parent
|
||||||
self.add_ref_to_parent();
|
let _ = self.add_ref_to_parent();
|
||||||
|
|
||||||
if let Err(err) = self.create_blob_ref(ts_remote.clone()) {
|
if let Err(err) = self.create_blob_ref(ts_remote.clone()) {
|
||||||
eprintln!("err: saving blob ref of {}: {}", self.get_relative_file_path().display(), err);
|
eprintln!("err: saving blob ref of {}: {}", self.get_relative_file_path().display(), err);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::store::object::{blob::Blob, tree::Tree};
|
|||||||
use crate::commands::status::{State, LocalObj};
|
use crate::commands::status::{State, LocalObj};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
enum ObjType {
|
pub enum ObjType {
|
||||||
TREE,
|
TREE,
|
||||||
BLOB,
|
BLOB,
|
||||||
DEFAULT
|
DEFAULT
|
||||||
@@ -26,12 +26,13 @@ pub trait ObjMethods {
|
|||||||
fn get_name(&self) -> String;
|
fn get_name(&self) -> String;
|
||||||
fn get_hash_path(&self) -> String;
|
fn get_hash_path(&self) -> String;
|
||||||
fn get_local_obj(&self) -> LocalObj;
|
fn get_local_obj(&self) -> LocalObj;
|
||||||
fn get_line(&self) -> String;
|
fn get_line(&self, obj_type: ObjType) -> String;
|
||||||
fn add_ref_to_parent(&self) -> io::Result<()>;
|
fn add_ref_to_parent(&self) -> io::Result<()>;
|
||||||
fn rm(&mut self) -> io::Result<()>;
|
fn rm(&mut self) -> io::Result<()>;
|
||||||
fn rm_node(&mut self) -> io::Result<()>;
|
fn rm_node(&mut self) -> io::Result<()>;
|
||||||
fn rm_node_down(&mut self) -> io::Result<()>;
|
fn rm_node_down(&mut self) -> io::Result<()>;
|
||||||
fn exists_on_remote(&mut self) -> bool;
|
fn exists_on_remote(&mut self) -> bool;
|
||||||
|
fn has_changes(&mut self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Obj {
|
pub struct Obj {
|
||||||
@@ -89,12 +90,17 @@ impl ObjMethods for Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// build line for parent reference
|
// build line for parent reference
|
||||||
fn get_line(&self) -> String {
|
fn get_line(&self, obj_type: ObjType) -> String {
|
||||||
format!("tree {} {}", self.get_hash_path(), self.get_name())
|
let type_str = match obj_type {
|
||||||
|
ObjType::BLOB => "blob",
|
||||||
|
ObjType::TREE => "tree",
|
||||||
|
ObjType::DEFAULT => "default",
|
||||||
|
};
|
||||||
|
format!("{} {} {}", type_str, self.get_hash_path(), self.get_name())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_ref_to_parent(&self) -> io::Result<()> {
|
fn add_ref_to_parent(&self) -> io::Result<()> {
|
||||||
let line = self.get_line();
|
let line = self.get_line(self.obj_type);
|
||||||
if self.get_relative_file_path().iter().count() == 1 {
|
if self.get_relative_file_path().iter().count() == 1 {
|
||||||
head::add_line(line)?;
|
head::add_line(line)?;
|
||||||
} else {
|
} else {
|
||||||
@@ -104,11 +110,8 @@ impl ObjMethods for Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rm_node(&mut self) -> io::Result<()> {
|
fn rm_node(&mut self) -> io::Result<()> {
|
||||||
// remove self object and children object
|
|
||||||
self.rm_node_down();
|
|
||||||
|
|
||||||
// remove parent reference to self
|
// remove parent reference to self
|
||||||
let line = self.get_line();
|
let line = self.get_line(self.obj_type);
|
||||||
if self.get_relative_file_path().iter().count() == 1 {
|
if self.get_relative_file_path().iter().count() == 1 {
|
||||||
head::rm_line(&line)?;
|
head::rm_line(&line)?;
|
||||||
} else {
|
} else {
|
||||||
@@ -129,7 +132,21 @@ impl ObjMethods for Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exists_on_remote(&mut self) -> bool {
|
fn exists_on_remote(&mut self) -> bool {
|
||||||
PathBuf::from(self.get_hash_path()).exists()
|
self.obj_path.exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_changes(&mut self) -> bool {
|
||||||
|
if !self.obj_path.exists() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.obj_type {
|
||||||
|
ObjType::BLOB => Blob::from_path(self.relative_file_path.clone()).has_changes(),
|
||||||
|
ObjType::TREE => Tree::from_path(self.relative_file_path.clone()).has_changes(),
|
||||||
|
ObjType::DEFAULT => {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,8 +183,8 @@ impl ObjMethods for Blob {
|
|||||||
self.obj.get_hash_path()
|
self.obj.get_hash_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_line(&self) -> String {
|
fn get_line(&self, _: ObjType) -> String {
|
||||||
self.obj.get_line()
|
self.obj.get_line(ObjType::BLOB)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_ref_to_parent(&self) -> io::Result<()> {
|
fn add_ref_to_parent(&self) -> io::Result<()> {
|
||||||
@@ -175,6 +192,8 @@ impl ObjMethods for Blob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rm_node(&mut self) -> io::Result<()> {
|
fn rm_node(&mut self) -> io::Result<()> {
|
||||||
|
// remove self object and children object
|
||||||
|
let _ = self.rm_node_down();
|
||||||
self.obj.rm_node()
|
self.obj.rm_node()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +215,10 @@ impl ObjMethods for Blob {
|
|||||||
fn exists_on_remote(&mut self) -> bool {
|
fn exists_on_remote(&mut self) -> bool {
|
||||||
self.obj.exists_on_remote()
|
self.obj.exists_on_remote()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_changes(&mut self) -> bool {
|
||||||
|
self.obj.has_changes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjMethods for Tree {
|
impl ObjMethods for Tree {
|
||||||
@@ -231,8 +254,8 @@ impl ObjMethods for Tree {
|
|||||||
self.obj.get_hash_path()
|
self.obj.get_hash_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_line(&self) -> String {
|
fn get_line(&self, _: ObjType) -> String {
|
||||||
self.obj.get_line()
|
self.obj.get_line(ObjType::TREE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_ref_to_parent(&self) -> io::Result<()> {
|
fn add_ref_to_parent(&self) -> io::Result<()> {
|
||||||
@@ -240,6 +263,8 @@ impl ObjMethods for Tree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rm_node(&mut self) -> io::Result<()> {
|
fn rm_node(&mut self) -> io::Result<()> {
|
||||||
|
// remove self object and children object
|
||||||
|
let _ = self.rm_node_down();
|
||||||
self.obj.rm_node()
|
self.obj.rm_node()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,6 +296,10 @@ impl ObjMethods for Tree {
|
|||||||
fn exists_on_remote(&mut self) -> bool {
|
fn exists_on_remote(&mut self) -> bool {
|
||||||
self.obj.exists_on_remote()
|
self.obj.exists_on_remote()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_changes(&mut self) -> bool {
|
||||||
|
self.obj.has_changes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Obj {
|
impl Obj {
|
||||||
@@ -287,6 +316,7 @@ impl Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_path<S>(path: S) -> Obj where S: IntoPathBuf {
|
pub fn from_path<S>(path: S) -> Obj where S: IntoPathBuf {
|
||||||
|
|
||||||
let path = path.into();
|
let path = path.into();
|
||||||
let mut hasher = Sha1::new();
|
let mut hasher = Sha1::new();
|
||||||
hasher.input_str(path.to_str().unwrap());
|
hasher.input_str(path.to_str().unwrap());
|
||||||
@@ -297,8 +327,13 @@ impl Obj {
|
|||||||
obj_path.push(dir);
|
obj_path.push(dir);
|
||||||
obj_path.push(res);
|
obj_path.push(res);
|
||||||
|
|
||||||
|
// set to absolute path if not already
|
||||||
let root = path::repo_root();
|
let root = path::repo_root();
|
||||||
let abs_path = root.join(path.clone());
|
let abs_path = match path.clone().starts_with(root.clone()) {
|
||||||
|
true => path.clone(),
|
||||||
|
false => root.join(path.clone())
|
||||||
|
};
|
||||||
|
|
||||||
Obj {
|
Obj {
|
||||||
name: match abs_path.file_name() {
|
name: match abs_path.file_name() {
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
@@ -321,9 +356,9 @@ impl Obj {
|
|||||||
|
|
||||||
/// load from the information line stored in the object
|
/// load from the information line stored in the object
|
||||||
pub fn from_line(line: String, base_dir: Option<PathBuf>) -> Box<dyn ObjMethods> {
|
pub fn from_line(line: String, base_dir: Option<PathBuf>) -> Box<dyn ObjMethods> {
|
||||||
let mut split = line.rsplit(' ');
|
let mut split = line.trim().rsplit(' ');
|
||||||
if split.clone().count() != 3 {
|
if split.clone().count() != 3 {
|
||||||
eprintln!("fatal: invalid object(s)");
|
eprintln!("fatal: invalid object(s) ({})", line.trim());
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::utils::into::IntoPathBuf;
|
use crate::utils::into::IntoPathBuf;
|
||||||
use crate::store::object::object::Obj;
|
use crate::store::object::object::Obj;
|
||||||
use std::path::PathBuf;
|
use crate::store::object::update_dates;
|
||||||
use crate::store::object::object::ObjMethods;
|
use crate::store::object::object::ObjMethods;
|
||||||
use std::fs::{self, File, OpenOptions};
|
use std::fs::{self, File, OpenOptions};
|
||||||
use std::io::{self, BufRead, BufReader, Write, Lines};
|
use std::io::{self, BufRead, BufReader, Write};
|
||||||
|
|
||||||
pub struct Tree {
|
pub struct Tree {
|
||||||
pub obj: Obj,
|
pub obj: Obj,
|
||||||
@@ -42,14 +42,20 @@ impl Tree {
|
|||||||
if let Ok(file) = File::open(self.get_obj_path()) {
|
if let Ok(file) = File::open(self.get_obj_path()) {
|
||||||
self.buf_reader = Some(BufReader::new(file));
|
self.buf_reader = Some(BufReader::new(file));
|
||||||
|
|
||||||
// skip first line if is head
|
// skip first line (declaration) if is not head
|
||||||
if !self.is_head {
|
if !self.is_head {
|
||||||
self.next();
|
let mut line = String::new();
|
||||||
|
self.buf_reader.as_mut().unwrap().read_line(&mut line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_changes(&mut self) -> bool {
|
||||||
|
todo!();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn next(&mut self) -> Option<Box<dyn ObjMethods>> {
|
pub fn next(&mut self) -> Option<Box<dyn ObjMethods>> {
|
||||||
self.read();
|
self.read();
|
||||||
//if let Some(ref mut file) = self.buf_reader {
|
//if let Some(ref mut file) = self.buf_reader {
|
||||||
@@ -80,22 +86,34 @@ impl Tree {
|
|||||||
|
|
||||||
pub fn create(&self, date: &str, up_parent: bool) -> io::Result<()> {
|
pub fn create(&self, date: &str, up_parent: bool) -> io::Result<()> {
|
||||||
// add tree reference to parent
|
// add tree reference to parent
|
||||||
self.add_ref_to_parent();
|
let _ = self.add_ref_to_parent();
|
||||||
|
|
||||||
// create tree object
|
// create tree object
|
||||||
let mut content = format!("{} {}", self.get_name(), date);
|
let content = format!("{} {}", self.get_name(), date);
|
||||||
//create_obj(self.get_hash_path(), &content)?;
|
|
||||||
// todo!();
|
// create parent dir if needed
|
||||||
|
let mut obj_path = self.get_obj_path();
|
||||||
|
obj_path.pop();
|
||||||
|
if !obj_path.exists() {
|
||||||
|
fs::create_dir_all(obj_path)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open ref file
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.create_new(true)
|
||||||
|
.write(true)
|
||||||
|
.open(self.get_obj_path())?;
|
||||||
|
|
||||||
// update date for all parent
|
// update date for all parent
|
||||||
//todo!();
|
// if up_parent {
|
||||||
//if up_parent {
|
// if let Err(err) = update_dates(self.get_relative_file_path(), date) {
|
||||||
// update_dates(path, date)?;
|
// eprintln!("err: updating parent date of {}: {}", self.get_relative_file_path().display(), err);
|
||||||
//}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
writeln!(file, "{}", content)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// create
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,42 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, ArgMatches, Command, ArgAction};
|
||||||
|
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
use crate::commands::add::AddArgs;
|
use crate::commands::add::AddArgs;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("add")
|
Command::new("add")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("files")
|
Arg::new("files")
|
||||||
.required(true)
|
.required_unless_present("all")
|
||||||
.conflicts_with("all")
|
.conflicts_with("all")
|
||||||
.multiple(true)
|
.num_args(1..)
|
||||||
.takes_value(true)
|
|
||||||
.value_name("FILE")
|
.value_name("FILE")
|
||||||
.help("Files to add"),
|
.help("Files to add"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("force")
|
Arg::new("force")
|
||||||
.short("f")
|
.short('f')
|
||||||
.long("force")
|
.long("force")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.help("Allow adding otherwise ignored files."),
|
.help("Allow adding otherwise ignored files."),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("all")
|
Arg::new("all")
|
||||||
.short("A")
|
.short('A')
|
||||||
.long("all")
|
.long("all")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.help("This adds, modifies, and removes index entries to match the working tree"),
|
.help("This adds, modifies, and removes index entries to match the working tree"),
|
||||||
)
|
)
|
||||||
.about("Add changes to the index")
|
.about("Add changes to the index")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
commands::add::add(AddArgs {
|
commands::add::add(AddArgs {
|
||||||
files: args.values_of("files"),
|
files: match args.get_many::<String>("files") {
|
||||||
force: args.is_present("force"),
|
None => vec![],
|
||||||
all: args.is_present("all"),
|
Some(vals) => vals.map(|s| s.to_string()).collect(),
|
||||||
|
},
|
||||||
|
force: *args.get_one::<bool>("force").unwrap(),
|
||||||
|
all: *args.get_one::<bool>("all").unwrap(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,52 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, Command, ArgMatches};
|
||||||
use textwrap::{fill, Options};
|
// use textwrap::{fill, Options};
|
||||||
|
|
||||||
use crate::commands::clone::{self, CloneArgs};
|
use crate::commands::clone::CloneArgs;
|
||||||
use crate::global;
|
use crate::global;
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
|
|
||||||
fn sized_str<'a>(content: &'a str) -> &'a str {
|
// fn sized_str<'a>(content: &'a str) -> &'a str {
|
||||||
fill(content, Options::new(70).width).as_str();
|
// fill(content, Options::new(70).width).as_str();
|
||||||
"ok"
|
// "ok"
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn test() -> String {
|
pub fn create() -> Command {
|
||||||
String::from("ok")
|
// let remote_desc = sized_str(&format!("The repository to clone from. See the NEXTSYNC URLS section below for more information on specifying repositories."));
|
||||||
}
|
// let depth_desc = sized_str(&format!("Depth of the recursive fetch of object properties. This value should be lower when there are a lot of files per directory and higher when there are a lot of subdirectories with fewer files. (Default: {})", clone::DEPTH));
|
||||||
|
Command::new("clone")
|
||||||
pub fn create() -> App<'static, 'static> {
|
|
||||||
let remote_desc = sized_str(&format!("The repository to clone from. See the NEXTSYNC URLS section below for more information on specifying repositories."));
|
|
||||||
let depth_desc = sized_str(&format!("Depth of the recursive fetch of object properties. This value should be lower when there are a lot of files per directory and higher when there are a lot of subdirectories with fewer files. (Default: {})", clone::DEPTH));
|
|
||||||
SubCommand::with_name("clone")
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("remote")
|
Arg::new("remote")
|
||||||
.required(true)
|
.required(true)
|
||||||
.takes_value(true)
|
.num_args(1)
|
||||||
.value_name("REMOTE")
|
.value_name("REMOTE")
|
||||||
//.help(_desc)
|
//.help(_desc)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("depth")
|
Arg::new("depth")
|
||||||
.short("d")
|
.short('d')
|
||||||
.long("depth")
|
.long("depth")
|
||||||
.required(false)
|
.required(false)
|
||||||
.takes_value(true)
|
.num_args(1)
|
||||||
//.help(&depth_desc)
|
//.help(&depth_desc)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("directory")
|
Arg::new("directory")
|
||||||
.required(false)
|
.required(false)
|
||||||
.takes_value(true)
|
.num_args(1)
|
||||||
.value_name("DIRECTORY")
|
.value_name("DIRECTORY")
|
||||||
)
|
)
|
||||||
.about("Clone a repository into a new directory")
|
.about("Clone a repository into a new directory")
|
||||||
.after_help("NEXTSYNC URLS\nThe following syntaxes may be used:\n\t- user@host.xz/path/to/repo\n\t- http[s]://host.xz/apps/files/?dir=/path/to/repo&fileid=111111\n\t- [http[s]://]host.xz/remote.php/dav/files/user/path/to/repo\n")
|
.after_help("NEXTSYNC URLS\nThe following syntaxes may be used:\n\t- user@host.xz/path/to/repo\n\t- http[s]://host.xz/apps/files/?dir=/path/to/repo&fileid=111111\n\t- [http[s]://]host.xz/remote.php/dav/files/user/path/to/repo\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
if let Some(val) = args.values_of("directory") {
|
if let Some(val) = args.get_one::<String>("directory") {
|
||||||
global::global::set_dir_path(String::from(val.clone().next().unwrap()));
|
global::global::set_dir_path(String::from(val.to_string()));
|
||||||
}
|
}
|
||||||
if let Some(remote) = args.values_of("remote") {
|
if let Some(remote) = args.get_one::<String>("remote") {
|
||||||
commands::clone::clone(CloneArgs {
|
commands::clone::clone(CloneArgs {
|
||||||
remote,
|
remote: remote.to_string(),
|
||||||
depth: args.values_of("depth").map(
|
depth: args.get_one::<String>("depth").cloned(),
|
||||||
|mut val| val.next().unwrap().to_owned()
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, Command, ArgMatches};
|
||||||
use crate::commands::config::ConfigSetArgs;
|
use crate::commands::config::ConfigSetArgs;
|
||||||
|
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("config")
|
Command::new("config")
|
||||||
.about("Get and set repository or global options")
|
.about("Get and set repository or global options")
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("get")
|
Command::new("get")
|
||||||
.about("Get the value of a configuration variable")
|
.about("Get the value of a configuration variable")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("name")
|
Arg::new("name")
|
||||||
.help("The name of the configuration variable")
|
.help("The name of the configuration variable")
|
||||||
.required(true)
|
.required(true)
|
||||||
.index(1)
|
.index(1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("set")
|
Command::new("set")
|
||||||
.about("Set a configuration variable")
|
.about("Set a configuration variable")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("name")
|
Arg::new("name")
|
||||||
.help("The name of the configuration variable")
|
.help("The name of the configuration variable")
|
||||||
.required(true)
|
.required(true)
|
||||||
.index(1)
|
.index(1)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("value")
|
Arg::new("value")
|
||||||
.help("The value to set")
|
.help("The value to set")
|
||||||
.required(true)
|
.required(true)
|
||||||
.index(2)
|
.index(2)
|
||||||
@@ -34,20 +34,15 @@ pub fn create() -> App<'static, 'static> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
|
|
||||||
match args.subcommand() {
|
match args.subcommand() {
|
||||||
("set", Some(set_matches)) => {
|
Some(("set", set_matches)) => {
|
||||||
commands::config::config_set(ConfigSetArgs {
|
commands::config::config_set(ConfigSetArgs {
|
||||||
name: set_matches.values_of("name"),
|
name: set_matches.get_one::<String>("name").unwrap().to_string(),
|
||||||
value: set_matches.values_of("value"),
|
value: set_matches.get_one::<String>("value").unwrap().to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => println!("Invalid or missing subcommand for 'config'"),
|
_ => println!("Invalid or missing subcommand for 'config'"),
|
||||||
}
|
}
|
||||||
// AddArgs {
|
|
||||||
// files: args.values_of("files"),
|
|
||||||
// force: args.is_present("force"),
|
|
||||||
// all: args.is_present("all"),
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, Command, ArgMatches};
|
||||||
|
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
use crate::commands::credential::CredentialArgs;
|
use crate::commands::credential::CredentialArgs;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("credential")
|
Command::new("credential")
|
||||||
.about("Manage set of credentials")
|
.about("Manage set of credentials")
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("add")
|
Command::new("add")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("username")
|
Arg::new("username")
|
||||||
.required(true)
|
.required(true)
|
||||||
.takes_value(true)
|
.num_args(1)
|
||||||
.value_name("NAME")
|
.value_name("NAME")
|
||||||
.help("The username used to connect to nextcloud"),
|
.help("The username used to connect to nextcloud"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("password")
|
Arg::new("password")
|
||||||
.required(false)
|
.required(false)
|
||||||
.takes_value(true)
|
.num_args(1)
|
||||||
.value_name("PASSWORD")
|
.value_name("PASSWORD")
|
||||||
.help("The passowd used to connect to nextcloud (optional)"),
|
.help("The passowd used to connect to nextcloud (optional)"),
|
||||||
)
|
)
|
||||||
@@ -26,12 +26,12 @@ pub fn create() -> App<'static, 'static> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
match args.subcommand() {
|
match args.subcommand() {
|
||||||
("add", Some(add_matches)) => {
|
Some(("add", add_matches)) => {
|
||||||
commands::credential::credential_add(CredentialArgs {
|
commands::credential::credential_add(CredentialArgs {
|
||||||
username: add_matches.values_of("username"),
|
username: add_matches.get_one::<String>("username").unwrap().to_string(),
|
||||||
password: add_matches.values_of("password"),
|
password: add_matches.get_one::<String>("password").cloned(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => println!("Invalid or missing subcommand for 'credential'"),
|
_ => println!("Invalid or missing subcommand for 'credential'"),
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, Command, ArgMatches};
|
||||||
|
|
||||||
use crate::global;
|
use crate::global;
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("init")
|
Command::new("init")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("directory")
|
Arg::new("directory")
|
||||||
.required(false)
|
.required(false)
|
||||||
.takes_value(true)
|
.num_args(1)
|
||||||
.value_name("DIRECTORY")
|
.value_name("DIRECTORY")
|
||||||
)
|
)
|
||||||
.about("Create an empty Nextsync repository")
|
.about("Create an empty Nextsync repository")
|
||||||
// Create an empty nextsync repository or reinitialize an existing one
|
// Create an empty nextsync repository or reinitialize an existing one
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
if let Some(val) = args.values_of("directory") {
|
if let Some(val) = args.get_one::<String>("directory") {
|
||||||
global::global::set_dir_path(String::from(val.clone().next().unwrap()));
|
global::global::set_dir_path(val.to_string());
|
||||||
}
|
}
|
||||||
commands::init::init();
|
commands::init::init();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, Command, ArgMatches};
|
||||||
|
|
||||||
use crate::global;
|
use crate::global;
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("pull")
|
Command::new("pull")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("path")
|
Arg::new("path")
|
||||||
.required(false)
|
.required(false)
|
||||||
.takes_value(true)
|
.num_args(1)
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help("The path to pull."),
|
.help("The path to pull."),
|
||||||
)
|
)
|
||||||
.about("Fetch and integrate changes from the nextcloud server.")
|
.about("Fetch and integrate changes from the nextcloud server.")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
if let Some(val) = args.values_of("path") {
|
if let Some(val) = args.get_one::<String>("path") {
|
||||||
global::global::set_dir_path(String::from(val.clone().next().unwrap()));
|
global::global::set_dir_path(val.to_string());
|
||||||
}
|
}
|
||||||
commands::pull::pull();
|
commands::pull::pull();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use clap::{App, SubCommand};
|
use clap::Command;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("push")
|
Command::new("push")
|
||||||
.about("Push changes on nextcloud")
|
.about("Push changes on nextcloud")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, Command, ArgMatches, ArgAction};
|
||||||
|
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
use crate::commands::remote::RemoteArgs;
|
use crate::commands::remote::RemoteArgs;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("remote")
|
Command::new("remote")
|
||||||
.about("Manage set of tracked repositories")
|
.about("Manage set of tracked repositories")
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("add")
|
Command::new("add")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("name")
|
Arg::new("name")
|
||||||
.required(true)
|
.required(true)
|
||||||
.index(1)
|
.index(1)
|
||||||
.help("The name of the remote"),
|
.help("The name of the remote"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("url")
|
Arg::new("url")
|
||||||
.required(true)
|
.required(true)
|
||||||
.index(2)
|
.index(2)
|
||||||
.help("The url of the remote"),
|
.help("The url of the remote"),
|
||||||
@@ -23,25 +23,24 @@ pub fn create() -> App<'static, 'static> {
|
|||||||
.about("Add a new remote to this repository")
|
.about("Add a new remote to this repository")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("verbose")
|
Arg::new("verbose")
|
||||||
.short("v")
|
.short('v')
|
||||||
.long("verbose")
|
.long("verbose")
|
||||||
.required(false)
|
.action(ArgAction::SetTrue)
|
||||||
.takes_value(false)
|
|
||||||
.help("Be a little more verbose and show remote url after name.")
|
.help("Be a little more verbose and show remote url after name.")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
match args.subcommand() {
|
match args.subcommand() {
|
||||||
("add", Some(add_matches)) => {
|
Some(("add", add_matches)) => {
|
||||||
commands::remote::remote_add(RemoteArgs {
|
commands::remote::remote_add(RemoteArgs {
|
||||||
name: add_matches.values_of("name"),
|
name: add_matches.get_one::<String>("name").unwrap().to_string(),
|
||||||
url: add_matches.values_of("url"),
|
url: add_matches.get_one::<String>("url").unwrap().to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
commands::remote::remote_list(args.is_present("verbose"));
|
commands::remote::remote_list(*args.get_one::<bool>("verbose").unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, Command, ArgMatches};
|
||||||
|
|
||||||
use crate::global;
|
use crate::global;
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("remote-diff")
|
Command::new("remote-diff")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("path")
|
Arg::new("path")
|
||||||
.required(false)
|
.required(false)
|
||||||
.takes_value(true)
|
.num_args(1)
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help("The path to pull."),
|
.help("The path to pull."),
|
||||||
)
|
)
|
||||||
@@ -16,9 +16,9 @@ pub fn create() -> App<'static, 'static> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
if let Some(val) = args.values_of("path") {
|
if let Some(val) = args.get_one::<String>("path") {
|
||||||
global::global::set_dir_path(String::from(val.clone().next().unwrap()));
|
global::global::set_dir_path(val.to_string());
|
||||||
}
|
}
|
||||||
commands::remote_diff::remote_diff();
|
commands::remote_diff::remote_diff();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use clap::{App, SubCommand};
|
use clap::Command;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("reset")
|
Command::new("reset")
|
||||||
.about("Clear the index")
|
.about("Clear the index")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
use clap::{Arg, Command, ArgMatches};
|
||||||
|
|
||||||
use crate::global;
|
use crate::global;
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
use crate::commands::status::StatusArgs;
|
use crate::commands::status::StatusArgs;
|
||||||
|
|
||||||
pub fn create() -> App<'static, 'static> {
|
pub fn create() -> Command {
|
||||||
SubCommand::with_name("status")
|
Command::new("status")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("directory")
|
Arg::new("directory")
|
||||||
.required(false)
|
.num_args(1)
|
||||||
.takes_value(true)
|
|
||||||
.value_name("DIRECTORY")
|
.value_name("DIRECTORY")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("nostyle")
|
Arg::new("nostyle")
|
||||||
.long("nostyle")
|
.long("nostyle")
|
||||||
.help("Status with minium information and style"),
|
.help("Status with minium information and style"),
|
||||||
)
|
)
|
||||||
.about("Show the working tree status")
|
.about("Show the working tree status")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler(args: &ArgMatches<'_>) {
|
pub fn handler(args: &ArgMatches) {
|
||||||
if let Some(val) = args.values_of("directory") {
|
if let Some(val) = args.get_one::<String>("directory") {
|
||||||
global::global::set_dir_path(String::from(val.clone().next().unwrap()));
|
global::global::set_dir_path(val.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
commands::status::status(StatusArgs {
|
commands::status::status(StatusArgs {
|
||||||
nostyle: args.is_present("nostyle"),
|
nostyle: args.contains_id("nostyle"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,3 +22,9 @@ impl IntoPathBuf for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoPathBuf for &str {
|
||||||
|
fn into(self) -> PathBuf {
|
||||||
|
PathBuf::from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pub fn enumerate_remote(
|
|||||||
let mut deleted: Vec<PathBuf> = vec![];
|
let mut deleted: Vec<PathBuf> = vec![];
|
||||||
let mut files: Vec<ObjProps> = vec![];
|
let mut files: Vec<ObjProps> = vec![];
|
||||||
let mut objs_hashmap: HashMap<String, Vec<String>> = HashMap::new();
|
let mut objs_hashmap: HashMap<String, Vec<String>> = HashMap::new();
|
||||||
|
|
||||||
objs_hashmap.insert(
|
objs_hashmap.insert(
|
||||||
options.relative_s.clone().unwrap_or(String::new()),
|
options.relative_s.clone().unwrap_or(String::new()),
|
||||||
Vec::new());
|
Vec::new());
|
||||||
@@ -53,7 +54,11 @@ pub fn enumerate_remote(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// separate folders and files in response
|
// separate folders and files in response
|
||||||
let d = options.depth.clone().unwrap_or("0".to_owned()).parse::<u16>().unwrap();
|
let d = options.depth.clone()
|
||||||
|
.unwrap_or("0".to_owned())
|
||||||
|
.parse::<u16>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// first element is not used as it is the fetched folder
|
// first element is not used as it is the fetched folder
|
||||||
if let Some(should_skip_fct) = should_skip.clone() {
|
if let Some(should_skip_fct) = should_skip.clone() {
|
||||||
iter_with_skip_fct(
|
iter_with_skip_fct(
|
||||||
@@ -82,6 +87,7 @@ pub fn enumerate_remote(
|
|||||||
&mut all_folders);
|
&mut all_folders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// go through all folders not checked for deletion before
|
// go through all folders not checked for deletion before
|
||||||
// as they were empty
|
// as they were empty
|
||||||
if let Some(_) = should_skip.clone() {
|
if let Some(_) = should_skip.clone() {
|
||||||
@@ -90,18 +96,13 @@ pub fn enumerate_remote(
|
|||||||
objs_hashmap.remove(&key);
|
objs_hashmap.remove(&key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbg!(deleted);
|
|
||||||
dbg!(objs_hashmap);
|
|
||||||
|
|
||||||
(all_folders, files)
|
(all_folders, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_depth(obj: &ObjProps) -> u16 {
|
fn calc_depth(obj: &ObjProps) -> u16 {
|
||||||
calc_depth_string(obj.relative_s.clone().unwrap_or(String::new()))
|
let path = obj.relative_s.clone().unwrap_or(String::new());
|
||||||
}
|
path.split("/").count() as u16
|
||||||
|
|
||||||
fn calc_depth_string(s: String) -> u16 {
|
|
||||||
s.split("/").count() as u16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_with_skip_fct(
|
fn iter_with_skip_fct(
|
||||||
@@ -121,7 +122,6 @@ fn iter_with_skip_fct(
|
|||||||
let current_depth = calc_depth(object);
|
let current_depth = calc_depth(object);
|
||||||
|
|
||||||
if object.is_dir() {
|
if object.is_dir() {
|
||||||
|
|
||||||
// add folder to parent folder only if exists
|
// add folder to parent folder only if exists
|
||||||
let mut r_path = PathBuf::from(object.relative_s.clone().unwrap());
|
let mut r_path = PathBuf::from(object.relative_s.clone().unwrap());
|
||||||
r_path.pop();
|
r_path.pop();
|
||||||
|
|||||||
22
tests/add.rs
22
tests/add.rs
@@ -26,7 +26,6 @@ fn lines_should_not_contains(lines: Vec<String>, str: &str) {
|
|||||||
}
|
}
|
||||||
assert!(line.find(str).is_none());
|
assert!(line.find(str).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_status_lines(client: &mut ClientTest) -> Vec<String> {
|
fn collect_status_lines(client: &mut ClientTest) -> Vec<String> {
|
||||||
@@ -40,7 +39,9 @@ fn collect_status_lines(client: &mut ClientTest) -> Vec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod push_tests {
|
mod add_tests {
|
||||||
|
use crate::utils::{server::ServerTest, status_utils::status_should_be_empty};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -95,4 +96,21 @@ mod push_tests {
|
|||||||
client.clean();
|
client.clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_file_no_changes() {
|
||||||
|
// add a file push it and add it again
|
||||||
|
let (mut client, mut server) = init_test();
|
||||||
|
|
||||||
|
let _ = client.add_file("file1", "foo");
|
||||||
|
client.run_cmd_ok("add file1");
|
||||||
|
client.run_cmd_ok("push");
|
||||||
|
|
||||||
|
status_should_be_empty(&mut client);
|
||||||
|
|
||||||
|
client.run_cmd_ok("add file1");
|
||||||
|
status_should_be_empty(&mut client);
|
||||||
|
|
||||||
|
clean_test(client, &mut server)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
36
tests/pull.rs
Normal file
36
tests/pull.rs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
mod utils;
|
||||||
|
use utils::{utils::*};
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod pull_tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple_pull() {
|
||||||
|
let (mut client, mut server) = init_test();
|
||||||
|
|
||||||
|
let _ = server.add_file("file1", "foo");
|
||||||
|
client.run_cmd_ok("pull");
|
||||||
|
|
||||||
|
// tests
|
||||||
|
assert!(client.has_file("file1", "foo"));
|
||||||
|
|
||||||
|
clean_test(client, &mut server);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple_pull_directory() {
|
||||||
|
let (mut client, mut server) = init_test();
|
||||||
|
|
||||||
|
let _ = server.add_dir("dir");
|
||||||
|
let _ = server.add_file("dir/file1", "foo");
|
||||||
|
|
||||||
|
client.run_cmd_ok("pull");
|
||||||
|
|
||||||
|
// tests
|
||||||
|
assert!(client.has_file("dir/file1", "foo"));
|
||||||
|
|
||||||
|
clean_test(client, &mut server);
|
||||||
|
}
|
||||||
|
}
|
||||||
110
tests/push.rs
110
tests/push.rs
@@ -1,7 +1,5 @@
|
|||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
use utils::{utils::*, server::ServerTest, client::ClientTest};
|
use utils::{utils::*, status_utils::*};
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod push_tests {
|
mod push_tests {
|
||||||
@@ -9,9 +7,7 @@ mod push_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn simple_push() {
|
fn simple_push() {
|
||||||
let id = get_random_test_id();
|
let (mut client, mut server) = init_test();
|
||||||
let mut server = ServerTest::new(id.clone()).init();
|
|
||||||
let mut client = ClientTest::new(id).init();
|
|
||||||
|
|
||||||
let _ = client.add_file("file1", "foo");
|
let _ = client.add_file("file1", "foo");
|
||||||
client.run_cmd_ok("add file1");
|
client.run_cmd_ok("add file1");
|
||||||
@@ -19,16 +15,16 @@ mod push_tests {
|
|||||||
|
|
||||||
// tests
|
// tests
|
||||||
assert!(server.has_file("file1", "foo"));
|
assert!(server.has_file("file1", "foo"));
|
||||||
|
let (staged, not_staged) = client.get_status();
|
||||||
|
lines_should_not_contains(staged, "file1");
|
||||||
|
lines_should_not_contains(not_staged, "file1");
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn push_update() {
|
fn push_update() {
|
||||||
let id = get_random_test_id();
|
let (mut client, mut server) = init_test();
|
||||||
let mut server = ServerTest::new(id.clone()).init();
|
|
||||||
let mut client = ClientTest::new(id).init();
|
|
||||||
|
|
||||||
// init content of file1
|
// init content of file1
|
||||||
let _ = client.add_file("file1", "foo");
|
let _ = client.add_file("file1", "foo");
|
||||||
@@ -38,6 +34,10 @@ mod push_tests {
|
|||||||
// tests
|
// tests
|
||||||
assert!(server.has_file("file1", "foo"));
|
assert!(server.has_file("file1", "foo"));
|
||||||
|
|
||||||
|
let (staged, not_staged) = client.get_status();
|
||||||
|
lines_should_not_contains(staged, "file1");
|
||||||
|
lines_should_not_contains(not_staged, "file1");
|
||||||
|
|
||||||
// change content of file1
|
// change content of file1
|
||||||
let _ = client.add_file("file1", "bar");
|
let _ = client.add_file("file1", "bar");
|
||||||
client.run_cmd_ok("add file1");
|
client.run_cmd_ok("add file1");
|
||||||
@@ -45,16 +45,16 @@ mod push_tests {
|
|||||||
|
|
||||||
// tests
|
// tests
|
||||||
assert!(server.has_file("file1", "bar"));
|
assert!(server.has_file("file1", "bar"));
|
||||||
|
let (staged, not_staged) = client.get_status();
|
||||||
|
lines_should_not_contains(staged, "file1");
|
||||||
|
lines_should_not_contains(not_staged, "file1");
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn push_dir_explicit() {
|
fn push_dir_explicit() {
|
||||||
let id = get_random_test_id();
|
let (mut client, mut server) = init_test();
|
||||||
let mut server = ServerTest::new(id.clone()).init();
|
|
||||||
let mut client = ClientTest::new(id).init();
|
|
||||||
|
|
||||||
let _ = client.add_dir("dir");
|
let _ = client.add_dir("dir");
|
||||||
let _ = client.add_file("dir/file2", "bar");
|
let _ = client.add_file("dir/file2", "bar");
|
||||||
@@ -65,16 +65,18 @@ mod push_tests {
|
|||||||
|
|
||||||
// tests
|
// tests
|
||||||
assert!(server.has_file("dir/file2", "bar"));
|
assert!(server.has_file("dir/file2", "bar"));
|
||||||
|
let (staged, not_staged) = client.get_status();
|
||||||
|
lines_should_not_contains(staged.clone(), "file2");
|
||||||
|
lines_should_not_contains(staged, "foo");
|
||||||
|
lines_should_not_contains(not_staged.clone(), "file2");
|
||||||
|
lines_should_not_contains(not_staged, "foo");
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn push_dir_implicit() {
|
fn push_dir_implicit() {
|
||||||
let id = get_random_test_id();
|
let (mut client, mut server) = init_test();
|
||||||
let mut server = ServerTest::new(id.clone()).init();
|
|
||||||
let mut client = ClientTest::new(id).init();
|
|
||||||
|
|
||||||
let _ = client.add_dir("dir");
|
let _ = client.add_dir("dir");
|
||||||
let _ = client.add_file("dir/file2", "bar");
|
let _ = client.add_file("dir/file2", "bar");
|
||||||
@@ -85,16 +87,18 @@ mod push_tests {
|
|||||||
|
|
||||||
// tests
|
// tests
|
||||||
assert!(server.has_file("dir/file2", "bar"));
|
assert!(server.has_file("dir/file2", "bar"));
|
||||||
|
let (staged, not_staged) = client.get_status();
|
||||||
|
lines_should_not_contains(staged.clone(), "file2");
|
||||||
|
lines_should_not_contains(staged, "foo");
|
||||||
|
lines_should_not_contains(not_staged.clone(), "file2");
|
||||||
|
lines_should_not_contains(not_staged, "foo");
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn push_all() {
|
fn push_all() {
|
||||||
let id = get_random_test_id();
|
let (mut client, mut server) = init_test();
|
||||||
let mut server = ServerTest::new(id.clone()).init();
|
|
||||||
let mut client = ClientTest::new(id).init();
|
|
||||||
|
|
||||||
let _ = client.add_file("file1", "foo");
|
let _ = client.add_file("file1", "foo");
|
||||||
let _ = client.add_dir("dir");
|
let _ = client.add_dir("dir");
|
||||||
@@ -107,8 +111,58 @@ mod push_tests {
|
|||||||
// tests
|
// tests
|
||||||
assert!(server.has_file("file1", "foo"));
|
assert!(server.has_file("file1", "foo"));
|
||||||
assert!(server.has_file("dir/file2", "bar"));
|
assert!(server.has_file("dir/file2", "bar"));
|
||||||
|
let (staged, not_staged) = client.get_status();
|
||||||
|
assert!(staged.len() == 0);
|
||||||
|
assert!(not_staged.len() == 0);
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn push_file_deletion() {
|
||||||
|
let (mut client, mut server) = init_test();
|
||||||
|
|
||||||
|
let _ = client.add_file("file1", "foo");
|
||||||
|
|
||||||
|
// push file1
|
||||||
|
client.run_cmd_ok("add file1");
|
||||||
|
client.run_cmd_ok("push");
|
||||||
|
|
||||||
|
// tests
|
||||||
|
assert!(server.has_file("file1", "foo"));
|
||||||
|
status_should_be_empty(&mut client);
|
||||||
|
|
||||||
|
// remove it
|
||||||
|
let _ = client.remove_file("file1");
|
||||||
|
client.run_cmd_ok("add file1");
|
||||||
|
client.run_cmd_ok("push");
|
||||||
|
|
||||||
|
// tests
|
||||||
|
assert!(server.has_not_file("file1"));
|
||||||
|
status_should_be_empty(&mut client);
|
||||||
|
|
||||||
|
clean_test(client, &mut server);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn push_dir_deletion() {
|
||||||
|
let (mut client, mut server) = init_test();
|
||||||
|
|
||||||
|
// push dir and file2
|
||||||
|
let _ = client.add_dir("dir");
|
||||||
|
let _ = client.add_file("dir/file2", "bar");
|
||||||
|
client.run_cmd_ok("add dir");
|
||||||
|
client.run_cmd_ok("push");
|
||||||
|
|
||||||
|
// tests
|
||||||
|
assert!(server.has_file("dir/file2", "bar"));
|
||||||
|
|
||||||
|
// push deletion
|
||||||
|
let _ = client.remove_dir("dir");
|
||||||
|
client.run_cmd_ok("add dir");
|
||||||
|
client.run_cmd_ok("push");
|
||||||
|
assert!(server.has_not_dir("dir"));
|
||||||
|
|
||||||
|
clean_test(client, &mut server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,3 +6,9 @@ pub mod client;
|
|||||||
|
|
||||||
#[path = "utils/utils.rs"]
|
#[path = "utils/utils.rs"]
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
|
#[path = "utils/status_utils.rs"]
|
||||||
|
pub mod status_utils;
|
||||||
|
|
||||||
|
#[path = "utils/files_utils.rs"]
|
||||||
|
pub mod files_utils;
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
|
use std::str;
|
||||||
use std::process::{Command, Output};
|
use std::process::{Command, Output};
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use super::files_utils::has_files;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
pub struct ClientTest {
|
pub struct ClientTest {
|
||||||
user: String, // the nextcloud user
|
user: String, // the nextcloud user
|
||||||
volume: String, // temp dir for the test
|
volume: String, // temp dir for the test
|
||||||
test_id: String, // name of the test (e.g nextsync_rand)
|
pub test_id: String, // name of the test (e.g nextsync_rand)
|
||||||
exe_path: PathBuf, // absolute path of nextsync executable
|
exe_path: PathBuf, // absolute path of nextsync executable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
impl ClientTest {
|
impl ClientTest {
|
||||||
pub fn new(id: String) -> Self {
|
pub fn new(id: String) -> Self {
|
||||||
// create a directory in /tmp with the given id
|
// create a directory in /tmp with the given id
|
||||||
@@ -90,4 +95,68 @@ impl ClientTest {
|
|||||||
file.write_all(content.as_bytes())?;
|
file.write_all(content.as_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_file(&mut self, name: &str) -> std::io::Result<()> {
|
||||||
|
let mut path = self.volume.clone();
|
||||||
|
path.push_str("/");
|
||||||
|
path.push_str(name);
|
||||||
|
fs::remove_file(path)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_dir(&mut self, name: &str) -> std::io::Result<()> {
|
||||||
|
let mut path = self.volume.clone();
|
||||||
|
path.push_str("/");
|
||||||
|
path.push_str(name);
|
||||||
|
fs::remove_dir_all(path)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_file(&mut self, file: &str, content: &str) -> bool {
|
||||||
|
let full_path = PathBuf::from(self.volume.clone()).join(file);
|
||||||
|
|
||||||
|
has_files(full_path, file, content, self.test_id.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get the files given by the status command in two vector (staged and not staged)
|
||||||
|
pub fn get_status(&mut self) -> (Vec<String>, Vec<String>) {
|
||||||
|
let out = self.run_cmd("status");
|
||||||
|
|
||||||
|
let lines: Vec<String> = str::from_utf8(&out.stdout)
|
||||||
|
.unwrap()
|
||||||
|
.split("\n")
|
||||||
|
.map(|s| s.to_owned())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut staged = vec![];
|
||||||
|
let mut not_staged = vec![];
|
||||||
|
let mut in_staged = true;
|
||||||
|
let mut counter = 0;
|
||||||
|
for line in lines {
|
||||||
|
if line.find("not staged").is_some() {
|
||||||
|
in_staged = false;
|
||||||
|
counter = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip two first line as there are not files
|
||||||
|
if counter < 2 {
|
||||||
|
counter += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if line == String::from("") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if in_staged {
|
||||||
|
staged.push(line);
|
||||||
|
} else {
|
||||||
|
not_staged.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (staged, not_staged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
tests/utils/files_utils.rs
Normal file
50
tests/utils/files_utils.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use std::io::{BufReader, BufRead};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn has_files(full_path: PathBuf, file: &str, content: &str, test_id: String) -> bool
|
||||||
|
{
|
||||||
|
if !full_path.exists() {
|
||||||
|
println!("id: {}", test_id.clone());
|
||||||
|
eprintln!("File '{}' doesn't exists", file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let f = File::open(full_path).unwrap();
|
||||||
|
for line in BufReader::new(f).lines(){
|
||||||
|
if let Ok(line) = line {
|
||||||
|
if line != content {
|
||||||
|
println!("id: {}", test_id);
|
||||||
|
eprintln!("File '{}' is not equal, {} != {}", file, line, content);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return line == content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn has_not_file(full_path: PathBuf, file: &str, test_id: String) -> bool
|
||||||
|
{
|
||||||
|
if full_path.exists() {
|
||||||
|
println!("id: {}", test_id.clone());
|
||||||
|
eprintln!("File '{}' exists but it shouldn't", file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn has_not_dir(full_path: PathBuf, dir: &str, test_id: String) -> bool
|
||||||
|
{
|
||||||
|
if full_path.exists() {
|
||||||
|
println!("id: {}", test_id.clone());
|
||||||
|
eprintln!("Dir '{}' exists but it shouldn't", dir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::fs::{self, File, Permissions};
|
use std::fs::{self, File, Permissions};
|
||||||
use std::io::{BufReader, BufRead};
|
use std::io::Write;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use super::files_utils::{self, has_files};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub struct ServerTest {
|
pub struct ServerTest {
|
||||||
user: String,
|
user: String,
|
||||||
volume: PathBuf,
|
volume: PathBuf,
|
||||||
test_id: String
|
pub test_id: String
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -25,18 +27,20 @@ impl ServerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(mut self) -> Self {
|
pub fn init(&mut self) -> &mut ServerTest{
|
||||||
self.add_dir(self.test_id.clone());
|
self.add_dir(&self.test_id.clone());
|
||||||
self.volume = self.volume.join(self.test_id.clone());
|
self.volume = self.volume.join(self.test_id.clone());
|
||||||
self.sync_test()
|
self.sync_root();
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clean(mut self) -> Self {
|
pub fn clean(&mut self) -> &mut ServerTest{
|
||||||
self.remove_dir(self.test_id.clone());
|
self.remove_dir(self.test_id.clone());
|
||||||
self.sync_root()
|
self.sync_root();
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_dir(&mut self, path: String) -> &mut ServerTest {
|
pub fn add_dir(&mut self, path: &str) -> &mut ServerTest {
|
||||||
let mut full_path = self.volume.clone();
|
let mut full_path = self.volume.clone();
|
||||||
full_path.push(path);
|
full_path.push(path);
|
||||||
|
|
||||||
@@ -51,65 +55,69 @@ impl ServerTest {
|
|||||||
Err(e) => eprintln!("Error creating directory: {}", e),
|
Err(e) => eprintln!("Error creating directory: {}", e),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do not sync test directory when creating it
|
||||||
|
if !path.ends_with("_nextsync")
|
||||||
|
{
|
||||||
|
self.sync_test();
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_file(&mut self, name: &str, content: &str) -> std::io::Result<()> {
|
||||||
|
let mut full_path = self.volume.clone();
|
||||||
|
full_path.push(name);
|
||||||
|
|
||||||
|
let mut file = File::create(full_path)?;
|
||||||
|
file.write_all(content.as_bytes())?;
|
||||||
|
self.sync_test();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remove_dir(&mut self, path: String) -> &mut ServerTest {
|
pub fn remove_dir(&mut self, path: String) -> &mut ServerTest {
|
||||||
let mut full_path = self.volume.clone();
|
let mut full_path = self.volume.clone();
|
||||||
full_path.push(path);
|
full_path.push(path);
|
||||||
|
|
||||||
let _ = fs::remove_dir_all(&full_path);
|
let _ = fs::remove_dir_all(&full_path);
|
||||||
|
self.sync_test();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync_root(self) -> Self {
|
fn sync_root(&self) -> &Self {
|
||||||
self.sync("")
|
self.sync("")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync_test(self) -> Self {
|
fn sync_test(&self) -> &Self {
|
||||||
let test_id = self.test_id.clone();
|
let test_id = self.test_id.clone();
|
||||||
self.sync(&test_id)
|
self.sync(&test_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync(self, path: &str) -> Self {
|
fn sync(&self, path: &str) -> &Self {
|
||||||
// perform the occ files:scan command inside the nextcloud docker container
|
// perform the occ files:scan command inside the nextcloud docker container
|
||||||
|
|
||||||
let nextcloud_docker = "master-nextcloud-1";
|
let nextcloud_docker = "master-nextcloud-1";
|
||||||
let mut args = String::from("exec -ti --user www-data");
|
let args = format!("exec -t --user www-data {} /var/www/html/occ files:scan --path=/{}/files/{}", nextcloud_docker, &self.user, path);
|
||||||
args.push_str(nextcloud_docker);
|
|
||||||
args.push_str("/var/www/html/occ files:scan --path=/");
|
|
||||||
args.push_str(&self.user);
|
|
||||||
args.push_str("files/");
|
|
||||||
args.push_str(path);
|
|
||||||
|
|
||||||
let _output = Command::new("docker")
|
let _output = Command::new("docker")
|
||||||
.args(args.split(" "))
|
.args(args.split(" "))
|
||||||
.output()
|
.output()
|
||||||
.expect("Could not execute nextsync command");
|
.expect("Could not execute docker exec command");
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_file(&mut self, file: &str, content: &str) -> bool {
|
pub fn has_file(&mut self, file: &str, content: &str) -> bool {
|
||||||
let full_path = self.volume.clone().join(file);
|
let full_path = self.volume.clone().join(file);
|
||||||
|
has_files(full_path, file, content, self.test_id.clone())
|
||||||
|
}
|
||||||
|
|
||||||
if !full_path.exists() {
|
pub fn has_not_file(&mut self, file: &str) -> bool {
|
||||||
println!("id: {}", self.test_id.clone());
|
let full_path = self.volume.clone().join(file);
|
||||||
eprintln!("File '{}' doesn't exists on the server", file);
|
files_utils::has_not_file(full_path, file, self.test_id.clone())
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let f = File::open(full_path).unwrap();
|
pub fn has_not_dir(&mut self, dir: &str) -> bool {
|
||||||
for line in BufReader::new(f).lines(){
|
let full_path = self.volume.clone().join(dir);
|
||||||
if let Ok(line) = line {
|
dbg!(full_path.clone());
|
||||||
if line != content {
|
files_utils::has_not_file(full_path, dir, self.test_id.clone())
|
||||||
println!("id: {}", self.test_id.clone());
|
|
||||||
eprintln!("File '{}' is not equal, {} != {}", file, line, content);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return line == content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
tests/utils/status_utils.rs
Normal file
27
tests/utils/status_utils.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
use super::client::ClientTest;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn lines_should_not_contains(lines: Vec<String>, str: &str) {
|
||||||
|
for line in lines {
|
||||||
|
if line.find(str).is_some() {
|
||||||
|
eprintln!("'{}' found in '{}'", str, line);
|
||||||
|
}
|
||||||
|
assert!(line.find(str).is_none());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn status_should_be_empty(client: &mut ClientTest) {
|
||||||
|
let (staged, not_staged) = client.get_status();
|
||||||
|
if staged.len() != 0 {
|
||||||
|
eprintln!("id: {}", client.test_id.clone());
|
||||||
|
eprintln!("Staged should be empty but has '{}' line(s)", staged.len());
|
||||||
|
assert!(staged.len() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if staged.len() != 0 {
|
||||||
|
eprintln!("id: {}", client.test_id.clone());
|
||||||
|
eprintln!("Not Staged should be empty but has '{}' line(s)", not_staged.len());
|
||||||
|
assert!(not_staged.len() == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
use rand::{distributions::Alphanumeric, Rng};
|
use rand::{distributions::Alphanumeric, Rng};
|
||||||
|
use super::client::ClientTest;
|
||||||
|
use super::server::ServerTest;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
pub fn get_random_test_id() -> String {
|
pub fn get_random_test_id() -> String {
|
||||||
let mut id: String = rand::thread_rng()
|
let mut id: String = rand::thread_rng()
|
||||||
.sample_iter(&Alphanumeric)
|
.sample_iter(&Alphanumeric)
|
||||||
@@ -9,3 +12,20 @@ pub fn get_random_test_id() -> String {
|
|||||||
id.push_str("_nextsync");
|
id.push_str("_nextsync");
|
||||||
id.to_owned()
|
id.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn init_test() -> (ClientTest, ServerTest) {
|
||||||
|
|
||||||
|
let id = get_random_test_id();
|
||||||
|
let mut server = ServerTest::new(id.clone());
|
||||||
|
server.init();
|
||||||
|
let client = ClientTest::new(id).init();
|
||||||
|
(client, server)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn clean_test(client: ClientTest, server: &mut ServerTest) {
|
||||||
|
client.clean();
|
||||||
|
server.clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user