Auto update (w/ cli)

This commit is contained in:
veeso 2021-09-10 22:22:15 +02:00
parent 8bb05406c8
commit 06a67de14f
21 changed files with 1093 additions and 215 deletions

View File

@ -28,13 +28,20 @@ Released on ??
> 🍁 Autumn update 🍇
- **Aws S3**
- Added support for the aws-s3 protocol
- Operate on your bucket directly from the file explorer
- You can also save your buckets as bookmarks
- Added support for the aws-s3 protocol.
- Operate on your bucket directly from the file explorer.
- You can also save your buckets as bookmarks.
- Aws s3 reads credentials directly from your credentials file at `$HOME/.aws/credentials` or from environment. Read more in the user manual.
- **Auto update** ⬇️
- Possibility to update termscp directly via GUI or CLI.
- Install update via CLI running `(sudo) termscp --update`.
- Install update via GUI from auth form: when the "new version message" is displayed press `<CTRL+R>`, then enter `YES` in the radio input asking whether to install the update.
- Dependencies:
- Added `rust-s3 0.27-rc4`
- Added `self_update 0.27.0`
- Updated `argh` to `0.1.6`
- Updated `tui-realm-stdlib` to `0.6.2`
- Removed `ureq`
## 0.6.1

606
Cargo.lock generated
View File

