debian-workbench-0.3.0/.cargo_vcs_info.json0000644000000001561046102023000142620ustar { "git": { "sha1": "3b9cbb7b9877a7eb426a9dcfd1077d1f415d556f" }, "path_in_vcs": "debian-workbench" }debian-workbench-0.3.0/Cargo.lock0000644000002537061046102023000122500ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "addr2line" version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] [[package]] name = "adler2" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "android_system_properties" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ "libc", ] [[package]] name = "anstream" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", "windows-sys 0.61.2", ] [[package]] name = "anyhow" version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "atomic-waker" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" dependencies = [ "aws-lc-sys", "zeroize", ] [[package]] name = "aws-lc-sys" version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" dependencies = [ "cc", "cmake", "dunce", "fs_extra", ] [[package]] name = "backtrace" version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", "windows-link", ] [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "breezyshim" version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3758bdbf07c417a35b2b3864dd79ba59f6f083815da3e6666beb15786bdb0b8" dependencies = [ "chrono", "ctor", "deb822-lossless", "debian-changelog", "debian-control", "debversion", "difflib", "dirty-tracker", "lazy-regex", "lazy_static", "log", "patchkit", "percent-encoding", "pyo3", "pyo3-filelike", "regex", "serde", "tempfile", "url", "whoami", ] [[package]] name = "bumpalo" version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bytes" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" version = "1.2.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" dependencies = [ "find-msvc-tools", "jobserver", "libc", "shlex", ] [[package]] name = "cesu8" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", "windows-link", ] [[package]] name = "clap" version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", ] [[package]] name = "clap_builder" version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", "clap_lex", "strsim", ] [[package]] name = "clap_derive" version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "clap_lex" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cmake" version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" dependencies = [ "cc", ] [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "combine" version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", ] [[package]] name = "configparser" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" [[package]] name = "core-foundation" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "core-foundation" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "countme" version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" [[package]] name = "cpufeatures" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crossbeam-channel" version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", ] [[package]] name = "csv" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" dependencies = [ "csv-core", "itoa", "ryu", "serde_core", ] [[package]] name = "csv-core" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" dependencies = [ "memchr", ] [[package]] name = "ctor" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e" dependencies = [ "ctor-proc-macro", "dtor", ] [[package]] name = "ctor-proc-macro" version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" [[package]] name = "deb822-derive" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e83ef29a094bcb2b7dd0f609ace7f5a34ef9a62e0731ebd350637640320a3b15" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "deb822-fast" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "114c474fa4cd5d6d24bb5e68b36fa4ef70f5b830e3cc14a9b66a12e71a15aeb9" dependencies = [ "deb822-derive", ] [[package]] name = "deb822-lossless" version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faaa7a773199a9a6d6bcacd9a838bf55de295bc2f918870d5245712efca46d74" dependencies = [ "pyo3", "regex", "rowan", "serde", ] [[package]] name = "debian-analyzer" version = "0.160.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea81c6cbcb3cda14ca1e19c4df63d9978391cdab5e78144093aa8cc32c915d7" dependencies = [ "breezyshim", "chrono", "configparser", "deb822-lossless", "debian-changelog", "debian-control", "debian-copyright", "debversion", "dep3", "difflib", "distro-info", "filetime", "hex", "lazy-regex", "lazy_static", "log", "makefile-lossless", "maplit", "merge3", "patchkit", "pyo3", "quote", "regex", "reqwest", "semver", "serde", "serde_json", "sha1", "tempfile", "toml_edit", "url", ] [[package]] name = "debian-changelog" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e861544f3732a63762386518e660af2dc5637cdaf6d8f0091faf9ac00cc10755" dependencies = [ "chrono", "debversion", "lazy-regex", "log", "rowan", "textwrap", "whoami", ] [[package]] name = "debian-control" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa82175cd66315e4da43c2c0d6a91a925c0c0592a5fb0e8d34d3d843bd221def" dependencies = [ "chrono", "deb822-fast", "deb822-lossless", "debversion", "pyo3", "regex", "rowan", "url", ] [[package]] name = "debian-copyright" version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3945e6b8948e9c84a5b0bd5ae9cfd632ada990d0da4fc49ff27e85274d5dbe08" dependencies = [ "deb822-fast", "deb822-lossless", "debversion", "regex", ] [[package]] name = "debian-workbench" version = "0.3.0" dependencies = [ "breezyshim", "chrono", "clap", "configparser", "deb822-lossless", "debian-analyzer", "debian-changelog", "debian-control", "debian-copyright", "debversion", "dep3", "difflib", "distro-info", "env_logger", "filetime", "hex", "lazy-regex", "lazy_static", "log", "makefile-lossless", "maplit", "merge3", "patchkit", "regex", "reqwest", "semver", "serde", "serde_json", "serial_test", "sha1", "svp-client", "tempfile", "toml_edit", "url", ] [[package]] name = "debversion" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8ba0e270fb9f27dbb4c46e08d2ad27e69501d6ca573bfdf9e0aa793e7377929" dependencies = [ "chrono", "lazy-regex", "num-bigint", "pyo3", "serde", ] [[package]] name = "dep3" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "832c55a9cf6298eb1c6a82b827cabdedac7f9d0053f334739cfdab36637c5305" dependencies = [ "chrono", "deb822-fast", "deb822-lossless", "url", ] [[package]] name = "difflib" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", ] [[package]] name = "dirty-tracker" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57f673af5cabab0d10b822fae4b348c2f5fdc56d90474e26f5dcde0f94fce488" dependencies = [ "notify", "tempfile", ] [[package]] name = "displaydoc" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "distro-info" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef12237f2ced990e453ec0b69230752e73be0a357817448c50a62f8bbbe0ca71" dependencies = [ "chrono", "csv", "failure", ] [[package]] name = "dtor" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" dependencies = [ "dtor-proc-macro", ] [[package]] name = "dtor-proc-macro" version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" [[package]] name = "dunce" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "encoding_rs" version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] name = "env_filter" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", ] [[package]] name = "env_logger" version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "anstream", "anstyle", "env_filter", "jiff", "log", ] [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", "windows-sys 0.61.2", ] [[package]] name = "failure" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" dependencies = [ "backtrace", "failure_derive", ] [[package]] name = "failure_derive" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", "synstructure 0.12.6", ] [[package]] name = "fastrand" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "filetime" version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", "libredox", ] [[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "form_urlencoded" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] [[package]] name = "fs_extra" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "fsevent-sys" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" dependencies = [ "libc", ] [[package]] name = "futures-channel" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", ] [[package]] name = "futures-core" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", "futures-util", ] [[package]] name = "futures-io" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-sink" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", "futures-io", "futures-sink", "futures-task", "memchr", "pin-project-lite", "slab", ] [[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", ] [[package]] name = "getrandom" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", "libc", "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] [[package]] name = "getrandom" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", "wasip2", "wasip3", ] [[package]] name = "gimli" version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "h2" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", "http", "indexmap", "slab", "tokio", "tokio-util", "tracing", ] [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "foldhash", ] [[package]] name = "hashbrown" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", "itoa", ] [[package]] name = "http-body" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", ] [[package]] name = "http-body-util" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", "http", "http-body", "pin-project-lite", ] [[package]] name = "httparse" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", "futures-channel", "futures-core", "h2", "http", "http-body", "httparse", "itoa", "pin-project-lite", "smallvec", "tokio", "want", ] [[package]] name = "hyper-rustls" version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", "hyper-util", "rustls", "tokio", "tokio-rustls", "tower-service", ] [[package]] name = "hyper-util" version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64", "bytes", "futures-channel", "futures-util", "http", "http-body", "hyper", "ipnet", "libc", "percent-encoding", "pin-project-lite", "socket2", "system-configuration", "tokio", "tower-service", "tracing", "windows-registry", ] [[package]] name = "iana-time-zone" version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "log", "wasm-bindgen", "windows-core", ] [[package]] name = "iana-time-zone-haiku" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ "cc", ] [[package]] name = "icu_collections" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", "utf8_iter", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_locale_core" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", "tinystr", "writeable", "zerovec", ] [[package]] name = "icu_normalizer" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", "zerovec", ] [[package]] name = "icu_normalizer_data" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", "writeable", "yoke", "zerofrom", "zerotrie", "zerovec", ] [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "idna" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", "utf8_iter", ] [[package]] name = "idna_adapter" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", ] [[package]] name = "indexmap" version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", "hashbrown 0.17.0", "serde", "serde_core", ] [[package]] name = "inotify" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" dependencies = [ "bitflags 1.3.2", "inotify-sys", "libc", ] [[package]] name = "inotify-sys" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" dependencies = [ "libc", ] [[package]] name = "ipnet" version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" dependencies = [ "memchr", "serde", ] [[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" dependencies = [ "jiff-static", "log", "portable-atomic", "portable-atomic-util", "serde_core", ] [[package]] name = "jiff-static" version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "jni" version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ "cesu8", "cfg-if", "combine", "jni-sys 0.3.1", "log", "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] [[package]] name = "jni-sys" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" dependencies = [ "jni-sys 0.4.1", ] [[package]] name = "jni-sys" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" dependencies = [ "jni-sys-macros", ] [[package]] name = "jni-sys-macros" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", "syn 2.0.117", ] [[package]] name = "jobserver" version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ "cfg-if", "futures-util", "once_cell", "wasm-bindgen", ] [[package]] name = "kqueue" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" dependencies = [ "kqueue-sys", "libc", ] [[package]] name = "kqueue-sys" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" dependencies = [ "bitflags 1.3.2", "libc", ] [[package]] name = "lazy-regex" version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bae91019476d3ec7147de9aa291cadb6d870abf2f3015d2da73a90325ac1496" dependencies = [ "lazy-regex-proc_macros", "once_cell", "regex", ] [[package]] name = "lazy-regex-proc_macros" version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4de9c1e1439d8b7b3061b2d209809f447ca33241733d9a3c01eabf2dc8d94358" dependencies = [ "proc-macro2", "quote", "regex", "syn 2.0.117", ] [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128fmt" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libredox" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ "bitflags 2.11.1", "libc", "plain", "redox_syscall 0.7.4", ] [[package]] name = "linux-raw-sys" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ "scopeguard", ] [[package]] name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru-slab" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "makefile-lossless" version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49c5d6730a2357dfe4afd130b5fc9952fd312dad81d7adf4ede3be33df9604a5" dependencies = [ "log", "rowan", ] [[package]] name = "maplit" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "memchr" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "merge3" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4b277bc3c7e2bc163abc6c0069f53715b52dc34442c0e807cc8758c7113524f" dependencies = [ "clap", "difflib", ] [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] [[package]] name = "mio" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", "wasi", "windows-sys 0.48.0", ] [[package]] name = "mio" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", "windows-sys 0.61.2", ] [[package]] name = "notify" version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ "bitflags 2.11.1", "crossbeam-channel", "filetime", "fsevent-sys", "inotify", "kqueue", "libc", "log", "mio 0.8.11", "walkdir", "windows-sys 0.48.0", ] [[package]] name = "num-bigint" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", ] [[package]] name = "num-integer" version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ "num-traits", ] [[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "object" version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] [[package]] name = "once_cell" version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl-probe" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "parking_lot" version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall 0.5.18", "smallvec", "windows-link", ] [[package]] name = "patchkit" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5364f5b47b05204e0eb3e5427657769dd1924f4ec3e2b823c0575546049439a" dependencies = [ "chrono", "lazy-regex", "lazy_static", "once_cell", "proc-macro2", "regex", "rowan", ] [[package]] name = "percent-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project-lite" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "plain" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "portable-atomic" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] [[package]] name = "ppv-lite86" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] [[package]] name = "prettyplease" version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn 2.0.117", ] [[package]] name = "proc-macro2" version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "pyo3" version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12" dependencies = [ "chrono", "libc", "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", "serde", ] [[package]] name = "pyo3-build-config" version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e" dependencies = [ "target-lexicon", ] [[package]] name = "pyo3-ffi" version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e" dependencies = [ "libc", "pyo3-build-config", ] [[package]] name = "pyo3-filelike" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a8cb6cd0231ea816b4452c0cd37b5215f9ec45b66ed3e748fad8eb39cfd4997" dependencies = [ "pyo3", ] [[package]] name = "pyo3-macros" version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", "syn 2.0.117", ] [[package]] name = "pyo3-macros-backend" version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb" dependencies = [ "heck", "proc-macro2", "pyo3-build-config", "quote", "syn 2.0.117", ] [[package]] name = "quinn" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash 2.1.2", "rustls", "socket2", "thiserror 2.0.18", "tokio", "tracing", "web-time", ] [[package]] name = "quinn-proto" version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", "rand", "ring", "rustc-hash 2.1.2", "rustls", "rustls-pki-types", "slab", "thiserror 2.0.18", "tinyvec", "tracing", "web-time", ] [[package]] name = "quinn-udp" version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2", "tracing", "windows-sys 0.60.2", ] [[package]] name = "quote" version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "r-efi" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] [[package]] name = "redox_syscall" version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags 2.11.1", ] [[package]] name = "redox_syscall" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ "bitflags 2.11.1", ] [[package]] name = "regex" version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ "base64", "bytes", "encoding_rs", "futures-channel", "futures-core", "futures-util", "h2", "http", "http-body", "http-body-util", "hyper", "hyper-rustls", "hyper-util", "js-sys", "log", "mime", "percent-encoding", "pin-project-lite", "quinn", "rustls", "rustls-pki-types", "rustls-platform-verifier", "serde", "serde_json", "sync_wrapper", "tokio", "tokio-rustls", "tower", "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", ] [[package]] name = "ring" version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", ] [[package]] name = "rowan" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "417a3a9f582e349834051b8a10c8d71ca88da4211e4093528e36b9845f6b5f21" dependencies = [ "countme", "hashbrown 0.14.5", "rustc-hash 1.1.0", "text-size", ] [[package]] name = "rustc-demangle" version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustix" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", "windows-sys 0.61.2", ] [[package]] name = "rustls" version = "0.23.39" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e" dependencies = [ "aws-lc-rs", "once_cell", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-native-certs" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", "security-framework", ] [[package]] name = "rustls-pki-types" version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "web-time", "zeroize", ] [[package]] name = "rustls-platform-verifier" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", "jni", "log", "once_cell", "rustls", "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki", "security-framework", "security-framework-sys", "webpki-root-certs", "windows-sys 0.61.2", ] [[package]] name = "rustls-platform-verifier-android" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", ] [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "scc" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" dependencies = [ "sdd", ] [[package]] name = "schannel" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sdd" version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" [[package]] name = "security-framework" version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags 2.11.1", "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", ] [[package]] name = "serde_core" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "serde_json" version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", "serde", "serde_core", "zmij", ] [[package]] name = "serial_test" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "911bd979bf1070a3f3aa7b691a3b3e9968f339ceeec89e08c280a8a22207a32f" dependencies = [ "futures-executor", "futures-util", "log", "once_cell", "parking_lot", "scc", "serial_test_derive", ] [[package]] name = "serial_test_derive" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a7d91949b85b0d2fb687445e448b40d322b6b3e4af6b44a29b21d9a5f33e6d9" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "sha1" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", "digest", ] [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "slab" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smawk" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "socket2" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", "windows-sys 0.61.2", ] [[package]] name = "stable_deref_trait" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "svp-client" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cbf71541e926b5bd10daa99f2f1670a5526b4758aa792ffb45eaaf146add439" dependencies = [ "log", "serde", "serde_json", "url", ] [[package]] name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "syn" version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] [[package]] name = "synstructure" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", "unicode-xid", ] [[package]] name = "synstructure" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "system-configuration" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ "bitflags 2.11.1", "core-foundation 0.9.4", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "target-lexicon" version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "tempfile" version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", ] [[package]] name = "text-size" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" [[package]] name = "textwrap" version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" dependencies = [ "smawk", "unicode-linebreak", "unicode-width", ] [[package]] name = "thiserror" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ "thiserror-impl 2.0.18", ] [[package]] name = "thiserror-impl" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "thiserror-impl" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "tinystr" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", ] [[package]] name = "tinyvec" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" version = "1.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" dependencies = [ "bytes", "libc", "mio 1.2.0", "pin-project-lite", "socket2", "windows-sys 0.61.2", ] [[package]] name = "tokio-rustls" version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", ] [[package]] name = "tokio-util" version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", ] [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ "indexmap", "toml_datetime", "toml_parser", "toml_writer", "winnow", ] [[package]] name = "toml_parser" version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ "winnow", ] [[package]] name = "toml_writer" version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tower" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", "pin-project-lite", "sync_wrapper", "tokio", "tower-layer", "tower-service", ] [[package]] name = "tower-http" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags 2.11.1", "bytes", "futures-util", "http", "http-body", "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", ] [[package]] name = "tower-layer" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", ] [[package]] name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-linebreak" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-width" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", "serde_derive", ] [[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", ] [[package]] name = "want" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ "try-lock", ] [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ "wit-bindgen 0.57.1", ] [[package]] name = "wasip3" version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ "wit-bindgen 0.51.0", ] [[package]] name = "wasite" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" version = "0.4.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ "bumpalo", "proc-macro2", "quote", "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-encoder" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" dependencies = [ "leb128fmt", "wasmparser", ] [[package]] name = "wasm-metadata" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", "indexmap", "wasm-encoder", "wasmparser", ] [[package]] name = "wasmparser" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.11.1", "hashbrown 0.15.5", "indexmap", "semver", ] [[package]] name = "web-sys" version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "web-time" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "webpki-root-certs" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" dependencies = [ "rustls-pki-types", ] [[package]] name = "whoami" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" dependencies = [ "libredox", "wasite", "web-sys", ] [[package]] name = "winapi-util" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "windows-core" version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", "windows-link", "windows-result", "windows-strings", ] [[package]] name = "windows-implement" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "windows-interface" version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-registry" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ "windows-link", "windows-result", "windows-strings", ] [[package]] name = "windows-result" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] [[package]] name = "windows-sys" version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ "windows-targets 0.42.2", ] [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets 0.48.5", ] [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets 0.52.6", ] [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ "windows-targets 0.53.5", ] [[package]] name = "windows-sys" version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] [[package]] name = "windows-targets" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ "windows_aarch64_gnullvm 0.42.2", "windows_aarch64_msvc 0.42.2", "windows_i686_gnu 0.42.2", "windows_i686_msvc 0.42.2", "windows_x86_64_gnu 0.42.2", "windows_x86_64_gnullvm 0.42.2", "windows_x86_64_msvc 0.42.2", ] [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm 0.48.5", "windows_aarch64_msvc 0.48.5", "windows_i686_gnu 0.48.5", "windows_i686_msvc 0.48.5", "windows_x86_64_gnu 0.48.5", "windows_x86_64_gnullvm 0.48.5", "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] [[package]] name = "windows-targets" version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", "windows_i686_gnullvm 0.53.1", "windows_i686_msvc 0.53.1", "windows_x86_64_gnu 0.53.1", "windows_x86_64_gnullvm 0.53.1", "windows_x86_64_msvc 0.53.1", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" dependencies = [ "wit-bindgen-rust-macro", ] [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "wit-bindgen-core" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" dependencies = [ "anyhow", "heck", "wit-parser", ] [[package]] name = "wit-bindgen-rust" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", "indexmap", "prettyplease", "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", ] [[package]] name = "wit-bindgen-rust-macro" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" dependencies = [ "anyhow", "prettyplease", "proc-macro2", "quote", "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] [[package]] name = "wit-component" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.11.1", "indexmap", "log", "serde", "serde_derive", "serde_json", "wasm-encoder", "wasm-metadata", "wasmparser", "wit-parser", ] [[package]] name = "wit-parser" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", "indexmap", "log", "semver", "serde", "serde_derive", "serde_json", "unicode-xid", "wasmparser", ] [[package]] name = "writeable" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "yoke" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", "zerofrom", ] [[package]] name = "yoke-derive" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", "synstructure 0.13.2", ] [[package]] name = "zerocopy" version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "zerofrom" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", "synstructure 0.13.2", ] [[package]] name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", "zerofrom", ] [[package]] name = "zerovec" version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] [[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" debian-workbench-0.3.0/Cargo.toml0000644000000064071046102023000122650ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "debian-workbench" version = "0.3.0" authors = ["Jelmer Vernooij "] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "Debian workbench" homepage = "https://github.com/jelmer/debian-analyzer" documentation = "https://docs.rs/debian-workbench" readme = false license = "GPL-2.0+" repository = "https://github.com/jelmer/debian-analyzer" [features] cli = [ "dep:clap", "dep:env_logger", ] debian = ["dep:debian-analyzer"] default = ["merge3"] merge3 = ["dep:merge3"] svp = ["dep:svp-client"] [lib] name = "debian_workbench" path = "src/lib.rs" [[bin]] name = "deb-vcs-publish" path = "src/bin/deb-vcs-publish.rs" required-features = ["cli"] [[bin]] name = "detect-changelog-behaviour" path = "src/bin/detect-changelog-behaviour.rs" required-features = ["cli"] [dependencies.breezyshim] version = ">=0.7.5, <0.8" features = [ "debian", "dirty-tracker", ] [dependencies.chrono] version = "0.4.42" features = ["serde"] [dependencies.clap] version = "4,<5" features = [ "derive", "env", "suggestions", "cargo", "string", ] optional = true [dependencies.configparser] version = "3" [dependencies.deb822-lossless] version = ">=0.5.0, <0.6" [dependencies.debian-analyzer] version = ">=0.160.14, <0.161" optional = true [dependencies.debian-changelog] version = "0.2.10" [dependencies.debian-control] version = ">=0.2.8, <0.4" [dependencies.debian-copyright] version = ">=0.1.29, <0.2" [dependencies.debversion] version = ">=0.5.0, <0.6" features = [ "serde", "python-debian", ] [dependencies.dep3] version = ">=0.2.0, <0.3" features = ["lossless"] [dependencies.difflib] version = "0.4.0" [dependencies.distro-info] version = ">=0.4.0, <0.5" [dependencies.env_logger] version = ">=0.10, <0.12" optional = true [dependencies.filetime] version = "0.2.10" [dependencies.hex] version = "0.4.3" [dependencies.lazy-regex] version = "3.4" [dependencies.lazy_static] version = "1.5" [dependencies.log] version = "0.4.18" [dependencies.makefile-lossless] version = ">=0.3.17, <0.4" [dependencies.maplit] version = "1.0.2" [dependencies.merge3] version = "0.2" optional = true [dependencies.patchkit] version = ">=0.2.2, <0.3" [dependencies.regex] version = "1.12.2" [dependencies.reqwest] version = ">=0.12.10, <0.14" features = [ "blocking", "json", ] [dependencies.semver] version = "1" [dependencies.serde] version = "1.0.145" features = ["derive"] [dependencies.serde_json] version = "1.0.85" [dependencies.sha1] version = "0.10.6" [dependencies.svp-client] version = "0.2.0" optional = true [dependencies.tempfile] version = "3.20" [dependencies.toml_edit] version = ">=0.23, <0.26" [dependencies.url] version = "2.4" [dev-dependencies.serial_test] version = ">=3, <4" debian-workbench-0.3.0/Cargo.toml.orig000064400000000000000000000040141046102023000157140ustar 00000000000000[package] name = "debian-workbench" version = "0.3.0" authors = [ "Jelmer Vernooij "] edition = "2021" license = "GPL-2.0+" description = "Debian workbench" repository = "https://github.com/jelmer/debian-analyzer" homepage = "https://github.com/jelmer/debian-analyzer" documentation = "https://docs.rs/debian-workbench" [dependencies] debversion = { version = ">=0.5.0, <0.6", features = ["serde", "python-debian"] } log = "0.4.18" lazy-regex = "3.4" serde = { version = "1.0.145", features = ["derive"] } breezyshim = { version = ">=0.7.5, <0.8", features = ["debian", "dirty-tracker"] } configparser = "3" clap = { version = "4,<5", features = ["derive", "env", "suggestions", "cargo", "string"], optional = true } env_logger = { version = ">=0.10, <0.12", optional = true } serde_json = "1.0.85" chrono = { version = "0.4.42", features = ["serde"] } distro-info = { version = ">=0.4.0, <0.5" } url = "2.4" tempfile = "3.20" maplit = "1.0.2" lazy_static = "1.5" debian-changelog = "0.2.10" debian-control = ">=0.2.8, <0.4" debian-copyright = ">=0.1.29, <0.2" makefile-lossless = ">=0.3.17, <0.4" patchkit = ">=0.2.2, <0.3" dep3 = { version = ">=0.2.0, <0.3", features = ["lossless"] } reqwest = { version = ">=0.12.10, <0.14", features = ["blocking", "json"] } merge3 = { version = "0.2", optional = true } difflib = "0.4.0" deb822-lossless = ">=0.5.0, <0.6" toml_edit = ">=0.23, <0.26" semver = "1" filetime = "0.2.10" sha1 = "0.10.6" hex = "0.4.3" svp-client = { version = "0.2.0", optional = true } regex = "1.12.2" debian-analyzer = { path = "../debian-analyzer", version = ">=0.160.14, <0.161", optional = true } [features] svp = ["dep:svp-client"] default = ["merge3"] cli = ["dep:clap", "dep:env_logger"] merge3 = ["dep:merge3"] debian = ["dep:debian-analyzer"] [lib] [[bin]] name = "detect-changelog-behaviour" path = "src/bin/detect-changelog-behaviour.rs" required-features = ["cli"] [[bin]] name = "deb-vcs-publish" path = "src/bin/deb-vcs-publish.rs" required-features = ["cli"] [dev-dependencies] serial_test = ">=3, <4" debian-workbench-0.3.0/src/abstract_control.rs000064400000000000000000000364011046102023000175320ustar 00000000000000//! Abstract interface for editing debian packages, whether backed by real control files or //! debcargo files. use crate::relations::ensure_relation; use debian_control::lossless::relations::{Entry, Relations}; use std::path::Path; /// Interface for editing debian packages, whether backed by real control files or debcargo files. pub trait AbstractControlEditor { /// Get the source package. fn source<'a>(&'a mut self) -> Option + 'a>>; /// Get the binary packages. fn binaries<'a>(&'a mut self) -> Vec>; /// Commit the changes. fn commit(&self) -> bool; /// Wrap and sort the control file. fn wrap_and_sort(&mut self); } /// An abstract source package. pub trait AbstractSource<'a> { /// Get the name of the source package. fn name(&self) -> Option; /// Ensure that a build dependency is present. fn ensure_build_dep(&mut self, dep: Entry); /// Set the maintainer of the source package. fn set_maintainer(&mut self, maintainer: &str); /// Set the uploaders of the source package. fn set_uploaders(&mut self, uploaders: &[&str]); /// Set the VCS URL for the source package. fn set_vcs_url(&mut self, vcs_type: &str, url: &str); /// Get the VCS URL for the source package. fn get_vcs_url(&self, vcs_type: &str) -> Option; } /// An abstract binary package. pub trait AbstractBinary { /// Get the name of the binary package. fn name(&self) -> Option; } use crate::debcargo::{DebcargoBinary, DebcargoEditor, DebcargoSource}; use debian_control::{Binary as PlainBinary, Control as PlainControl, Source as PlainSource}; impl AbstractControlEditor for DebcargoEditor { fn source<'a>(&'a mut self) -> Option + 'a>> { Some(Box::new(DebcargoEditor::source(self)) as Box>) } fn binaries<'a>(&'a mut self) -> Vec> { DebcargoEditor::binaries(self) .map(|b| Box::new(b) as Box) .collect() } fn commit(&self) -> bool { DebcargoEditor::commit(self).unwrap() } fn wrap_and_sort(&mut self) {} } impl AbstractBinary for PlainBinary { fn name(&self) -> Option { self.name() } } impl AbstractSource<'_> for PlainSource { fn name(&self) -> Option { self.name() } fn ensure_build_dep(&mut self, dep: Entry) { if let Some(mut build_deps) = self.build_depends() { ensure_relation(&mut build_deps, dep); self.set_build_depends(&build_deps); } else { self.set_build_depends(&Relations::from(vec![dep])); } } fn set_maintainer(&mut self, maintainer: &str) { (self as &mut debian_control::lossless::Source).set_maintainer(maintainer); } fn set_uploaders(&mut self, uploaders: &[&str]) { (self as &mut debian_control::lossless::Source).set_uploaders(uploaders); } fn set_vcs_url(&mut self, vcs_type: &str, url: &str) { let field_name = format!("Vcs-{}", vcs_type); self.as_mut_deb822().set(&field_name, url); } fn get_vcs_url(&self, vcs_type: &str) -> Option { let field_name = format!("Vcs-{}", vcs_type); self.as_deb822().get(&field_name) } } impl AbstractBinary for DebcargoBinary<'_> { fn name(&self) -> Option { Some(self.name().to_string()) } } impl<'a> AbstractSource<'a> for DebcargoSource<'a> { fn name(&self) -> Option { self.name() } fn ensure_build_dep(&mut self, dep: Entry) { // TODO: Check that it's not already there if let Some(build_deps) = self .toml_section_mut() .get_mut("build_depends") .and_then(|v| v.as_array_mut()) { build_deps.push(dep.to_string()); } } fn set_maintainer(&mut self, maintainer: &str) { (self as &mut crate::debcargo::DebcargoSource).set_maintainer(maintainer); } fn set_uploaders(&mut self, uploaders: &[&str]) { (self as &mut crate::debcargo::DebcargoSource) .set_uploaders(uploaders.iter().map(|s| s.to_string()).collect::>()); } fn set_vcs_url(&mut self, vcs_type: &str, url: &str) { (self as &mut crate::debcargo::DebcargoSource).set_vcs_url(vcs_type, url); } fn get_vcs_url(&self, vcs_type: &str) -> Option { match vcs_type.to_lowercase().as_str() { "git" => self.vcs_git(), "browser" => self.vcs_browser(), _ => self.get_extra_field(&format!("Vcs-{}", vcs_type)), } } } impl> AbstractControlEditor for E { fn source<'a>(&'a mut self) -> Option + 'a>> { PlainControl::source(self).map(|s| Box::new(s) as Box) } fn binaries<'a>(&'a mut self) -> Vec> { PlainControl::binaries(self) .map(|b| Box::new(b) as Box) .collect() } fn commit(&self) -> bool { !(self as &dyn crate::editor::Editor) .commit() .unwrap() .is_empty() } fn wrap_and_sort(&mut self) { (self as &mut dyn crate::editor::Editor).wrap_and_sort( deb822_lossless::Indentation::Spaces(4), false, None, ) } } /// Open a control file for editing. pub fn edit_control<'a>( tree: &dyn breezyshim::workingtree::WorkingTree, subpath: &Path, ) -> Result, crate::editor::EditorError> { if tree.has_filename(&subpath.join("debian/debcargo.toml")) { Ok(Box::new(crate::debcargo::DebcargoEditor::from_directory( &tree.abspath(subpath).unwrap(), )?)) } else { let control_path = tree.abspath(&subpath.join(std::path::Path::new("debian/control"))); Ok(Box::new(crate::control::TemplatedControlEditor::open( control_path.unwrap(), )?) as Box) } } #[cfg(test)] mod tests { use breezyshim::controldir::{create_standalone_workingtree, ControlDirFormat}; use breezyshim::prelude::*; use std::path::Path; use std::str::FromStr; #[test] fn test_edit_control_debcargo() { let td = tempfile::tempdir().unwrap(); let tree = create_standalone_workingtree(td.path(), &ControlDirFormat::default()).unwrap(); // Write dummy debcargo.toml tree.mkdir(Path::new("debian")).unwrap(); std::fs::write( td.path().join("debian/debcargo.toml"), br#" maintainer = "Alice " homepage = "https://example.com" description = "Example package" "#, ) .unwrap(); std::fs::write( td.path().join("Cargo.toml"), br#" [package] name = "example" version = "0.1.0" edition = "2018" "#, ) .unwrap(); tree.add(&[(Path::new("debian")), (Path::new("debian/debcargo.toml"))]) .unwrap(); let editor = super::edit_control(&tree, Path::new("")).unwrap(); editor.commit(); } #[test] fn test_edit_control_regular() { let td = tempfile::tempdir().unwrap(); let tree = create_standalone_workingtree(td.path(), &ControlDirFormat::default()).unwrap(); // Write dummy debian/control tree.mkdir(Path::new("debian")).unwrap(); tree.put_file_bytes_non_atomic( Path::new("debian/control"), br#" Source: example Maintainer: Alice Homepage: https://example.com Package: example Architecture: any Description: Example package "#, ) .unwrap(); tree.add(&[(Path::new("debian")), (Path::new("debian/control"))]) .unwrap(); let editor = super::edit_control(&tree, Path::new("")).unwrap(); editor.commit(); } #[test] fn test_edit_source_ensure_build_depends() { let td = tempfile::tempdir().unwrap(); let tree = create_standalone_workingtree(td.path(), &ControlDirFormat::default()).unwrap(); // Write dummy debian/control tree.mkdir(Path::new("debian")).unwrap(); tree.put_file_bytes_non_atomic( Path::new("debian/control"), br#" Source: example Maintainer: Alice Build-Depends: libc6 Package: example Architecture: any Description: Example package "#, ) .unwrap(); tree.add(&[Path::new("debian/control")]).unwrap(); let mut editor = super::edit_control(&tree, Path::new("")).unwrap(); let mut source = editor.source().unwrap(); source.ensure_build_dep( debian_control::lossless::relations::Entry::from_str("libssl-dev").unwrap(), ); std::mem::drop(source); editor.commit(); let text = tree.get_file_text(Path::new("debian/control")).unwrap(); assert_eq!( std::str::from_utf8(&text).unwrap(), r#" Source: example Maintainer: Alice Build-Depends: libc6, libssl-dev Package: example Architecture: any Description: Example package "# ); } #[test] fn test_abstract_source_set_vcs_url_plain() { let td = tempfile::tempdir().unwrap(); let tree = create_standalone_workingtree(td.path(), &ControlDirFormat::default()).unwrap(); // Write dummy debian/control tree.mkdir(Path::new("debian")).unwrap(); tree.put_file_bytes_non_atomic( Path::new("debian/control"), br#"Source: example Maintainer: Alice Package: example Architecture: any Description: Example package "#, ) .unwrap(); tree.add(&[Path::new("debian/control")]).unwrap(); let mut editor = super::edit_control(&tree, Path::new("")).unwrap(); let mut source = editor.source().unwrap(); // Test setting various VCS URLs source.set_vcs_url("Git", "https://github.com/example/repo.git"); source.set_vcs_url("Browser", "https://github.com/example/repo"); std::mem::drop(source); editor.commit(); let text = tree.get_file_text(Path::new("debian/control")).unwrap(); assert_eq!( std::str::from_utf8(&text).unwrap(), r#"Source: example Maintainer: Alice Vcs-Git: https://github.com/example/repo.git Vcs-Browser: https://github.com/example/repo Package: example Architecture: any Description: Example package "# ); } #[test] fn test_abstract_source_set_vcs_url_debcargo() { let td = tempfile::tempdir().unwrap(); let tree = create_standalone_workingtree(td.path(), &ControlDirFormat::default()).unwrap(); // Write dummy debcargo.toml tree.mkdir(Path::new("debian")).unwrap(); std::fs::write( td.path().join("debian/debcargo.toml"), br#"maintainer = "Alice " "#, ) .unwrap(); std::fs::write( td.path().join("Cargo.toml"), br#"[package] name = "example" version = "0.1.0" "#, ) .unwrap(); tree.add(&[(Path::new("debian")), (Path::new("debian/debcargo.toml"))]) .unwrap(); let mut editor = super::edit_control(&tree, Path::new("")).unwrap(); let mut source = editor.source().unwrap(); // Test setting native VCS URLs source.set_vcs_url("Git", "https://github.com/example/repo.git"); source.set_vcs_url("Browser", "https://github.com/example/repo"); // Test setting non-native VCS URL source.set_vcs_url("Svn", "https://svn.example.com/repo"); std::mem::drop(source); editor.commit(); // Read back the debcargo.toml to verify let content = std::fs::read_to_string(td.path().join("debian/debcargo.toml")).unwrap(); assert_eq!( content, r#"maintainer = "Alice " [source] vcs_git = "https://github.com/example/repo.git" vcs_browser = "https://github.com/example/repo" extra_lines = ["Vcs-Svn: https://svn.example.com/repo"] "# ); } #[test] fn test_abstract_source_get_vcs_url_plain() { let td = tempfile::tempdir().unwrap(); let tree = create_standalone_workingtree(td.path(), &ControlDirFormat::default()).unwrap(); // Write dummy debian/control with VCS fields tree.mkdir(Path::new("debian")).unwrap(); tree.put_file_bytes_non_atomic( Path::new("debian/control"), br#"Source: example Maintainer: Alice Vcs-Git: https://github.com/example/repo.git Vcs-Browser: https://github.com/example/repo Vcs-Svn: https://svn.example.com/repo Package: example Architecture: any Description: Example package "#, ) .unwrap(); tree.add(&[Path::new("debian/control")]).unwrap(); let mut editor = super::edit_control(&tree, Path::new("")).unwrap(); let source = editor.source().unwrap(); // Test getting various VCS URLs assert_eq!( source.get_vcs_url("Git"), Some("https://github.com/example/repo.git".to_string()) ); assert_eq!( source.get_vcs_url("Browser"), Some("https://github.com/example/repo".to_string()) ); assert_eq!( source.get_vcs_url("Svn"), Some("https://svn.example.com/repo".to_string()) ); assert_eq!(source.get_vcs_url("Bzr"), None); } #[test] fn test_abstract_source_get_vcs_url_debcargo() { let td = tempfile::tempdir().unwrap(); let tree = create_standalone_workingtree(td.path(), &ControlDirFormat::default()).unwrap(); // Write dummy debcargo.toml with VCS fields tree.mkdir(Path::new("debian")).unwrap(); std::fs::write( td.path().join("debian/debcargo.toml"), br#"maintainer = "Alice " [source] vcs_git = "https://github.com/example/repo.git" vcs_browser = "https://github.com/example/repo" extra_lines = ["Vcs-Svn: https://svn.example.com/repo", "Vcs-Bzr: https://bzr.example.com/repo"] "#, ) .unwrap(); std::fs::write( td.path().join("Cargo.toml"), br#"[package] name = "example" version = "0.1.0" "#, ) .unwrap(); tree.add(&[(Path::new("debian")), (Path::new("debian/debcargo.toml"))]) .unwrap(); let mut editor = super::edit_control(&tree, Path::new("")).unwrap(); let source = editor.source().unwrap(); // Test getting native VCS URLs assert_eq!( source.get_vcs_url("Git"), Some("https://github.com/example/repo.git".to_string()) ); assert_eq!( source.get_vcs_url("Browser"), Some("https://github.com/example/repo".to_string()) ); // Test getting non-native VCS URLs from extra_lines assert_eq!( source.get_vcs_url("Svn"), Some("https://svn.example.com/repo".to_string()) ); assert_eq!( source.get_vcs_url("Bzr"), Some("https://bzr.example.com/repo".to_string()) ); // Test getting non-existent VCS URL assert_eq!(source.get_vcs_url("Hg"), None); } } debian-workbench-0.3.0/src/bin/deb-vcs-publish.rs000064400000000000000000000103451046102023000177250ustar 00000000000000use breezyshim::controldir::open; use breezyshim::error::Error; use breezyshim::prelude::*; use breezyshim::workingtree; use clap::Parser; use debian_changelog::get_maintainer; use debian_workbench::publish::{create_vcs_url, update_official_vcs}; use debian_workbench::get_committer; use std::io::Write as _; #[derive(clap::Args, Clone, Debug)] #[group()] struct OutputArgs {} #[derive(Parser, Debug)] #[command(author, version)] struct Args { /// Enable debug output #[arg(long, default_value_t = false)] debug: bool, /// Print user identity that would be used when committing #[arg(long, default_value_t = false)] identity: bool, /// directory to run in #[arg(short, long, default_value = std::env::current_dir().unwrap().into_os_string(), value_name = "DIR")] directory: std::path::PathBuf, /// Do not create the repository #[arg(default_value_t = false)] no_create: bool, #[arg(default_value_t = false)] force: bool, /// Push branch #[arg(default_value_t = false)] push: bool, url: Option, } fn main() -> Result<(), Box> { let args = Args::parse(); env_logger::builder() .format(|buf, record| writeln!(buf, "{}", record.args())) .filter( None, if args.debug { log::LevelFilter::Debug } else { log::LevelFilter::Info }, ) .init(); breezyshim::init(); let (wt, subpath) = match workingtree::open_containing(&args.directory) { Ok((wt, subpath)) => (wt, subpath.display().to_string()), Err(Error::NotBranchError(_msg, _)) => { log::error!("No version control directory found (e.g. a .git directory)."); std::process::exit(1); } Err(Error::DependencyNotPresent(name, _reason)) => { log::error!( "Unable to open tree at {}: missing package {}", args.directory.display(), name ); std::process::exit(1); } Err(e) => { log::error!("Unable to open tree at {}: {}", args.directory.display(), e); std::process::exit(1); } }; if args.identity { println!("Committer identity: {}", get_committer(&wt)); let (maintainer, email) = get_maintainer().unwrap_or(("".to_string(), "".to_string())); println!("Changelog identity: {} <{}>", maintainer, email); std::process::exit(0); } let parsed_vcs = match update_official_vcs( &wt, std::path::Path::new(subpath.as_str()), args.url.as_ref(), None, None, Some(args.force), ) { Ok(o) => o, Err(e) => { log::error!("Unable to update official VCS: {}", e); std::process::exit(1); } }; let repo_url: url::Url = parsed_vcs.repo_url.parse().unwrap(); if !args.no_create { match create_vcs_url(&repo_url, parsed_vcs.branch.as_deref()) { Ok(()) => {} Err(Error::UnsupportedForge(_)) => { log::error!("Unable to find a way to create {}", repo_url); } Err(Error::ForgeProjectExists(..)) | Err(Error::AlreadyControlDir(..)) => { log::error!("Unable to create {}: already exists", repo_url); std::process::exit(1); } Err(Error::ForgeLoginRequired) => { log::error!("Unable to create {}: login required", repo_url); std::process::exit(1); } Err(e) => { log::error!("Unable to create {}: {}", repo_url, e); std::process::exit(1); } } } let controldir = open(&repo_url, None).unwrap(); let branch = match controldir.open_branch(parsed_vcs.branch.as_deref()) { Ok(branch) => branch, Err(Error::NotBranchError(_, _)) => controldir .create_branch(parsed_vcs.branch.as_deref()) .unwrap(), Err(e) => { log::error!("Unable to open or create branch: {}", e); std::process::exit(1); } }; wt.branch() .push(branch.as_ref(), false, None, None) .unwrap(); Ok(()) } debian-workbench-0.3.0/src/bin/detect-changelog-behaviour.rs000064400000000000000000000024651046102023000221210ustar 00000000000000use breezyshim::workingtree; use clap::Parser; use std::io::Write as _; #[derive(Parser)] #[command(author, version)] struct Args { /// Be verbose #[clap(long)] verbose: bool, /// The directory to check #[clap(default_value = ".")] directory: std::path::PathBuf, } fn main() { let args = Args::parse(); env_logger::builder() .format(|buf, record| writeln!(buf, "{}", record.args())) .filter( None, if args.verbose { log::LevelFilter::Debug } else { log::LevelFilter::Info }, ) .init(); breezyshim::init(); let (wt, subpath) = workingtree::open_containing(&args.directory).unwrap(); let debian_path = if debian_workbench::control_files_in_root(&wt, subpath.as_path()) { subpath } else { subpath.join("debian") }; let changelog_behaviour = debian_workbench::detect_gbp_dch::guess_update_changelog(&wt, debian_path.as_path(), None); if let Some(changelog_behaviour) = changelog_behaviour { log::info!("{}", changelog_behaviour.explanation); println!("{}", changelog_behaviour.update_changelog); } else { log::info!("Unable to determine changelog updating behaviour"); std::process::exit(1) } } debian-workbench-0.3.0/src/changelog.rs000064400000000000000000000505671046102023000161270ustar 00000000000000//! Functions for working with debian/changelog files. use crate::release_info; use breezyshim::error::Error; use breezyshim::prelude::*; use breezyshim::tree::TreeChange; use debian_changelog::ChangeLog; /// Check whether the only change in a tree is to the last changelog entry. /// /// # Arguments /// * `tree`: Tree to analyze /// * `changelog_path`: Path to the changelog file /// * `changes`: Changes in the tree pub fn only_changes_last_changelog_block<'a>( tree: &dyn WorkingTree, basis_tree: &dyn Tree, changelog_path: &std::path::Path, changes: impl Iterator, ) -> Result { let read_lock = tree.lock_read(); let basis_lock = basis_tree.lock_read(); let mut changes_seen = false; for change in changes { if let Some(path) = change.path.1.as_ref() { if path == std::path::Path::new("") { continue; } if path == changelog_path { changes_seen = true; continue; } if !tree.has_versioned_directories() && changelog_path.starts_with(path) { // Directory leading up to changelog continue; } } // If the change is not in the changelog, it's not just a changelog change return Ok(false); } if !changes_seen { // Doesn't change the changelog at all return Ok(false); } let mut new_cl = match tree.get_file(changelog_path) { Ok(f) => ChangeLog::read(f)?, Err(Error::NoSuchFile(_)) => { return Ok(false); } Err(e) => { panic!("Error reading changelog: {}", e); } }; let mut old_cl = match basis_tree.get_file(changelog_path) { Ok(f) => ChangeLog::read(f)?, Err(Error::NoSuchFile(_)) => { return Ok(true); } Err(e) => { panic!("Error reading changelog: {}", e); } }; let first_entry = if let Some(e) = new_cl.pop_first() { e } else { // No entries return Ok(false); }; if first_entry.distributions().as_deref() != Some(&["UNRELEASED".into()]) { // Not unreleased return Ok(false); } old_cl.pop_first(); std::mem::drop(read_lock); std::mem::drop(basis_lock); Ok(new_cl.to_string() == old_cl.to_string()) } /// Find the last distribution the package was uploaded to. pub fn find_last_distribution(cl: &ChangeLog) -> Option { for block in cl.iter() { if block.is_unreleased() != Some(true) { if let Some(distributions) = block.distributions() { if distributions.len() == 1 { return Some(distributions[0].to_string()); } } } } None } /// Given a tree, find the previous upload to the distribution. /// /// When e.g. Ubuntu merges from Debian they want to build with /// -vPREV_VERSION. Here's where we find that previous version. /// /// We look at the last changelog entry and find the upload target. /// We then search backwards until we find the same target. That's /// the previous version that we return. /// /// We require there to be a previous version, otherwise we throw /// an error. /// /// It's not a simple string comparison to find the same target in /// a previous version, as we should consider old series in e.g. /// Ubuntu. pub fn find_previous_upload(changelog: &ChangeLog) -> Option { let current_target = find_last_distribution(changelog)?; // multiple debian pockets with all debian releases let all_debian = crate::release_info::debian_releases() .iter() .flat_map(|r| { release_info::DEBIAN_POCKETS .iter() .map(move |t| format!("{}{}", r, t)) }) .collect::>(); let all_ubuntu = crate::release_info::ubuntu_releases() .iter() .flat_map(|r| { release_info::UBUNTU_POCKETS .iter() .map(move |t| format!("{}{}", r, t)) }) .collect::>(); let match_targets = if all_debian.contains(¤t_target) { vec![current_target] } else if all_ubuntu.contains(¤t_target) { let mut match_targets = crate::release_info::ubuntu_releases(); if current_target.contains('-') { let distro = current_target.split('-').next().unwrap(); match_targets.extend( release_info::DEBIAN_POCKETS .iter() .map(|r| format!("{}{}", r, distro)), ); } match_targets } else { // If we do not recognize the current target in order to apply special // rules to it, then just assume that only previous uploads to exactly // the same target count. vec![current_target] }; for block in changelog.iter().skip(1) { if match_targets.contains(&block.distributions().unwrap()[0]) { return block.version().clone(); } } None } #[derive(Debug)] /// Error type for find_changelog pub enum FindChangelogError { /// No changelog found in the given files MissingChangelog(Vec), /// Add a changelog at the given file AddChangelog(std::path::PathBuf), /// Error parsing the changelog ChangelogParseError(String), /// Error from breezyshim BrzError(breezyshim::error::Error), } impl std::fmt::Display for FindChangelogError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { FindChangelogError::MissingChangelog(files) => { write!(f, "No changelog found in {:?}", files) } FindChangelogError::AddChangelog(file) => { write!(f, "Add a changelog at {:?}", file) } FindChangelogError::ChangelogParseError(e) => write!(f, "{}", e), FindChangelogError::BrzError(e) => write!(f, "{}", e), } } } impl std::error::Error for FindChangelogError {} impl From for FindChangelogError { fn from(e: breezyshim::error::Error) -> Self { FindChangelogError::BrzError(e) } } /// Find the changelog in the given tree. /// /// First looks for 'debian/changelog'. If "merge" is true will also /// look for 'changelog'. /// /// The returned changelog is created with 'allow_empty_author=True' /// as some people do this but still want to build. /// 'max_blocks' defaults to 1 to try and prevent old broken /// changelog entries from causing the command to fail. /// /// "top_level" is a subset of "merge" mode. It indicates that the /// '.bzr' dir is at the same level as 'changelog' etc., rather /// than being at the same level as 'debian/'. /// /// # Arguments /// * `tree`: Tree to look in /// * `subpath`: Path to the changelog file /// * `merge`: Whether this is a "merge" package /// /// # Returns /// * (changelog, top_level) where changelog is the Changelog, /// and top_level is a boolean indicating whether the file is /// located at 'changelog' (rather than 'debian/changelog') if /// merge was given, False otherwise. pub fn find_changelog( tree: &dyn Tree, subpath: &std::path::Path, merge: Option, ) -> Result<(ChangeLog, bool), FindChangelogError> { let mut top_level = false; let lock = tree.lock_read(); let mut changelog_file = subpath.join("debian/changelog"); if !tree.has_filename(&changelog_file) { let mut checked_files = vec![changelog_file.to_path_buf()]; let changelog_file = if merge.unwrap_or(false) { // Assume LarstiQ's layout (.bzr in debian/) let changelog_file = subpath.join("changelog"); top_level = true; if !tree.has_filename(&changelog_file) { checked_files.push(changelog_file); None } else { Some(changelog_file) } } else { None }; if changelog_file.is_none() { return Err(FindChangelogError::MissingChangelog(checked_files)); } } else if merge.unwrap_or(true) && tree.has_filename(&subpath.join("changelog")) { // If it is a "top_level" package and debian is a symlink to // "." then it will have found debian/changelog. Try and detect // this. let debian_file = subpath.join("debian"); if tree.is_versioned(&debian_file) && tree.kind(&debian_file)? == breezyshim::tree::Kind::Symlink && tree.get_symlink_target(&debian_file)?.as_path() == std::path::Path::new(".") { changelog_file = "changelog".into(); top_level = true; } } log::debug!( "Using '{}' to get package information", changelog_file.display() ); if !tree.is_versioned(&changelog_file) { return Err(FindChangelogError::AddChangelog(changelog_file)); } let contents = tree.get_file_text(&changelog_file)?; std::mem::drop(lock); let changelog = ChangeLog::read_relaxed(contents.as_slice()).unwrap(); Ok((changelog, top_level)) } #[cfg(test)] mod tests { use super::*; use breezyshim::workingtree::GenericWorkingTree; pub const COMMITTER: &str = "Test User "; #[test] fn test_find_previous_upload() { let cl = r#"test (1.0-1) unstable; urgency=medium * Initial release. -- Test User Fri, 01 Jan 2021 00:00:00 +0000 "# .parse() .unwrap(); assert_eq!(super::find_previous_upload(&cl), None); let cl = r#"test (1.0-1) unstable; urgency=medium * More change. -- Test User Fri, 01 Jan 2021 00:00:00 +0000 test (1.0-0) unstable; urgency=medium * Initial release. -- Test User Fri, 01 Jan 2021 00:00:00 +0000 "# .parse() .unwrap(); assert_eq!( super::find_previous_upload(&cl), Some("1.0-0".parse().unwrap()) ); } mod test_only_changes_last_changelog_block { use super::*; use breezyshim::controldir::{create_standalone_workingtree, ControlDirFormat}; use breezyshim::tree::Path; fn make_package_tree(p: &std::path::Path) -> GenericWorkingTree { let tree = create_standalone_workingtree(p, &ControlDirFormat::default()).unwrap(); std::fs::create_dir_all(p.join("debian")).unwrap(); std::fs::write( p.join("debian/control"), r###"Source: blah Vcs-Git: https://example.com/blah Testsuite: autopkgtest Binary: blah Arch: all "###, ) .unwrap(); std::fs::write( p.join("debian/changelog"), r###"blah (0.2) UNRELEASED; urgency=medium * And a change. -- Blah Sat, 13 Oct 2018 11:21:39 +0100 blah (0.1) unstable; urgency=medium * Initial release. (Closes: #911016) -- Blah Sat, 13 Oct 2018 11:21:39 +0100 "###, ) .unwrap(); tree.add(&[ Path::new("debian"), Path::new("debian/changelog"), Path::new("debian/control"), ]) .unwrap(); tree.build_commit() .message("Initial thingy.") .committer(COMMITTER) .commit() .unwrap(); tree } #[test] fn test_no_changes() { let td = tempfile::tempdir().unwrap(); let tree = make_package_tree(td.path()); let basis_tree = tree.basis_tree().unwrap(); let lock_read = tree.lock_read(); let basis_lock_read = basis_tree.lock_read(); let changes = tree .iter_changes(&basis_tree, None, None, None) .unwrap() .collect::, _>>() .unwrap(); assert!(!only_changes_last_changelog_block( &tree, &tree.basis_tree().unwrap(), Path::new("debian/changelog"), changes.iter() ) .unwrap()); std::mem::drop(basis_lock_read); std::mem::drop(lock_read); } #[test] fn test_other_change() { let td = tempfile::tempdir().unwrap(); let tree = make_package_tree(td.path()); std::fs::write( td.path().join("debian/control"), r###"Source: blah Vcs-Bzr: https://example.com/blah Testsuite: autopkgtest Binary: blah Arch: all "###, ) .unwrap(); let basis_tree = tree.basis_tree().unwrap(); let lock_read = tree.lock_read(); let basis_lock_read = basis_tree.lock_read(); let changes = tree .iter_changes(&basis_tree, None, None, None) .unwrap() .collect::, _>>() .unwrap(); assert!(!only_changes_last_changelog_block( &tree, &tree.basis_tree().unwrap(), Path::new("debian/changelog"), changes.iter() ) .unwrap()); std::mem::drop(basis_lock_read); std::mem::drop(lock_read); } #[test] fn test_other_changes() { let td = tempfile::tempdir().unwrap(); let tree = make_package_tree(td.path()); std::fs::write( td.path().join("debian/control"), r###"Source: blah Vcs-Bzr: https://example.com/blah Testsuite: autopkgtest Binary: blah Arch: all "###, ) .unwrap(); std::fs::write( td.path().join("debian/changelog"), r###"blah (0.1) UNRELEASED; urgency=medium * Initial release. (Closes: #911016) * Some other change. -- Blah Sat, 13 Oct 2018 11:21:39 +0100 "###, ) .unwrap(); let basis_tree = tree.basis_tree().unwrap(); let lock_read = tree.lock_read(); let basis_lock_read = basis_tree.lock_read(); let changes = tree .iter_changes(&basis_tree, None, None, None) .unwrap() .collect::, _>>() .unwrap(); assert!(!only_changes_last_changelog_block( &tree, &tree.basis_tree().unwrap(), Path::new("debian/changelog"), changes.iter() ) .unwrap()); std::mem::drop(basis_lock_read); std::mem::drop(lock_read); } #[test] fn test_changes_to_other_changelog_entries() { let td = tempfile::tempdir().unwrap(); let tree = make_package_tree(td.path()); std::fs::write( td.path().join("debian/changelog"), r###"blah (0.2) UNRELEASED; urgency=medium * debian/changelog: And a change. -- Blah Sat, 13 Oct 2018 11:21:39 +0100 blah (0.1) unstable; urgency=medium * debian/changelog: Initial release. (Closes: #911016) -- Blah Sat, 13 Oct 2018 11:21:39 +0100 "###, ) .unwrap(); let basis_tree = tree.basis_tree().unwrap(); let lock_read = tree.lock_read(); let basis_lock_read = basis_tree.lock_read(); let changes = tree .iter_changes(&basis_tree, None, None, None) .unwrap() .collect::, _>>() .unwrap(); assert!(!only_changes_last_changelog_block( &tree, &tree.basis_tree().unwrap(), Path::new("debian/changelog"), changes.iter() ) .unwrap()); std::mem::drop(basis_lock_read); std::mem::drop(lock_read); } #[test] fn test_changes_to_last_only() { let td = tempfile::tempdir().unwrap(); let tree = make_package_tree(td.path()); std::fs::write( td.path().join("debian/changelog"), r###"blah (0.2) UNRELEASED; urgency=medium * And a change. * Not a team upload. -- Blah Sat, 13 Oct 2018 11:21:39 +0100 blah (0.1) unstable; urgency=medium * Initial release. (Closes: #911016) -- Blah Sat, 13 Oct 2018 11:21:39 +0100 "###, ) .unwrap(); let basis_tree = tree.basis_tree().unwrap(); let lock_read = tree.lock_read(); let basis_lock_read = basis_tree.lock_read(); let changes = tree .iter_changes(&basis_tree, None, None, None) .unwrap() .collect::, _>>() .unwrap(); assert!(only_changes_last_changelog_block( &tree, &tree.basis_tree().unwrap(), Path::new("debian/changelog"), changes.iter() ) .unwrap()); std::mem::drop(basis_lock_read); std::mem::drop(lock_read); } #[test] fn test_only_new_changelog() { use breezyshim::tree::MutableTree; let td = tempfile::tempdir().unwrap(); let tree = create_standalone_workingtree(td.path(), "git").unwrap(); let lock_write = tree.lock_write(); std::fs::create_dir_all(td.path().join("debian")).unwrap(); std::fs::write( td.path().join("debian/changelog"), r###"blah (0.1) unstable; urgency=medium * Initial release. (Closes: #911016) -- Blah Sat, 13 Oct 2018 11:21:39 +0100 "###, ) .unwrap(); let basis_tree = tree.basis_tree().unwrap(); let lock_read = tree.lock_read(); let basis_lock_read = basis_tree.lock_read(); tree.add(&[Path::new("debian"), Path::new("debian/changelog")]) .unwrap(); let changes = tree .iter_changes(&basis_tree, None, None, None) .unwrap() .collect::, _>>() .unwrap(); assert!(only_changes_last_changelog_block( &tree, &tree.basis_tree().unwrap(), Path::new("debian/changelog"), changes.iter() ) .unwrap()); std::mem::drop(basis_lock_read); std::mem::drop(lock_read); std::mem::drop(lock_write); } #[test] fn test_changes_to_last_only_but_released() { let td = tempfile::tempdir().unwrap(); let tree = make_package_tree(td.path()); std::fs::write( td.path().join("debian/changelog"), r###"blah (0.2) unstable; urgency=medium * And a change. -- Blah Sat, 13 Oct 2018 11:21:39 +0100 blah (0.1) unstable; urgency=medium * Initial release. (Closes: #911016) -- Blah Sat, 13 Oct 2018 11:21:39 +0100 "###, ) .unwrap(); tree.build_commit() .message("release") .committer(COMMITTER) .commit() .unwrap(); std::fs::write( td.path().join("debian/changelog"), r###"blah (0.2) unstable; urgency=medium * And a change. * Team Upload. -- Blah Sat, 13 Oct 2018 11:21:39 +0100 blah (0.1) unstable; urgency=medium * Initial release. (Closes: #911016) -- Blah Sat, 13 Oct 2018 11:21:39 +0100 "###, ) .unwrap(); let basis_tree = tree.basis_tree().unwrap(); let lock_read = tree.lock_read(); let basis_lock_read = basis_tree.lock_read(); let changes = tree .iter_changes(&basis_tree, None, None, None) .unwrap() .collect::, _>>() .unwrap(); assert!(!only_changes_last_changelog_block( &tree, &tree.basis_tree().unwrap(), Path::new("debian/changelog"), changes.iter() ) .unwrap()); std::mem::drop(basis_lock_read); std::mem::drop(lock_read); } } } debian-workbench-0.3.0/src/config.rs000064400000000000000000000127671046102023000154450ustar 00000000000000//! Lintian-brush configuration file. use crate::Certainty; use breezyshim::tree::WorkingTree; use configparser::ini::Ini; use log::warn; const SUPPORTED_KEYS: &[&str] = &[ "compat-release", "minimum-certainty", "allow-reformatting", "update-changelog", ]; /// Configuration file name pub const PACKAGE_CONFIG_FILENAME: &str = "debian/lintian-brush.conf"; /// Configuration file pub struct Config { obj: Ini, } impl Config { /// Load configuration from a working tree pub fn from_workingtree( tree: &dyn WorkingTree, subpath: &std::path::Path, ) -> std::io::Result { let path = tree .abspath(&subpath.join(PACKAGE_CONFIG_FILENAME)) .unwrap(); Self::load_from_path(&path) } /// Load configuration from a path pub fn load_from_path(path: &std::path::Path) -> Result { let mut ini = Ini::new(); let data = std::fs::read_to_string(path)?; ini.read(data).map_err(|e| std::io::Error::other(e))?; for (section, contents) in ini.get_map_ref() { if section != "default" { warn!( "unknown section {} in {}, ignoring.", section, path.display() ); continue; } for key in contents.keys() { if !SUPPORTED_KEYS.contains(&key.as_str()) { warn!( "unknown key {} in section {} in {}, ignoring.", key, section, path.display() ); continue; } } } Ok(Config { obj: ini }) } /// Return the compatibility release. pub fn compat_release(&self) -> Option { self.obj.get("default", "compat-release").and_then(|value| { let codename = crate::release_info::resolve_release_codename(&value, None); if codename.is_none() { warn!("unknown compat release {}, ignoring.", value); } codename }) } /// Return whether reformatting is allowed. pub fn allow_reformatting(&self) -> Option { match self.obj.getbool("default", "allow-reformatting") { Ok(value) => value, Err(e) => { warn!("invalid allow-reformatting value {}, ignoring.", e); None } } } /// Return the minimum certainty level for changes to be applied. pub fn minimum_certainty(&self) -> Option { self.obj .get("default", "minimum-certainty") .and_then(|value| { value .parse::() .inspect_err(|_e| { warn!("invalid minimum-certainty value {}, ignoring.", value); }) .ok() }) } /// Return whether the changelog should be updated. pub fn update_changelog(&self) -> Option { match self.obj.getbool("default", "update-changelog") { Ok(value) => value, Err(e) => { warn!("invalid update-changelog value {}, ignoring.", e); None } } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_compat_release() { let td = tempfile::tempdir().unwrap(); std::fs::create_dir(td.path().join("debian")).unwrap(); std::fs::write( td.path().join("debian/lintian-brush.conf"), "compat-release = testing\n", ) .unwrap(); let cfg = Config::load_from_path(&td.path().join("debian/lintian-brush.conf")).unwrap(); let testing = crate::release_info::resolve_release_codename("testing", None); assert_eq!(cfg.compat_release(), testing); } #[test] fn test_minimum_certainty() { let td = tempfile::tempdir().unwrap(); std::fs::create_dir(td.path().join("debian")).unwrap(); std::fs::write( td.path().join("debian/lintian-brush.conf"), "minimum-certainty = possible\n", ) .unwrap(); let cfg = Config::load_from_path(&td.path().join("debian/lintian-brush.conf")).unwrap(); assert_eq!(cfg.minimum_certainty(), Some(Certainty::Possible)); } #[test] fn test_update_changelog() { let td = tempfile::tempdir().unwrap(); std::fs::create_dir(td.path().join("debian")).unwrap(); std::fs::write( td.path().join("debian/lintian-brush.conf"), "update-changelog = True\n", ) .unwrap(); let cfg = Config::load_from_path(&td.path().join("debian/lintian-brush.conf")).unwrap(); assert_eq!(cfg.update_changelog(), Some(true)); } #[test] fn test_unknown() { let td = tempfile::tempdir().unwrap(); std::fs::create_dir(td.path().join("debian")).unwrap(); std::fs::write( td.path().join("debian/lintian-brush.conf"), "unknown = dunno\n", ) .unwrap(); let cfg = Config::load_from_path(&td.path().join("debian/lintian-brush.conf")).unwrap(); assert_eq!(cfg.compat_release(), None); } #[test] fn test_missing() { let td = tempfile::tempdir().unwrap(); let path = td.path().join("debian/lintian-brush.conf"); let cfg = Config::load_from_path(&path); assert!(cfg.is_err()); } } debian-workbench-0.3.0/src/control.rs000064400000000000000000002143401046102023000156470ustar 00000000000000//! Tools for working with Debian control files. use crate::editor::{Editor, EditorError, FsEditor, GeneratedFile}; use crate::relations::{ensure_relation, is_relation_implied}; use deb822_lossless::Paragraph; use debian_control::lossless::relations::Relations; use std::ops::{Deref, DerefMut}; use std::path::{Path, PathBuf}; /// Format a description based on summary and long description lines. pub fn format_description(summary: &str, long_description: Vec<&str>) -> String { let mut ret = summary.to_string() + "\n"; for line in long_description { ret.push(' '); ret.push_str(line); ret.push('\n'); } ret } #[derive(Debug, Clone, PartialEq, Eq, Copy)] /// The type of a control file template. pub enum TemplateType { /// A rule in the debian/rules file that generates the control file. Rules, /// Generated by gnome-pkg-tools. Gnome, /// Generated by pg_buildext. Postgresql, /// Generated by a set of files in the debian/control.in directory. Directory, /// Generated by cdbs. Cdbs, /// Generated by debcargo. Debcargo, } /// Error type for template expansion operations #[derive(Debug)] pub enum TemplateExpansionError { /// The expansion failed with an error message Failed(String), /// The expand command is missing ExpandCommandMissing(String), /// Unknown templating type encountered UnknownTemplating(PathBuf, Option), /// A change conflict occurred Conflict(ChangeConflict), } impl From for TemplateExpansionError { fn from(e: ChangeConflict) -> Self { TemplateExpansionError::Conflict(e) } } impl std::fmt::Display for TemplateExpansionError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { TemplateExpansionError::Failed(s) => write!(f, "Failed: {}", s), TemplateExpansionError::ExpandCommandMissing(s) => { write!(f, "Command not found: {}", s) } TemplateExpansionError::UnknownTemplating(p1, p2) => { if let Some(p2) = p2 { write!( f, "Unknown templating: {} -> {}", p1.display(), p2.display() ) } else { write!(f, "Unknown templating: {}", p1.display()) } } TemplateExpansionError::Conflict(c) => write!(f, "Conflict: {}", c), } } } impl std::error::Error for TemplateExpansionError {} /// Run the dh_gnome_clean command. /// /// This needs to do some post-hoc cleaning, since dh_gnome_clean writes various debhelper log /// files that should not be checked in. /// /// # Arguments /// * `path` - Path to run dh_gnome_clean in /// /// # Errors /// Returns an error if: /// - Pre-existing .debhelper.log files are found /// - No changelog file exists /// - The dh_gnome_clean command is not found /// - The command fails to execute pub fn dh_gnome_clean(path: &std::path::Path) -> Result<(), TemplateExpansionError> { for entry in std::fs::read_dir(path.join("debian")).unwrap().flatten() { if entry .file_name() .to_string_lossy() .ends_with(".debhelper.log") { return Err(TemplateExpansionError::Failed( "pre-existing .debhelper.log files".to_string(), )); } } if !path.join("debian/changelog").exists() { return Err(TemplateExpansionError::Failed( "no changelog file".to_string(), )); } let result = std::process::Command::new("dh_gnome_clean") .current_dir(path) .output(); match result { Ok(output) => { if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); return Err(TemplateExpansionError::Failed(stderr.to_string())); } } Err(e) if e.kind() == std::io::ErrorKind::NotFound => { return Err(TemplateExpansionError::ExpandCommandMissing( "dh_gnome_clean".to_string(), )); } Err(e) => { return Err(TemplateExpansionError::Failed(e.to_string())); } } for entry in std::fs::read_dir(path.join("debian")).unwrap().flatten() { if entry .file_name() .to_string_lossy() .ends_with(".debhelper.log") { std::fs::remove_file(entry.path()).unwrap(); } } Ok(()) } /// Run the 'pg_buildext updatecontrol' command. /// /// # Arguments /// * `path` - Path to run pg_buildext updatecontrol in /// /// # Errors /// Returns an error if: /// - The pg_buildext command is not found /// - The command fails to execute pub fn pg_buildext_updatecontrol(path: &std::path::Path) -> Result<(), TemplateExpansionError> { let result = std::process::Command::new("pg_buildext") .arg("updatecontrol") .current_dir(path) .output(); match result { Ok(output) => { if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); return Err(TemplateExpansionError::Failed(stderr.to_string())); } } Err(e) if e.kind() == std::io::ErrorKind::NotFound => { return Err(TemplateExpansionError::ExpandCommandMissing( "pg_buildext".to_string(), )); } Err(e) => { return Err(TemplateExpansionError::Failed(e.to_string())); } } Ok(()) } /// Expand a control template. /// /// # Arguments /// * `template_path` - Path to the control template /// * `path` - Path to the control file /// * `template_type` - Type of the template /// /// # Returns /// Ok if the template was successfully expanded fn expand_control_template( template_path: &std::path::Path, path: &std::path::Path, template_type: TemplateType, ) -> Result<(), TemplateExpansionError> { let package_root = path.parent().unwrap().parent().unwrap(); match template_type { TemplateType::Rules => { let path_time = match std::fs::metadata(path) { Ok(metadata) => Some(metadata.modified().unwrap()), Err(e) if e.kind() == std::io::ErrorKind::NotFound => None, Err(e) => panic!("Failed to get mtime of {}: {}", path.display(), e), }; while let Ok(metadata) = std::fs::metadata(template_path) { if Some(metadata.modified().unwrap()) == path_time { // Wait until mtime has changed, so that make knows to regenerate. filetime::set_file_mtime(template_path, filetime::FileTime::now()).unwrap(); } else { break; } } let result = std::process::Command::new("./debian/rules") .arg("debian/control") .current_dir(package_root) .output(); match result { Ok(output) => { if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); Err(TemplateExpansionError::Failed(format!( "Exit code {} running ./debian/rules debian/control: {}", output.status, stderr ))) } else { Ok(()) } } Err(e) => Err(TemplateExpansionError::Failed(format!( "Failed to run ./debian/rules debian/control: {}", e ))), } } TemplateType::Gnome => dh_gnome_clean(package_root), TemplateType::Postgresql => pg_buildext_updatecontrol(package_root), TemplateType::Cdbs => unreachable!(), TemplateType::Debcargo => unreachable!(), TemplateType::Directory => Err(TemplateExpansionError::UnknownTemplating( path.to_path_buf(), Some(template_path.to_path_buf()), )), } } #[derive(Debug, Clone)] struct Deb822Changes( std::collections::HashMap<(String, String), Vec<(String, Option, Option)>>, ); impl Deb822Changes { fn new() -> Self { Self(std::collections::HashMap::new()) } fn insert( &mut self, para_key: (String, String), field: String, old_value: Option, new_value: Option, ) { self.0 .entry(para_key) .or_default() .push((field, old_value, new_value)); } #[allow(dead_code)] fn normalized(&self) -> Vec<((&str, &str), Vec<(&str, Option<&str>, Option<&str>)>)> { let mut ret: Vec<_> = self .0 .iter() .map(|(k, v)| { ((k.0.as_str(), k.1.as_str()), { let mut v: Vec<_> = v .iter() .map(|(f, o, n)| (f.as_str(), o.as_deref(), n.as_deref())) .collect(); v.sort(); v }) }) .collect(); ret.sort_by_key(|(k, _)| *k); ret } } // Update a control file template based on changes to the file itself. // // # Arguments // * `template_path` - Path to the control template // * `path` - Path to the control file // * `changes` - Changes to apply // * `expand_template` - Whether to expand the template after updating it // // # Returns // Ok if the template was successfully updated fn update_control_template( template_path: &std::path::Path, template_type: TemplateType, path: &std::path::Path, changes: Deb822Changes, expand_template: bool, ) -> Result { if template_type == TemplateType::Directory { // We can't handle these yet return Err(TemplateExpansionError::UnknownTemplating( path.to_path_buf(), Some(template_path.to_path_buf()), )); } let mut template_editor = FsEditor::::new(template_path, true, false).unwrap(); let resolve_conflict = match template_type { TemplateType::Cdbs => Some(resolve_cdbs_template as ResolveDeb822Conflict), _ => None, }; apply_changes(&mut template_editor, changes.clone(), resolve_conflict)?; if !template_editor.has_changed() { // A bit odd, since there were changes to the output file. Anyway. return Ok(false); } match template_editor.commit() { Ok(_) => {} Err(e) => return Err(TemplateExpansionError::Failed(e.to_string())), } if expand_template { match template_type { TemplateType::Cdbs => { let mut editor = FsEditor::::new(path, true, false).unwrap(); apply_changes(&mut editor, changes, None)?; match editor.commit() { Ok(_) => {} Err(e) => return Err(TemplateExpansionError::Failed(e.to_string())), } } _ => { expand_control_template(template_path, path, template_type)?; } } } Ok(true) } #[derive(Debug, PartialEq, Eq)] /// A change conflict. pub struct ChangeConflict { /// Paragraph key, i.e. ("Source", "foo") pub para_key: (String, String), /// Field that conflicted pub field: String, /// Old value in the control file pub actual_old_value: Option, /// Old value in the template pub template_old_value: Option, /// New value in the control file pub actual_new_value: Option, } impl std::fmt::Display for ChangeConflict { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "{}/{}: {} -> {} (template: {})", self.para_key.0, self.para_key.1, self.actual_old_value.as_deref().unwrap_or(""), self.actual_new_value.as_deref().unwrap_or(""), self.template_old_value.as_deref().unwrap_or("") ) } } impl std::error::Error for ChangeConflict {} type ResolveDeb822Conflict = fn( para_key: (&str, &str), field: &str, actual_old_value: Option<&str>, template_old_value: Option<&str>, actual_new_value: Option<&str>, ) -> Result, ChangeConflict>; fn resolve_cdbs_template( para_key: (&str, &str), field: &str, actual_old_value: Option<&str>, template_old_value: Option<&str>, actual_new_value: Option<&str>, ) -> Result, ChangeConflict> { if para_key.0 == "Source" && field == "Build-Depends" && template_old_value.is_some() && actual_old_value.is_some() && actual_new_value.is_some() { if actual_new_value .unwrap() .contains(actual_old_value.unwrap()) { // We're simply adding to the existing list return Ok(Some( actual_new_value .unwrap() .replace(actual_old_value.unwrap(), template_old_value.unwrap()), )); } else { let old_rels: Relations = actual_old_value.unwrap().parse().unwrap(); let new_rels: Relations = actual_new_value.unwrap().parse().unwrap(); let template_old_value = template_old_value.unwrap(); let (mut ret, errors) = Relations::parse_relaxed(template_old_value, true); if !errors.is_empty() { log::debug!("Errors parsing template value: {:?}", errors); } for v in new_rels.entries() { if old_rels.entries().any(|r| is_relation_implied(&v, &r)) { continue; } ensure_relation(&mut ret, v); } return Ok(Some(ret.to_string())); } } Err(ChangeConflict { para_key: (para_key.0.to_string(), para_key.1.to_string()), field: field.to_string(), actual_old_value: actual_old_value.map(|v| v.to_string()), template_old_value: template_old_value.map(|v| v.to_string()), actual_new_value: actual_new_value.map(|s| s.to_string()), }) } /// Guess the type for a control template. /// /// # Arguments /// * `template_path` - Path to the control template /// * `debian_path` - Path to the debian directory /// /// # Returns /// Template type; None if unknown pub fn guess_template_type( template_path: &std::path::Path, debian_path: Option<&std::path::Path>, ) -> Option { // TODO(jelmer): This should use a proper make file parser of some sort.. if let Some(debian_path) = debian_path { match std::fs::read(debian_path.join("rules")) { Ok(file) => { for line in file.split(|&c| c == b'\n') { if line.starts_with(b"debian/control:") { return Some(TemplateType::Rules); } if line.starts_with(b"debian/%: debian/%.in") { return Some(TemplateType::Rules); } if line.starts_with(b"include /usr/share/blends-dev/rules") { return Some(TemplateType::Rules); } } } Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} Err(e) => panic!( "Failed to read {}: {}", debian_path.join("rules").display(), e ), } } match std::fs::read(template_path) { Ok(template) => { let template_str = std::str::from_utf8(&template).unwrap(); if template_str.contains("@GNOME_TEAM@") { return Some(TemplateType::Gnome); } if template_str.contains("PGVERSION") { return Some(TemplateType::Postgresql); } if template_str.contains("@cdbs@") { return Some(TemplateType::Cdbs); } let control = debian_control::Control::read_relaxed(std::io::Cursor::new(&template)) .unwrap() .0; let build_depends = control.source().and_then(|s| s.build_depends()); if build_depends.iter().any(|d| { d.entries() .any(|e| e.relations().any(|r| r.name() == "gnome-pkg-tools")) }) { return Some(TemplateType::Gnome); } if build_depends.iter().any(|d| { d.entries() .any(|e| e.relations().any(|r| r.name() == "cdbs")) }) { return Some(TemplateType::Cdbs); } } Err(_) if template_path.is_dir() => { return Some(TemplateType::Directory); } Err(e) => panic!("Failed to read {}: {}", template_path.display(), e), } if let Some(debian_path) = debian_path { if debian_path.join("debcargo.toml").exists() { return Some(TemplateType::Debcargo); } } None } /// Apply a set of changes to this deb822 instance. /// /// # Arguments /// * `changes` - Changes to apply /// * `resolve_conflict` - Callback to resolve conflicts fn apply_changes( deb822: &mut deb822_lossless::Deb822, mut changes: Deb822Changes, resolve_conflict: Option, ) -> Result<(), ChangeConflict> { fn default_resolve_conflict( para_key: (&str, &str), field: &str, actual_old_value: Option<&str>, template_old_value: Option<&str>, actual_new_value: Option<&str>, ) -> Result, ChangeConflict> { Err(ChangeConflict { para_key: (para_key.0.to_string(), para_key.1.to_string()), field: field.to_string(), actual_old_value: actual_old_value.map(|v| v.to_string()), template_old_value: template_old_value.map(|v| v.to_string()), actual_new_value: actual_new_value.map(|s| s.to_string()), }) } let resolve_conflict = resolve_conflict.unwrap_or(default_resolve_conflict); for mut paragraph in deb822.paragraphs() { let items: Vec<_> = paragraph.items().collect(); for item in items { for (key, old_value, mut new_value) in changes.0.remove(&item).unwrap_or_default() { if paragraph.get(&key) != old_value { new_value = resolve_conflict( (&item.0, &item.1), &key, old_value.as_deref(), paragraph.get(&key).as_deref(), new_value.as_deref(), )?; } if let Some(new_value) = new_value.as_ref() { paragraph.set(&key, new_value); } else { paragraph.remove(&key); } } } } // Add any new paragraphs that weren't processed earlier for (key, p) in changes.0.drain() { let mut paragraph = deb822.add_paragraph(); for (field, old_value, mut new_value) in p { if old_value.is_some() { new_value = resolve_conflict( (&key.0, &key.1), &field, old_value.as_deref(), paragraph.get(&field).as_deref(), new_value.as_deref(), )?; } if let Some(new_value) = new_value { paragraph.set(&field, &new_value); } } } Ok(()) } fn find_template_path(path: &Path) -> Option { for ext in &["in", "m4"] { let template_path = path.with_extension(ext); if template_path.exists() { return Some(template_path); } } None } /// An editor for a control file that may be generated from a template. /// /// This editor will automatically expand the template if it does not exist. /// It will also automatically update the template if the control file is changed. /// /// # Example /// /// ```rust /// use std::path::Path; /// use debian_workbench::control::TemplatedControlEditor; /// let td = tempfile::tempdir().unwrap(); /// let mut editor = TemplatedControlEditor::create(td.path().join("control")).unwrap(); /// editor.add_source("foo").set_architecture(Some("all")); /// editor.commit().unwrap(); /// ``` pub struct TemplatedControlEditor { /// The primary editor for the control file. primary: FsEditor, /// The template that was used to generate the control file. template: Option