difftreelog
refactor remove shell-outs for ssh
in: trunk
15 files changed
Cargo.lockdiffbeforeafterboth318 packageslockfile v3
Might be heavy and slow!
abort-on-drop
0.2.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5dd6d700ad9af641490c1f7d67980d2de4d1433016e5b12f819448d3c832142adepends onused byaddr2line
0.21.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cbdepends onused byadler
1.0.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35feused byaead
0.5.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0depends onaes
0.8.3crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2depends onused byaes-gcm
0.10.3crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1used byage
0.9.2crates.io↘ 29↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6d55a4d912c80a92762ffd1c884065f3f9646467d22c95390e824a0ff7def472depends on- aes
0.8.3 - aes-gcm
0.10.3 - age-core
0.9.0 - base64
0.13.1 - bcrypt-pbkdf
0.9.0 - bech32
0.9.1 - cbc
0.1.2 - chacha20poly1305
0.10.1 - cipher
0.4.4 - cookie-factory
0.3.2 - ctr
0.9.2 - curve25519-dalek
3.2.0 - hkdf
0.12.3 - hmac
0.12.1 - i18n-embed
0.13.9 - i18n-embed-fl
0.6.7 - lazy_static
1.4.0 - nom
7.1.3 - num-traits
0.2.17 - pin-project
1.1.3 - rand
0.7.3 - rand
0.8.5 - rsa
0.7.2 - rust-embed
6.8.1 - scrypt
0.10.0 - sha2
0.10.8 - subtle
2.5.0 - x25519-dalek
1.1.1 - zeroize
1.6.0
- aes
age-core
0.9.0crates.io↘ 9↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume3d2e815ac879dc23c1139e720d21c6cd4d1276345c772587285d965a69b8f32depends onused byaho-corasick
1.1.1crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518abdepends onalejandra
3.0.0github.com/kamadorueda/alejandra↘ 3↖ 1sourcegit+https://github.com/kamadorueda/alejandra#e53c2c6c6c103dc3f848dbd9fbd93ee7c69c109fdepends onused byandroid_system_properties
0.1.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311depends onused byandroid-tzdata
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0used byansi-str
0.8.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1cf4578926a981ab0ca955dc023541d19de37112bc24c1a197bd806d3d86ad1ddepends onused byansitok
0.2.0crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum220044e6a1bb31ddee4e3db724d29767f352de47445a6cd75e1a173142136c83anstream
0.6.4crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44depends onused byanstyle
1.0.4crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87anstyle-parse
0.2.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140depends onused byanstyle-query
1.0.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494bdepends onused byanstyle-wincon
3.0.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628depends onused byanyhow
1.0.75crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6arc-swap
1.6.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6used byasync-trait
0.1.74crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9depends onused byatty
0.2.14crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8depends onused byautocfg
1.1.0crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fabacktrace
0.3.69crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837depends onused bybase64
0.13.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8used bybase64
0.21.5crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9used bybcrypt-pbkdf
0.9.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3806a8db60cf56efee531616a34a6aaa9a114d6da2add861b0fa4a188881b2c7depends onused bybitflags
1.3.2crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718abitflags
2.4.1crates.io↘ 1↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07depends onblock-buffer
0.10.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71depends onused byblock-padding
0.3.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93depends onused byblowfish
0.9.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7depends onused bybumpalo
3.14.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aecused bybytecount
0.6.7crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205used bybyteorder
1.4.3crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610bytes
1.5.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223used bycbc
0.1.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6depends onused bycbitset
0.2.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29b6ad25ae296159fb0da12b970b2fe179b234584d7cd294c891e2bbb284466bdepends onused bycc
1.0.83crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0depends oncfg-if
1.0.0crates.io↘ 0↖ 15sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbaf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fdchacha20
0.9.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818depends onused bychacha20poly1305
0.10.1crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35used bychrono
0.4.31crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38depends onused bycipher
0.4.4crates.io↘ 3↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3daddepends onclap
4.4.7crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17bdepends onclap_builder
4.4.7crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663depends onused byclap_derive
4.4.7crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442used byclap_lex
0.6.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1used bycolorchoice
1.0.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumacbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7used byconsole
0.15.7crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8used byconst-oid
0.9.5crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6fused bycookie-factory
0.3.2crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126bused bycore-foundation-sys
0.8.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efaused bycountme
2.0.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum328b822bdcba4d4e402be8d9adb6eebf269f969f8eadef977a553ff3c4fbcb58used bycpufeatures
0.2.9crates.io↘ 1↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1depends oncrypto-common
0.1.6crates.io↘ 3↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3ctr
0.9.2crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835depends onused bycurve25519-dalek
3.2.0crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61used bydashmap
5.5.3crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856used byder
0.6.1crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4dedepends onderanged
0.3.9crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3depends onused bydigest
0.9.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066depends onused bydigest
0.10.7crates.io↘ 4↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292dirs
5.0.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225depends onused bydirs-sys
0.4.1crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321cused bydisplaydoc
0.2.4crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175ddepends onused byeither
1.9.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07used byencode_unicode
0.3.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831fused byenv_logger
0.10.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0used byequivalent
1.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5used byerrno
0.3.5crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860depends onused byfastrand
2.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5used byfind-crate
0.6.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2depends onfleet
0.1.0workspace↘ 33↖ 0depends on- abort-on-drop
0.2.2 - age
0.9.2 - age-core
0.9.0 - anyhow
1.0.75 - async-trait
0.1.74 - base64
0.21.5 - chrono
0.4.31 - clap
4.4.7 - futures
0.3.29 - hostname
0.3.1 - human-repr
1.1.0 - indicatif
0.17.7 - itertools
0.11.0 - nixlike
0.1.0 - once_cell
1.18.0 - openssh
0.10.1 - owo-colors
3.5.0 - peg
0.8.2 - r2d2
0.8.10 - regex
1.10.2 - serde
1.0.190 - serde_json
1.0.107 - shlex
1.2.0 - tabled
0.14.0 - tempfile
3.8.1 - time
0.3.30 - tokio
1.33.0 - tokio-util
0.7.10 - tracing
0.1.37 - tracing-indicatif
0.3.5 - tracing-subscriber
0.3.17 - unindent
0.2.3 - z85
3.0.5
- abort-on-drop
fleet-install-secrets
0.1.0workspace↘ 10↖ 0fluent
0.16.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum61f69378194459db76abd2ce3952b790db103ceb003008d3d50d97c41ff847a7depends onfluent-bundle
0.15.2crates.io↘ 8↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffddepends onused byfluent-langneg
0.13.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94depends onfluent-syntax
0.11.0crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78depends onfnv
1.0.7crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1used byfutures
0.3.29crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumda0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335depends onused byfutures-channel
0.3.29crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacbdepends onfutures-core
0.3.29crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumeb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088cfutures-executor
0.3.29crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bcused byfutures-io
0.3.29crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaafutures-macro
0.3.29crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddbdepends onused byfutures-sink
0.3.29crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817futures-task
0.3.29crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumefd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2futures-util
0.3.29crates.io↘ 10↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104depends ongeneric-array
0.14.7crates.io↘ 2↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9adepends ongetrandom
0.1.16crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fceused bygetrandom
0.2.10crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbe4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427ghash
0.5.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40depends onused bygimli
0.28.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0used byhashbrown
0.9.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04used byhashbrown
0.14.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12used byheck
0.4.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8hermit-abi
0.1.19crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33depends onused byhermit-abi
0.3.3crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7hkdf
0.12.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437depends onused byhmac
0.12.1crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5edepends onhostname
0.3.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867depends onused byhuman-repr
1.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf58b778a5761513caf593693f8951c97a5b610841e754788400f32102eefdff1used byhumantime
2.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4used byi18n-config
0.4.6crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0c9ce3c48cbc21fd5b22b9331f32b5b51f6ad85d969b99e793427332e76e7640i18n-embed
0.13.9crates.io↘ 13↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum92a86226a7a16632de6723449ee5fe70bac5af718bc642ee9ca2f0f6e14fa1fadepends onused byi18n-embed-fl
0.6.7crates.io↘ 13↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd26a3d3569737dfaac7fc1c4078e6af07471c3060b8e570bcd83cdd5f4685395depends onused byi18n-embed-impl
0.8.2crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma2a4d5bff745c9a6e1459c490059281b353a4ab0a4e1e58b3eeeaef71f97d07bused byiana-time-zone
0.1.57crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613depends onused byiana-time-zone-haiku
0.1.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269fdepends onused byindexmap
2.0.2crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897depends onused byindicatif
0.17.7crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25depends oninout
0.1.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5depends onused byinstant
0.1.12crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2cdepends onused byintl_pluralrules
7.0.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972depends onused byintl-memoizer
0.5.1crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66fdepends onio_tee
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4b3f7cef34251886990511df1c61443aa928499d598a9473929ab5a90a527304used byis_ci
1.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fbused byis-terminal
0.4.9crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8bused byitertools
0.11.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57depends onused byitoa
1.0.9crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumaf150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38used byjs-sys
0.3.64crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935adepends onlazy_static
1.4.0crates.io↘ 1↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646depends onlibc
0.2.149crates.io↘ 0↖ 26sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29bused by- android_system_properties
0.1.5 - atty
0.2.14 - backtrace
0.3.69 - cc
1.0.83 - console
0.15.7 - cpufeatures
0.2.9 - dirs-sys
0.4.1 - errno
0.3.5 - getrandom
0.1.16 - getrandom
0.2.10 - hermit-abi
0.1.19 - hostname
0.3.1 - libmimalloc-sys
0.1.35 - libredox
0.0.1 - mio
0.8.8 - nix
0.27.1 - num_cpus
1.16.0 - openssh
0.10.1 - parking_lot_core
0.9.8 - rand
0.7.3 - rand
0.8.5 - rustix
0.38.21 - signal-hook-registry
1.4.1 - socket2
0.5.4 - tokio
1.33.0 - tokio-pipe
0.2.12
- android_system_properties
libm
0.2.7crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4libmimalloc-sys
0.1.35crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3979b5c37ece694f1f5e51e7ecc871fdb0f517ed04ee45f88d15d6d553cb9664depends onused bylibredox
0.0.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8used bylinked-hash-map
0.5.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770fused bylinux-raw-sys
0.4.10crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumda2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03fused bylock_api
0.4.10crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16depends onlog
0.4.20crates.io↘ 0↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8fmatch_cfg
0.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4used bymatchers
0.1.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558depends onused bymemchr
2.6.4crates.io↘ 0↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167memoffset
0.6.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79cedepends onused bymimalloc
0.1.39crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfa01922b5ea280a911e323e4d2fd24b7fe5cc4042e0d2cda3c40775cdc4bdc9cdepends onused byminimal-lexical
0.2.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79aused byminiz_oxide
0.7.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7depends onused bymio
0.8.8crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2used bynix
0.27.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053depends onused bynixlike
0.1.0workspace↘ 8↖ 1nom
7.1.3crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4adepends onnu-ansi-term
0.46.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84depends onused bynum_cpus
1.16.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43depends onused bynum-bigint-dig
0.8.4crates.io↘ 9↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151depends onused bynum-integer
0.1.45crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9depends onnum-iter
0.1.43crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252used bynum-traits
0.2.17crates.io↘ 2↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267cdepends onnumber_prefix
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3used byobject
0.32.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0depends onused byonce_cell
1.18.0crates.io↘ 0↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576dopaque-debug
0.3.0crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5openssh
0.10.1crates.io↘ 8↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3dfe68c42d6ee6bd9de175b7a5d9bb86aa99d4e2fa7cf2f2a44e97f60b6d2759depends onused byoption-ext
0.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7dused byoverload
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39used byowo-colors
3.5.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6fdepends onused bypapergrid
0.10.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma2ccbe15f2b6db62f9a9871642746427e297b0ceb85f9a7f1ee5ff47d184d0c8used byparking_lot
0.12.1crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228fdepends onparking_lot_core
0.9.8crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447pbkdf2
0.11.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917depends onpeg
0.8.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum400bcab7d219c38abf8bd7cc2054eb9bbbd4312d66f6a5557d572a203f646f61depends onused bypeg-macros
0.8.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum46e61cce859b76d19090f62da50a9fe92bab7c2a5f09e183763559a2ac392c90used bypeg-runtime
0.8.2crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum36bae92c60fa2398ce4678b98b2c4b5a7c61099961ca1fa305aec04a9ad28922used bypin-project
1.1.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422depends onused bypin-project-internal
1.1.3crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405depends onused bypin-project-lite
0.2.13crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58pin-utils
0.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184used bypkcs1
0.4.1crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumeff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719depends onused bypkcs8
0.9.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4baused bypoly1305
0.8.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abfused bypolyval
0.6.1crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fbused byportable-atomic
1.4.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338bused bypowerfmt
0.2.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391used byppv-lite86
0.2.17crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6deproc-macro-error
1.0.4crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumda25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38cproc-macro-error-attr
1.0.4crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869used byproc-macro2
1.0.69crates.io↘ 1↖ 23sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92dadepends onused by- async-trait
0.1.74 - clap_derive
4.4.7 - displaydoc
0.2.4 - futures-macro
0.3.29 - i18n-embed-fl
0.6.7 - i18n-embed-impl
0.8.2 - peg-macros
0.8.2 - pin-project-internal
1.1.3 - proc-macro-error
1.0.4 - proc-macro-error-attr
1.0.4 - quote
1.0.33 - rust-embed-impl
6.8.1 - serde_derive
1.0.190 - syn
1.0.109 - syn
2.0.38 - tabled_derive
0.6.0 - thiserror-impl
1.0.50 - tokio-macros
2.1.0 - tracing-attributes
0.1.26 - vte_generate_state_changes
0.1.1 - wasm-bindgen-backend
0.2.87 - wasm-bindgen-macro-support
0.2.87 - zeroize_derive
1.4.2
- async-trait
quote
1.0.33crates.io↘ 1↖ 23sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293caedepends onused by- async-trait
0.1.74 - clap_derive
4.4.7 - displaydoc
0.2.4 - futures-macro
0.3.29 - i18n-embed-fl
0.6.7 - i18n-embed-impl
0.8.2 - peg-macros
0.8.2 - pin-project-internal
1.1.3 - proc-macro-error
1.0.4 - proc-macro-error-attr
1.0.4 - rust-embed-impl
6.8.1 - serde_derive
1.0.190 - syn
1.0.109 - syn
2.0.38 - tabled_derive
0.6.0 - thiserror-impl
1.0.50 - tokio-macros
2.1.0 - tracing-attributes
0.1.26 - vte_generate_state_changes
0.1.1 - wasm-bindgen-backend
0.2.87 - wasm-bindgen-macro
0.2.87 - wasm-bindgen-macro-support
0.2.87 - zeroize_derive
1.4.2
- async-trait
r2d2
0.8.10crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93used byrand
0.7.3crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03used byrand
0.8.5crates.io↘ 3↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404rand_chacha
0.2.2crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402depends onused byrand_chacha
0.3.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88depends onused byrand_core
0.5.1crates.io↘ 1↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19depends onrand_core
0.6.4crates.io↘ 1↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922cdepends onrand_hc
0.2.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613cdepends onused byredox_syscall
0.3.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29depends onused byredox_syscall
0.4.1crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aadepends onused byredox_users
0.4.4crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4used byregex
1.10.2crates.io↘ 4↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343regex-automata
0.1.10crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132depends onused byregex-automata
0.4.3crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483fused byregex-syntax
0.6.29crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1used byregex-syntax
0.8.2crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9frnix
0.10.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8024a523e8836f1a5d051203dc00d833357fee94e351b51348dfaeca5364daa9depends onused byron
0.8.1crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94used byrowan
0.12.6crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma1b36e449f3702f3b0c821411db1cbdf30fb451726a9456dce5dabcd44420043used byrsa
0.7.2crates.io↘ 13↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099cdepends onused byrust-embed
6.8.1crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661used byrust-embed-impl
6.8.1crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1acused byrust-embed-utils
7.8.1crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74depends onrustc-demangle
0.1.23crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76used byrustc-hash
1.1.0crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2rustix
0.38.21crates.io↘ 5↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3ryu
1.0.15crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741used bysalsa20
0.10.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213depends onused bysame-file
1.0.6crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502depends onused byscheduled-thread-pool
0.2.7crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19depends onused byscopeguard
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49used byscrypt
0.10.0crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45dused bysecrecy
0.8.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91edepends onused byself_cell
0.10.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8afused byserde
1.0.190crates.io↘ 1↖ 18sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7depends onserde_derive
1.0.190crates.io↘ 3↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3depends onserde_json
1.0.107crates.io↘ 3↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65depends onserde_spanned
0.6.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186depends onused byserde-transcode
1.1.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2depends onused bysha2
0.10.8crates.io↘ 3↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8depends onsharded-slab
0.1.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31depends onused byshell-escape
0.1.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184fused byshlex
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380used bysignal-hook-registry
1.4.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1depends onused bysignature
1.6.4crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7cdepends onused byslab
0.4.9crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67depends onused bysmallvec
1.11.1crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5asmol_str
0.1.24crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9depends onused bysocket2
0.5.4crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989edepends onused byspin
0.5.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042dused byspki
0.6.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212bdepends onused bystrsim
0.10.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623subtle
2.5.0crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebcsupports-color
1.3.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8ba6faf2ca7ee42fdd458f4347ae0a9bd6bcc445ad7cb57ad82b383f18870d6fdepends onused bysyn
1.0.109crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237syn
2.0.38crates.io↘ 3↖ 15sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408bused by- async-trait
0.1.74 - clap_derive
4.4.7 - displaydoc
0.2.4 - futures-macro
0.3.29 - i18n-embed-fl
0.6.7 - i18n-embed-impl
0.8.2 - pin-project-internal
1.1.3 - rust-embed-impl
6.8.1 - serde_derive
1.0.190 - thiserror-impl
1.0.50 - tokio-macros
2.1.0 - tracing-attributes
0.1.26 - wasm-bindgen-backend
0.2.87 - wasm-bindgen-macro-support
0.2.87 - zeroize_derive
1.4.2
- async-trait
tabled
0.14.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdfe9c3632da101aba5131ed63f9eed38665f8b3c68703a6bb18124835c1a5d22used bytabled_derive
0.6.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum99f688a08b54f4f02f0a3c382aefdb7884d3d69609f785bd253dc033243e3fe4used bytempfile
3.8.1crates.io↘ 5↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5termcolor
1.3.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64depends onused byterminal_size
0.3.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7depends onused bytext-size
1.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233used bythiserror
1.0.50crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2depends onthiserror-impl
1.0.50crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8depends onused bythread_local
1.1.7crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152depends onused bytime
0.3.30crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5used bytime-core
0.1.2crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3used bytime-macros
0.2.15crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20depends onused bytinystr
0.7.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8faa444297615a4e020acb64146b0603c9c395c03a97c17fd9028816d3b4d63edepends onused bytokio
1.33.0crates.io↘ 11↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653depends ontokio-macros
2.1.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675edepends onused bytokio-pipe
0.2.12crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf213a84bffbd61b8fa0ba8a044b4bbe35d471d0b518867181e82bd5c15542784depends onused bytokio-util
0.7.10crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15depends onused bytoml
0.5.11crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234depends onused bytoml
0.8.0crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc226a7bba6d859b63c92c4b4fe69c5b6b72d0cb897dbc8e6012298e6154cb56eused bytoml_datetime
0.6.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4bdepends onused bytoml_edit
0.20.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8ff63e60a958cefbb518ae1fd6566af80d9d4be430a33f3723dfc47d1d411d95used bytracing
0.1.37crates.io↘ 4↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8tracing-attributes
0.1.26crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4abdepends onused bytracing-core
0.1.31crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79adepends ontracing-indicatif
0.3.5crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum57e05fe4a1c906d94b275d8aeb8ff8b9deaca502aeb59ae8ab500a92b8032ac8used bytracing-log
0.1.3crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922used bytracing-subscriber
0.3.17crates.io↘ 10↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77depends ontype-map
0.4.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46depends onused bytypenum
1.17.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825unic-langid
0.9.1crates.io↘ 1↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2fdepends onunic-langid-impl
0.9.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ffdepends onused byunicase
2.7.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89depends onused byunicode-ident
1.0.12crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4bunicode-width
0.1.11crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85unindent
0.2.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ceused byuniversal-hash
0.5.1crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07eadepends onused byutf8parse
0.2.1crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370avaluable
0.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6dused byversion_check
0.9.4crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483fvt100
0.15.2crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum84cd863bf0db7e392ba3bd04994be3473491b31e66340672af5d11943c6274deused byvte
0.10.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983used byvte
0.11.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197used byvte_generate_state_changes
0.1.1crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ffdepends onwalkdir
2.4.0crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54eedepends onwasi
0.9.0+wasi-snapshot-preview1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519used bywasi
0.11.0+wasi-snapshot-preview1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423used bywasm-bindgen
0.2.87crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342depends onwasm-bindgen-backend
0.2.87crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abddepends onwasm-bindgen-macro
0.2.87crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1dused bywasm-bindgen-macro-support
0.2.87crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7bused bywinapi
0.3.9crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419winapi-i686-pc-windows-gnu
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6used bywinapi-util
0.1.6crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596depends onwinapi-x86_64-pc-windows-gnu
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183fused bywindows
0.48.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700fdepends onused bywindows_aarch64_gnullvm
0.42.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8used bywindows_aarch64_gnullvm
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8used bywindows_aarch64_msvc
0.42.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43used bywindows_aarch64_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bcused bywindows_i686_gnu
0.42.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84fused bywindows_i686_gnu
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743eused bywindows_i686_msvc
0.42.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060used bywindows_i686_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406used bywindows_x86_64_gnu
0.42.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36used bywindows_x86_64_gnu
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718eused bywindows_x86_64_gnullvm
0.42.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3used bywindows_x86_64_gnullvm
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044ccused bywindows_x86_64_msvc
0.42.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0used bywindows_x86_64_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538used bywindows-sys
0.45.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0depends onused bywindows-sys
0.48.0crates.io↘ 1↖ 11sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9depends onwindows-targets
0.42.2crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071depends onused bywindows-targets
0.48.5crates.io↘ 7↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940cdepends onwinnow
0.5.15crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefcdepends onused byx25519-dalek
1.1.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4fused byz85
3.0.5crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2a599daf1b507819c1121f0bf87fa37eb19daac6aff3aefefd4e6e2e0f2020fczeroize
1.6.0crates.io↘ 1↖ 10sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9depends onzeroize_derive
1.4.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69depends onused by
Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,3 +1,7 @@
[workspace]
members = ["crates/*", "cmds/*"]
resolver = "2"
+
+[workspace.dependencies]
+nixlike = { path = "./crates/nixlike" }
+better-command = { path = "./crates/better-command" }
cmds/fleet/Cargo.tomldiffbeforeafterboth--- a/cmds/fleet/Cargo.toml
+++ b/cmds/fleet/Cargo.toml
@@ -6,6 +6,8 @@
edition = "2021"
[dependencies]
+nixlike.workspace = true
+better-command.workspace = true
anyhow = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
@@ -15,7 +17,6 @@
hostname = "0.3.1"
age-core = "0.9.0"
peg = "0.8.2"
-nixlike = { path = "../../crates/nixlike" }
age = { version = "0.9.2", features = ["ssh", "armor"] }
base64 = "0.21.5"
chrono = { version = "0.4.31", features = ["serde"] }
cmds/fleet/src/better_nix_eval.rsdiffbeforeafterboth--- a/cmds/fleet/src/better_nix_eval.rs
+++ b/cmds/fleet/src/better_nix_eval.rs
@@ -1,3 +1,6 @@
+//! Wrapper around nix repl, which allows to work on nix code, without relying on
+//! nix libexpr. I mean, nix libexpr is good, but until it has no C bindings, this is the royal PITA.
+
use std::collections::HashMap;
use std::ffi::{OsStr, OsString};
use std::fmt::{self, Display};
@@ -6,6 +9,7 @@
use std::sync::{Arc, OnceLock};
use anyhow::{anyhow, bail, ensure, Context, Result};
+use better_command::{ClonableHandler, NixHandler, Handler, NoopHandler};
use futures::StreamExt;
use itertools::Itertools;
use r2d2::{Pool, PooledConnection};
@@ -14,11 +18,9 @@
use tokio::io::AsyncWriteExt;
use tokio::process::{ChildStderr, ChildStdin, ChildStdout, Command};
use tokio::select;
-use tokio::sync::{mpsc, oneshot};
+use tokio::sync::{mpsc, oneshot, Mutex};
use tokio_util::codec::{FramedRead, LinesCodec};
use tracing::{debug, error, warn, Level};
-
-use crate::command::{ClonableHandler, Handler, NixHandler, NoopHandler};
const REPL_DELIMITER: &str = "\"FLEET_MAGIC_REPL_DELIMITER\"";
@@ -30,6 +32,8 @@
string_wrapping: (String, String),
number_wrapping: (String, String),
+ executing_command: Arc<Mutex<()>>,
+
next_id: u32,
free_list: Vec<u32>,
}
@@ -219,6 +223,8 @@
string_wrapping: Default::default(),
number_wrapping: Default::default(),
+ executing_command: Arc::new(Mutex::new(())),
+
next_id: 0,
free_list: vec![],
};
@@ -331,6 +337,10 @@
expr: impl AsRef<[u8]>,
err_handler: &mut dyn Handler,
) -> Result<String> {
+ // Prevent two commands from being executed in parallel, messing with each other.
+ let _lock = self.executing_command.clone();
+ let _guard = _lock.lock().await;
+
self.send_command(expr).await?;
// It will be echoed
self.send_command(REPL_DELIMITER).await?;
cmds/fleet/src/cmds/build_systems.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/build_systems.rs
+++ b/cmds/fleet/src/cmds/build_systems.rs
@@ -3,11 +3,11 @@
use std::{env::current_dir, time::Duration};
use crate::command::MyCommand;
-use crate::host::Config;
+use crate::host::{Config, ConfigHost};
use crate::nix_go;
use anyhow::{anyhow, Result};
use clap::Parser;
-use itertools::Itertools;
+use itertools::Itertools as _;
use tokio::{task::LocalSet, time::sleep};
use tracing::{error, field, info, info_span, warn, Instrument};
@@ -112,12 +112,12 @@
current: bool,
datetime: String,
}
-async fn get_current_generation(config: &Config, host: &str) -> Result<Generation> {
- let mut cmd = MyCommand::new("nix-env");
+async fn get_current_generation(host: &ConfigHost) -> Result<Generation> {
+ let mut cmd = host.cmd("nix-env").await?;
cmd.comparg("--profile", "/nix/var/nix/profiles/system")
.arg("--list-generations");
// Sudo is required due to --list-generations acquiring lock on the profile.
- let data = config.run_string_on(host, cmd, true).await?;
+ let data = cmd.sudo().run_string().await?;
let generations = data
.split('\n')
.map(|e| e.trim())
@@ -161,25 +161,12 @@
.map_err(|_e| anyhow!("bad list-generations output"))?
.ok_or_else(|| anyhow!("failed to find generation"))?;
Ok(current)
-}
-
-async fn systemctl_stop(config: &Config, host: &str, unit: &str) -> Result<()> {
- let mut cmd = MyCommand::new("systemctl");
- cmd.arg("stop").arg(unit);
- config.run_on(host, cmd, true).await
-}
-
-async fn systemctl_start(config: &Config, host: &str, unit: &str) -> Result<()> {
- let mut cmd = MyCommand::new("systemctl");
- cmd.arg("start").arg(unit);
- config.run_on(host, cmd, true).await
}
async fn execute_upload(
build: &BuildSystems,
- config: &Config,
action: UploadAction,
- host: &str,
+ host: &ConfigHost,
built: PathBuf,
) -> Result<()> {
let mut failed = false;
@@ -191,15 +178,15 @@
if !build.disable_rollback {
let _span = info_span!("preparing").entered();
info!("preparing for rollback");
- let generation = get_current_generation(config, host).await?;
+ let generation = get_current_generation(&host).await?;
info!(
"rollback target would be {} {}",
generation.id, generation.datetime
);
{
- let mut cmd = MyCommand::new("sh");
+ let mut cmd = host.cmd("sh").await?;
cmd.arg("-c").arg(format!("mark=$(mktemp -p /etc -t fleet_rollback_marker.XXXXX) && echo -n {} > $mark && mv --no-clobber $mark /etc/fleet_rollback_marker", generation.id));
- if let Err(e) = config.run_on(host, cmd, true).await {
+ if let Err(e) = cmd.sudo().run().await {
error!("failed to set rollback marker: {e}");
failed = true;
}
@@ -215,37 +202,41 @@
// if we fail to perform generation switch in time, then we will still call the activation script, and this may break something.
// Anyway, reboot will still help in this case.
if action.should_schedule_rollback_run() {
- let mut cmd = MyCommand::new("systemd-run");
+ let mut cmd = host.cmd("systemd-run").await?;
cmd.comparg("--on-active", "3min")
.comparg("--unit", "rollback-watchdog-run")
.arg("systemctl")
.arg("start")
.arg("rollback-watchdog.service");
- if let Err(e) = config.run_on(host, cmd, true).await {
+ if let Err(e) = cmd.sudo().run().await {
error!("failed to schedule rollback run: {e}");
failed = true;
}
}
}
+
if action.should_switch_profile() && !failed {
info!("switching generation");
- let mut cmd = MyCommand::new("nix-env");
+ let mut cmd = host.cmd("nix-env").await?;
cmd.comparg("--profile", "/nix/var/nix/profiles/system")
.comparg("--set", &built);
- if let Err(e) = config.run_on(host, cmd, true).await {
+ if let Err(e) = cmd.sudo().run().await {
error!("failed to switch generation: {e}");
failed = true;
}
}
+
+ // FIXME: Connection might be disconnected after activation run
+
if action.should_activate() && !failed {
let _span = info_span!("activating").entered();
info!("executing activation script");
let mut switch_script = built.clone();
switch_script.push("bin");
switch_script.push("switch-to-configuration");
- let mut cmd = MyCommand::new(switch_script);
+ let mut cmd = host.cmd(switch_script).await?;
cmd.arg(action.name());
- if let Err(e) = config.run_on(host, cmd, true).in_current_span().await {
+ if let Err(e) = cmd.sudo().run().in_current_span().await {
error!("failed to activate: {e}");
failed = true;
}
@@ -253,7 +244,8 @@
if !build.disable_rollback {
if failed {
info!("executing rollback");
- if let Err(e) = systemctl_start(config, host, "rollback-watchdog.service")
+ if let Err(e) = host
+ .systemctl_start("rollback-watchdog.service")
.instrument(info_span!("rollback"))
.await
{
@@ -261,27 +253,29 @@
}
} else {
info!("trying to mark upgrade as successful");
- let mut cmd = MyCommand::new("rm");
- cmd.arg("-f").arg("/etc/fleet_rollback_marker");
- if let Err(e) = config.run_on(host, cmd, true).in_current_span().await {
+ if let Err(e) = host
+ .rm_file("/etc/fleet_rollback_marker", true)
+ .in_current_span()
+ .await
+ {
error!("failed to remove rollback marker. This is bad, as the system will be rolled back by watchdog: {e}")
}
}
info!("disarming watchdog, just in case");
- if let Err(_e) = systemctl_stop(config, host, "rollback-watchdog.timer").await {
+ if let Err(_e) = host.systemctl_stop("rollback-watchdog.timer").await {
// It is ok, if there was no reboot - then timer might not be running.
}
if action.should_schedule_rollback_run() {
- if let Err(e) = systemctl_stop(config, host, "rollback-watchdog-run.timer").await {
+ if let Err(e) = host.systemctl_stop("rollback-watchdog-run.timer").await {
error!("failed to disarm rollback run: {e}");
}
}
- } else {
- let mut cmd = MyCommand::new("rm");
- cmd.arg("-f").arg("/etc/fleet_rollback_marker");
- if let Err(_e) = config.run_on(host, cmd, true).in_current_span().await {
- // Marker might not exist, yet better try to remove it.
- }
+ } else if let Err(_e) = host
+ .rm_file("/etc/fleet_rollback_marker", true)
+ .in_current_span()
+ .await
+ {
+ // Marker might not exist, yet better try to remove it.
}
Ok(())
}
@@ -289,12 +283,13 @@
impl BuildSystems {
async fn build_task(self, config: Config, host: String) -> Result<()> {
info!("building");
+ let host = config.host(&host).await?;
let action = Action::from(self.subcommand.clone());
let fleet_field = &config.fleet_field;
let drv = nix_go!(
fleet_field.buildSystems(Obj {
localSystem: { config.local_system.clone() }
- })[{ action.build_attr() }][{ host }]
+ })[{ action.build_attr() }][{ &host.name }]
);
let outputs = drv.build().await.map_err(|e| {
if action.build_attr() == "sdImage" {
@@ -309,9 +304,10 @@
match action {
Action::Upload { action } => {
- if !config.is_local(&host) {
+ if !config.is_local(&host.name) {
info!("uploading system closure");
{
+ // TODO: Move to remote_derivation method.
// Alternatively, nix store make-content-addressed can be used,
// at least for the first deployment, to provide trusted store key.
//
@@ -329,13 +325,11 @@
}
let mut tries = 0;
loop {
- let mut nix = MyCommand::new("nix");
- nix.arg("copy")
- .arg("--substitute-on-destination")
- .comparg("--to", format!("ssh-ng://{host}"))
- .arg(out_output);
- match nix.run_nix().await {
- Ok(()) => break,
+ match host.remote_derivation(out_output).await {
+ Ok(remote) => {
+ assert!(&remote == out_output, "CA derivations aren't implemented");
+ break;
+ }
Err(e) if tries < 3 => {
tries += 1;
warn!("Copy failure ({}/3): {}", tries, e);
@@ -346,19 +340,19 @@
}
}
if let Some(action) = action {
- execute_upload(&self, &config, action, &host, out_output.clone()).await?
+ execute_upload(&self, action, &host, out_output.clone()).await?
}
}
Action::Package(PackageAction::SdImage) => {
let mut out = current_dir()?;
- out.push(format!("sd-image-{}", host));
+ out.push(format!("sd-image-{}", host.name));
info!("linking sd image to {:?}", out);
symlink(out_output, out)?;
}
Action::Package(PackageAction::InstallationCd) => {
let mut out = current_dir()?;
- out.push(format!("installation-cd-{}", host));
+ out.push(format!("installation-cd-{}", host.name));
info!("linking iso image to {:?}", out);
symlink(out_output, out)?;
@@ -379,6 +373,17 @@
let this = this.clone();
let span = info_span!("deployment", host = field::display(&host.name));
let hostname = host.name;
+ // FIXME: Since the introduction of better-nix-eval,
+ // due to single repl used for builds, hosts are waiting for each other to build,
+ // instead of building concurrently.
+ //
+ // Open multiple repls?
+ //
+ // Create build batcher, which will behave similar to golangs
+ // WaitGroup, and start executing once all the build tasks are scheduled?
+ // This also allows to cleanup build output, as there will be no longer
+ // "waiting for remote machine" messages in the cases when one package is needed for
+ // multiple hosts.
set.spawn_local(
(async move {
match this.build_task(config, hostname).await {
cmds/fleet/src/cmds/secrets/mod.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/secrets/mod.rs
+++ b/cmds/fleet/src/cmds/secrets/mod.rs
@@ -7,7 +7,7 @@
use anyhow::{anyhow, bail, ensure, Context, Result};
use chrono::{DateTime, Utc};
use clap::Parser;
-use futures::{StreamExt, TryStreamExt};
+use futures::StreamExt;
use itertools::Itertools;
use owo_colors::OwoColorize;
use std::{
@@ -404,9 +404,8 @@
target_recipients.into_iter().collect::<Result<Vec<_>>>()?;
if let Some(data) = secret.secret.secret {
- let encrypted = config
- .reencrypt_on_host(identity_holder, data, target_recipients)
- .await?;
+ let host = config.host(&identity_holder).await?;
+ let encrypted = host.reencrypt(data, target_recipients).await?;
secret.secret.secret = Some(encrypted);
}
@@ -481,9 +480,8 @@
target_recipients.into_iter().collect::<Result<Vec<_>>>()?;
if let Some(secret) = data.secret.secret {
- let encrypted = config
- .reencrypt_on_host(identity_holder, secret, target_recipients)
- .await?;
+ let host = config.host(identity_holder).await?;
+ let encrypted = host.reencrypt(secret, target_recipients).await?;
data.secret.secret = Some(encrypted);
}
cmds/fleet/src/command.rsdiffbeforeafterboth--- a/cmds/fleet/src/command.rs
+++ b/cmds/fleet/src/command.rs
@@ -1,23 +1,15 @@
-use std::{
- collections::HashMap,
- ffi::OsStr,
- pin,
- process::Stdio,
- sync::{Arc, Mutex},
- task::Poll,
-};
+use std::thread::sleep;
+use std::time::Duration;
+use std::{ffi::OsStr, pin, process::Stdio, sync::Arc, task::Poll};
use anyhow::{anyhow, Result};
+use better_command::{Handler, NixHandler, PlainHandler};
use futures::StreamExt;
use itertools::Either;
-use once_cell::sync::Lazy;
use openssh::{OverSsh, OwningCommand, Session};
-use regex::Regex;
-use serde::{de::Visitor, Deserialize};
use tokio::{io::AsyncRead, process::Command, select};
use tokio_util::codec::{BytesCodec, FramedRead, LinesCodec};
-use tracing::{info, info_span, warn, Span};
-use tracing_indicatif::span_ext::IndicatifSpanExt;
+use tracing::{info, debug};
fn escape_bash(input: &str, out: &mut String) {
const TO_ESCAPE: &str = "$ !\"#&'()*,;<>?[\\]^`{|}";
@@ -87,9 +79,7 @@
return self;
}
let mut out = Self::new("env");
- if let Some(session) = self.ssh_session {
- out = out.ssh_session(session);
- }
+ out.ssh_session = self.ssh_session;
for (k, v) in self.env {
assert!(!k.contains('='));
out.arg(format!("{k}={v}"));
@@ -179,21 +169,11 @@
out
} else {
let mut out = Self::new("sudo");
+ out.ssh_session = self.ssh_session.take();
out.args(self.into_args());
out
}
}
- pub fn ssh_session(mut self, on: Arc<Session>) -> Self {
- self.ssh_session = Some(on);
- self
- }
- pub fn ssh(mut self, on: impl AsRef<OsStr>) -> Self {
- let mut out = Self::new("ssh");
- out.ssh_session = self.ssh_session.take();
- out.arg(on).arg("--");
- out.arg(self.into_string());
- out
- }
pub async fn run(self) -> Result<()> {
let str = self.clone().into_string();
@@ -276,259 +256,6 @@
let v = run_nix_inner_raw_ssh(str, cmd, false, handler, None).await?;
assert!(v.is_none());
Ok(())
-}
-
-pub trait Handler: Send {
- fn handle_line(&mut self, e: &str);
-}
-
-pub struct ClonableHandler<H>(Arc<Mutex<H>>);
-impl<H> Clone for ClonableHandler<H> {
- fn clone(&self) -> Self {
- Self(self.0.clone())
- }
-}
-impl<H> ClonableHandler<H> {
- pub fn new(inner: H) -> Self {
- Self(Arc::new(Mutex::new(inner)))
- }
-}
-impl<H: Handler> Handler for ClonableHandler<H> {
- fn handle_line(&mut self, e: &str) {
- self.0.lock().unwrap().handle_line(e)
- }
-}
-
-struct PlainHandler;
-impl Handler for PlainHandler {
- fn handle_line(&mut self, e: &str) {
- info!(target: "log", "{e}");
- }
-}
-
-pub struct NoopHandler;
-impl Handler for NoopHandler {
- fn handle_line(&mut self, _e: &str) {}
-}
-
-#[derive(Default)]
-pub struct NixHandler {
- spans: HashMap<u64, Span>,
-}
-fn process_message(m: &str) -> String {
- static OSC_CLEANER: Lazy<Regex> =
- Lazy::new(|| Regex::new(r"\x1B\]([^\x07\x1C]*[\x07\x1C])?|\r").unwrap());
- static DETABBER: Lazy<Regex> = Lazy::new(|| Regex::new(r"\t").unwrap());
- let m = OSC_CLEANER.replace_all(m, "");
- // Indicatif can't format tabs. This is not the correct tab formatting, as correct one should be aligned,
- // and not just be replaced with the constant number of spaces, but it's ok for now, as statuses are single-line.
- DETABBER.replace_all(m.as_ref(), " ").to_string()
-}
-impl Handler for NixHandler {
- fn handle_line(&mut self, e: &str) {
- if let Some(e) = e.strip_prefix("@nix ") {
- let log: NixLog = match serde_json::from_str(e) {
- Ok(l) => l,
- Err(err) => {
- warn!("failed to parse nix log line {:?}: {}", e, err);
- return;
- }
- };
- match log {
- NixLog::Msg { msg, raw_msg, .. } => {
- #[allow(clippy::nonminimal_bool)]
- if !(msg.starts_with("\u{1b}[35;1mwarning:\u{1b}[0m Git tree '") && msg.ends_with("' is dirty"))
- && !msg.starts_with("\u{1b}[35;1mwarning:\u{1b}[0m not writing modified lock file of flake")
- && msg != "\u{1b}[35;1mwarning:\u{1b}[0m \u{1b}[31;1merror:\u{1b}[0m SQLite database '\u{1b}[35;1m/nix/var/nix/db/db.sqlite\u{1b}[0m' is busy" {
- if let Some(raw_msg) = raw_msg {
- if !msg.is_empty() {
- info!(target: "nix", "{}\n{}", raw_msg.trim_end(), msg.trim_end())
- } else {
- info!(target: "nix", "{}", raw_msg.trim_end())
- }
- } else {
- info!(target: "nix", "{}", msg.trim_end())
- }
- }
- }
- NixLog::Start {
- ref fields,
- typ,
- id,
- ..
- } if typ == 105 && !fields.is_empty() => {
- if let [LogField::String(drv), ..] = &fields[..] {
- let mut drv = drv.as_str();
- if let Some(pkg) = drv.strip_prefix("/nix/store/") {
- let mut it = pkg.splitn(2, '-');
- it.next();
- if let Some(pkg) = it.next() {
- drv = pkg;
- }
- }
- info!(target: "nix","building {}", drv);
- let span = info_span!("build", drv);
- span.pb_start();
- self.spans.insert(id, span);
- } else {
- warn!("bad build log: {:?}", log)
- }
- }
- NixLog::Start {
- ref fields,
- typ,
- id,
- ..
- } if typ == 100 && fields.len() >= 3 => {
- if let [LogField::String(drv), LogField::String(from), LogField::String(to), ..] =
- &fields[..]
- {
- let mut drv = drv.as_str();
-
- if let Some(pkg) = drv.strip_prefix("/nix/store/") {
- let mut it = pkg.splitn(2, '-');
- it.next();
- if let Some(pkg) = it.next() {
- drv = pkg;
- }
- }
- // info!(target: "nix","copying {} {} -> {}", drv, from, to);
- let span = info_span!("copy", from, to, drv);
- span.pb_start();
- self.spans.insert(id, span);
- } else {
- warn!("bad copy log: {:?}", log)
- }
- }
- NixLog::Start { text, typ, id, .. }
- if typ == 0 || typ == 102 || typ == 103 || typ == 104 =>
- {
- if !text.is_empty()
- && text != "querying info about missing paths"
- && text != "copying 0 paths"
- // Too much spam on lazy-trees branch
- && !(text.starts_with("copying '") && text.ends_with("' to the store"))
- {
- let span = info_span!("job");
- span.pb_start();
- span.pb_set_message(&process_message(text.trim()));
- self.spans.insert(id, span);
- info!(target: "nix", "{}", text);
- }
- }
- NixLog::Start {
- text,
- level: 0,
- typ: 108,
- ..
- } if text.is_empty() => {
- // Cache lookup? Coupled with copy log
- }
- NixLog::Start {
- text,
- level: 4,
- typ: 109,
- ..
- } if text.starts_with("querying info about ") => {
- // Cache lookup
- }
- NixLog::Start {
- text,
- level: 4,
- typ: 101,
- ..
- } if text.starts_with("downloading ") => {
- // NAR downloading, coupled with copy log
- }
- NixLog::Start {
- text,
- level: 1,
- typ: 111,
- ..
- } if text.starts_with("waiting for a machine to build ") => {
- // Useless repeating notification about build
- }
- NixLog::Start {
- text,
- level: 3,
- typ: 111,
- ..
- } if text.starts_with("resolved derivation: ") => {
- // CA resolved
- }
- NixLog::Start {
- text,
- level: 1,
- typ: 111,
- id,
- ..
- } if text.starts_with("waiting for lock on ") => {
- let mut drv = text.strip_prefix("waiting for lock on ").unwrap();
- if let Some(txt) = drv.strip_prefix("\u{1b}[35;1m'") {
- drv = txt;
- }
- if let Some(txt) = drv.strip_suffix("'\u{1b}[0m") {
- drv = txt;
- }
- if let Some(txt) = drv.split("', '").next() {
- drv = txt;
- }
- if let Some(pkg) = drv.strip_prefix("/nix/store/") {
- let mut it = pkg.splitn(2, '-');
- it.next();
- if let Some(pkg) = it.next() {
- drv = pkg;
- }
- }
- let span = info_span!("waiting on drv", drv);
- span.pb_start();
- self.spans.insert(id, span);
- // Concurrent build of the same message
- }
- NixLog::Stop { id, .. } => {
- self.spans.remove(&id);
- }
- NixLog::Result { fields, id, typ } if typ == 101 && !fields.is_empty() => {
- if let Some(span) = self.spans.get(&id) {
- if let LogField::String(s) = &fields[0] {
- span.pb_set_message(&process_message(s.trim()));
- } else {
- warn!("bad fields: {fields:?}");
- }
- } else {
- warn!("unknown result id: {id} {typ} {fields:?}");
- }
- // dbg!(fields, id, typ);
- }
- NixLog::Result { fields, id, typ } if typ == 105 && fields.len() >= 4 => {
- if let Some(span) = self.spans.get(&id) {
- if let [LogField::Num(done), LogField::Num(expected), LogField::Num(_running), LogField::Num(_failed)] =
- &fields[..4]
- {
- span.pb_set_length(*expected);
- span.pb_set_position(*done);
- } else {
- warn!("bad fields: {fields:?}");
- }
- } else {
- // warn!("unknown result id: {id} {typ} {fields:?}");
- // Unaccounted progress.
- }
- // dbg!(fields, id, typ);
- }
- NixLog::Result { typ, .. } if typ == 104 || typ == 106 => {
- // Set phase, expected
- }
- _ => warn!("unknown log: {:?}", log),
- };
- } else {
- let e = e.trim();
- if e.starts_with("Failed tcsetattr(TCSADRAIN): ") {
- return;
- }
- info!("{e}")
- }
- }
}
async fn run_nix_inner_raw(
@@ -540,6 +267,7 @@
) -> Result<Option<Vec<u8>>> {
cmd.stderr(Stdio::piped());
cmd.stdout(Stdio::piped());
+ debug!("running command {cmd:?} on local");
let mut child = cmd.spawn()?;
let mut stderr = child.stderr.take().unwrap();
let stdout = child.stdout.take().unwrap();
@@ -600,6 +328,7 @@
err_handler: &mut dyn Handler,
mut out_handler: Option<&mut dyn Handler>,
) -> Result<Option<Vec<u8>>> {
+ debug!("running command {cmd:?} over ssh");
cmd.stderr(openssh::Stdio::piped());
cmd.stdout(openssh::Stdio::piped());
let mut child = cmd.spawn().await?;
@@ -656,77 +385,4 @@
}
Ok(out_buf)
-}
-
-pub trait ErrorRecorder: Send {
- /// Return true to discard message from logging
- fn push_message(&mut self, msg: &str) -> bool;
-}
-
-#[derive(Debug)]
-enum LogField {
- String(String),
- Num(u64),
-}
-
-impl<'de> Deserialize<'de> for LogField {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: serde::Deserializer<'de>,
- {
- struct StringOrNum;
- impl<'de> Visitor<'de> for StringOrNum {
- type Value = LogField;
-
- fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- write!(f, "string or unsigned")
- }
-
- fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
- where
- E: serde::de::Error,
- {
- Ok(LogField::String(v.to_owned()))
- }
-
- fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
- where
- E: serde::de::Error,
- {
- Ok(LogField::Num(v))
- }
- }
-
- deserializer.deserialize_any(StringOrNum)
- }
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase", tag = "action")]
-#[allow(dead_code)]
-enum NixLog {
- Msg {
- level: u32,
- msg: String,
- raw_msg: Option<String>,
- },
- Start {
- id: u64,
- level: u32,
- #[serde(default)]
- fields: Vec<LogField>,
- text: String,
- #[serde(rename = "type")]
- typ: u32,
- },
- Stop {
- id: u64,
- },
- Result {
- id: u64,
- #[serde(rename = "type")]
- typ: u32,
- #[serde(default)]
- fields: Vec<LogField>,
- },
}
cmds/fleet/src/host.rsdiffbeforeafterboth--- a/cmds/fleet/src/host.rs
+++ b/cmds/fleet/src/host.rs
@@ -9,7 +9,6 @@
sync::{Arc, Mutex, MutexGuard, OnceLock},
};
-use age::Recipient;
use anyhow::{anyhow, bail, Context, Result};
use clap::{ArgGroup, Parser};
use openssh::SessionBuilder;
@@ -50,10 +49,12 @@
pub struct ConfigHost {
pub name: String,
+ pub local: bool,
pub session: OnceLock<Arc<openssh::Session>>,
}
impl ConfigHost {
- pub async fn open_session(&self) -> Result<Arc<openssh::Session>> {
+ async fn open_session(&self) -> Result<Arc<openssh::Session>> {
+ assert!(!self.local, "do not open ssh connection to local session");
// FIXME: TOCTOU
if let Some(session) = &self.session.get() {
return Ok((*session).clone());
@@ -96,8 +97,12 @@
D::from_str(&text).map_err(|e| anyhow!("failed to parse value: {e}"))
}
pub async fn cmd(&self, cmd: impl AsRef<OsStr>) -> Result<MyCommand> {
- let session = self.open_session().await?;
- Ok(MyCommand::new_on(cmd, session))
+ if self.local {
+ Ok(MyCommand::new(cmd))
+ } else {
+ let session = self.open_session().await?;
+ Ok(MyCommand::new_on(cmd, session))
+ }
}
pub async fn decrypt(&self, data: SecretData) -> Result<Vec<u8>> {
@@ -110,8 +115,25 @@
.context("failed to call remote host for decrypt")?;
z85::decode(encoded.trim_end()).context("bad encoded data? outdated host?")
}
+ pub async fn reencrypt(&self, data: SecretData, targets: Vec<String>) -> Result<SecretData> {
+ let mut cmd = self.cmd("fleet-install-secrets").await?;
+ cmd.arg("reencrypt").eqarg("--secret", data.encode_z85());
+ for target in targets {
+ cmd.eqarg("--targets", target);
+ }
+ let encoded = cmd
+ .sudo()
+ .run_string()
+ .await
+ .context("failed to call remote host for decrypt")?;
+ SecretData::decode_z85(encoded.trim_end()).context("bad encoded data? outdated host?")
+ }
/// Returns path for futureproofing, as path might change i.e on conversion to CA
pub async fn remote_derivation(&self, path: &PathBuf) -> Result<PathBuf> {
+ if self.local {
+ // Path is located locally, thus already trusted.
+ return Ok(path.to_owned());
+ }
let mut nix = MyCommand::new("nix");
nix.arg("copy")
.arg("--substitute-on-destination")
@@ -120,6 +142,25 @@
nix.run_nix().await?;
Ok(path.to_owned())
}
+ pub async fn systemctl_stop(&self, name: &str) -> Result<()> {
+ let mut cmd = self.cmd("systemctl").await?;
+ cmd.arg("stop").arg(name);
+ cmd.sudo().run().await
+ }
+ pub async fn systemctl_start(&self, name: &str) -> Result<()> {
+ let mut cmd = self.cmd("systemctl").await?;
+ cmd.arg("start").arg(name);
+ cmd.sudo().run().await
+ }
+
+ pub async fn rm_file(&self, path: impl AsRef<OsStr>, sudo: bool) -> Result<()> {
+ let mut cmd = self.cmd("rm").await?;
+ cmd.arg("-f").arg(path);
+ if sudo {
+ cmd = cmd.sudo()
+ }
+ cmd.run().await
+ }
}
impl Config {
@@ -134,35 +175,12 @@
}
pub fn is_local(&self, host: &str) -> bool {
self.opts.localhost.as_ref().map(|s| s as &str) == Some(host)
- }
-
- pub async fn run_on(&self, host: &str, mut command: MyCommand, sudo: bool) -> Result<()> {
- if sudo {
- command = command.sudo();
- }
- if !self.is_local(host) {
- command = command.ssh(host);
- }
- command.run().await
- }
- pub async fn run_string_on(
- &self,
- host: &str,
- mut command: MyCommand,
- sudo: bool,
- ) -> Result<String> {
- if sudo {
- command = command.sudo();
- }
- if !self.is_local(host) {
- command = command.ssh(host);
- }
- command.run_string().await
}
pub async fn host(&self, name: &str) -> Result<ConfigHost> {
Ok(ConfigHost {
name: name.to_owned(),
+ local: self.is_local(name),
session: OnceLock::new(),
})
}
@@ -172,6 +190,7 @@
let mut out = vec![];
for name in names {
out.push(ConfigHost {
+ local: self.is_local(&name),
name,
session: OnceLock::new(),
})
@@ -225,27 +244,6 @@
let mut data = self.data_mut();
let host_secrets = data.host_secrets.entry(host.to_owned()).or_default();
host_secrets.insert(secret, value);
- }
-
- pub async fn reencrypt_on_host(
- &self,
- host: &str,
- data: SecretData,
- targets: Vec<String>,
- ) -> Result<SecretData> {
- let mut recmd = MyCommand::new("fleet-install-secrets");
- recmd.arg("reencrypt").eqarg("--secret", data.encode_z85());
- for target in targets {
- recmd.eqarg("--targets", target);
- }
- recmd = recmd.sudo().ssh(host);
- let encoded = recmd
- .run_string()
- .await
- .context("failed to call remote host for decrypt")?
- .trim()
- .to_owned();
- SecretData::decode_z85(&encoded)
}
pub fn host_secret(&self, host: &str, secret: &str) -> Result<FleetSecret> {
cmds/fleet/src/keys.rsdiffbeforeafterboth--- a/cmds/fleet/src/keys.rs
+++ b/cmds/fleet/src/keys.rs
@@ -1,6 +1,5 @@
use std::str::FromStr;
-use crate::command::MyCommand;
use crate::host::Config;
use age::Recipient;
use anyhow::{anyhow, Result};
@@ -30,10 +29,11 @@
Ok(key)
} else {
warn!("Loading key for {}", host);
- let mut cmd = MyCommand::new("cat");
+ let host = self.host(host).await?;
+ let mut cmd = host.cmd("cat").await?;
cmd.arg("/etc/ssh/ssh_host_ed25519_key.pub");
- let key = self.run_string_on(host, cmd, false).await?;
- self.update_key(host, key.clone());
+ let key = cmd.run_string().await?;
+ self.update_key(&host.name, key.clone());
Ok(key)
}
}
cmds/remowt-agent/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/cmds/remowt-agent/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "remowt-agent"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
cmds/remowt-agent/README.adocdiffbeforeafterboth--- /dev/null
+++ b/cmds/remowt-agent/README.adoc
@@ -0,0 +1,16 @@
+= Remowt agent
+
+Working with remote machine programmatically is not always easy.
+
+Sure, you have ssh, sftp, and that kind of fancy stuff, but what about minimal distributions, routers?
+
+Well, sftp can be replaced with FISH... But what if remote machine isn't accessible over ssh at all? What if the only communication channel you have is uart?
+
+What if remote host has not enough tools to implement the functionality you need?
+
+Remowt is intended to solve this in a way similar to how some RAT toolkits (I.e metasploit) do - you inject minimal agent, setup some communication channel to it (stdio perhaps?), and then you deploy payloads on it, and the payloads perform the actual work.
+
+== Non-targets
+
+Minimal executable size:: As long as it transferred only once, it shouldn't be a problem to keep it a reasonable size.
+Be stealthy:: As it solves the problem almost the same way as metasploit, it is possible to use it as something bad, but this is not the remowt intended purpose, and never will be.
cmds/remowt-agent/src/main.rsdiffbeforeafterboth--- /dev/null
+++ b/cmds/remowt-agent/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("Hello, world!");
+}
crates/better-command/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/crates/better-command/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "better-command"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+once_cell = "1.19.0"
+regex = "1.10.2"
+serde = { version = "1.0.193", features = ["derive"] }
+serde_json = "1.0.108"
+tracing = "0.1.40"
+tracing-indicatif = "0.3.6"
crates/better-command/src/handler.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/better-command/src/handler.rs
@@ -0,0 +1,305 @@
+//! Collection of handlers, which transform program-specific stdout format to tracing
+
+use std::collections::HashMap;
+use std::sync::{Arc, Mutex};
+
+use once_cell::sync::Lazy;
+use regex::Regex;
+use serde::Deserialize;
+use tracing::{Span, info, warn, info_span};
+use tracing_indicatif::span_ext::IndicatifSpanExt as _;
+
+pub trait Handler: Send {
+ fn handle_line(&mut self, e: &str);
+}
+
+/// Handler wrapper, which can be cloned.
+pub struct ClonableHandler<H>(Arc<Mutex<H>>);
+impl<H> Clone for ClonableHandler<H> {
+ fn clone(&self) -> Self {
+ Self(self.0.clone())
+ }
+}
+impl<H> ClonableHandler<H> {
+ pub fn new(inner: H) -> Self {
+ Self(Arc::new(Mutex::new(inner)))
+ }
+}
+impl<H: Handler> Handler for ClonableHandler<H> {
+ fn handle_line(&mut self, e: &str) {
+ self.0.lock().unwrap().handle_line(e)
+ }
+}
+
+/// Converts command output to tracing lines
+pub struct PlainHandler;
+impl Handler for PlainHandler {
+ fn handle_line(&mut self, e: &str) {
+ info!(target: "log", "{e}");
+ }
+}
+
+/// Ignores output
+pub struct NoopHandler;
+impl Handler for NoopHandler {
+ fn handle_line(&mut self, _e: &str) {}
+}
+
+/// Transform nix internal-json logs to tracing spans.
+#[derive(Default)]
+pub struct NixHandler {
+ spans: HashMap<u64, Span>,
+}
+#[derive(Deserialize, Debug)]
+#[serde(untagged)]
+enum LogField {
+ String(String),
+ Num(u64),
+}
+
+/// Nix internal-json log line type
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "camelCase", tag = "action")]
+#[allow(dead_code)]
+enum NixLog {
+ Msg {
+ level: u32,
+ msg: String,
+ raw_msg: Option<String>,
+ },
+ Start {
+ id: u64,
+ level: u32,
+ #[serde(default)]
+ fields: Vec<LogField>,
+ text: String,
+ #[serde(rename = "type")]
+ typ: u32,
+ },
+ Stop {
+ id: u64,
+ },
+ Result {
+ id: u64,
+ #[serde(rename = "type")]
+ typ: u32,
+ #[serde(default)]
+ fields: Vec<LogField>,
+ },
+}
+fn process_message(m: &str) -> String {
+ // Supposed to remove formatting characters except colors, as some programs try to reset cursor position etc.
+ static OSC_CLEANER: Lazy<Regex> =
+ Lazy::new(|| Regex::new(r"\x1B\]([^\x07\x1C]*[\x07\x1C])?|\r").unwrap());
+ static DETABBER: Lazy<Regex> = Lazy::new(|| Regex::new(r"\t").unwrap());
+ let m = OSC_CLEANER.replace_all(m, "");
+ // Indicatif can't format tabs. This is not the correct tab formatting, as correct one should be aligned,
+ // and not just be replaced with the constant number of spaces, but it's ok for now, as statuses are single-line.
+ DETABBER.replace_all(m.as_ref(), " ").to_string()
+}
+impl Handler for NixHandler {
+ fn handle_line(&mut self, e: &str) {
+ if let Some(e) = e.strip_prefix("@nix ") {
+ let log: NixLog = match serde_json::from_str(e) {
+ Ok(l) => l,
+ Err(err) => {
+ warn!("failed to parse nix log line {:?}: {}", e, err);
+ return;
+ }
+ };
+ match log {
+ NixLog::Msg { msg, raw_msg, .. } => {
+ #[allow(clippy::nonminimal_bool)]
+ if !(msg.starts_with("\u{1b}[35;1mwarning:\u{1b}[0m Git tree '") && msg.ends_with("' is dirty"))
+ && !msg.starts_with("\u{1b}[35;1mwarning:\u{1b}[0m not writing modified lock file of flake")
+ && msg != "\u{1b}[35;1mwarning:\u{1b}[0m \u{1b}[31;1merror:\u{1b}[0m SQLite database '\u{1b}[35;1m/nix/var/nix/db/db.sqlite\u{1b}[0m' is busy" {
+ if let Some(raw_msg) = raw_msg {
+ if !msg.is_empty() {
+ info!(target: "nix", "{}\n{}", raw_msg.trim_end(), msg.trim_end())
+ } else {
+ info!(target: "nix", "{}", raw_msg.trim_end())
+ }
+ } else {
+ info!(target: "nix", "{}", msg.trim_end())
+ }
+ }
+ }
+ NixLog::Start {
+ ref fields,
+ typ,
+ id,
+ ..
+ } if typ == 105 && !fields.is_empty() => {
+ if let [LogField::String(drv), ..] = &fields[..] {
+ let mut drv = drv.as_str();
+ if let Some(pkg) = drv.strip_prefix("/nix/store/") {
+ let mut it = pkg.splitn(2, '-');
+ it.next();
+ if let Some(pkg) = it.next() {
+ drv = pkg;
+ }
+ }
+ info!(target: "nix","building {}", drv);
+ let span = info_span!("build", drv);
+ span.pb_start();
+ self.spans.insert(id, span);
+ } else {
+ warn!("bad build log: {:?}", log)
+ }
+ }
+ NixLog::Start {
+ ref fields,
+ typ,
+ id,
+ ..
+ } if typ == 100 && fields.len() >= 3 => {
+ if let [LogField::String(drv), LogField::String(from), LogField::String(to), ..] =
+ &fields[..]
+ {
+ let mut drv = drv.as_str();
+
+ if let Some(pkg) = drv.strip_prefix("/nix/store/") {
+ let mut it = pkg.splitn(2, '-');
+ it.next();
+ if let Some(pkg) = it.next() {
+ drv = pkg;
+ }
+ }
+ // info!(target: "nix","copying {} {} -> {}", drv, from, to);
+ let span = info_span!("copy", from, to, drv);
+ span.pb_start();
+ self.spans.insert(id, span);
+ } else {
+ warn!("bad copy log: {:?}", log)
+ }
+ }
+ NixLog::Start { text, typ, id, .. }
+ if typ == 0 || typ == 102 || typ == 103 || typ == 104 =>
+ {
+ if !text.is_empty()
+ && text != "querying info about missing paths"
+ && text != "copying 0 paths"
+ // Too much spam on lazy-trees branch
+ && !(text.starts_with("copying '") && text.ends_with("' to the store"))
+ {
+ let span = info_span!("job");
+ span.pb_start();
+ span.pb_set_message(&process_message(text.trim()));
+ self.spans.insert(id, span);
+ info!(target: "nix", "{}", text);
+ }
+ }
+ NixLog::Start {
+ text,
+ level: 0,
+ typ: 108,
+ ..
+ } if text.is_empty() => {
+ // Cache lookup? Coupled with copy log
+ }
+ NixLog::Start {
+ text,
+ level: 4,
+ typ: 109,
+ ..
+ } if text.starts_with("querying info about ") => {
+ // Cache lookup
+ }
+ NixLog::Start {
+ text,
+ level: 4,
+ typ: 101,
+ ..
+ } if text.starts_with("downloading ") => {
+ // NAR downloading, coupled with copy log
+ }
+ NixLog::Start {
+ text,
+ level: 1,
+ typ: 111,
+ ..
+ } if text.starts_with("waiting for a machine to build ") => {
+ // Useless repeating notification about build
+ }
+ NixLog::Start {
+ text,
+ level: 3,
+ typ: 111,
+ ..
+ } if text.starts_with("resolved derivation: ") => {
+ // CA resolved
+ }
+ NixLog::Start {
+ text,
+ level: 1,
+ typ: 111,
+ id,
+ ..
+ } if text.starts_with("waiting for lock on ") => {
+ let mut drv = text.strip_prefix("waiting for lock on ").unwrap();
+ if let Some(txt) = drv.strip_prefix("\u{1b}[35;1m'") {
+ drv = txt;
+ }
+ if let Some(txt) = drv.strip_suffix("'\u{1b}[0m") {
+ drv = txt;
+ }
+ if let Some(txt) = drv.split("', '").next() {
+ drv = txt;
+ }
+ if let Some(pkg) = drv.strip_prefix("/nix/store/") {
+ let mut it = pkg.splitn(2, '-');
+ it.next();
+ if let Some(pkg) = it.next() {
+ drv = pkg;
+ }
+ }
+ let span = info_span!("waiting on drv", drv);
+ span.pb_start();
+ self.spans.insert(id, span);
+ // Concurrent build of the same message
+ }
+ NixLog::Stop { id, .. } => {
+ self.spans.remove(&id);
+ }
+ NixLog::Result { fields, id, typ } if typ == 101 && !fields.is_empty() => {
+ if let Some(span) = self.spans.get(&id) {
+ if let LogField::String(s) = &fields[0] {
+ span.pb_set_message(&process_message(s.trim()));
+ } else {
+ warn!("bad fields: {fields:?}");
+ }
+ } else {
+ warn!("unknown result id: {id} {typ} {fields:?}");
+ }
+ // dbg!(fields, id, typ);
+ }
+ NixLog::Result { fields, id, typ } if typ == 105 && fields.len() >= 4 => {
+ if let Some(span) = self.spans.get(&id) {
+ if let [LogField::Num(done), LogField::Num(expected), LogField::Num(_running), LogField::Num(_failed)] =
+ &fields[..4]
+ {
+ span.pb_set_length(*expected);
+ span.pb_set_position(*done);
+ } else {
+ warn!("bad fields: {fields:?}");
+ }
+ } else {
+ // warn!("unknown result id: {id} {typ} {fields:?}");
+ // Unaccounted progress.
+ }
+ // dbg!(fields, id, typ);
+ }
+ NixLog::Result { typ, .. } if typ == 104 || typ == 106 => {
+ // Set phase, expected
+ }
+ _ => warn!("unknown log: {:?}", log),
+ };
+ } else {
+ let e = e.trim();
+ if e.starts_with("Failed tcsetattr(TCSADRAIN): ") {
+ return;
+ }
+ info!("{e}")
+ }
+ }
+}
crates/better-command/src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/better-command/src/lib.rs
@@ -0,0 +1,17 @@
+mod handler;
+pub use handler::{Handler, PlainHandler, NoopHandler, NixHandler, ClonableHandler};
+
+pub fn add(left: usize, right: usize) -> usize {
+ left + right
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn it_works() {
+ let result = add(2, 2);
+ assert_eq!(result, 4);
+ }
+}