@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aes"
version = "0.6.0"
@ -263,12 +269,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "chunked_transfer"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
[[package]]
name = "cipher"
version = "0.2.5"
@ -287,6 +287,21 @@ dependencies = [
"bitflags",
]
[[package]]
name = "console"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"regex",
"terminal_size",
"unicode-width",
"winapi",
]
[[package]]
name = "content_inspector"
version = "0.2.4"
@ -346,6 +361,15 @@ dependencies = [
"debug-helper",
]
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "crossterm"
version = "0.20.0"
@ -477,6 +501,45 @@ version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding_rs"
version = "0.8.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "filetime"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98"
dependencies = [
"cfg-if 1.0.0",
"libc",
"redox_syscall 0.2.10",
"winapi",
]
[[package]]
name = "flate2"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80edafed416a46fb378521624fab1cfa2eb514784fd8921adbe8a8d8321da811"
dependencies = [
"cfg-if 1.0.0",
"crc32fast",
"libc",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -508,12 +571,55 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "futures-channel"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
[[package]]
name = "futures-io"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
[[package]]
name = "futures-sink"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
[[package]]
name = "futures-task"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
[[package]]
name = "futures-util"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
dependencies = [
"autocfg",
"futures-core",
"futures-io",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "generic-array"
version = "0.14.4"
@ -546,6 +652,25 @@ dependencies = [
"wasi 0.10.0+wasi-snapshot-preview1",
]
[[package]]
name = "h2"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
@ -555,6 +680,12 @@ dependencies = [
"ahash",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.3.3"
@ -564,6 +695,15 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
@ -612,6 +752,66 @@ dependencies = [
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5"
dependencies = [
"bytes",
"http",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
[[package]]
name = "httpdate"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
[[package]]
name = "hyper"
version = "0.14.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13f67199e765030fa08fe0bd581af683f0d5bc04ea09c2b1102012c5fb90e7fd"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "idna"
version = "0.2.3"
@ -623,6 +823,28 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "indexmap"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [
"autocfg",
"hashbrown 0.11.2",
]
[[package]]
name = "indicatif"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
dependencies = [
"console",
"lazy_static",
"number_prefix",
"regex",
]
[[package]]
name = "instant"
version = "0.1.10"
@ -632,6 +854,12 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "ipnet"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
[[package]]
name = "itoa"
version = "0.4.8"
@ -787,6 +1015,12 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "mime"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "minidom"
version = "0.13.0"
@ -796,6 +1030,16 @@ dependencies = [
"quick-xml",
]
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]]
name = "mio"
version = "0.7.13"
@ -921,6 +1165,22 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "number_prefix"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
[[package]]
name = "once_cell"
version = "1.8.0"
@ -983,7 +1243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c672c7ad9ec066e428c00eb917124a06f08db19e2584de982cc34b1f4c12485"
dependencies = [
"dlv-list",
"hashbrown",
"hashbrown 0.9.1",
]
[[package]]
@ -1062,12 +1322,27 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]]
name = "pin-project-lite"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.19"
@ -1252,18 +1527,38 @@ dependencies = [
]
[[package]]
name = "ring"
version = "0.16.20"
name = "reqwest"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22"
dependencies = [
"cc",
"libc",
"once_cell",
"spin",
"untrusted",
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"hyper-tls",
"ipnet",
"js-sys",
"lazy_static",
"log",
"mime",
"native-tls",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winapi",
"winreg",
]
[[package]]
@ -1316,19 +1611,6 @@ dependencies = [
"url",
]
[[package]]
name = "rustls"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
dependencies = [
"base64",
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "ryu"
version = "1.0.5"
@ -1351,16 +1633,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sct"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "secret-service"
version = "1.1.3"
@ -1423,6 +1695,45 @@ dependencies = [
"libc",
]
[[package]]
name = "self_update"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb85f1802f7b987237b8525c0fde86ea86f31c957c1875467c727d5b921179c"
dependencies = [
"either",
"flate2",
"hyper",
"indicatif",
"log",
"quick-xml",
"regex",
"reqwest",
"semver",
"serde_json",
"tar",
"tempfile",
"zip",
]
[[package]]
name = "semver"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
dependencies = [
"pest",
]
[[package]]
name = "serde"
version = "1.0.130"
@ -1466,6 +1777,18 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.9.8"
@ -1520,6 +1843,12 @@ dependencies = [
"termcolor",
]
[[package]]
name = "slab"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
[[package]]
name = "smallvec"
version = "1.6.1"
@ -1533,10 +1862,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
[[package]]
name = "spin"
version = "0.5.2"
name = "socket2"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "ssh2"
@ -1580,6 +1913,17 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "tar"
version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c"
dependencies = [
"filetime",
"libc",
"xattr",
]
[[package]]
name = "tempfile"
version = "3.2.0"
@ -1603,6 +1947,16 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "termscp"
version = "0.7.0"
@ -1627,6 +1981,7 @@ dependencies = [
"regex",
"rpassword",
"rust-s3",
"self_update",
"serde",
"simplelog",
"ssh2",
@ -1637,7 +1992,6 @@ dependencies = [
"toml",
"tui-realm-stdlib",
"tuirealm",
"ureq",
"users",
"whoami",
"wildmatch 2.1.0",
@ -1718,7 +2072,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4efe6fc2395938c8155973d7be49fe8d03a843726e285e100a8a383cc0154ce"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"num_cpus",
"pin-project-lite",
"winapi",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
@ -1732,6 +2102,20 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]
[[package]]
name = "toml"
version = "0.5.8"
@ -1741,6 +2125,38 @@ dependencies = [
"serde",
]
[[package]]
name = "tower-service"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
[[package]]
name = "tracing"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
dependencies = [
"cfg-if 1.0.0",
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8"
dependencies = [
"lazy_static",
]
[[package]]
name = "try-lock"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "tui"
version = "0.16.0"
@ -1781,6 +2197,12 @@ version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "unicode-bidi"
version = "0.3.6"
@ -1823,30 +2245,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "ureq"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3131cd6cb18488da91da1d10ed31e966f453c06b65bf010d35638456976a3fd7"
dependencies = [
"base64",
"chunked_transfer",
"log",
"once_cell",
"rustls",
"serde",
"serde_json",
"url",
"webpki",
"webpki-roots",
]
[[package]]
name = "url"
version = "2.2.2"
@ -1881,6 +2279,16 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "want"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
dependencies = [
"log",
"try-lock",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
@ -1900,6 +2308,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e68338db6becec24d3c7977b5bf8a48be992c934b5d07177e3931f5dc9b076c"
dependencies = [
"cfg-if 1.0.0",
"serde",
"serde_json",
"wasm-bindgen-macro",
]
@ -1918,6 +2328,18 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.77"
@ -1957,25 +2379,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki"
version = "0.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "webpki-roots"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
dependencies = [
"webpki",
]
[[package]]
name = "which"
version = "4.2.2"
@ -2040,8 +2443,39 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "winreg"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
dependencies = [
"winapi",
]
[[package]]
name = "xattr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
dependencies = [
"libc",
]
[[package]]
name = "xml-rs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
[[package]]
name = "zip"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815"
dependencies = [
"byteorder",
"crc32fast",
"flate2",
"thiserror",
"time",
]

View File

@ -45,6 +45,7 @@ rand = "0.8.4"
regex = "1.5.4"
rpassword = "5.0.1"
rust-s3 = { version = "0.27.0-rc4", default-features = false, features = [ "sync-native-tls", "sync" ] }
self_update = { version = "0.27.0", features = [ "archive-tar", "archive-zip", "compression-flate2", "compression-zip-deflate" ] }
serde = { version = "^1.0.0", features = [ "derive" ] }
simplelog = "0.10.0"
ssh2 = "0.9.0"
@ -55,7 +56,6 @@ thiserror = "^1.0.0"
toml = "0.5.8"
tui-realm-stdlib = "0.6.2"
tuirealm = "0.6.0"
ureq = { version = "2.1.0", features = [ "json" ] }
whoami = "1.1.1"
wildmatch = "2.0.0"

View File

@ -24,7 +24,7 @@
## About termscp 🖥
Termscp is a feature rich terminal file transfer and explorer, with support for SCP/SFTP/FTP/S3. So basically is a terminal utility with an TUI to connect to a remote server to retrieve and upload files and to interact with the local file system. It is **Linux**, **MacOS**, **BSD** and **Windows** compatible and supports SFTP, SCP, FTP, FTPS and S3.
Termscp is a feature rich terminal file transfer and explorer, with support for SCP/SFTP/FTP/S3. So basically is a terminal utility with an TUI to connect to a remote server to retrieve and upload files and to interact with the local file system. It is **Linux**, **MacOS**, **FreeBSD** and **Windows** compatible and supports SFTP, SCP, FTP, FTPS and S3.
![Explorer](assets/images/explorer.gif)
@ -33,10 +33,10 @@ Termscp is a feature rich terminal file transfer and explorer, with support for
## Features 🎁
- 📁 Different communication protocols
- SFTP
- SCP
- FTP and FTPS
- Aws S3
- **SFTP**
- **SCP**
- **FTP** and **FTPS**
- **Aws S3**
- 🖥 Explore and operate on the remote and on the local machine file system with a handy UI
- Create, remove, rename, search, view and edit files
- ⭐ Connect to your favourite hosts through built-in bookmarks and recent connections
@ -71,6 +71,8 @@ while if you're a Windows user, you can install termscp with [Chocolatey](https:
For more information or other platforms, please visit [veeso.github.io](https://veeso.github.io/termscp/#get-started) to view all installation methods.
⚠️ If you're looking on how to update termscp just run termscp from CLI with: `(sudo) termscp --update` ⚠️
### Requirements ❗
- **Linux** users:
@ -157,6 +159,7 @@ termscp is powered by these aweseome projects:
- [open-rs](https://github.com/Byron/open-rs)
- [rpassword](https://github.com/conradkleinespel/rpassword)
- [rust-s3](https://github.com/durch/rust-s3)
- [self_update](https://github.com/jaemk/self_update)
- [ssh2-rs](https://github.com/alexcrichton/ssh2-rs)
- [suppaftp](https://github.com/veeso/suppaftp)
- [textwrap](https://github.com/mgeisler/textwrap)

View File

@ -1,7 +1,7 @@
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: deploy.sh <version>"
echo "Usage: docker.sh <version>"
exit 1
fi
@ -19,8 +19,15 @@ cd x86_64_debian9/
docker build --tag termscp-${VERSION}-x86_64_debian9 .
cd -
mkdir -p ${PKGS_DIR}/deb/
mkdir -p ${PKGS_DIR}/x86_64-unknown-linux-gnu/
CONTAINER_NAME=$(docker create termscp-${VERSION}-x86_64_debian9 termscp-${VERSION}-x86_64_debian9)
docker cp ${CONTAINER_NAME}:/usr/src/termscp/target/debian/termscp_${VERSION}_amd64.deb ${PKGS_DIR}/deb/
docker cp ${CONTAINER_NAME}:/usr/src/termscp/target/release/termscp ${PKGS_DIR}/x86_64-unknown-linux-gnu/
# Make tar.gz
cd ${PKGS_DIR}/x84_64-unknown-linux-gnu/
tar cvzf termscp-v${VERSION}-x86_64-unknown-linux-gnu.tar.gz termscp
rm termscp
cd -
# Build x86_64_centos7
cd x86_64_centos7/
docker build --tag termscp-${VERSION}-x86_64_centos7 .

30
dist/build/freebsd.sh vendored Executable file
View File

@ -0,0 +1,30 @@
#!/bin/sh
if [ -z "$1" ]; then
echo "Usage: freebsd.sh <version>"
exit 1
fi
VERSION=$1
set -e # Don't fail
# Go to root dir
cd ../../
# Check if in correct directory
if [ ! -f Cargo.toml ]; then
echo "Please start freebsd.sh from dist/build/ directory"
exit 1
fi
# Build release
cargo build --release && cargo strip
# Make pkg
cd target/release/
PKG="termscp-v${VERSION}-x86_64-unknown-freebsd.tar.gz"
tar czf $PKG termscp
sha256sum $PKG
mkdir -p ../../dist/pkgs/freebsd/
mv $PKG ../../dist/pkgs/freebsd/$PKG
exit $?

30
dist/build/macos.sh vendored Executable file
View File

@ -0,0 +1,30 @@
#!/bin/sh
if [ -z "$1" ]; then
echo "Usage: macos.sh <version>"
exit 1
fi
VERSION=$1
set -e # Don't fail
# Go to root dir
cd ../../
# Check if in correct directory
if [ ! -f Cargo.toml ]; then
echo "Please start macos.sh from dist/build/ directory"
exit 1
fi
# Build release
cargo build --release && cargo strip
# Make pkg
cd target/release/
PKG="termscp-v${VERSION}-x86_64-apple-darwin.tar.gz"
tar czf $PKG termscp
sha256sum $PKG
mkdir -p ../../dist/pkgs/macos/
mv $PKG ../../dist/pkgs/macos/$PKG
exit $?

20
dist/build/windows.ps1 vendored Executable file
View File

@ -0,0 +1,20 @@
$ErrorActionPreference = 'Stop';
if ($args.Count -eq 0) {
Write-Output "Usage: windows.ps1 <version>"
exit 1
}
$version = $args[0]
# Go to root directory
Set-Location ..\..\
# Build
cargo build --release
# Make zip
$zipName = "termscp-v$version-x86_64-pc-windows-msvc.zip"
Set-Location .\target\release\
Compress-Archive termscp $zipName
# Get checksum
checksum.exe -t sha256 $zipName
Move-Item $zipName .\..\..\dist\pkgs\windows\$zipName

View File

@ -4,16 +4,21 @@ WORKDIR /usr/src/
# Add toolchains
RUN rustup target add x86_64-unknown-linux-gnu
# Install dependencies
RUN apt update && apt install -y rpm
RUN apt update && apt install -y \
git \
gcc \
pkg-config \
libssl-dev \
libssh2-1-dev \
libdbus-1-dev \
curl
# Clone repository
RUN git clone https://github.com/veeso/termscp.git
# Set workdir to termscp
WORKDIR /usr/src/termscp/
# Install cargo RPM/Deb
RUN cargo install cargo-deb cargo-rpm cargo-strip
RUN cargo install cargo-strip
# Build for x86_64
RUN cargo build --release --target x86_64-unknown-linux-gnu && cargo strip
# Build pkgs
RUN cargo deb && cargo rpm init && cargo rpm build
CMD ["sh"]

View File

@ -37,6 +37,7 @@ termscp can be started with the following options:
- `-c, --config` Open termscp starting from the configuration page
- `-q, --quiet` Disable logging
- `-t, --theme <path>` Import specified theme
- `-u, --update` Update termscp to latest version
- `-v, --version` Print version info
- `-h, --help` Print help page

View File

@ -53,13 +53,13 @@ extern crate path_slash;
extern crate rand;
extern crate regex;
extern crate s3;
extern crate self_update;
extern crate ssh2;
extern crate suppaftp;
extern crate tempfile;
extern crate textwrap;
extern crate tui_realm_stdlib;
extern crate tuirealm;
extern crate ureq;
#[cfg(target_family = "unix")]
extern crate users;
extern crate whoami;

View File

@ -62,6 +62,7 @@ use system::logging;
enum Task {
Activity(NextActivity),
ImportTheme(PathBuf),
InstallUpdate,
}
#[derive(FromArgs)]
@ -84,6 +85,12 @@ struct Args {
quiet: bool,
#[argh(option, short = 't', description = "import specified theme")]
theme: Option<String>,
#[argh(
switch,
short = 'u',
description = "update termscp to the latest version"
)]
update: bool,
#[argh(
option,
short = 'T',
@ -177,6 +184,9 @@ fn parse_args(args: Args) -> Result<RunOpts, String> {
if let Some(theme) = args.theme {
run_opts.task = Task::ImportTheme(PathBuf::from(theme));
}
if args.update {
run_opts.task = Task::InstallUpdate;
}
// @! Ordinary mode
// Remote argument
if let Some(remote) = args.positional.get(0) {
@ -256,6 +266,16 @@ fn run(mut run_opts: RunOpts) -> i32 {
1
}
},
Task::InstallUpdate => match support::install_update() {
Ok(msg) => {
println!("{}", msg);
0
}
Err(err) => {
eprintln!("Could not install update: {}", err);
1
}
},
Task::Activity(activity) => {
// Get working directory
let wrkdir: PathBuf = match env::current_dir() {

View File

@ -26,7 +26,11 @@
* SOFTWARE.
*/
// mod
use crate::system::{environment, theme_provider::ThemeProvider};
use crate::system::{
auto_update::{Update, UpdateStatus},
environment,
theme_provider::ThemeProvider,
};
use std::fs;
use std::path::{Path, PathBuf};
@ -51,6 +55,23 @@ pub fn import_theme(p: &Path) -> Result<(), String> {
.map_err(|e| format!("Could not import theme: {}", e))
}
/// ### install_update
///
/// Install latest version of termscp if an update is available
pub fn install_update() -> Result<String, String> {
match Update::default()
.show_progress(true)
.ask_confirm(true)
.upgrade()
{
Ok(UpdateStatus::AlreadyUptodate) => Ok("termscp is already up to date".to_string()),
Ok(UpdateStatus::UpdateInstalled(v)) => {
Ok(format!("termscp has been updated to version {}", v))
}
Err(err) => Err(err.to_string()),
}
}
/// ### get_config_dir
///
/// Get configuration directory

233
src/system/auto_update.rs Normal file
View File

@ -0,0 +1,233 @@
//! ## Auto update
//!
//! Automatic update module. This module is used to upgrade the current version of termscp to the latest available on Github
/**
* MIT License
*
* termscp - Copyright (c) 2021 Christian Visintin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
use crate::utils::parser::parse_semver;
pub use self_update::errors::Error as UpdateError;
use self_update::{
backends::github::Update as GithubUpdater, cargo_crate_version, update::Release as UpdRelease,
Status,
};
/// ### UpdateStatus
///
/// The status of the update in case of success
#[derive(Debug, Eq, PartialEq)]
pub enum UpdateStatus {
/// Termscp is already up to date
AlreadyUptodate,
/// The update has been correctly installed
UpdateInstalled(String),
}
/// ## Release
///
/// Info related to a github release
#[derive(Debug)]
pub struct Release {
pub version: String,
pub body: String,
}
/// ## Update
///
/// The update structure defines the options used to install the update.
/// Once you're fine with the options, just call the `upgrade()` method to upgrade termscp.
#[derive(Debug)]
pub struct Update {
ask_confirm: bool,
progress: bool,
}
impl Update {
/// ### show_progress
///
/// Set whether to show or not the progress bar
pub fn show_progress(mut self, opt: bool) -> Self {
self.progress = opt;
self
}
/// ### ask_confirm
///
/// Set whether to ask for confirm when updating
pub fn ask_confirm(mut self, opt: bool) -> Self {
self.ask_confirm = opt;
self
}
pub fn upgrade(self) -> Result<UpdateStatus, UpdateError> {
info!("Updating termscp...");
GithubUpdater::configure()
// Set default options
.repo_owner("veeso")
.repo_name("termscp")
.bin_name("termscp")
.current_version(cargo_crate_version!())
.no_confirm(!self.ask_confirm)
.show_download_progress(self.progress)
.show_output(self.progress)
.build()?
.update()
.map(UpdateStatus::from)
}
/// ### is_new_version_available
///
/// Returns whether a new version of termscp is available
/// In case of success returns Ok(Option<Release>), where the Option is Some(new_version);
/// otherwise if no version is available, return None
/// In case of error returns Error with the error description
pub fn is_new_version_available() -> Result<Option<Release>, UpdateError> {
info!("Checking whether a new version is available...");
GithubUpdater::configure()
// Set default options
.repo_owner("veeso")
.repo_name("termscp")
.bin_name("termscp")
.current_version(cargo_crate_version!())
.no_confirm(true)
.show_download_progress(false)
.show_output(false)
.build()?
.get_latest_release()
.map(Release::from)
.map(Self::check_version)
}
/// ### check_version
///
/// In case received version is newer than current one, version as Some is returned; otherwise None
fn check_version(r: Release) -> Option<Release> {
match parse_semver(r.version.as_str()) {
Some(new_version) => {
// Check if version is different
debug!(
"New version: {}; current version: {}",
new_version,
cargo_crate_version!()
);
if new_version.as_str() > "cargo_crate_version!()" {
Some(r) // New version is available
} else {
None // No new version
}
}
None => None,
}
}
}
impl Default for Update {
fn default() -> Self {
Self {
progress: false,
ask_confirm: false,
}
}
}
impl From<Status> for UpdateStatus {
fn from(s: Status) -> Self {
match s {
Status::UpToDate(_) => Self::AlreadyUptodate,
Status::Updated(v) => Self::UpdateInstalled(v),
}
}
}
impl From<UpdRelease> for Release {
fn from(r: UpdRelease) -> Self {
Self {
version: r.version,
body: r.body.unwrap_or_default(),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn auto_update_default() {
let upd: Update = Update::default();
assert_eq!(upd.ask_confirm, false);
assert_eq!(upd.progress, false);
let upd = upd.ask_confirm(true).show_progress(true);
assert_eq!(upd.ask_confirm, true);
assert_eq!(upd.progress, true);
}
#[test]
fn auto_update() {
// Wno version
assert_eq!(
Update::default()
.show_progress(true)
.upgrade()
.ok()
.unwrap(),
UpdateStatus::AlreadyUptodate,
);
}
#[test]
fn check_for_updates() {
println!("{:?}", Update::is_new_version_available());
assert!(Update::is_new_version_available().is_ok());
}
#[test]
fn update_status() {
assert_eq!(
UpdateStatus::from(Status::Updated(String::from("0.6.0"))),
UpdateStatus::UpdateInstalled(String::from("0.6.0"))
);
assert_eq!(
UpdateStatus::from(Status::UpToDate(String::from("0.6.0"))),
UpdateStatus::AlreadyUptodate
);
}
#[test]
fn release() {
let release: UpdRelease = UpdRelease {
name: String::from("termscp 0.7.0"),
version: String::from("0.7.0"),
date: String::from("2021-09-12T00:00:00Z"),
body: Some(String::from("fixed everything")),
assets: vec![],
};
let release: Release = Release::from(release);
assert_eq!(release.body.as_str(), "fixed everything");
assert_eq!(release.version.as_str(), "0.7.0");
}
}

View File

@ -26,6 +26,7 @@
* SOFTWARE.
*/
// modules
pub mod auto_update;
pub mod bookmarks_client;
pub mod config_client;
pub mod environment;

View File

@ -27,6 +27,9 @@
*/
use super::{AuthActivity, FileTransferParams, FileTransferProtocol};
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams, ProtocolParams};
use crate::system::auto_update::{Update, UpdateStatus};
use tuirealm::tui::style::Color;
impl AuthActivity {
/// ### protocol_opt_to_enum
@ -151,4 +154,31 @@ impl AuthActivity {
entry_directory: None,
})
}
// -- update install
/// ### install_update
///
/// Install latest termscp version via GUI
pub(super) fn install_update(&mut self) {
// Umount release notes
self.umount_release_notes();
// Mount wait box
self.mount_wait("Installing update. Please wait…");
// Install update
let result = Update::default().show_progress(false).upgrade();
// Umount wait
self.umount_wait();
// Show outcome
match result {
Ok(UpdateStatus::AlreadyUptodate) => {
self.mount_info("termscp is already up to date!", Color::Cyan)
}
Ok(UpdateStatus::UpdateInstalled(ver)) => self.mount_info(
format!("termscp has been updated to version {}!", ver),
Color::Green,
),
Err(err) => self.mount_error(format!("Could not install update: {}", err)),
}
}
}

View File

@ -35,8 +35,8 @@ mod view;
use super::{Activity, Context, ExitReason};
use crate::config::themes::Theme;
use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
use crate::system::auto_update::{Release, Update as TermscpUpdate};
use crate::system::bookmarks_client::BookmarksClient;
use crate::utils::git;
// Includes
use crossterm::event::Event;
@ -51,6 +51,8 @@ const COMPONENT_TEXT_NEW_VERSION_NOTES: &str = "TEXTAREA_NEW_VERSION";
const COMPONENT_TEXT_FOOTER: &str = "TEXT_FOOTER";
const COMPONENT_TEXT_HELP: &str = "TEXT_HELP";
const COMPONENT_TEXT_ERROR: &str = "TEXT_ERROR";
const COMPONENT_TEXT_INFO: &str = "TEXT_INFO";
const COMPONENT_TEXT_WAIT: &str = "TEXT_WAIT";
const COMPONENT_TEXT_SIZE_ERR: &str = "TEXT_SIZE_ERR";
const COMPONENT_INPUT_ADDR: &str = "INPUT_ADDRESS";
const COMPONENT_INPUT_PORT: &str = "INPUT_PORT";
@ -65,6 +67,7 @@ const COMPONENT_RADIO_QUIT: &str = "RADIO_QUIT";
const COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK: &str = "RADIO_DELETE_BOOKMARK";
const COMPONENT_RADIO_BOOKMARK_DEL_RECENT: &str = "RADIO_DELETE_RECENT";
const COMPONENT_RADIO_BOOKMARK_SAVE_PWD: &str = "RADIO_SAVE_PASSWORD";
const COMPONENT_RADIO_INSTALL_UPDATE: &str = "RADIO_INSTALL_UPDATE";
const COMPONENT_BOOKMARKS_LIST: &str = "BOOKMARKS_LIST";
const COMPONENT_RECENTS_LIST: &str = "RECENTS_LIST";
@ -119,12 +122,12 @@ impl AuthActivity {
if ctx.config().get_check_for_updates() {
debug!("Check for updates is enabled");
// Send request
match git::check_for_updates(env!("CARGO_PKG_VERSION")) {
Ok(Some(git::GithubTag { tag_name, body })) => {
match TermscpUpdate::is_new_version_available() {
Ok(Some(Release { version, body })) => {
// If some, store version and release notes
info!("Latest version is: {}", tag_name);
info!("Latest version is: {}", version);
ctx.store_mut()
.set_string(STORE_KEY_LATEST_VERSION, tag_name);
.set_string(STORE_KEY_LATEST_VERSION, version);
ctx.store_mut().set_string(STORE_KEY_RELEASE_NOTES, body);
}
Ok(None) => {

View File

@ -32,8 +32,9 @@ use super::{
COMPONENT_INPUT_S3_BUCKET, COMPONENT_INPUT_S3_PROFILE, COMPONENT_INPUT_S3_REGION,
COMPONENT_INPUT_USERNAME, COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK,
COMPONENT_RADIO_BOOKMARK_DEL_RECENT, COMPONENT_RADIO_BOOKMARK_SAVE_PWD,
COMPONENT_RADIO_PROTOCOL, COMPONENT_RADIO_QUIT, COMPONENT_RECENTS_LIST, COMPONENT_TEXT_ERROR,
COMPONENT_TEXT_HELP, COMPONENT_TEXT_NEW_VERSION_NOTES, COMPONENT_TEXT_SIZE_ERR,
COMPONENT_RADIO_INSTALL_UPDATE, COMPONENT_RADIO_PROTOCOL, COMPONENT_RADIO_QUIT,
COMPONENT_RECENTS_LIST, COMPONENT_TEXT_ERROR, COMPONENT_TEXT_HELP, COMPONENT_TEXT_INFO,
COMPONENT_TEXT_NEW_VERSION_NOTES, COMPONENT_TEXT_SIZE_ERR, COMPONENT_TEXT_WAIT,
};
use crate::ui::keymap::*;
use tui_realm_stdlib::InputPropsBuilder;
@ -252,15 +253,44 @@ impl Update for AuthActivity {
self.umount_error();
None
}
(COMPONENT_TEXT_ERROR, _) => None,
(COMPONENT_TEXT_NEW_VERSION_NOTES, key)
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
{
// -- Text info
(COMPONENT_TEXT_INFO, key) if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER => {
// Umount text info
self.umount_info();
None
}
(COMPONENT_TEXT_ERROR, _) | (COMPONENT_TEXT_INFO, _) => None,
// -- Text wait
(COMPONENT_TEXT_WAIT, _) => None,
// -- Release notes
(COMPONENT_TEXT_NEW_VERSION_NOTES, key) if key == &MSG_KEY_ESC => {
// Umount release notes
self.umount_release_notes();
None
}
(COMPONENT_TEXT_NEW_VERSION_NOTES, key) if key == &MSG_KEY_TAB => {
// Focus to radio update
self.view.active(COMPONENT_RADIO_INSTALL_UPDATE);
None
}
(COMPONENT_TEXT_NEW_VERSION_NOTES, _) => None,
// -- Install update radio
(COMPONENT_RADIO_INSTALL_UPDATE, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => {
// Install update
self.install_update();
None
}
(COMPONENT_RADIO_INSTALL_UPDATE, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
// Umount
self.umount_release_notes();
None
}
(COMPONENT_RADIO_INSTALL_UPDATE, key) if key == &MSG_KEY_TAB => {
// Focus to changelog
self.view.active(COMPONENT_TEXT_NEW_VERSION_NOTES);
None
}
(COMPONENT_RADIO_INSTALL_UPDATE, _) => None,
// Help
(_, key) if key == &MSG_KEY_CTRL_H => {
// Show help

View File

@ -209,7 +209,7 @@ impl AuthActivity {
.with_spans(vec![
TextSpan::from("termscp "),
TextSpan::new(version.as_str()).underlined().bold(),
TextSpan::from(" is NOW available! Get it from <https://veeso.github.io/termscp/>; view release notes with <CTRL+R>"),
TextSpan::from(" is NOW available! Install update and view release notes with <CTRL+R>"),
])
.build(),
)),
@ -360,6 +360,22 @@ impl AuthActivity {
self.view.render(super::COMPONENT_TEXT_ERROR, f, popup);
}
}
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_INFO) {
if props.visible {
let popup = draw_area_in(f.size(), 50, 10);
f.render_widget(Clear, popup);
// make popup
self.view.render(super::COMPONENT_TEXT_INFO, f, popup);
}
}
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_WAIT) {
if props.visible {
let popup = draw_area_in(f.size(), 50, 10);
f.render_widget(Clear, popup);
// make popup
self.view.render(super::COMPONENT_TEXT_WAIT, f, popup);
}
}
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_SIZE_ERR) {
if props.visible {
let popup = draw_area_in(f.size(), 80, 20);
@ -403,10 +419,22 @@ impl AuthActivity {
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_NEW_VERSION_NOTES) {
if props.visible {
// make popup
let popup = draw_area_in(f.size(), 90, 90);
let popup = draw_area_in(f.size(), 90, 85);
f.render_widget(Clear, popup);
let popup_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Percentage(90), // Notes
Constraint::Length(3), // Install radio
]
.as_ref(),
)
.split(popup);
self.view
.render(super::COMPONENT_TEXT_NEW_VERSION_NOTES, f, popup);
.render(super::COMPONENT_TEXT_NEW_VERSION_NOTES, f, popup_chunks[0]);
self.view
.render(super::COMPONENT_RADIO_INSTALL_UPDATE, f, popup_chunks[1]);
}
}
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_HELP) {
@ -515,7 +543,7 @@ impl AuthActivity {
/// ### mount_error
///
/// Mount error box
pub(super) fn mount_error(&mut self, text: &str) {
pub(super) fn mount_error<S: AsRef<str>>(&mut self, text: S) {
// Mount
let err_color = self.theme().misc_error_dialog;
self.view.mount(
@ -526,7 +554,7 @@ impl AuthActivity {
.with_borders(Borders::ALL, BorderType::Thick, err_color)
.bold()
.with_text_alignment(Alignment::Center)
.with_texts(vec![TextSpan::from(text)])
.with_texts(vec![TextSpan::from(text.as_ref().to_string())])
.build(),
)),
);
@ -541,6 +569,61 @@ impl AuthActivity {
self.view.umount(super::COMPONENT_TEXT_ERROR);
}
/// ### mount_info
///
/// Mount info box
pub(super) fn mount_info<S: AsRef<str>>(&mut self, text: S, color: Color) {
// Mount
self.view.mount(
super::COMPONENT_TEXT_INFO,
Box::new(Paragraph::new(
ParagraphPropsBuilder::default()
.with_borders(Borders::ALL, BorderType::Thick, color)
.bold()
.with_text_alignment(Alignment::Center)
.with_texts(vec![TextSpan::from(text.as_ref().to_string())])
.with_foreground(color)
.build(),
)),
);
// Give focus to error
self.view.active(super::COMPONENT_TEXT_INFO);
}
/// ### umount_info
///
/// Umount info message
pub(super) fn umount_info(&mut self) {
self.view.umount(super::COMPONENT_TEXT_INFO);
}
/// ### mount_error
///
/// Mount wait box
pub(super) fn mount_wait(&mut self, text: &str) {
// Mount
self.view.mount(
super::COMPONENT_TEXT_WAIT,
Box::new(Paragraph::new(
ParagraphPropsBuilder::default()
.with_borders(Borders::ALL, BorderType::Thick, Color::Reset)
.bold()
.with_text_alignment(Alignment::Center)
.with_texts(vec![TextSpan::from(text)])
.build(),
)),
);
// Give focus to error
self.view.active(super::COMPONENT_TEXT_WAIT);
}
/// ### umount_wait
///
/// Umount wait message
pub(super) fn umount_wait(&mut self) {
self.view.umount(super::COMPONENT_TEXT_WAIT);
}
/// ### mount_size_err
///
/// Mount size error
@ -785,7 +868,22 @@ impl AuthActivity {
.build(),
)),
);
self.view.active(super::COMPONENT_TEXT_NEW_VERSION_NOTES);
// Mount install popup
self.view.mount(
super::COMPONENT_RADIO_INSTALL_UPDATE,
Box::new(Radio::new(
RadioPropsBuilder::default()
.with_color(Color::LightYellow)
.with_inverted_color(Color::Black)
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow)
.with_title("Install new version?", Alignment::Left)
.with_options(&["Yes", "No"])
.with_value(0)
.rewind(true)
.build(),
)),
);
self.view.active(super::COMPONENT_RADIO_INSTALL_UPDATE);
}
}
}
@ -795,6 +893,7 @@ impl AuthActivity {
/// Umount release notes text area
pub(super) fn umount_release_notes(&mut self) {
self.view.umount(super::COMPONENT_TEXT_NEW_VERSION_NOTES);
self.view.umount(super::COMPONENT_RADIO_INSTALL_UPDATE);
}
/// ### get_protocol

View File

@ -1,95 +0,0 @@
//! ## git
//!
//! `git` is the module which provides utilities to interact through the GIT API and to perform some stuff at git level
/**
* MIT License
*
* termscp - Copyright (c) 2021 Christian Visintin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// Locals
use super::parser::parse_semver;
// Others
use serde::Deserialize;
#[derive(Debug, Deserialize)]
/// ## GithubTag
///
/// Info related to a github tag
pub struct GithubTag {
pub tag_name: String,
pub body: String,
}
/// ### check_for_updates
///
/// Check if there is a new version available for termscp.
/// This is performed through the Github API
/// In case of success returns Ok(Option<GithubTag>), where the Option is Some(new_version); otherwise if no version is available, return None
/// In case of error returns Error with the error description
pub fn check_for_updates(current_version: &str) -> Result<Option<GithubTag>, String> {
// Send request
let github_tag: Result<GithubTag, String> =
match ureq::get("https://api.github.com/repos/veeso/termscp/releases/latest").call() {
Ok(response) => response.into_json::<GithubTag>().map_err(|x| x.to_string()),
Err(err) => Err(err.to_string()),
};
// Check version
match github_tag {
Err(err) => Err(err),
Ok(tag) => {
// Parse version
match parse_semver(tag.tag_name.as_str()) {
Some(new_version) => {
// Check if version is different
if new_version.as_str() > current_version {
Ok(Some(tag)) // New version is available
} else {
Ok(None) // No new version
}
}
None => Err(String::from("Got bad response from Github")),
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg(not(all(
any(
target_os = "macos",
target_os = "freebsd",
target_os = "netbsd",
target_os = "netbsd"
),
feature = "github-actions"
)))]
fn test_utils_git_check_for_updates() {
assert!(check_for_updates("100.0.0").ok().unwrap().is_none());
assert!(check_for_updates("0.0.1").ok().unwrap().is_some());
}
}

View File

@ -29,7 +29,6 @@
pub mod crypto;
pub mod file;
pub mod fmt;
pub mod git;
pub mod parser;
pub mod path;
pub mod random;