Only command and commandfinish events are logged.
The dirty, logsource, track and ignore configuration items
are not supported yet.
To indicate commands executed without Python, a (rust) prefix is added
in corresponding log messages.
( )
Alphare |
hg-reviewers |
Only command and commandfinish events are logged.
The dirty, logsource, track and ignore configuration items
are not supported yet.
To indicate commands executed without Python, a (rust) prefix is added
in corresponding log messages.
No Linters Available |
No Unit Test Coverage |
rust/rhg/src/blackbox.rs | ||
---|---|---|
61 | Right. This comment was obsolete anyway so I’ve removed it. (date-format is part of this commit and there’s not quoting in config syntax outside of list-values, see previous commit.) | |
116 | Oh do you mean that (glob) expected output in .t files makes it hard to expect a literal ? character? https://docs.rs/users/0.11.0/users/fn.get_current_username.html says “This function to return None if the current user does not exist, which could happen if they were deleted after the program started running.” so I don’t expect this ??? fallback to show up a lot in practice and I think it’s not worth testing it. |
Path | Packages | |||
---|---|---|---|---|
M | rust/Cargo.lock (35 lines) | |||
M | rust/hg-core/src/dirstate/parsers.rs (8 lines) | |||
M | rust/hg-core/src/repo.rs (9 lines) | |||
M | rust/hg-core/src/utils.rs (29 lines) | |||
M | rust/rhg/Cargo.toml (2 lines) | |||
A | M | rust/rhg/src/blackbox.rs (161 lines) | ||
M | rust/rhg/src/main.rs (48 lines) | |||
M | tests/test-rhg.t (12 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
9dec02ee2bc6 | 1558b07cc6b3 | Simon Sapin | Feb 16 2021, 7:08 AM |
Status | Author | Revision | |
---|---|---|---|
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin | ||
Closed | SimonSapin |
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
[[package]] | [[package]] | ||||
name = "cfg-if" | name = "cfg-if" | ||||
version = "1.0.0" | version = "1.0.0" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
[[package]] | [[package]] | ||||
name = "chrono" | |||||
version = "0.4.19" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
dependencies = [ | |||||
"libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
"num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
"num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
"time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
] | |||||
[[package]] | |||||
name = "clap" | name = "clap" | ||||
version = "2.33.3" | version = "2.33.3" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
dependencies = [ | dependencies = [ | ||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", | "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", | "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
version = "0.4.3" | version = "0.4.3" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
dependencies = [ | dependencies = [ | ||||
"adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", | "adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
] | ] | ||||
[[package]] | [[package]] | ||||
name = "num-integer" | |||||
version = "0.1.44" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
dependencies = [ | |||||
"autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
"num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
] | |||||
[[package]] | |||||
name = "num-traits" | name = "num-traits" | ||||
version = "0.2.14" | version = "0.2.14" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
dependencies = [ | dependencies = [ | ||||
"autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
] | ] | ||||
[[package]] | [[package]] | ||||
dependencies = [ | dependencies = [ | ||||
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", | "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
] | ] | ||||
[[package]] | [[package]] | ||||
name = "rhg" | name = "rhg" | ||||
version = "0.1.0" | version = "0.1.0" | ||||
dependencies = [ | dependencies = [ | ||||
"chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
"clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", | "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)", | "derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | "format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"hg-core 0.1.0", | "hg-core 0.1.0", | ||||
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", | "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"micro-timer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | "micro-timer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
"users 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
] | ] | ||||
[[package]] | [[package]] | ||||
name = "rust-crypto" | name = "rust-crypto" | ||||
version = "0.2.36" | version = "0.2.36" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
dependencies = [ | dependencies = [ | ||||
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", | "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
[[package]] | [[package]] | ||||
name = "unicode-xid" | name = "unicode-xid" | ||||
version = "0.2.1" | version = "0.2.1" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
[[package]] | [[package]] | ||||
name = "users" | |||||
version = "0.11.0" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
dependencies = [ | |||||
"libc 0.2.81 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", | |||||
] | |||||
[[package]] | |||||
name = "vcpkg" | name = "vcpkg" | ||||
version = "0.2.11" | version = "0.2.11" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
[[package]] | [[package]] | ||||
name = "vec_map" | name = "vec_map" | ||||
version = "0.8.2" | version = "0.8.2" | ||||
source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
"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 bitmaps 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" | "checksum bitmaps 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" | ||||
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" | "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" | ||||
"checksum bytes-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3196ba300c7bc9282a4331e878496cb3e9603a898a8f1446601317163e16ca52" | "checksum bytes-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3196ba300c7bc9282a4331e878496cb3e9603a898a8f1446601317163e16ca52" | ||||
"checksum bytes-cast-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb" | "checksum bytes-cast-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb" | ||||
"checksum cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" | "checksum cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" | ||||
"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 cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | "checksum cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||||
"checksum chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" | |||||
"checksum clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" | "checksum clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)" = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" | ||||
"checksum const_fn 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826" | "checksum const_fn 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826" | ||||
"checksum cpython 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfaf3847ab963e40c4f6dd8d6be279bdf74007ae2413786a0dcbb28c52139a95" | "checksum cpython 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfaf3847ab963e40c4f6dd8d6be279bdf74007ae2413786a0dcbb28c52139a95" | ||||
"checksum crc32fast 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" | "checksum crc32fast 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" | ||||
"checksum crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" | "checksum crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" | ||||
"checksum crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" | "checksum crossbeam-channel 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" | ||||
"checksum crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" | "checksum crossbeam-deque 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" | ||||
"checksum crossbeam-epoch 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" | "checksum crossbeam-epoch 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" | ||||
"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" | "checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" | ||||
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" | "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" | ||||
"checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" | "checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" | ||||
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" | "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" | ||||
"checksum memoffset 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" | "checksum memoffset 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" | ||||
"checksum micro-timer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2620153e1d903d26b72b89f0e9c48d8c4756cba941c185461dddc234980c298c" | "checksum micro-timer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2620153e1d903d26b72b89f0e9c48d8c4756cba941c185461dddc234980c298c" | ||||
"checksum micro-timer-macros 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e28a3473e6abd6e9aab36aaeef32ad22ae0bd34e79f376643594c2b152ec1c5d" | "checksum micro-timer-macros 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e28a3473e6abd6e9aab36aaeef32ad22ae0bd34e79f376643594c2b152ec1c5d" | ||||
"checksum miniz_oxide 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" | "checksum miniz_oxide 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" | ||||
"checksum num-integer 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" | |||||
"checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" | "checksum num-traits 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" | ||||
"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" | "checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" | ||||
"checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" | "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" | ||||
"checksum pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" | "checksum pkg-config 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" | ||||
"checksum ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" | "checksum ppv-lite86 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" | ||||
"checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" | "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" | ||||
"checksum proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" | "checksum proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" | ||||
"checksum proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" | "checksum proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" | ||||
"checksum termcolor 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" | "checksum termcolor 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" | ||||
"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 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" | "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" | ||||
"checksum time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" | "checksum time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" | ||||
"checksum twox-hash 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" | "checksum twox-hash 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" | ||||
"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" | "checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" | ||||
"checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" | "checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" | ||||
"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" | "checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" | ||||
"checksum users 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" | |||||
"checksum vcpkg 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" | "checksum vcpkg 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" | ||||
"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" | "checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" | ||||
"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" | "checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" | ||||
"checksum wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" | "checksum wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" | ||||
"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.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | "checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | ||||
"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.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" | "checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" | ||||
"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" | ||||
"checksum zstd 0.5.3+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8" | "checksum zstd 0.5.3+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8" | ||||
"checksum zstd-safe 2.0.5+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055" | "checksum zstd-safe 2.0.5+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055" | ||||
"checksum zstd-sys 1.4.17+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b" | "checksum zstd-sys 1.4.17+zstd.1.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b" |
const MIN_ENTRY_SIZE: usize = 17; | const MIN_ENTRY_SIZE: usize = 17; | ||||
type ParseResult<'a> = ( | type ParseResult<'a> = ( | ||||
&'a DirstateParents, | &'a DirstateParents, | ||||
Vec<(&'a HgPath, DirstateEntry)>, | Vec<(&'a HgPath, DirstateEntry)>, | ||||
Vec<(&'a HgPath, &'a HgPath)>, | Vec<(&'a HgPath, &'a HgPath)>, | ||||
); | ); | ||||
pub fn parse_dirstate_parents( | |||||
contents: &[u8], | |||||
) -> Result<&DirstateParents, HgError> { | |||||
let (parents, _rest) = DirstateParents::from_bytes(contents) | |||||
.map_err(|_| HgError::corrupted("Too little data for dirstate."))?; | |||||
Ok(parents) | |||||
} | |||||
#[timed] | #[timed] | ||||
pub fn parse_dirstate(mut contents: &[u8]) -> Result<ParseResult, HgError> { | pub fn parse_dirstate(mut contents: &[u8]) -> Result<ParseResult, HgError> { | ||||
let mut copies = Vec::new(); | let mut copies = Vec::new(); | ||||
let mut entries = Vec::new(); | let mut entries = Vec::new(); | ||||
let (parents, rest) = DirstateParents::from_bytes(contents) | let (parents, rest) = DirstateParents::from_bytes(contents) | ||||
.map_err(|_| HgError::corrupted("Too little data for dirstate."))?; | .map_err(|_| HgError::corrupted("Too little data for dirstate."))?; | ||||
contents = rest; | contents = rest; |
// The undescore prefix silences the "never used" warning. Remove before | // The undescore prefix silences the "never used" warning. Remove before | ||||
// using. | // using. | ||||
pub fn _working_directory_vfs(&self) -> Vfs<'_> { | pub fn _working_directory_vfs(&self) -> Vfs<'_> { | ||||
Vfs { | Vfs { | ||||
base: &self.working_directory, | base: &self.working_directory, | ||||
} | } | ||||
} | } | ||||
pub fn dirstate_parents( | |||||
&self, | |||||
) -> Result<crate::dirstate::DirstateParents, HgError> { | |||||
let dirstate = self.hg_vfs().mmap_open("dirstate")?; | |||||
let parents = | |||||
crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?; | |||||
Ok(parents.clone()) | |||||
} | |||||
} | } | ||||
impl Vfs<'_> { | impl Vfs<'_> { | ||||
pub fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf { | pub fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf { | ||||
self.base.join(relative_path) | self.base.join(relative_path) | ||||
} | } | ||||
pub fn read( | pub fn read( |
pub(crate) fn strip_suffix<'a>(s: &'a str, suffix: &str) -> Option<&'a str> { | pub(crate) fn strip_suffix<'a>(s: &'a str, suffix: &str) -> Option<&'a str> { | ||||
if s.ends_with(suffix) { | if s.ends_with(suffix) { | ||||
Some(&s[..s.len() - suffix.len()]) | Some(&s[..s.len() - suffix.len()]) | ||||
} else { | } else { | ||||
None | None | ||||
} | } | ||||
} | } | ||||
#[cfg(unix)] | |||||
pub fn shell_quote(value: &[u8]) -> Vec<u8> { | |||||
// TODO: Use the `matches!` macro when we require Rust 1.42+ | |||||
if value.iter().all(|&byte| match byte { | |||||
b'a'..=b'z' | |||||
| b'A'..=b'Z' | |||||
| b'0'..=b'9' | |||||
| b'.' | |||||
| b'_' | |||||
| b'/' | |||||
| b'+' | |||||
| b'-' => true, | |||||
_ => false, | |||||
}) { | |||||
value.to_owned() | |||||
} else { | |||||
let mut quoted = Vec::with_capacity(value.len() + 2); | |||||
quoted.push(b'\''); | |||||
for &byte in value { | |||||
if byte == b'\'' { | |||||
quoted.push(b'\\'); | |||||
} | |||||
quoted.push(byte); | |||||
} | |||||
quoted.push(b'\''); | |||||
quoted | |||||
} | |||||
} | |||||
pub fn current_dir() -> Result<std::path::PathBuf, HgError> { | pub fn current_dir() -> Result<std::path::PathBuf, HgError> { | ||||
std::env::current_dir().map_err(|error| HgError::IoError { | std::env::current_dir().map_err(|error| HgError::IoError { | ||||
error, | error, | ||||
context: IoErrorContext::CurrentDir, | context: IoErrorContext::CurrentDir, | ||||
}) | }) | ||||
} | } | ||||
pub fn current_exe() -> Result<std::path::PathBuf, HgError> { | pub fn current_exe() -> Result<std::path::PathBuf, HgError> { | ||||
std::env::current_exe().map_err(|error| HgError::IoError { | std::env::current_exe().map_err(|error| HgError::IoError { | ||||
error, | error, | ||||
context: IoErrorContext::CurrentExe, | context: IoErrorContext::CurrentExe, | ||||
}) | }) | ||||
} | } |
[package] | [package] | ||||
name = "rhg" | name = "rhg" | ||||
version = "0.1.0" | version = "0.1.0" | ||||
authors = [ | authors = [ | ||||
"Antoine Cezar <antoine.cezar@octobus.net>", | "Antoine Cezar <antoine.cezar@octobus.net>", | ||||
"Raphaël Gomès <raphael.gomes@octobus.net>", | "Raphaël Gomès <raphael.gomes@octobus.net>", | ||||
] | ] | ||||
edition = "2018" | edition = "2018" | ||||
[dependencies] | [dependencies] | ||||
hg-core = { path = "../hg-core"} | hg-core = { path = "../hg-core"} | ||||
chrono = "0.4.19" | |||||
clap = "2.33.1" | clap = "2.33.1" | ||||
derive_more = "0.99" | derive_more = "0.99" | ||||
log = "0.4.11" | log = "0.4.11" | ||||
micro-timer = "0.3.1" | micro-timer = "0.3.1" | ||||
env_logger = "0.7.1" | env_logger = "0.7.1" | ||||
format-bytes = "0.2.0" | format-bytes = "0.2.0" | ||||
users = "0.11.0" |
//! Logging for repository events, including commands run in the repository. | |||||
use crate::CliInvocation; | |||||
use format_bytes::format_bytes; | |||||
use hg::errors::HgError; | |||||
use hg::repo::Repo; | |||||
use hg::utils::{files::get_bytes_from_os_str, shell_quote}; | |||||
const ONE_MEBIBYTE: u64 = 1 << 20; | |||||
// TODO: somehow keep defaults in sync with `configitem` in `hgext/blackbox.py` | |||||
const DEFAULT_MAX_SIZE: u64 = ONE_MEBIBYTE; | |||||
const DEFAULT_MAX_FILES: u32 = 7; | |||||
// Python does not support %.3f, only %f | |||||
const DEFAULT_DATE_FORMAT: &str = "%Y/%m/%d %H:%M:%S%.3f"; | |||||
type DateTime = chrono::DateTime<chrono::Local>; | |||||
pub struct ProcessStartTime { | |||||
/// For measuring duration | |||||
monotonic_clock: std::time::Instant, | |||||
/// For formatting with year, month, day, etc. | |||||
calendar_based: DateTime, | |||||
} | |||||
impl ProcessStartTime { | |||||
pub fn now() -> Self { | |||||
Self { | |||||
monotonic_clock: std::time::Instant::now(), | |||||
calendar_based: chrono::Local::now(), | |||||
} | |||||
} | |||||
} | |||||
pub struct Blackbox<'a> { | |||||
process_start_time: &'a ProcessStartTime, | |||||
/// Do nothing if this is `None` | |||||
configured: Option<ConfiguredBlackbox<'a>>, | |||||
} | |||||
struct ConfiguredBlackbox<'a> { | |||||
repo: &'a Repo, | |||||
max_size: u64, | |||||
max_files: u32, | |||||
date_format: &'a str, | |||||
} | |||||
impl<'a> Blackbox<'a> { | |||||
pub fn new( | |||||
invocation: &'a CliInvocation<'a>, | |||||
process_start_time: &'a ProcessStartTime, | |||||
) -> Result<Self, HgError> { | |||||
let configured = if let Ok(repo) = invocation.repo { | |||||
let config = invocation.config(); | |||||
if config.get(b"extensions", b"blackbox").is_none() { | |||||
// The extension is not enabled | |||||
None | |||||
} else { | |||||
Some(ConfiguredBlackbox { | |||||
repo, | |||||
Alphare: You've got a NBSP here ;) | |||||
Right. This comment was obsolete anyway so I’ve removed it. (date-format is part of this commit and there’s not quoting in config syntax outside of list-values, see previous commit.) SimonSapin: Right. This comment was obsolete anyway so I’ve removed it. (`date-format` is part of this… | |||||
max_size: config | |||||
.get_byte_size(b"blackbox", b"maxsize")? | |||||
.unwrap_or(DEFAULT_MAX_SIZE), | |||||
max_files: config | |||||
.get_u32(b"blackbox", b"maxfiles")? | |||||
.unwrap_or(DEFAULT_MAX_FILES), | |||||
date_format: config | |||||
.get_str(b"blackbox", b"date-format")? | |||||
.unwrap_or(DEFAULT_DATE_FORMAT), | |||||
}) | |||||
} | |||||
} else { | |||||
// Without a local repository there’s no `.hg/blackbox.log` to | |||||
// write to. | |||||
None | |||||
}; | |||||
Ok(Self { | |||||
process_start_time, | |||||
configured, | |||||
}) | |||||
} | |||||
pub fn log_command_start(&self) { | |||||
if let Some(configured) = &self.configured { | |||||
let message = format_bytes!(b"(rust) {}", format_cli_args()); | |||||
configured.log(&self.process_start_time.calendar_based, &message); | |||||
} | |||||
} | |||||
pub fn log_command_end(&self, exit_code: i32) { | |||||
if let Some(configured) = &self.configured { | |||||
let now = chrono::Local::now(); | |||||
let duration = self | |||||
.process_start_time | |||||
.monotonic_clock | |||||
.elapsed() | |||||
.as_secs_f64(); | |||||
let message = format_bytes!( | |||||
b"(rust) {} exited {} after {} seconds", | |||||
format_cli_args(), | |||||
exit_code, | |||||
format_bytes::Utf8(format_args!("{:.03}", duration)) | |||||
); | |||||
configured.log(&now, &message); | |||||
} | |||||
} | |||||
} | |||||
impl ConfiguredBlackbox<'_> { | |||||
fn log(&self, date_time: &DateTime, message: &[u8]) { | |||||
let date = format_bytes::Utf8(date_time.format(self.date_format)); | |||||
let user = users::get_current_username().map(get_bytes_from_os_str); | |||||
let user = user.as_deref().unwrap_or(b"???"); | |||||
let rev = format_bytes::Utf8(match self.repo.dirstate_parents() { | |||||
Ok(parents) if parents.p2 == hg::revlog::node::NULL_NODE => { | |||||
Problem with this is that it conflicts with .t output. Or was it intentional? Alphare: Problem with this is that it conflicts with `.t` output. Or was it intentional? | |||||
Oh do you mean that (glob) expected output in .t files makes it hard to expect a literal ? character? https://docs.rs/users/0.11.0/users/fn.get_current_username.html says “This function to return None if the current user does not exist, which could happen if they were deleted after the program started running.” so I don’t expect this ??? fallback to show up a lot in practice and I think it’s not worth testing it. SimonSapin: Oh do you mean that `(glob)` expected output in `.t` files makes it hard to expect a literal `? | |||||
I don't think it's worth testing either, I just meant I would have chosen a different set of characters just to avoid confusion. It's not a dealbreaker. Alphare: I don't think it's worth testing either, I just meant I would have chosen a different set of… | |||||
format!("{:x}", parents.p1) | |||||
} | |||||
Ok(parents) => format!("{:x}+{:x}", parents.p1, parents.p2), | |||||
Err(_dirstate_corruption_error) => { | |||||
// TODO: log a non-fatal warning to stderr | |||||
"???".to_owned() | |||||
} | |||||
}); | |||||
let pid = std::process::id(); | |||||
let line = format_bytes!( | |||||
b"{} {} @{} ({})> {}\n", | |||||
date, | |||||
user, | |||||
rev, | |||||
pid, | |||||
message | |||||
); | |||||
let result = | |||||
hg::logging::LogFile::new(self.repo.hg_vfs(), "blackbox.log") | |||||
.max_size(Some(self.max_size)) | |||||
.max_files(self.max_files) | |||||
.write(&line); | |||||
match result { | |||||
Ok(()) => {} | |||||
Err(_io_error) => { | |||||
// TODO: log a non-fatal warning to stderr | |||||
} | |||||
} | |||||
} | |||||
} | |||||
fn format_cli_args() -> Vec<u8> { | |||||
let mut args = std::env::args_os(); | |||||
let _ = args.next(); // Skip the first (or zeroth) arg, the name of the `rhg` executable | |||||
let mut args = args.map(|arg| shell_quote(&get_bytes_from_os_str(arg))); | |||||
let mut formatted = Vec::new(); | |||||
if let Some(arg) = args.next() { | |||||
formatted.extend(arg) | |||||
} | |||||
for arg in args { | |||||
formatted.push(b' '); | |||||
formatted.extend(arg) | |||||
} | |||||
formatted | |||||
} |
extern crate log; | extern crate log; | ||||
use crate::ui::Ui; | use crate::ui::Ui; | ||||
use clap::App; | use clap::App; | ||||
use clap::AppSettings; | use clap::AppSettings; | ||||
use clap::Arg; | use clap::Arg; | ||||
use clap::ArgMatches; | use clap::ArgMatches; | ||||
use format_bytes::format_bytes; | use format_bytes::format_bytes; | ||||
use hg::config::Config; | use hg::config::Config; | ||||
use hg::repo::{Repo, RepoError}; | use hg::repo::{Repo, RepoError}; | ||||
use std::path::{Path, PathBuf}; | use std::path::{Path, PathBuf}; | ||||
mod blackbox; | |||||
mod error; | mod error; | ||||
mod exitcode; | mod exitcode; | ||||
mod ui; | mod ui; | ||||
use error::CommandError; | use error::CommandError; | ||||
fn add_global_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> { | fn add_global_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> { | ||||
app.arg( | app.arg( | ||||
Arg::with_name("repository") | Arg::with_name("repository") | ||||
.takes_value(true) | .takes_value(true) | ||||
// Ok: `--config section.key1=val --config section.key2=val2` | // Ok: `--config section.key1=val --config section.key2=val2` | ||||
.multiple(true) | .multiple(true) | ||||
// Not ok: `--config section.key1=val section.key2=val2` | // Not ok: `--config section.key1=val section.key2=val2` | ||||
.number_of_values(1), | .number_of_values(1), | ||||
) | ) | ||||
} | } | ||||
fn main_with_result(ui: &ui::Ui) -> Result<(), CommandError> { | fn main_with_result( | ||||
ui: &ui::Ui, | |||||
process_start_time: &blackbox::ProcessStartTime, | |||||
) -> Result<(), CommandError> { | |||||
env_logger::init(); | env_logger::init(); | ||||
let app = App::new("rhg") | let app = App::new("rhg") | ||||
.setting(AppSettings::AllowInvalidUtf8) | .setting(AppSettings::AllowInvalidUtf8) | ||||
.setting(AppSettings::SubcommandRequired) | .setting(AppSettings::SubcommandRequired) | ||||
.setting(AppSettings::VersionlessSubcommands) | .setting(AppSettings::VersionlessSubcommands) | ||||
.version("0.0.1"); | .version("0.0.1"); | ||||
let app = add_global_args(app); | let app = add_global_args(app); | ||||
let app = add_subcommand_args(app); | let app = add_subcommand_args(app); | ||||
Ok(repo) => Ok(repo), | Ok(repo) => Ok(repo), | ||||
Err(RepoError::NotFound { at }) if repo_path.is_none() => { | Err(RepoError::NotFound { at }) if repo_path.is_none() => { | ||||
// Not finding a repo is not fatal yet, if `-R` was not given | // Not finding a repo is not fatal yet, if `-R` was not given | ||||
Err(NoRepoInCwdError { cwd: at }) | Err(NoRepoInCwdError { cwd: at }) | ||||
} | } | ||||
Err(error) => return Err(error.into()), | Err(error) => return Err(error.into()), | ||||
}; | }; | ||||
run(&CliInvocation { | let invocation = CliInvocation { | ||||
ui, | ui, | ||||
subcommand_args, | subcommand_args, | ||||
non_repo_config, | non_repo_config, | ||||
repo: repo.as_ref(), | repo: repo.as_ref(), | ||||
}) | }; | ||||
let blackbox = blackbox::Blackbox::new(&invocation, process_start_time)?; | |||||
blackbox.log_command_start(); | |||||
let result = run(&invocation); | |||||
blackbox.log_command_end(exit_code(&result)); | |||||
result | |||||
} | } | ||||
fn main() { | fn main() { | ||||
// Run this first, before we find out if the blackbox extension is even | |||||
// enabled, in order to include everything in-between in the duration | |||||
// measurements. Reading config files can be slow if they’re on NFS. | |||||
let process_start_time = blackbox::ProcessStartTime::now(); | |||||
let ui = ui::Ui::new(); | let ui = ui::Ui::new(); | ||||
let exit_code = match main_with_result(&ui) { | let result = main_with_result(&ui, &process_start_time); | ||||
if let Err(CommandError::Abort { message }) = &result { | |||||
if !message.is_empty() { | |||||
// Ignore errors when writing to stderr, we’re already exiting | |||||
// with failure code so there’s not much more we can do. | |||||
let _ = ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); | |||||
} | |||||
} | |||||
std::process::exit(exit_code(&result)) | |||||
} | |||||
fn exit_code(result: &Result<(), CommandError>) -> i32 { | |||||
match result { | |||||
Ok(()) => exitcode::OK, | Ok(()) => exitcode::OK, | ||||
Err(CommandError::Abort { .. }) => exitcode::ABORT, | |||||
// Exit with a specific code and no error message to let a potential | // Exit with a specific code and no error message to let a potential | ||||
// wrapper script fallback to Python-based Mercurial. | // wrapper script fallback to Python-based Mercurial. | ||||
Err(CommandError::Unimplemented) => exitcode::UNIMPLEMENTED, | Err(CommandError::Unimplemented) => exitcode::UNIMPLEMENTED, | ||||
Err(CommandError::Abort { message }) => { | |||||
if !message.is_empty() { | |||||
// Ignore errors when writing to stderr, we’re already exiting | |||||
// with failure code so there’s not much more we can do. | |||||
let _ = | |||||
ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); | |||||
} | |||||
exitcode::ABORT | |||||
} | } | ||||
}; | |||||
std::process::exit(exit_code) | |||||
} | } | ||||
macro_rules! subcommands { | macro_rules! subcommands { | ||||
($( $command: ident )+) => { | ($( $command: ident )+) => { | ||||
mod commands { | mod commands { | ||||
$( | $( | ||||
pub mod $command; | pub mod $command; | ||||
)+ | )+ |
And check that basic rhg commands work with sharing | And check that basic rhg commands work with sharing | ||||
$ cd repo5 | $ cd repo5 | ||||
$ rhg files | $ rhg files | ||||
a | a | ||||
$ rhg cat -r 0 a | $ rhg cat -r 0 a | ||||
a | a | ||||
The blackbox extension is supported | |||||
$ echo "[extensions]" >> $HGRCPATH | |||||
$ echo "blackbox =" >> $HGRCPATH | |||||
$ echo "[blackbox]" >> $HGRCPATH | |||||
$ echo "maxsize = 1" >> $HGRCPATH | |||||
$ rhg files > /dev/null | |||||
$ cat .hg/blackbox.log | |||||
????/??/?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files exited 0 after 0.??? seconds (glob) | |||||
$ cat .hg/blackbox.log.1 | |||||
????/??/?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files (glob) | |||||
You've got a NBSP here ;)