Add colored output
Colored output can be controlled on the command line with `--use-color auto|always|never`. The default is `auto`, which enables color if `imdl` detects that it is printing to a terminal. Color can be disabled entirely by setting the `NO_COLOR` environment variable. type: added
This commit is contained in:
parent
b334fa49b2
commit
d1f8f24d8e
5
.github/workflows/rust.yaml
vendored
5
.github/workflows/rust.yaml
vendored
|
@ -29,7 +29,10 @@ jobs:
|
||||||
run: cargo build --verbose
|
run: cargo build --verbose
|
||||||
- name: Test
|
- name: Test
|
||||||
run: cargo test --verbose
|
run: cargo test --verbose
|
||||||
- name: Lint
|
- name: Clippy
|
||||||
run: cargo clippy
|
run: cargo clippy
|
||||||
- name: Format
|
- name: Format
|
||||||
run: cargo fmt -- --check
|
run: cargo fmt -- --check
|
||||||
|
- name: Lint
|
||||||
|
if: matrix.os != 'windows-latest'
|
||||||
|
run: "! grep --color -REn 'FIXME|TODO|XXX' src"
|
||||||
|
|
66
Cargo.lock
generated
66
Cargo.lock
generated
|
@ -16,6 +16,14 @@ dependencies = [
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -63,6 +71,18 @@ name = "doc-comment"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
|
@ -89,6 +109,14 @@ dependencies = [
|
||||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -103,6 +131,9 @@ dependencies = [
|
||||||
name = "imdl"
|
name = "imdl"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"md5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"md5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -128,6 +159,14 @@ name = "libc"
|
||||||
version = "0.2.66"
|
version = "0.2.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matches"
|
name = "matches"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
|
@ -185,6 +224,11 @@ dependencies = [
|
||||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-error"
|
||||||
|
version = "1.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -274,7 +318,7 @@ name = "same-file"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -413,6 +457,14 @@ dependencies = [
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
@ -482,7 +534,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -506,7 +558,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -520,18 +572,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
||||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||||
|
"checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||||
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
||||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||||
"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97"
|
"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97"
|
||||||
|
"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
||||||
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||||
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||||
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
|
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
|
||||||
|
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||||
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
|
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
|
||||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||||
|
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||||
"checksum md5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
"checksum md5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||||
|
@ -540,6 +596,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum proc-macro-error 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "53c98547ceaea14eeb26fcadf51dc70d01a2479a7839170eae133721105e4428"
|
"checksum proc-macro-error 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "53c98547ceaea14eeb26fcadf51dc70d01a2479a7839170eae133721105e4428"
|
||||||
"checksum proc-macro-error-attr 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c2bf5d493cf5d3e296beccfd61794e445e830dfc8070a9c248ad3ee071392c6c"
|
"checksum proc-macro-error-attr 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c2bf5d493cf5d3e296beccfd61794e445e830dfc8070a9c248ad3ee071392c6c"
|
||||||
"checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
|
"checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
|
||||||
|
"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||||
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
|
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
|
||||||
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
||||||
|
@ -567,6 +624,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
|
"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
|
||||||
"checksum syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd3937748a7eccff61ba5b90af1a20dbf610858923a9192ea0ecb0cb77db1d0"
|
"checksum syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd3937748a7eccff61ba5b90af1a20dbf610858923a9192ea0ecb0cb77db1d0"
|
||||||
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||||
|
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
|
||||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||||
|
@ -580,5 +638,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
27
Cargo.toml
27
Cargo.toml
|
@ -12,18 +12,21 @@ repository = "https://github.com/casey/intermodal"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2"
|
ansi_term = "0.12"
|
||||||
md5 = "0.7"
|
atty = "0.2"
|
||||||
regex = "1"
|
env_logger = "0.7"
|
||||||
serde_bencode = "0.2"
|
libc = "0.2"
|
||||||
serde_bytes = "0.11"
|
md5 = "0.7"
|
||||||
sha1 = "0.6"
|
regex = "1"
|
||||||
snafu = "0.6"
|
serde_bencode = "0.2"
|
||||||
structopt = "0.3"
|
serde_bytes = "0.11"
|
||||||
tempfile = "3"
|
sha1 = "0.6"
|
||||||
url = "2"
|
snafu = "0.6"
|
||||||
walkdir = "2"
|
static_assertions = "1"
|
||||||
static_assertions = "1.1.0"
|
structopt = "0.3"
|
||||||
|
tempfile = "3"
|
||||||
|
url = "2"
|
||||||
|
walkdir = "2"
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1"
|
version = "1"
|
||||||
|
|
35
README.md
35
README.md
|
@ -1 +1,36 @@
|
||||||
# intermodal: a 40' shipping container for the Internet
|
# intermodal: a 40' shipping container for the Internet
|
||||||
|
|
||||||
|
## Colored Output
|
||||||
|
|
||||||
|
Intermodal features colored help, error, and informational output. Colored
|
||||||
|
output is disabled if Intermodal detects that it is not printing to a TTY.
|
||||||
|
|
||||||
|
To disable colored output, set the `NO_COLOR` environment variable to any
|
||||||
|
valu or pass `--use-color never` on the command line.
|
||||||
|
|
||||||
|
To force colored output, pass `--use-color always` on the command line.
|
||||||
|
|
||||||
|
## Semantic Versioning and Unstable Features
|
||||||
|
|
||||||
|
Intermodal follows [semantic versioning](https://semver.org/).
|
||||||
|
|
||||||
|
In particular:
|
||||||
|
|
||||||
|
- v0.0.X: Breaking changes may be introduced at any time.
|
||||||
|
- v0.X.Y: Breaking changes may only be introduced with a minor version number
|
||||||
|
bump.
|
||||||
|
- vX.Y.Z: Breaking changes may only be introduced with a major version number
|
||||||
|
bump
|
||||||
|
|
||||||
|
To avoid premature stabilization and excessive version churn, unstable features
|
||||||
|
are unavailable unless the `--unstable` / `-u` flag is passed. Unstable
|
||||||
|
features may be changed or removed at any time.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ imdl torrent stats --input tmp
|
||||||
|
error: Feature `torrent stats subcommand` cannot be used without passing the `--unstable` flag
|
||||||
|
$ imdl --unstable torrent stats tmp
|
||||||
|
Torrents processed: 0
|
||||||
|
Read failed: 0
|
||||||
|
Decode failed: 0
|
||||||
|
```
|
||||||
|
|
|
@ -3,7 +3,7 @@ pub(crate) use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cmp::{Ordering, Reverse},
|
cmp::{Ordering, Reverse},
|
||||||
collections::{BTreeMap, HashMap},
|
collections::{BTreeMap, HashMap},
|
||||||
convert::TryInto,
|
convert::{Infallible, TryInto},
|
||||||
env,
|
env,
|
||||||
ffi::{OsStr, OsString},
|
ffi::{OsStr, OsString},
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
|
@ -11,7 +11,8 @@ pub(crate) use std::{
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process, str,
|
process,
|
||||||
|
str::{self, FromStr},
|
||||||
time::{SystemTime, SystemTimeError},
|
time::{SystemTime, SystemTimeError},
|
||||||
usize,
|
usize,
|
||||||
};
|
};
|
||||||
|
@ -28,7 +29,7 @@ pub(crate) use url::Url;
|
||||||
pub(crate) use walkdir::WalkDir;
|
pub(crate) use walkdir::WalkDir;
|
||||||
|
|
||||||
// modules
|
// modules
|
||||||
pub(crate) use crate::{bencode, consts, error, torrent};
|
pub(crate) use crate::{bencode, consts, error, torrent, use_color};
|
||||||
|
|
||||||
// traits
|
// traits
|
||||||
pub(crate) use crate::{
|
pub(crate) use crate::{
|
||||||
|
@ -38,7 +39,8 @@ pub(crate) use crate::{
|
||||||
// structs and enums
|
// structs and enums
|
||||||
pub(crate) use crate::{
|
pub(crate) use crate::{
|
||||||
env::Env, error::Error, file_info::FileInfo, hasher::Hasher, info::Info, metainfo::Metainfo,
|
env::Env, error::Error, file_info::FileInfo, hasher::Hasher, info::Info, metainfo::Metainfo,
|
||||||
mode::Mode, opt::Opt, subcommand::Subcommand, torrent::Torrent,
|
mode::Mode, opt::Opt, style::Style, subcommand::Subcommand, torrent::Torrent,
|
||||||
|
use_color::UseColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
// test modules
|
// test modules
|
||||||
|
|
57
src/env.rs
57
src/env.rs
|
@ -4,7 +4,8 @@ pub(crate) struct Env {
|
||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
dir: Box<dyn AsRef<Path>>,
|
dir: Box<dyn AsRef<Path>>,
|
||||||
pub(crate) err: Box<dyn Write>,
|
pub(crate) err: Box<dyn Write>,
|
||||||
pub(crate) _out: Box<dyn Write>,
|
pub(crate) out: Box<dyn Write>,
|
||||||
|
err_style: Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Env {
|
impl Env {
|
||||||
|
@ -14,14 +15,42 @@ impl Env {
|
||||||
Err(error) => panic!("Failed to get current directory: {}", error),
|
Err(error) => panic!("Failed to get current directory: {}", error),
|
||||||
};
|
};
|
||||||
|
|
||||||
Self::new(dir, io::stdout(), io::stderr(), env::args())
|
let err_style = if env::var_os("NO_COLOR").is_some()
|
||||||
|
|| env::var_os("TERM").as_deref() == Some(OsStr::new("dumb"))
|
||||||
|
|| !atty::is(atty::Stream::Stderr)
|
||||||
|
{
|
||||||
|
Style::inactive()
|
||||||
|
} else {
|
||||||
|
Style::active()
|
||||||
|
};
|
||||||
|
|
||||||
|
Self::new(dir, io::stdout(), io::stderr(), err_style, env::args())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn run(&mut self) -> Result<(), Error> {
|
pub(crate) fn run(&mut self) -> Result<(), Error> {
|
||||||
Opt::from_iter_safe(&self.args)?.run(self)
|
#[cfg(windows)]
|
||||||
|
ansi_term::enable_ansi_support().ok();
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
env_logger::Builder::from_env(
|
||||||
|
env_logger::Env::new()
|
||||||
|
.filter("JUST_LOG")
|
||||||
|
.write_style("JUST_LOG_STYLE"),
|
||||||
|
)
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let opt = Opt::from_iter_safe(&self.args)?;
|
||||||
|
|
||||||
|
match opt.use_color {
|
||||||
|
UseColor::Always => self.err_style = Style::active(),
|
||||||
|
UseColor::Auto => {}
|
||||||
|
UseColor::Never => self.err_style = Style::inactive(),
|
||||||
|
}
|
||||||
|
|
||||||
|
opt.run(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new<D, O, E, S, I>(dir: D, out: O, err: E, args: I) -> Self
|
pub(crate) fn new<D, O, E, S, I>(dir: D, out: O, err: E, err_style: Style, args: I) -> Self
|
||||||
where
|
where
|
||||||
D: AsRef<Path> + 'static,
|
D: AsRef<Path> + 'static,
|
||||||
O: Write + 'static,
|
O: Write + 'static,
|
||||||
|
@ -33,21 +62,35 @@ impl Env {
|
||||||
args: args.into_iter().map(Into::into).collect(),
|
args: args.into_iter().map(Into::into).collect(),
|
||||||
dir: Box::new(dir),
|
dir: Box::new(dir),
|
||||||
err: Box::new(err),
|
err: Box::new(err),
|
||||||
_out: Box::new(out),
|
out: Box::new(out),
|
||||||
|
err_style,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn status(&mut self) -> Result<(), i32> {
|
pub(crate) fn status(&mut self) -> Result<(), i32> {
|
||||||
use structopt::clap::ErrorKind;
|
use structopt::clap::ErrorKind;
|
||||||
|
|
||||||
if let Err(error) = self.run() {
|
if let Err(error) = self.run() {
|
||||||
if let Error::Clap { source } = error {
|
if let Error::Clap { source } = error {
|
||||||
write!(&mut self.err, "{}", source).ok();
|
if source.use_stderr() {
|
||||||
|
write!(&mut self.err, "{}", source).ok();
|
||||||
|
} else {
|
||||||
|
write!(&mut self.out, "{}", source).ok();
|
||||||
|
}
|
||||||
match source.kind {
|
match source.kind {
|
||||||
ErrorKind::VersionDisplayed | ErrorKind::HelpDisplayed => Ok(()),
|
ErrorKind::VersionDisplayed | ErrorKind::HelpDisplayed => Ok(()),
|
||||||
_ => Err(EXIT_FAILURE),
|
_ => Err(EXIT_FAILURE),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
write!(&mut self.err, "error: {}", error).ok();
|
writeln!(
|
||||||
|
&mut self.err,
|
||||||
|
"{}{}: {}{}",
|
||||||
|
self.err_style.error().paint("error"),
|
||||||
|
self.err_style.message().prefix(),
|
||||||
|
error,
|
||||||
|
self.err_style.message().suffix(),
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
Err(EXIT_FAILURE)
|
Err(EXIT_FAILURE)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
clippy::option_unwrap_used,
|
clippy::option_unwrap_used,
|
||||||
clippy::result_expect_used,
|
clippy::result_expect_used,
|
||||||
clippy::result_unwrap_used,
|
clippy::result_unwrap_used,
|
||||||
|
clippy::unreachable,
|
||||||
clippy::wildcard_enum_match_arm
|
clippy::wildcard_enum_match_arm
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
@ -53,8 +54,10 @@ mod mode;
|
||||||
mod opt;
|
mod opt;
|
||||||
mod path_ext;
|
mod path_ext;
|
||||||
mod reckoner;
|
mod reckoner;
|
||||||
|
mod style;
|
||||||
mod subcommand;
|
mod subcommand;
|
||||||
mod torrent;
|
mod torrent;
|
||||||
|
mod use_color;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
if let Err(code) = Env::main().status() {
|
if let Err(code) = Env::main().status() {
|
||||||
|
|
13
src/opt.rs
13
src/opt.rs
|
@ -1,18 +1,25 @@
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
|
|
||||||
use structopt::clap::AppSettings;
|
use structopt::clap::{AppSettings, ArgSettings};
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
#[structopt(
|
#[structopt(
|
||||||
about(consts::ABOUT),
|
about(consts::ABOUT),
|
||||||
version(consts::VERSION),
|
version(consts::VERSION),
|
||||||
author(consts::AUTHOR),
|
author(consts::AUTHOR),
|
||||||
setting(AppSettings::ColoredHelp),
|
global_setting(AppSettings::ColoredHelp),
|
||||||
setting(AppSettings::ColorAuto)
|
global_setting(AppSettings::ColorAuto)
|
||||||
)]
|
)]
|
||||||
pub(crate) struct Opt {
|
pub(crate) struct Opt {
|
||||||
#[structopt(long = "unstable", short = "u")]
|
#[structopt(long = "unstable", short = "u")]
|
||||||
unstable: bool,
|
unstable: bool,
|
||||||
|
#[structopt(
|
||||||
|
long = "color",
|
||||||
|
default_value = use_color::AUTO,
|
||||||
|
set = ArgSettings::CaseInsensitive,
|
||||||
|
possible_values = use_color::VALUES,
|
||||||
|
)]
|
||||||
|
pub(crate) use_color: UseColor,
|
||||||
#[structopt(subcommand)]
|
#[structopt(subcommand)]
|
||||||
subcommand: Subcommand,
|
subcommand: Subcommand,
|
||||||
}
|
}
|
||||||
|
|
30
src/style.rs
Normal file
30
src/style.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub(crate) struct Style {
|
||||||
|
active: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Style {
|
||||||
|
pub(crate) fn active() -> Self {
|
||||||
|
Self { active: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn inactive() -> Self {
|
||||||
|
Self { active: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn message(self) -> ansi_term::Style {
|
||||||
|
if self.active {
|
||||||
|
ansi_term::Style::new().bold()
|
||||||
|
} else {
|
||||||
|
ansi_term::Style::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn error(self) -> ansi_term::Style {
|
||||||
|
if self.active {
|
||||||
|
ansi_term::Style::new().fg(ansi_term::Color::Red).bold()
|
||||||
|
} else {
|
||||||
|
ansi_term::Style::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ impl TestEnv {
|
||||||
tempfile::tempdir().unwrap(),
|
tempfile::tempdir().unwrap(),
|
||||||
out.clone(),
|
out.clone(),
|
||||||
err.clone(),
|
err.clone(),
|
||||||
|
Style::inactive(),
|
||||||
iter::once(String::from("imdl")).chain(iter.into_iter().map(|item| item.into())),
|
iter::once(String::from("imdl")).chain(iter.into_iter().map(|item| item.into())),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -45,17 +45,19 @@ impl Stats {
|
||||||
let max = paths.iter().map(|(_, count)| *count).max().unwrap_or(0);
|
let max = paths.iter().map(|(_, count)| *count).max().unwrap_or(0);
|
||||||
let width = max.to_string().len();
|
let width = max.to_string().len();
|
||||||
|
|
||||||
errln!(env, "Keys:");
|
if !paths.is_empty() {
|
||||||
for (key, count) in &paths {
|
errln!(env, "Keys:");
|
||||||
if key.starts_with("info/files") {
|
for (key, count) in &paths {
|
||||||
continue;
|
if key.starts_with("info/files") {
|
||||||
}
|
continue;
|
||||||
errln!(env, "{:<width$} - {}", count, key, width = width);
|
}
|
||||||
}
|
|
||||||
for (key, count) in paths {
|
|
||||||
if key.starts_with("info/files") {
|
|
||||||
errln!(env, "{:<width$} - {}", count, key, width = width);
|
errln!(env, "{:<width$} - {}", count, key, width = width);
|
||||||
}
|
}
|
||||||
|
for (key, count) in paths {
|
||||||
|
if key.starts_with("info/files") {
|
||||||
|
errln!(env, "{:<width$} - {}", count, key, width = width);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !extractor.values.is_empty() {
|
if !extractor.values.is_empty() {
|
||||||
|
|
42
src/use_color.rs
Normal file
42
src/use_color.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
use crate::common::*;
|
||||||
|
|
||||||
|
pub(crate) const AUTO: &str = "auto";
|
||||||
|
pub(crate) const ALWAYS: &str = "always";
|
||||||
|
pub(crate) const NEVER: &str = "never";
|
||||||
|
|
||||||
|
pub(crate) const VALUES: &[&str] = &[AUTO, ALWAYS, NEVER];
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub(crate) enum UseColor {
|
||||||
|
Auto,
|
||||||
|
Always,
|
||||||
|
Never,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for UseColor {
|
||||||
|
type Err = Infallible;
|
||||||
|
|
||||||
|
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
||||||
|
match text.to_lowercase().as_str() {
|
||||||
|
AUTO => Ok(Self::Auto),
|
||||||
|
ALWAYS => Ok(Self::Always),
|
||||||
|
NEVER => Ok(Self::Never),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_str() {
|
||||||
|
assert_eq!(UseColor::Auto, AUTO.parse().unwrap());
|
||||||
|
assert_eq!(UseColor::Always, ALWAYS.parse().unwrap());
|
||||||
|
assert_eq!(UseColor::Never, NEVER.parse().unwrap());
|
||||||
|
assert_eq!(UseColor::Auto, AUTO.to_uppercase().parse().unwrap());
|
||||||
|
assert_eq!(UseColor::Always, ALWAYS.to_uppercase().parse().unwrap());
|
||||||
|
assert_eq!(UseColor::Never, NEVER.to_uppercase().parse().unwrap());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user