rebuildctl-0.22.1/.cargo_vcs_info.json0000644000000001430000000000100132450ustar { "git": { "sha1": "0df3e3f9cbdd02edd52d5a2bbde9e42718c2e268" }, "path_in_vcs": "tools" }rebuildctl-0.22.1/Cargo.lock0000644000001545560000000000100112420ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "addr2line" version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] name = "adler2" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "android-tzdata" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[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 = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", "once_cell", "windows-sys 0.59.0", ] [[package]] name = "anyhow" version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", "windows-targets", ] [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "bumpalo" version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "bzip2" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b89e7c29231c673a61a46e722602bcd138298f6b9e81e71119693534585f5c" dependencies = [ "bzip2-sys", ] [[package]] name = "bzip2-sys" version = "0.1.12+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ebc2f1a417f01e1da30ef264ee86ae31d2dcd2d603ea283d3c244a883ca2a9" dependencies = [ "cc", "libc", "pkg-config", ] [[package]] name = "cc" version = "1.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af" dependencies = [ "jobserver", "libc", "shlex", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[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.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", "windows-link", ] [[package]] name = "clap" version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" dependencies = [ "clap_builder", "clap_derive", ] [[package]] name = "clap_builder" version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" dependencies = [ "anstream", "anstyle", "clap_lex", "strsim", ] [[package]] name = "clap_complete" version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5c5508ea23c5366f77e53f5a0070e5a84e51687ec3ef9e0464c86dc8d13ce98" dependencies = [ "clap", ] [[package]] name = "clap_derive" version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "clap_lex" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "core-foundation" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" 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 = "crc32fast" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "data-encoding" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" [[package]] name = "dirs-next" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ "cfg-if", "dirs-sys-next", ] [[package]] name = "dirs-sys-next" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", "winapi", ] [[package]] name = "displaydoc" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "env_filter" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ "log", "regex", ] [[package]] name = "env_logger" version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" dependencies = [ "anstream", "anstyle", "env_filter", "humantime", "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.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", "windows-sys 0.59.0", ] [[package]] name = "filetime" version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", "libredox", "windows-sys 0.59.0", ] [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "miniz_oxide", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "futures-channel" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", ] [[package]] name = "futures-core" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "futures-sink" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-io", "futures-macro", "futures-sink", "futures-task", "memchr", "pin-project-lite", "pin-utils", "slab", ] [[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", "libc", "wasi", "wasm-bindgen", ] [[package]] name = "gimli" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "http" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", "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.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", "http", "http-body", "pin-project-lite", ] [[package]] name = "httparse" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", "futures-channel", "futures-util", "http", "http-body", "httparse", "itoa", "pin-project-lite", "smallvec", "tokio", "want", ] [[package]] name = "hyper-rustls" version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", "http", "hyper", "hyper-util", "rustls", "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", ] [[package]] name = "hyper-util" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", "futures-util", "http", "http-body", "hyper", "pin-project-lite", "socket2", "tokio", "tower-service", "tracing", ] [[package]] name = "iana-time-zone" version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "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 = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ "displaydoc", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_locid" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", "litemap", "tinystr", "writeable", "zerovec", ] [[package]] name = "icu_locid_transform" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ "displaydoc", "icu_locid", "icu_locid_transform_data", "icu_provider", "tinystr", "zerovec", ] [[package]] name = "icu_locid_transform_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] name = "icu_normalizer" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", "utf16_iter", "utf8_iter", "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] name = "icu_properties" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ "displaydoc", "icu_collections", "icu_locid_transform", "icu_properties_data", "icu_provider", "tinystr", "zerovec", ] [[package]] name = "icu_properties_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" [[package]] name = "icu_provider" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ "displaydoc", "icu_locid", "icu_provider_macros", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_provider_macros" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "idna" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ "idna_adapter", "smallvec", "utf8_iter", ] [[package]] name = "idna_adapter" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ "icu_normalizer", "icu_properties", ] [[package]] name = "indexmap" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "ipnet" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", ] [[package]] name = "libc" version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "libredox" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags", "libc", "redox_syscall", ] [[package]] name = "linux-raw-sys" version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "log" version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "lzma-sys" version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" dependencies = [ "cc", "libc", "pkg-config", ] [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", ] [[package]] name = "mio" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "wasi", "windows-sys 0.52.0", ] [[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", ] [[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.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "openssl-probe" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap", ] [[package]] name = "pin-project-lite" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "ppv-lite86" version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ "zerocopy", ] [[package]] name = "proc-macro2" version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quinn" version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" dependencies = [ "bytes", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", "rustls", "socket2", "thiserror 2.0.11", "tokio", "tracing", ] [[package]] name = "quinn-proto" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", "getrandom", "rand", "ring", "rustc-hash", "rustls", "rustls-pki-types", "slab", "thiserror 2.0.11", "tinyvec", "tracing", "web-time", ] [[package]] name = "quinn-udp" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2", "tracing", "windows-sys 0.59.0", ] [[package]] name = "quote" version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] name = "rebuildctl" version = "0.22.1" dependencies = [ "bzip2", "chrono", "clap", "clap_complete", "colored", "data-encoding", "dirs-next", "env_logger", "flate2", "glob", "nom", "rebuilderd-common", "regex", "serde", "serde-xml-rs", "serde_json", "tar", "tokio", "toml", "tree_magic_mini", "url", "xz2", "zstd", ] [[package]] name = "rebuilderd-common" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72e2f25b43fdcf1503b9cfb52019598f8aa1ef49d318147f3c14aaa801601c69" dependencies = [ "anyhow", "chrono", "clap", "colored", "dirs-next", "log", "reqwest", "serde", "toml", "url", ] [[package]] name = "redox_syscall" version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" dependencies = [ "bitflags", ] [[package]] name = "redox_users" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", "thiserror 1.0.69", ] [[package]] name = "regex" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ "base64", "bytes", "futures-channel", "futures-core", "futures-util", "http", "http-body", "http-body-util", "hyper", "hyper-rustls", "hyper-util", "ipnet", "js-sys", "log", "mime", "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls", "rustls-native-certs", "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", "tokio", "tokio-rustls", "tokio-util", "tower", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", "windows-registry", ] [[package]] name = "ring" version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73" dependencies = [ "cc", "cfg-if", "getrandom", "libc", "untrusted", "windows-sys 0.52.0", ] [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.59.0", ] [[package]] name = "rustls" version = "0.23.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ "once_cell", "ring", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-native-certs" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ "rustls-pki-types", ] [[package]] name = "rustls-pki-types" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" dependencies = [ "web-time", ] [[package]] name = "rustls-webpki" version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", "untrusted", ] [[package]] name = "rustversion" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ryu" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "schannel" version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "security-framework" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ "bitflags", "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "serde" version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] [[package]] name = "serde-xml-rs" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" dependencies = [ "log", "serde", "thiserror 1.0.69", "xml-rs", ] [[package]] name = "serde_derive" version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" dependencies = [ "itoa", "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] [[package]] name = "serde_urlencoded" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", "itoa", "ryu", "serde", ] [[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.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", ] [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[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 = "syn" version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" 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.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tar" version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" dependencies = [ "filetime", "libc", "xattr", ] [[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.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ "thiserror-impl 2.0.11", ] [[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", ] [[package]] name = "thiserror-impl" version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tinystr" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", "zerovec", ] [[package]] name = "tinyvec" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" 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.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", "libc", "mio", "pin-project-lite", "socket2", "tokio-macros", "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tokio-rustls" version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls", "tokio", ] [[package]] name = "tokio-util" version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", ] [[package]] name = "toml" version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", "toml_datetime", "toml_edit", ] [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow", ] [[package]] name = "tower" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", "sync_wrapper", "tokio", "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.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] [[package]] name = "tree_magic_mini" version = "3.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aac5e8971f245c3389a5a76e648bfc80803ae066a1243a75db0064d7c1129d63" dependencies = [ "fnv", "memchr", "nom", "once_cell", "petgraph", ] [[package]] name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "unicode-ident" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[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.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] [[package]] name = "utf16_iter" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[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 = "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.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-streams" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", ] [[package]] name = "web-sys" version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 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 = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ "windows-targets", ] [[package]] name = "windows-link" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" [[package]] name = "windows-registry" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ "windows-result", "windows-strings", "windows-targets", ] [[package]] name = "windows-result" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ "windows-targets", ] [[package]] name = "windows-strings" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ "windows-result", "windows-targets", ] [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[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_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[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_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[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_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" dependencies = [ "memchr", ] [[package]] name = "write16" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] name = "writeable" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "xattr" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909" dependencies = [ "libc", "linux-raw-sys", "rustix", ] [[package]] name = "xml-rs" version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" [[package]] name = "xz2" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" dependencies = [ "lzma-sys", ] [[package]] name = "yoke" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", "yoke-derive", "zerofrom", ] [[package]] name = "yoke-derive" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "zerofrom" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zerovec" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ "yoke", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "zstd" version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" version = "7.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" version = "2.0.14+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5" dependencies = [ "cc", "pkg-config", ] rebuildctl-0.22.1/Cargo.toml0000644000000045260000000000100112540ustar # 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 = "rebuildctl" version = "0.22.1" authors = ["kpcyrd "] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "rebuilderd - rebuildctl client" readme = false license = "GPL-3.0-or-later" repository = "https://github.com/kpcyrd/rebuilderd" [package.metadata.deb] assets = [ [ "target/release/rebuildctl", "usr/bin/", "755", ], [ "../contrib/confs/rebuilderd-sync.conf", "etc/", "644", ], [ "../contrib/systemd/rebuilderd-sync@.service", "/usr/lib/systemd/system/", "644", ], [ "../contrib/systemd/rebuilderd-sync@.timer", "/usr/lib/systemd/system/", "644", ], ] [[bin]] name = "rebuildctl" path = "src/main.rs" [dependencies.bzip2] version = "0.5" [dependencies.chrono] version = "0.4.19" features = ["serde"] [dependencies.clap] version = "4" features = ["derive"] [dependencies.clap_complete] version = "4.5.38" [dependencies.colored] version = "3" [dependencies.dirs-next] version = "2.0.0" [dependencies.env_logger] version = "0.11" [dependencies.flate2] version = "1.0.24" [dependencies.glob] version = "0.3.0" [dependencies.nom] version = "7.1.1" [dependencies.rebuilderd-common] version = "=0.22.1" [dependencies.regex] version = "1.5.6" [dependencies.serde] version = "1.0.137" features = ["derive"] [dependencies.serde-xml-rs] version = "0.6.0" [dependencies.serde_json] version = "1.0.81" [dependencies.tar] version = "0.4.38" [dependencies.tokio] version = "1.19.2" features = [ "macros", "rt-multi-thread", "io-std", "io-util", ] [dependencies.toml] version = "0.8" [dependencies.tree_magic_mini] version = "3.0.3" [dependencies.url] version = "2.2.2" [dependencies.xz2] version = "0.1" [dependencies.zstd] version = "0.13" features = ["pkg-config"] [dev-dependencies.data-encoding] version = "2" rebuildctl-0.22.1/Cargo.toml.orig000064400000000000000000000023411046102023000147260ustar 00000000000000[package] name = "rebuildctl" version = "0.22.1" description = "rebuilderd - rebuildctl client" authors = ["kpcyrd "] license = "GPL-3.0-or-later" repository = "https://github.com/kpcyrd/rebuilderd" edition = "2021" [package.metadata.deb] assets = [ ["target/release/rebuildctl", "usr/bin/", "755"], ["../contrib/confs/rebuilderd-sync.conf", "etc/", "644"], ["../contrib/systemd/rebuilderd-sync@.service", "/usr/lib/systemd/system/", "644"], ["../contrib/systemd/rebuilderd-sync@.timer", "/usr/lib/systemd/system/", "644"], ] [dependencies] bzip2 = "0.5" chrono = { version = "0.4.19", features=["serde"] } clap = { version = "4", features = ["derive"] } clap_complete = "4.5.38" colored = "3" dirs-next = "2.0.0" env_logger = "0.11" flate2 = "1.0.24" glob = "0.3.0" nom = "7.1.1" rebuilderd-common = { version= "=0.22.1", path="../common" } regex = "1.5.6" serde = { version="1.0.137", features=["derive"] } serde_json = "1.0.81" serde-xml-rs = "0.6.0" tar = "0.4.38" tokio = { version="1.19.2", features=["macros", "rt-multi-thread", "io-std", "io-util"] } toml = "0.8" tree_magic_mini = "3.0.3" url = "2.2.2" xz2 = "0.1" zstd = { version = "0.13", features = ["pkg-config"] } [dev-dependencies] data-encoding = "2" rebuildctl-0.22.1/src/args.rs000064400000000000000000000115231046102023000141320ustar 00000000000000use clap::{ArgAction, CommandFactory, Parser}; use clap_complete::Shell; use glob::Pattern; use rebuilderd_common::errors::*; use rebuilderd_common::Status; use std::io; use std::path::PathBuf; #[derive(Debug, Parser)] #[command(version)] pub struct Args { /// Verbose logging #[arg(short, long, global = true, action(ArgAction::Count))] pub verbose: u8, /// rebuilderd endpoint to talk to #[arg(short = 'H', long)] pub endpoint: Option, /// Configuration file path #[arg(short, long)] pub config: Option, /// Bypass tty detection and always use colors #[arg(short = 'C', long, global = true)] pub color: bool, #[command(subcommand)] pub subcommand: SubCommand, } #[derive(Debug, Parser)] pub enum SubCommand { /// Show worker status Status, /// Package related subcommands #[command(subcommand)] Pkgs(Pkgs), /// Queue related subcommands #[command(subcommand)] Queue(Queue), /// Generate shell completions Completions(Completions), } #[derive(Debug, Parser)] pub enum Pkgs { /// Sync package index Sync(PkgsSync), /// List known packages Ls(PkgsList), /// Sync package index with profile SyncProfile(PkgsSyncProfile), /// Read a package sync from stdin SyncStdin(PkgsSyncStdin), /// Requeue a given package Requeue(PkgsRequeue), /// Access the build log of the last rebuild Log(PkgsLog), /// Access the diffoscope of the last rebuild (if there is any) Diffoscope(PkgsDiffoscope), /// Access the attestation of the last rebuild (if there is any) Attestation(PkgsAttestation), } #[derive(Debug, Parser)] pub struct PkgsSyncProfile { #[arg(long)] pub print_json: bool, pub profile: String, #[arg(long = "sync-config", default_value = "/etc/rebuilderd-sync.conf")] pub config_file: String, } #[derive(Debug, Parser)] pub struct PkgsSyncStdin { pub distro: String, pub suite: String, } #[derive(Debug, Parser)] pub struct PkgsSync { pub distro: String, pub suite: String, pub source: String, #[arg(long = "architecture")] pub architectures: Vec, #[arg(long)] pub print_json: bool, #[arg(long = "maintainer")] pub maintainers: Vec, #[arg(long = "release")] pub releases: Vec, #[arg(long = "pkg")] pub pkgs: Vec, #[arg(long = "exclude")] pub excludes: Vec, #[arg(long)] pub sync_method: Option, } #[derive(Debug, Parser)] pub struct PkgsFilter { /// Filter packages matching this name #[arg(long)] pub name: Option, /// Filter packages matching this status #[arg(long)] pub status: Option, /// Filter packages matching this distro #[arg(long)] pub distro: Option, /// Filter packages matching this suite #[arg(long)] pub suite: Option, /// Filter packages matching this architecture #[arg(long)] pub architecture: Option, } #[derive(Debug, Parser)] pub struct PkgsList { #[command(flatten)] pub filter: PkgsFilter, #[arg(long)] pub json: bool, } #[derive(Debug, Parser)] pub struct PkgsRequeue { #[command(flatten)] pub filter: PkgsFilter, /// Requeue with given priority #[arg(long, default_value = "0")] pub priority: i32, /// Reset the status back to UNKWN #[arg(long)] pub reset: bool, } #[derive(Debug, Parser)] pub struct PkgsLog { #[command(flatten)] pub filter: PkgsFilter, } #[derive(Debug, Parser)] pub struct PkgsDiffoscope { #[command(flatten)] pub filter: PkgsFilter, } #[derive(Debug, Parser)] pub struct PkgsAttestation { #[command(flatten)] pub filter: PkgsFilter, } #[derive(Debug, Parser)] pub enum Queue { /// List the current build queue Ls(QueueList), /// Add a new task to the queue manually Push(QueuePush), /// Drop packages from queue matching given filter #[command(name = "drop")] Delete(QueueDrop), } #[derive(Debug, Parser)] pub struct QueueList { #[arg(long)] pub head: bool, #[arg(long)] pub json: bool, } #[derive(Debug, Parser)] pub struct QueuePush { pub distro: String, pub suite: String, pub name: String, pub version: Option, #[arg(long)] pub architecture: Option, #[arg(long, default_value = "0")] pub priority: i32, } #[derive(Debug, Parser)] pub struct QueueDrop { pub distro: String, pub suite: String, #[arg(long)] pub architecture: Option, pub name: String, pub version: Option, } #[derive(Debug, Parser)] pub struct Completions { pub shell: Shell, } pub fn gen_completions(args: &Completions) -> Result<()> { clap_complete::generate( args.shell, &mut Args::command(), "rebuildctl", &mut io::stdout(), ); Ok(()) } rebuildctl-0.22.1/src/config.rs000064400000000000000000000017721046102023000144500ustar 00000000000000use rebuilderd_common::errors::*; use serde::Deserialize; use std::collections::HashMap; use std::fs; use std::path::Path; #[derive(Debug, Deserialize)] pub struct SyncConfigFile { #[serde(rename = "profile")] pub profiles: HashMap, } impl SyncConfigFile { pub fn load>(path: P) -> Result { let buf = fs::read_to_string(path).context("Failed to read config file")?; let config = toml::from_str(&buf).context("Failed to load config")?; Ok(config) } } #[derive(Debug, Deserialize)] pub struct SyncProfile { pub distro: String, pub sync_method: Option, pub suite: String, #[serde(default)] pub releases: Vec, pub architecture: Option, #[serde(default)] pub architectures: Vec, pub source: String, #[serde(default)] pub maintainers: Vec, #[serde(default)] pub pkgs: Vec, #[serde(default)] pub excludes: Vec, } rebuildctl-0.22.1/src/decompress.rs000064400000000000000000000105151046102023000153420ustar 00000000000000use bzip2::read::BzDecoder; use flate2::read::GzDecoder; use rebuilderd_common::errors::*; use std::io::Read; use xz2::read::XzDecoder; #[derive(Debug, PartialEq, Eq)] pub enum CompressedWith { // .gz Gzip, // .bz2 Bzip2, // .xz Xz, // .zstd Zstd, Unknown, } pub fn detect_compression(bytes: &[u8]) -> CompressedWith { let mime = tree_magic_mini::from_u8(bytes); debug!("Detected mimetype for possibly compressed data: {:?}", mime); match mime { "application/gzip" => CompressedWith::Gzip, "application/x-bzip" => CompressedWith::Bzip2, "application/x-bzip2" => CompressedWith::Bzip2, "application/x-xz" => CompressedWith::Xz, "application/zstd" => CompressedWith::Zstd, _ => CompressedWith::Unknown, } } pub fn stream<'a>(comp: CompressedWith, bytes: &'a [u8]) -> Result> { match comp { CompressedWith::Gzip => Ok(Box::new(GzDecoder::new(bytes))), CompressedWith::Bzip2 => Ok(Box::new(BzDecoder::new(bytes))), CompressedWith::Xz => Ok(Box::new(XzDecoder::new(bytes))), CompressedWith::Zstd => Ok(Box::new(zstd::Decoder::new(bytes)?)), CompressedWith::Unknown => Ok(Box::new(bytes)), } } #[cfg(test)] mod tests { use super::*; use data_encoding::BASE64; #[test] fn detect_no_compression() { let comp = detect_compression(b"ohai"); assert_eq!(comp, CompressedWith::Unknown); } #[test] fn decompress_no_compression() { let bytes = b"ohai"; let comp = detect_compression(bytes); let mut buf = Vec::new(); stream(comp, bytes).unwrap().read_to_end(&mut buf).unwrap(); assert_eq!(bytes, b"ohai"); } #[test] fn detect_gzip_compression() { let bytes = BASE64 .decode(b"H4sIAAAAAAAAA8vPSMzkAgCKUC0+BQAAAA==") .unwrap(); let comp = detect_compression(&bytes); assert_eq!(comp, CompressedWith::Gzip); } #[test] fn decompress_gzip_compression() { let bytes = BASE64 .decode(b"H4sIAAAAAAAAA8vPSMzkAgCKUC0+BQAAAA==") .unwrap(); let comp = detect_compression(&bytes); assert_eq!(comp, CompressedWith::Gzip); let mut buf = Vec::new(); stream(comp, &bytes).unwrap().read_to_end(&mut buf).unwrap(); assert_eq!(buf, b"ohai\n"); } #[test] fn detect_bzip2_compression() { let bytes = BASE64 .decode(b"QlpoOTFBWSZTWZ+CN7sAAAJBAAAQIGCgADDNAMGmwHF3JFOFCQn4I3uw") .unwrap(); let comp = detect_compression(&bytes); assert_eq!(comp, CompressedWith::Bzip2); } #[test] fn decompress_bzip2_compression() { let bytes = BASE64 .decode(b"QlpoOTFBWSZTWZ+CN7sAAAJBAAAQIGCgADDNAMGmwHF3JFOFCQn4I3uw") .unwrap(); let comp = detect_compression(&bytes); assert_eq!(comp, CompressedWith::Bzip2); let mut buf = Vec::new(); stream(comp, &bytes).unwrap().read_to_end(&mut buf).unwrap(); assert_eq!(buf, b"ohai\n"); } #[test] fn detect_xz_compression() { let bytes = BASE64.decode(b"/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQAEb2hhaQoAAAAACyuekVbXbHMAAR0FuC2Arx+2830BAAAAAARZWg==").unwrap(); let comp = detect_compression(&bytes); assert_eq!(comp, CompressedWith::Xz); } #[test] fn decompress_xz_compression() { let bytes = BASE64.decode(b"/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQAEb2hhaQoAAAAACyuekVbXbHMAAR0FuC2Arx+2830BAAAAAARZWg==").unwrap(); let comp = detect_compression(&bytes); assert_eq!(comp, CompressedWith::Xz); let mut buf = Vec::new(); stream(comp, &bytes).unwrap().read_to_end(&mut buf).unwrap(); assert_eq!(buf, b"ohai\n"); } #[test] fn detect_zstd_compression() { let bytes = BASE64.decode(b"KLUv/QRYKQAAb2hhaQpnBE++").unwrap(); let comp = detect_compression(&bytes); assert_eq!(comp, CompressedWith::Zstd); } #[test] fn decompress_zstd_compression() { let bytes = BASE64.decode(b"KLUv/QRYKQAAb2hhaQpnBE++").unwrap(); let comp = detect_compression(&bytes); assert_eq!(comp, CompressedWith::Zstd); let mut buf = Vec::new(); stream(comp, &bytes).unwrap().read_to_end(&mut buf).unwrap(); assert_eq!(buf, b"ohai\n"); } } rebuildctl-0.22.1/src/main.rs000064400000000000000000000263711046102023000141310ustar 00000000000000use crate::args::*; use crate::config::SyncConfigFile; use clap::Parser; use colored::*; use env_logger::Env; use glob::Pattern; use rebuilderd_common::api::*; use rebuilderd_common::errors::*; use rebuilderd_common::http; use rebuilderd_common::utils; use serde::Serialize; use std::borrow::Cow; use std::fmt::Write as _; use std::io; use std::io::prelude::*; use tokio::io::AsyncReadExt; pub mod args; pub mod config; pub mod decompress; pub mod pager; pub mod schedule; fn patterns_from(patterns: &[String]) -> Result> { patterns .iter() .map(|p| Pattern::new(p).map_err(Error::from)) .collect() } fn print_json(x: &S) -> Result<()> { let mut stdout = io::stdout(); serde_json::to_writer_pretty(&mut stdout, &x)?; stdout.write_all(b"\n")?; Ok(()) } pub async fn sync(client: &Client, sync: PkgsSync) -> Result<()> { let method = if let Some(method) = &sync.sync_method { method.as_str() } else { sync.distro.as_str() }; let http = http::client()?; let mut pkgs = match method { "archlinux" => schedule::archlinux::sync(&http, &sync).await?, "debian" => schedule::debian::sync(&http, &sync).await?, "fedora" => schedule::fedora::sync(&http, &sync).await?, "tails" => schedule::tails::sync(&http, &sync).await?, unknown => bail!( "No integrated sync for {:?}, use --sync-method or `pkgs sync-stdin` instead", unknown ), }; pkgs.sort_by(|a, b| a.name.cmp(&b.name)); if sync.print_json { print_json(&pkgs)?; } else { sync_import( client, &SuiteImport { distro: sync.distro, suite: sync.suite, groups: pkgs, }, ) .await?; } Ok(()) } pub async fn sync_import(client: &Client, sync: &SuiteImport) -> Result<()> { info!("Sending current suite to api..."); client .sync_suite(sync) .await .context("Failed to send import to daemon")?; Ok(()) } async fn fetch_build_id_by_filter(client: &Client, filter: PkgsFilter) -> Result { let pkg = client .match_one_pkg(&ListPkgs { name: filter.name, status: filter.status, distro: filter.distro, suite: filter.suite, architecture: filter.architecture, }) .await .context("Failed to fetch package")?; let build_id = pkg.build_id.context("Package has not been built yet")?; Ok(build_id) } #[tokio::main] async fn main() -> Result<()> { let args = Args::parse(); let logging = match args.verbose { 0 => "info", 1 => "debug", _ => "trace", }; env_logger::init_from_env(Env::default().default_filter_or(logging)); if args.color { debug!("Bypass tty detection and always use colors"); colored::control::set_override(true); } let config = rebuilderd_common::config::load(args.config).context("Failed to load config file")?; let mut client = Client::new(config, args.endpoint)?; match args.subcommand { SubCommand::Status => { let mut stdout = io::stdout(); for worker in client.with_auth_cookie()?.list_workers().await? { let label = format!("{} ({})", worker.key.green(), worker.addr.yellow()); let status = if let Some(status) = worker.status { format!("{:?}", status).bold() } else { "idle".blue() }; if writeln!(stdout, "{:-40} => {}", label, status).is_err() { break; } } } SubCommand::Pkgs(Pkgs::Sync(args)) => sync(client.with_auth_cookie()?, args).await?, SubCommand::Pkgs(Pkgs::SyncProfile(args)) => { let mut config = SyncConfigFile::load(&args.config_file)?; let mut profile = config .profiles .remove(&args.profile) .ok_or_else(|| format_err!("Profile not found: {:?}", args.profile))?; // TODO: remove this after we've deprecated architecture= if let Some(arch) = profile.architecture { warn!("Deprecated option in config: replace `architecture = \"{}\"` with `architectures = [\"{}\"]`", arch, arch); profile.architectures.push(arch) } sync( client.with_auth_cookie()?, PkgsSync { distro: profile.distro, sync_method: profile.sync_method, suite: profile.suite, releases: profile.releases, architectures: profile.architectures, source: profile.source, print_json: args.print_json, maintainers: profile.maintainers, pkgs: patterns_from(&profile.pkgs)?, excludes: patterns_from(&profile.excludes)?, }, ) .await?; } SubCommand::Pkgs(Pkgs::SyncStdin(sync)) => { let mut stdin = tokio::io::stdin(); let mut buf = Vec::new(); stdin.read_to_end(&mut buf).await?; let pkgs = serde_json::from_slice(&buf) .context("Failed to deserialize pkg import from stdin")?; sync_import( client.with_auth_cookie()?, &SuiteImport { distro: sync.distro, suite: sync.suite, groups: pkgs, }, ) .await?; } SubCommand::Pkgs(Pkgs::Ls(ls)) => { let pkgs = client .list_pkgs(&ListPkgs { name: ls.filter.name, status: ls.filter.status, distro: ls.filter.distro, suite: ls.filter.suite, architecture: ls.filter.architecture, }) .await?; if ls.json { print_json(&pkgs)?; } else { let mut stdout = io::stdout(); for pkg in pkgs { let status_str = format!("[{}]", pkg.status.fancy()).bold(); let pkg_str = format!("{} {}", pkg.name.bold(), pkg.version.bold(),); let mut info = format!("{}, {}, {}", pkg.distro, pkg.suite, pkg.architecture,); if let Some(build_id) = pkg.build_id { write!(info, ", #{}", build_id)?; } if writeln!( stdout, "{} {:-60} ({}) {:?}", status_str, pkg_str, info, pkg.artifact_url, ) .is_err() { break; } } } } SubCommand::Pkgs(Pkgs::Requeue(args)) => { client .with_auth_cookie()? .requeue_pkgs(&RequeueQuery { name: args.filter.name, status: args.filter.status, priority: args.priority, distro: args.filter.distro, suite: args.filter.suite, architecture: args.filter.architecture, reset: args.reset, }) .await?; } SubCommand::Pkgs(Pkgs::Log(args)) => { let build_id = fetch_build_id_by_filter(&client, args.filter).await?; let log = client .fetch_log(build_id) .await .context("Failed to fetch build log")?; pager::write(&log)?; } SubCommand::Pkgs(Pkgs::Diffoscope(args)) => { let build_id = fetch_build_id_by_filter(&client, args.filter).await?; let diffoscope = client .fetch_diffoscope(build_id) .await .context("Failed to fetch diffoscope")?; pager::write(&diffoscope)?; } SubCommand::Pkgs(Pkgs::Attestation(args)) => { let build_id = fetch_build_id_by_filter(&client, args.filter).await?; let mut attestation = client .fetch_attestation(build_id) .await .context("Failed to fetch attestation")?; attestation.push(b'\n'); io::stdout().write_all(&attestation)?; } SubCommand::Queue(Queue::Ls(ls)) => { let limit = if ls.head { Some(25) } else { None }; let pkgs = client.list_queue(&ListQueue { limit }).await?; if ls.json { print_json(&pkgs)?; } else { let mut stdout = io::stdout(); for q in pkgs.queue { let pkg = q.pkgbase; let started_at = if let Some(started_at) = q.started_at { started_at.format("%Y-%m-%d %H:%M:%S").to_string() } else { String::new() }; let pkg_str = format!("{} {}", pkg.name.bold(), q.version,); let running = format!( "{:>11}", if let Some(started_at) = q.started_at { let duration = (pkgs.now - started_at).num_seconds(); Cow::Owned(utils::secs_to_human(duration)) } else { Cow::Borrowed("") } ); if writeln!( stdout, "{} {:-60} {} {:19} {:?} {:?} {:?}", q.queued_at .format("%Y-%m-%d %H:%M:%S") .to_string() .bright_black(), pkg_str, running.green(), started_at, pkg.distro, pkg.suite, pkg.architecture, ) .is_err() { break; } } } } SubCommand::Queue(Queue::Push(push)) => { client .with_auth_cookie()? .push_queue(&PushQueue { name: push.name, version: push.version, priority: push.priority, distro: push.distro, suite: push.suite, architecture: push.architecture, }) .await?; } SubCommand::Queue(Queue::Delete(push)) => { client .with_auth_cookie()? .drop_queue(&DropQueueItem { name: push.name, version: push.version, distro: push.distro, suite: push.suite, architecture: push.architecture, }) .await?; } SubCommand::Completions(completions) => args::gen_completions(&completions)?, } Ok(()) } rebuildctl-0.22.1/src/pager.rs000064400000000000000000000011401046102023000142660ustar 00000000000000use rebuilderd_common::errors::*; use std::env; use std::io::{self, IsTerminal, Write}; use std::process::{Command, Stdio}; pub fn write(buf: &[u8]) -> Result<()> { if io::stdout().is_terminal() && env::var_os("NOPAGER").is_none() { let mut cmd = Command::new("less") .args(["-R"]) .stdin(Stdio::piped()) .spawn() .context("Failed to spawn pager")?; if let Some(mut stdin) = cmd.stdin.take() { stdin.write_all(buf).ok(); } cmd.wait()?; } else { io::stdout().write_all(buf).ok(); } Ok(()) } rebuildctl-0.22.1/src/schedule/archlinux.rs000064400000000000000000000143561046102023000167760ustar 00000000000000use crate::args::PkgsSync; use crate::decompress; use crate::schedule::{fetch_url_or_path, Pkg}; use nom::bytes::complete::take_till; use rebuilderd_common::errors::*; use rebuilderd_common::http; use rebuilderd_common::{PkgArtifact, PkgGroup}; use std::collections::HashMap; use std::convert::TryInto; use std::io::prelude::*; use tar::{Archive, EntryType}; fn mirror_to_url(mut mirror: &str, repo: &str, arch: &str, file: &str) -> Result { let mut url = String::new(); loop { let (s, txt) = take_till::<_, _, ()>(|c| c == '$')(mirror).unwrap(); url.push_str(txt); if s.is_empty() { break; } let (s, var) = take_till::<_, _, ()>(|c| c == '/')(s).unwrap(); match var { "$repo" => url.push_str(repo), "$arch" => url.push_str(arch), _ => bail!("Unrecognized variable: {:?}", var), } mirror = s; } if !url.ends_with('/') { url.push('/'); } url.push_str(file); Ok(url) } #[derive(Debug)] pub struct ArchPkg { pub name: String, pub base: String, pub filename: String, pub version: String, pub architecture: String, pub packager: String, } impl Pkg for ArchPkg { fn pkg_name(&self) -> &str { &self.name } fn by_maintainer(&self, maintainers: &[String]) -> bool { maintainers.iter().any(|m| self.packager.starts_with(m)) } } #[derive(Debug, Default)] pub struct NewPkg { name: Vec, base: Vec, filename: Vec, version: Vec, architecture: Vec, packager: Vec, } impl TryInto for NewPkg { type Error = Error; fn try_into(self: NewPkg) -> Result { Ok(ArchPkg { name: self .name .first() .ok_or_else(|| anyhow!("Missing pkg name field"))? .to_string(), base: self .base .first() .ok_or_else(|| anyhow!("Missing pkg base field"))? .to_string(), filename: self .filename .first() .ok_or_else(|| anyhow!("Missing filename field"))? .to_string(), version: self .version .first() .ok_or_else(|| anyhow!("Missing version field"))? .to_string(), architecture: self .architecture .first() .ok_or_else(|| anyhow!("Missing architecture field"))? .to_string(), packager: self .packager .first() .ok_or_else(|| anyhow!("Missing packager field"))? .to_string(), }) } } pub fn extract_pkgs(bytes: &[u8]) -> Result> { let comp = decompress::detect_compression(bytes); let tar = decompress::stream(comp, bytes)?; let mut archive = Archive::new(tar); let mut pkgs = Vec::new(); for entry in archive.entries()? { let mut entry = entry?; if entry.header().entry_type() == EntryType::Regular { let mut pkg = NewPkg::default(); let mut content = String::new(); entry.read_to_string(&mut content)?; let mut iter = content.split('\n'); while let Some(key) = iter.next() { let mut values = Vec::new(); for value in &mut iter { if !value.is_empty() { values.push(value.to_string()); } else { break; } } match key { "%FILENAME%" => pkg.filename = values, "%NAME%" => pkg.name = values, "%BASE%" => pkg.base = values, "%VERSION%" => pkg.version = values, "%ARCH%" => pkg.architecture = values, "%PACKAGER%" => pkg.packager = values, _ => (), } } pkgs.push(pkg.try_into()?); } } Ok(pkgs) } pub async fn sync(http: &http::Client, sync: &PkgsSync) -> Result> { let source = if sync.source.ends_with(".db") { warn!("Detected legacy configuration for source, use the new format instead: https://mirrors.kernel.org/archlinux/$repo/os/$arch"); "https://mirrors.kernel.org/archlinux/$repo/os/$arch" } else { &sync.source }; let mut bases: HashMap<_, PkgGroup> = HashMap::new(); for arch in &sync.architectures { let db = mirror_to_url(source, &sync.suite, arch, &format!("{}.db", sync.suite))?; let bytes = fetch_url_or_path(http, &db).await?; info!("Parsing index ({} bytes)...", bytes.len()); for pkg in extract_pkgs(&bytes)? { if !pkg.matches(sync) { continue; } let url = mirror_to_url(source, &sync.suite, arch, &pkg.filename)?; let artifact = PkgArtifact { name: pkg.name, version: pkg.version.clone(), url, }; if let Some(group) = bases.get_mut(&pkg.base) { // TODO: multiple architectures could have the exact same package with arch=any group.add_artifact(artifact); } else { let mut group = PkgGroup::new( pkg.base.clone(), pkg.version, sync.distro.to_string(), sync.suite.to_string(), pkg.architecture, None, ); group.add_artifact(artifact); bases.insert(pkg.base, group); } } } Ok(bases.drain().map(|(_, v)| v).collect()) } #[cfg(test)] mod tests { use super::*; #[test] fn test_mirror_to_url() { let url = mirror_to_url( "https://ftp.halifax.rwth-aachen.de/archlinux/$repo/os/$arch", "core", "x86_64", "core.db", ) .unwrap(); assert_eq!( url, "https://ftp.halifax.rwth-aachen.de/archlinux/core/os/x86_64/core.db" ); } } rebuildctl-0.22.1/src/schedule/debian.rs000064400000000000000000001772301046102023000162240ustar 00000000000000use crate::args::PkgsSync; use crate::schedule::{fetch_url_or_path, Pkg}; use rebuilderd_common::errors::*; use rebuilderd_common::http; use rebuilderd_common::{PkgArtifact, PkgGroup}; use std::collections::HashMap; use std::io::prelude::*; use std::io::BufReader; use xz2::read::XzDecoder; pub const BIN_NMU_PREFIX: &str = "+b"; #[derive(Debug, Default)] pub struct SourcePkgBucket { pkgs: HashMap>, } impl SourcePkgBucket { pub fn new() -> SourcePkgBucket { SourcePkgBucket::default() } pub fn push(&mut self, pkg: DebianSourcePkg) { if let Some(list) = self.pkgs.get_mut(&pkg.base) { list.push(pkg); } else { self.pkgs.insert(pkg.base.clone(), vec![pkg]); } } pub fn get(&self, pkg: &DebianBinPkg) -> Result { let (name, version) = &pkg.source; let bin_nmu = pkg .version .rfind(BIN_NMU_PREFIX) .map(|idx| pkg.version.split_at(idx).1) .filter(|num| num[BIN_NMU_PREFIX.len()..].parse::().is_ok()) .unwrap_or(""); let list = self .pkgs .get(name) .with_context(|| anyhow!("No source package found with name: {:?}", name))?; // we currently track if the version was set explicitly or implicitly, keeping track just in case let version = match version { VersionConstraint::Explicit(version) => version, VersionConstraint::Implicit(version) => version, }; for src in list { if src.version == *version { let mut src_cpy = src.clone(); src_cpy.version.push_str(bin_nmu); return Ok(src_cpy); } } bail!("No matching source package found") } } #[derive(Debug, PartialEq, Eq)] pub enum VersionConstraint { Explicit(String), Implicit(String), } #[derive(Debug, PartialEq, Eq, Clone)] pub struct DebianSourcePkg { pub base: String, pub binary: Vec, pub version: String, pub directory: String, pub architecture: String, pub uploaders: Vec, } impl DebianSourcePkg { // this is necessary because the buildinfo folder structure doesn't align with `Directory:` in Sources.xz fn buildinfo_path(&self) -> String { let idx = self.directory.find('/').unwrap(); let (_, directory) = self.directory.split_at(idx + 1); let idx = directory.find('/').unwrap(); let (_, directory) = directory.split_at(idx + 1); directory.to_string() } fn buildinfo_url(&self, arch: &str) -> String { let directory = self.buildinfo_path(); let version_without_epoch = if let Some((_epoch, version)) = self.version.split_once(':') { version } else { &self.version }; let buildinfo_url = format!( "https://buildinfos.debian.net/buildinfo-pool/{}/{}_{}_{}.buildinfo", directory, self.base, version_without_epoch, arch ); buildinfo_url } } #[derive(Debug, PartialEq, Eq)] pub struct DebianBinPkg { name: String, version: String, source: (String, VersionConstraint), architecture: String, filename: String, uploaders: Vec, } impl Pkg for DebianBinPkg { fn pkg_name(&self) -> &str { &self.name } fn by_maintainer(&self, maintainers: &[String]) -> bool { self.uploaders .iter() .any(|uploader| maintainers.iter().any(|m| uploader.starts_with(m))) } } #[derive(Debug, Default)] pub struct NewPkg { base: Option, binary: Option>, source: Option, version: Option, directory: Option, architecture: Option, filename: Option, uploaders: Vec, } pub trait AnyhowTryFrom: Sized { fn try_from(x: T) -> Result; } impl AnyhowTryFrom for DebianSourcePkg { fn try_from(new: NewPkg) -> Result { Ok(DebianSourcePkg { base: new .base .ok_or_else(|| format_err!("Missing pkg base field"))?, binary: new .binary .ok_or_else(|| format_err!("Missing binary field"))?, version: new .version .ok_or_else(|| format_err!("Missing version field"))?, directory: new .directory .ok_or_else(|| format_err!("Missing directory field"))?, architecture: new .architecture .ok_or_else(|| format_err!("Missing architecture field"))?, uploaders: new.uploaders, }) } } impl AnyhowTryFrom for DebianBinPkg { fn try_from(new: NewPkg) -> Result { let name = new .base .ok_or_else(|| format_err!("Missing pkg base field"))?; let version = new .version .ok_or_else(|| format_err!("Missing version field"))?; let source = if let Some(source) = new.source { if let Some((name, version)) = source.split_once(' ') { let version = version .strip_prefix('(') .context("Malformed version in Source:")? .strip_suffix(')') .context("Malformed version in Source:")? .to_string(); (name.to_string(), VersionConstraint::Explicit(version)) } else { (source, VersionConstraint::Implicit(version.clone())) } } else { (name.clone(), VersionConstraint::Implicit(version.clone())) }; Ok(DebianBinPkg { name, version, source, architecture: new .architecture .ok_or_else(|| format_err!("Missing architecture field"))?, filename: new .filename .ok_or_else(|| format_err!("Missing filename field"))?, uploaders: new.uploaders, }) } } pub fn extract_pkg>(bytes: &[u8]) -> Result> { let r = XzDecoder::new(bytes); let r = BufReader::new(r); extract_pkgs_uncompressed(r) } pub fn extract_pkgs_uncompressed, R: BufRead>(r: R) -> Result> { let mut pkg = NewPkg::default(); let mut pkgs = Vec::new(); let mut lines = r.lines().peekable(); while let Some(line) = lines.next() { let line = line?; if line.is_empty() { pkgs.push(T::try_from(pkg)?); pkg = NewPkg::default(); } if let Some((a, b)) = line.split_once(": ") { match a { "Package" => pkg.base = Some(b.to_string()), "Binary" => { let mut binaries = Vec::new(); let mut value = b.to_string(); while value.ends_with(',') { if let Some(line) = lines.peek() { if let Ok(line) = line { if !line.starts_with(' ') { warn!("Line ended with comma, but next line is not multi-line"); break; } } } else { break; } let line = lines .next() .ok_or_else(|| anyhow!("Found comma on last line of file"))? .context("Failed to read line")?; value.push_str(&line); } for binary in value.split(", ") { binaries.push(binary.to_string()); } pkg.binary = Some(binaries); } "Version" => pkg.version = Some(b.to_string()), "Source" => pkg.source = Some(b.to_string()), "Directory" => pkg.directory = Some(b.to_string()), "Filename" => pkg.filename = Some(b.to_string()), "Architecture" => pkg.architecture = Some(b.to_string()), "Uploaders" => { let mut uploaders = Vec::new(); for uploader in b.split(", ") { uploaders.push(uploader.to_string()); } pkg.uploaders = uploaders; } _ => (), } } } Ok(pkgs) } #[derive(Debug, Default, PartialEq, Eq)] pub struct SyncState { groups: HashMap>, } impl SyncState { pub fn new() -> SyncState { SyncState::default() } fn ensure_group_exists( &mut self, src: &DebianSourcePkg, distro: String, suite: String, arch: &str, ) { // TODO: creating a new group isn't always needed let buildinfo_url = src.buildinfo_url(arch); let new_group = PkgGroup::new( src.base.clone(), src.version.clone(), distro, suite, arch.to_string(), Some(buildinfo_url), ); if let Some(list) = self.groups.get_mut(&src.base) { for group in list.iter() { if group.version == src.version && group.architecture == arch { return; } } list.push(new_group); } else { self.groups.insert(src.base.clone(), vec![new_group]); } } fn get_mut_group( &mut self, src: &DebianSourcePkg, distro: String, suite: String, arch: &str, ) -> &mut PkgGroup { self.ensure_group_exists(src, distro, suite, arch); // ensure_group_exists ensures the group exists let list = self.groups.get_mut(&src.base).unwrap(); for group in list { if group.version == src.version && group.architecture == arch { return group; } } // ensure_group_exists ensures the group exists unreachable!() } pub fn push( &mut self, src: &DebianSourcePkg, bin: DebianBinPkg, source: &str, distro: String, suite: String, ) { let group = self.get_mut_group(src, distro, suite, &bin.architecture); let url = format!("{}/{}", source, bin.filename); group.add_artifact(PkgArtifact { name: bin.name, version: bin.version, url, }); } pub fn to_vec(self) -> Vec { let mut out = self.groups.into_values().flatten().collect::>(); out.sort_by(|a, b| { a.name .cmp(&b.name) .then_with(|| a.version.cmp(&b.version)) .then_with(|| a.architecture.cmp(&b.architecture)) }); out } } pub async fn sync(http: &http::Client, sync: &PkgsSync) -> Result> { if sync.releases.len() > 1 { bail!("Tracking multiple releases in the same rebuilder is currently unsupported"); } let mut out = SyncState::new(); for release in &sync.releases { let mut sources = SourcePkgBucket::new(); // Downloading source package index let db_url = format!( "{}/dists/{}/{}/source/Sources.xz", sync.source, release, sync.suite ); let bytes = fetch_url_or_path(http, &db_url).await?; info!("Building map of all source packages"); for pkg in extract_pkg::(&bytes)? { debug!("Registering pkgbase: {:?}", pkg.base); sources.push(pkg); } for arch in &sync.architectures { // Downloading binary package index let db_url = format!( "{}/dists/{}/{}/binary-{}/Packages.xz", sync.source, release, sync.suite, arch ); let bytes = fetch_url_or_path(http, &db_url).await?; for pkg in extract_pkg::(&bytes)? { if !pkg.matches(sync) { continue; } debug!("Found binary package: {:?} {:?}", pkg.name, pkg.version); let src = sources.get(&pkg)?; debug!( "Matched binary package to source package: {:?} {:?}", src.base, src.version ); out.push( &src, pkg, &sync.source, sync.distro.clone(), sync.suite.clone(), ); } } } Ok(out.to_vec()) } #[cfg(test)] mod tests { use super::*; use std::io::Cursor; #[test] fn test_parse_bin_pkg_simple() { let bytes= b"Package: sniffglue Source: rust-sniffglue Version: 0.14.0-2 Installed-Size: 2344 Maintainer: Debian Rust Maintainers Architecture: amd64 Depends: libc6 (>= 2.32), libgcc-s1 (>= 4.2), libpcap0.8 (>= 1.5.1), libseccomp2 (>= 0.0.0~20120605) Description: Secure multithreaded packet sniffer Multi-Arch: allowed Built-Using: rust-nix (= 0.23.0-1), rust-pktparse (= 0.5.0-1), rust-seccomp-sys (= 0.1.3-1), rustc (= 1.56.0+dfsg1-2) Description-md5: e7f1183e49341488d3bd8fbe63b63f37 X-Cargo-Built-Using: rust-aho-corasick (= 0.7.10-1), rust-ansi-term (= 0.12.1-1), rust-anyhow (= 1.0.44-2), rust-arrayvec (= 0.5.1-1), rust-atty (= 0.2.14-2), rust-base64 (= 0.13.0-1), rust-bitflags (= 1.2.1-1), rust-block-buffer (= 0.9.0-4), rust-block-padding (= 0.2.1-1), rust-bstr (= 0.2.17-1), rust-byteorder (= 1.4.3-2), rust-cfg-if-0.1 (= 0.1.10-2), rust-cfg-if (= 1.0.0-1), rust-clap (= 2.33.3-1), rust-cpuid-bool (= 0.1.2-4), rust-dhcp4r (= 0.2.0-1), rust-digest (= 0.9.0-1), rust-dirs-next (= 2.0.0-1), rust-dirs-sys-next (= 0.1.1-1), rust-dns-parser (= 0.8.0-1), rust-enum-primitive (= 0.1.1-1), rust-env-logger (= 0.9.0-1), rust-generic-array (= 0.14.4-1), rust-humantime (= 2.1.0-1), rust-itoa (= 0.4.3-1), rust-lazy-static (= 1.4.0-1), rust-lexical-core (= 0.4.8-3), rust-libc (= 0.2.103-1), rust-log (= 0.4.11-2), rust-memchr (= 2.4.1-1), rust-memoffset (= 0.6.4-1), rust-nix (= 0.23.0-1), rust-nom (= 5.0.1-4), rust-num-cpus (= 1.13.0-1), rust-num-traits (= 0.2.14-1), rust-opaque-debug (= 0.3.0-1), rust-pcap-sys (= 0.1.3-2), rust-phf (= 0.8.0-2), rust-phf-shared (= 0.8.0-1), rust-pktparse (= 0.5.0-1), rust-quick-error (= 1.2.3-1), rust-reduce (= 0.1.1-1), rust-regex-automata (= 0.1.8-2), rust-regex (= 1.5.4-1), rust-regex-syntax (= 0.6.25-1), rust-rusticata-macros (= 2.0.4-1), rust-ryu (= 1.0.2-1), rust-seccomp-sys (= 0.1.3-1), rust-serde (= 1.0.130-2), rust-serde-json (= 1.0.41-1), rust-sha2 (= 0.9.2-2), rust-siphasher (= 0.3.1-1), rust-static-assertions (= 1.1.0-1), rust-strsim (= 0.9.3-1), rust-structopt (= 0.3.20-1), rust-strum (= 0.19.2-1), rust-syscallz (= 0.15.0-1), rust-termcolor (= 1.1.0-1), rust-textwrap (= 0.11.0-1), rust-time (= 0.1.42-1), rust-tls-parser (= 0.9.2-3), rust-toml (= 0.5.8-1), rust-typenum (= 1.12.0-1), rust-unicode-width (= 0.1.8-1), rust-users (= 0.11.0-1), rust-vec-map (= 0.8.1-2), rustc (= 1.56.0+dfsg1-2) Section: net Priority: optional Filename: pool/main/r/rust-sniffglue/sniffglue_0.14.0-2_amd64.deb Size: 732980 MD5sum: 177f9229266ad5eef3fb42fff0c07345 SHA256: 448c781a9e594227bc9f0d6c65b8beba2b3add68d3583020de188d4cfa365b40 "; let cursor = Cursor::new(bytes); let pkgs = extract_pkgs_uncompressed::(cursor).unwrap(); assert_eq!( &pkgs, &[DebianBinPkg { name: "sniffglue".to_string(), version: "0.14.0-2".to_string(), source: ( "rust-sniffglue".to_string(), VersionConstraint::Implicit("0.14.0-2".to_string()) ), architecture: "amd64".to_string(), filename: "pool/main/r/rust-sniffglue/sniffglue_0.14.0-2_amd64.deb".to_string(), uploaders: vec![], },] ); } #[test] fn test_parse_bin_pkg_with_epoch() { let bytes = b"Package: mariadb-server Source: mariadb-10.5 Version: 1:10.5.12-1 Installed-Size: 71 Maintainer: Debian MySQL Maintainers Architecture: all Depends: mariadb-server-10.5 (>= 1:10.5.12-1) Description: MariaDB database server (metapackage depending on the latest version) Homepage: https://mariadb.org/ Description-md5: a887647d25d472f89e220ceda2b6e041 Tag: devel::lang:c++, devel::lang:sql, devel::library, implemented-in::c++, interface::commandline, interface::daemon, network::server, protocol::db:mysql, role::devel-lib, role::metapackage, role::program, works-with::db Section: database Priority: optional Filename: pool/main/m/mariadb-10.5/mariadb-server_10.5.12-1_all.deb Size: 34856 MD5sum: 0dc2d34ec8673612de925bb516cadc51 SHA256: 0db2ae9db7de7cd88b02741a3fb19cf66f0043d56dcb129d91578f269973b286 "; let cursor = Cursor::new(bytes); let pkgs = extract_pkgs_uncompressed::(cursor).unwrap(); assert_eq!( &pkgs, &[DebianBinPkg { name: "mariadb-server".to_string(), version: "1:10.5.12-1".to_string(), source: ( "mariadb-10.5".to_string(), VersionConstraint::Implicit("1:10.5.12-1".to_string()) ), architecture: "all".to_string(), filename: "pool/main/m/mariadb-10.5/mariadb-server_10.5.12-1_all.deb".to_string(), uploaders: vec![], },] ); } #[test] fn test_parse_source_pkg() { let bytes = "Package: mariadb-10.5 Binary: libmariadb-dev, libmariadb-dev-compat, libmariadb3, libmariadbd19, libmariadbd-dev, mariadb-common, mariadb-client-core-10.5, mariadb-client-10.5, mariadb-server-core-10.5, mariadb-server-10.5, mariadb-server, mariadb-client, mariadb-backup, mariadb-plugin-connect, mariadb-plugin-s3, mariadb-plugin-rocksdb, mariadb-plugin-oqgraph, mariadb-plugin-mroonga, mariadb-plugin-spider, mariadb-plugin-gssapi-server, mariadb-plugin-gssapi-client, mariadb-plugin-cracklib-password-check, mariadb-test, mariadb-test-data Version: 1:10.5.12-1 Maintainer: Debian MySQL Maintainers Uploaders: Otto Kekäläinen Build-Depends: bison, cmake, cracklib-runtime , debhelper (>= 10), dh-exec, gdb , libaio-dev [linux-any], libboost-dev, libcrack2-dev (>= 2.9.0), libcurl4-openssl-dev | libcurl4-dev, libedit-dev, libedit-dev:native, libjemalloc-dev [linux-any], libjudy-dev, libkrb5-dev, liblz4-dev, libncurses5-dev (>= 5.0-6~), libncurses5-dev:native (>= 5.0-6~), libnuma-dev [linux-any], libpam0g-dev, libpcre2-dev, libsnappy-dev, libssl-dev, libssl-dev:native, libsystemd-dev [linux-any], libxml2-dev, libzstd-dev (>= 1.3.3), lsb-release, perl:any, po-debconf, psmisc, unixodbc-dev, uuid-dev, zlib1g-dev (>= 1:1.1.3-5~) Architecture: any all Standards-Version: 4.5.0 Format: 3.0 (quilt) Files: a0aa3e2839d3caf1b17a653968bd315d 4782 mariadb-10.5_10.5.12-1.dsc 2b103e8a462fd1a5ce6fc9dec4c23844 101914615 mariadb-10.5_10.5.12.orig.tar.gz 5c8baca3552e0a2b6400588fba1088d4 195 mariadb-10.5_10.5.12.orig.tar.gz.asc 4e7509cb525aa7a8be9ac405ef53d784 222380 mariadb-10.5_10.5.12-1.debian.tar.xz Vcs-Browser: https://salsa.debian.org/mariadb-team/mariadb-10.5 Vcs-Git: https://salsa.debian.org/mariadb-team/mariadb-10.5.git Checksums-Sha256: 0092ed302d547dd00843ada1bc85a783ee0a7aa4f0448b91d744226c6b311d55 4782 mariadb-10.5_10.5.12-1.dsc ab4f1ca69a30c5372e191a68e8b543a74168327680fb1f4067e8cc0a5582e4bd 101914615 mariadb-10.5_10.5.12.orig.tar.gz 0d3b97cfb7998fd0a62cbc6e6d8ae1340d52b616ac12e9eb8f2773a9775f82c6 195 mariadb-10.5_10.5.12.orig.tar.gz.asc 451dbbdaaedb6cf087ba38dd2708de6a31fa88a5333295be90c2323a414dc53c 222380 mariadb-10.5_10.5.12-1.debian.tar.xz Homepage: https://mariadb.org/ Package-List: libmariadb-dev deb libdevel optional arch=any libmariadb-dev-compat deb libdevel optional arch=any libmariadb3 deb libs optional arch=any libmariadbd-dev deb libdevel optional arch=any libmariadbd19 deb libs optional arch=any mariadb-backup deb database optional arch=any mariadb-client deb database optional arch=all mariadb-client-10.5 deb database optional arch=any mariadb-client-core-10.5 deb database optional arch=any mariadb-common deb database optional arch=all mariadb-plugin-connect deb database optional arch=any mariadb-plugin-cracklib-password-check deb database optional arch=any mariadb-plugin-gssapi-client deb database optional arch=any mariadb-plugin-gssapi-server deb database optional arch=any mariadb-plugin-mroonga deb database optional arch=any-alpha,any-amd64,any-arm,any-arm64,any-i386,any-ia64,any-mips64el,any-mips64r6el,any-mipsel,any-mipsr6el,any-nios2,any-powerpcel,any-ppc64el,any-sh3,any-sh4,any-tilegx mariadb-plugin-oqgraph deb database optional arch=any mariadb-plugin-rocksdb deb database optional arch=amd64,arm64,mips64el,ppc64el mariadb-plugin-s3 deb database optional arch=any mariadb-plugin-spider deb database optional arch=any mariadb-server deb database optional arch=all mariadb-server-10.5 deb database optional arch=any mariadb-server-core-10.5 deb database optional arch=any mariadb-test deb database optional arch=any mariadb-test-data deb database optional arch=all Testsuite: autopkgtest Testsuite-Triggers: eatmydata Directory: pool/main/m/mariadb-10.5 Priority: extra Section: misc "; let cursor = Cursor::new(bytes); let pkgs = extract_pkgs_uncompressed::(cursor).unwrap(); assert_eq!( &pkgs, &[DebianSourcePkg { base: "mariadb-10.5".to_string(), binary: vec![ "libmariadb-dev".to_string(), "libmariadb-dev-compat".to_string(), "libmariadb3".to_string(), "libmariadbd19".to_string(), "libmariadbd-dev".to_string(), "mariadb-common".to_string(), "mariadb-client-core-10.5".to_string(), "mariadb-client-10.5".to_string(), "mariadb-server-core-10.5".to_string(), "mariadb-server-10.5".to_string(), "mariadb-server".to_string(), "mariadb-client".to_string(), "mariadb-backup".to_string(), "mariadb-plugin-connect".to_string(), "mariadb-plugin-s3".to_string(), "mariadb-plugin-rocksdb".to_string(), "mariadb-plugin-oqgraph".to_string(), "mariadb-plugin-mroonga".to_string(), "mariadb-plugin-spider".to_string(), "mariadb-plugin-gssapi-server".to_string(), "mariadb-plugin-gssapi-client".to_string(), "mariadb-plugin-cracklib-password-check".to_string(), "mariadb-test".to_string(), "mariadb-test-data".to_string(), ], version: "1:10.5.12-1".to_string(), directory: "pool/main/m/mariadb-10.5".to_string(), architecture: "any all".to_string(), uploaders: vec!["Otto Kekäläinen ".to_string()], }] ); } #[test] fn test_generate_group_mariadb() { let src = DebianSourcePkg { base: "mariadb-10.5".to_string(), binary: vec![ "libmariadb-dev".to_string(), "libmariadb-dev-compat".to_string(), "libmariadb3".to_string(), "libmariadbd19".to_string(), "libmariadbd-dev".to_string(), "mariadb-common".to_string(), "mariadb-client-core-10.5".to_string(), "mariadb-client-10.5".to_string(), "mariadb-server-core-10.5".to_string(), "mariadb-server-10.5".to_string(), "mariadb-server".to_string(), "mariadb-client".to_string(), "mariadb-backup".to_string(), "mariadb-plugin-connect".to_string(), "mariadb-plugin-s3".to_string(), "mariadb-plugin-rocksdb".to_string(), "mariadb-plugin-oqgraph".to_string(), "mariadb-plugin-mroonga".to_string(), "mariadb-plugin-spider".to_string(), "mariadb-plugin-gssapi-server".to_string(), "mariadb-plugin-gssapi-client".to_string(), "mariadb-plugin-cracklib-password-check".to_string(), "mariadb-test".to_string(), "mariadb-test-data".to_string(), ], version: "1:10.5.12-1".to_string(), directory: "pool/main/m/mariadb-10.5".to_string(), architecture: "any all".to_string(), uploaders: vec!["Otto Kekäläinen ".to_string()], }; let bin = DebianBinPkg { name: "mariadb-server".to_string(), version: "1:10.5.12-1".to_string(), source: ( "mariadb-10.5".to_string(), VersionConstraint::Implicit("1:10.5.12-1".to_string()), ), architecture: "all".to_string(), filename: "pool/main/m/mariadb-10.5/mariadb-server_10.5.12-1_all.deb".to_string(), uploaders: vec![], }; let mut state = SyncState::new(); state.push( &src, bin, "https://deb.debian.org/debian", "debian".to_string(), "main".to_string(), ); let mut groups = HashMap::new(); groups.insert("mariadb-10.5".to_string(), vec![ PkgGroup { name: "mariadb-10.5".to_string(), version: "1:10.5.12-1".to_string(), distro: "debian".to_string(), suite: "main".to_string(), architecture: "all".to_string(), input_url: Some("https://buildinfos.debian.net/buildinfo-pool/m/mariadb-10.5/mariadb-10.5_10.5.12-1_all.buildinfo".to_string()), artifacts: vec![ PkgArtifact { name: "mariadb-server".to_string(), version: "1:10.5.12-1".to_string(), url: "https://deb.debian.org/debian/pool/main/m/mariadb-10.5/mariadb-server_10.5.12-1_all.deb".to_string(), } ], }, ]); assert_eq!(state, SyncState { groups }); } #[test] fn test_generate_group_sniffglue() { let bytes = "Package: librust-sniffglue-dev Source: rust-sniffglue Version: 0.14.0-2 Installed-Size: 317 Maintainer: Debian Rust Maintainers Architecture: amd64 Provides: librust-sniffglue+default-dev (= 0.14.0-2), librust-sniffglue-0+default-dev (= 0.14.0-2), librust-sniffglue-0-dev (= 0.14.0-2), librust-sniffglue-0.14+default-dev (= 0.14.0-2), librust-sniffglue-0.14-dev (= 0.14.0-2), librust-sniffglue-0.14.0+default-dev (= 0.14.0-2), librust-sniffglue-0.14.0-dev (= 0.14.0-2) Depends: librust-ansi-term-0.12+default-dev, librust-anyhow-1+default-dev, librust-atty-0.2+default-dev, librust-base64-0.13+default-dev, librust-bstr-0.2+default-dev (>= 0.2.12-~~), librust-dhcp4r-0.2+default-dev, librust-dirs-next-2+default-dev, librust-dns-parser-0.8+default-dev, librust-env-logger-0.9+default-dev, librust-libc-0.2+default-dev, librust-log-0.4+default-dev, librust-nix-0.23+default-dev, librust-nom-5+default-dev, librust-num-cpus-1+default-dev (>= 1.6-~~), librust-pcap-sys-0.1+default-dev (>= 0.1.3-~~), librust-pktparse-0.5+default-dev, librust-pktparse-0.5+serde-dev, librust-reduce-0.1+default-dev (>= 0.1.1-~~), librust-serde-1+default-dev, librust-serde-derive-1+default-dev, librust-serde-json-1+default-dev, librust-sha2-0.9+default-dev, librust-structopt-0.3+default-dev, librust-syscallz-0.15+default-dev, librust-tls-parser-0.9+default-dev, librust-toml-0.5+default-dev, librust-users-0.11+default-dev Description: Secure multithreaded packet sniffer - Rust source code Multi-Arch: same Description-md5: 81e67bbd8963c4189af0a9414f889972 Section: net Priority: optional Filename: pool/main/r/rust-sniffglue/librust-sniffglue-dev_0.14.0-2_amd64.deb Size: 125404 MD5sum: 6d57946f2f56b1b58d906eb29d6a021f SHA256: c452054c216359ef44adc9a5d35870d707f47e503051dfcb736f47df17058961 Package: sniffglue Source: rust-sniffglue Version: 0.14.0-2 Installed-Size: 2344 Maintainer: Debian Rust Maintainers Architecture: amd64 Depends: libc6 (>= 2.32), libgcc-s1 (>= 4.2), libpcap0.8 (>= 1.5.1), libseccomp2 (>= 0.0.0~20120605) Description: Secure multithreaded packet sniffer Multi-Arch: allowed Built-Using: rust-nix (= 0.23.0-1), rust-pktparse (= 0.5.0-1), rust-seccomp-sys (= 0.1.3-1), rustc (= 1.56.0+dfsg1-2) Description-md5: e7f1183e49341488d3bd8fbe63b63f37 X-Cargo-Built-Using: rust-aho-corasick (= 0.7.10-1), rust-ansi-term (= 0.12.1-1), rust-anyhow (= 1.0.44-2), rust-arrayvec (= 0.5.1-1), rust-atty (= 0.2.14-2), rust-base64 (= 0.13.0-1), rust-bitflags (= 1.2.1-1), rust-block-buffer (= 0.9.0-4), rust-block-padding (= 0.2.1-1), rust-bstr (= 0.2.17-1), rust-byteorder (= 1.4.3-2), rust-cfg-if-0.1 (= 0.1.10-2), rust-cfg-if (= 1.0.0-1), rust-clap (= 2.33.3-1), rust-cpuid-bool (= 0.1.2-4), rust-dhcp4r (= 0.2.0-1), rust-digest (= 0.9.0-1), rust-dirs-next (= 2.0.0-1), rust-dirs-sys-next (= 0.1.1-1), rust-dns-parser (= 0.8.0-1), rust-enum-primitive (= 0.1.1-1), rust-env-logger (= 0.9.0-1), rust-generic-array (= 0.14.4-1), rust-humantime (= 2.1.0-1), rust-itoa (= 0.4.3-1), rust-lazy-static (= 1.4.0-1), rust-lexical-core (= 0.4.8-3), rust-libc (= 0.2.103-1), rust-log (= 0.4.11-2), rust-memchr (= 2.4.1-1), rust-memoffset (= 0.6.4-1), rust-nix (= 0.23.0-1), rust-nom (= 5.0.1-4), rust-num-cpus (= 1.13.0-1), rust-num-traits (= 0.2.14-1), rust-opaque-debug (= 0.3.0-1), rust-pcap-sys (= 0.1.3-2), rust-phf (= 0.8.0-2), rust-phf-shared (= 0.8.0-1), rust-pktparse (= 0.5.0-1), rust-quick-error (= 1.2.3-1), rust-reduce (= 0.1.1-1), rust-regex-automata (= 0.1.8-2), rust-regex (= 1.5.4-1), rust-regex-syntax (= 0.6.25-1), rust-rusticata-macros (= 2.0.4-1), rust-ryu (= 1.0.2-1), rust-seccomp-sys (= 0.1.3-1), rust-serde (= 1.0.130-2), rust-serde-json (= 1.0.41-1), rust-sha2 (= 0.9.2-2), rust-siphasher (= 0.3.1-1), rust-static-assertions (= 1.1.0-1), rust-strsim (= 0.9.3-1), rust-structopt (= 0.3.20-1), rust-strum (= 0.19.2-1), rust-syscallz (= 0.15.0-1), rust-termcolor (= 1.1.0-1), rust-textwrap (= 0.11.0-1), rust-time (= 0.1.42-1), rust-tls-parser (= 0.9.2-3), rust-toml (= 0.5.8-1), rust-typenum (= 1.12.0-1), rust-unicode-width (= 0.1.8-1), rust-users (= 0.11.0-1), rust-vec-map (= 0.8.1-2), rustc (= 1.56.0+dfsg1-2) Section: net Priority: optional Filename: pool/main/r/rust-sniffglue/sniffglue_0.14.0-2_amd64.deb Size: 732980 MD5sum: 177f9229266ad5eef3fb42fff0c07345 SHA256: 448c781a9e594227bc9f0d6c65b8beba2b3add68d3583020de188d4cfa365b40 "; let cursor = Cursor::new(bytes); let bin_pkgs = extract_pkgs_uncompressed::(cursor).unwrap(); let bytes = "Package: rust-sniffglue Binary: librust-sniffglue-dev, sniffglue Version: 0.14.0-2 Maintainer: Debian Rust Maintainers Uploaders: kpcyrd Build-Depends: debhelper (>= 12), dh-cargo (>= 25), cargo:native, rustc:native, libstd-rust-dev, librust-ansi-term-0.12+default-dev, librust-anyhow-1+default-dev, librust-atty-0.2+default-dev, librust-base64-0.13+default-dev, librust-bstr-0.2+default-dev (>= 0.2.12-~~), librust-dhcp4r-0.2+default-dev, librust-dirs-next-2+default-dev, librust-dns-parser-0.8+default-dev, librust-env-logger-0.9+default-dev, librust-libc-0.2+default-dev, librust-log-0.4+default-dev, librust-nix-0.23+default-dev, librust-nom-5+default-dev, librust-num-cpus-1+default-dev (>= 1.6-~~), librust-pcap-sys-0.1+default-dev (>= 0.1.3-~~), librust-pktparse-0.5+default-dev, librust-pktparse-0.5+serde-dev, librust-reduce-0.1+default-dev (>= 0.1.1-~~), librust-serde-1+default-dev, librust-serde-derive-1+default-dev, librust-serde-json-1+default-dev, librust-sha2-0.9+default-dev, librust-structopt-0.3+default-dev, librust-syscallz-0.15+default-dev, librust-tls-parser-0.9+default-dev, librust-toml-0.5+default-dev, librust-users-0.11+default-dev Architecture: any Standards-Version: 4.5.1 Format: 3.0 (quilt) Files: cdb6bf3fb7a8725986b313a65dd3339b 3079 rust-sniffglue_0.14.0-2.dsc 80a7d2ab6becacf69213d9ce57d29274 134805 rust-sniffglue_0.14.0.orig.tar.gz 9902c121e4f5cf268b19ee8b88201979 7816 rust-sniffglue_0.14.0-2.debian.tar.xz Vcs-Browser: https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/sniffglue Vcs-Git: https://salsa.debian.org/rust-team/debcargo-conf.git [src/sniffglue] Checksums-Sha256: b9a77f9f918769ecded338c07a344257b17d1112918b1597a8c939a719444ea4 3079 rust-sniffglue_0.14.0-2.dsc f056bfa09e8fae5f4cc0e1d4e8ae3619050644b321800d0d6a8cc778eb80aaf3 134805 rust-sniffglue_0.14.0.orig.tar.gz cb3498dd85e18e7b2c7ad5cbef2ac56e4c598df0a0ac5024aa480f97de79b096 7816 rust-sniffglue_0.14.0-2.debian.tar.xz Package-List: librust-sniffglue-dev deb net optional arch=any sniffglue deb net optional arch=any Testsuite: autopkgtest Testsuite-Triggers: dh-cargo Directory: pool/main/r/rust-sniffglue Priority: extra Section: misc "; let cursor = Cursor::new(bytes); let src_pkgs = extract_pkgs_uncompressed::(cursor).unwrap(); let mut state = SyncState::new(); for bin in bin_pkgs { state.push( &src_pkgs[0], bin, "https://deb.debian.org/debian", "debian".to_string(), "main".to_string(), ); } let mut groups = HashMap::new(); groups.insert("rust-sniffglue".to_string(), vec![ PkgGroup { name: "rust-sniffglue".to_string(), version: "0.14.0-2".to_string(), distro: "debian".to_string(), suite: "main".to_string(), architecture: "amd64".to_string(), input_url: Some("https://buildinfos.debian.net/buildinfo-pool/r/rust-sniffglue/rust-sniffglue_0.14.0-2_amd64.buildinfo".to_string()), artifacts: vec![ PkgArtifact { name: "librust-sniffglue-dev".to_string(), version: "0.14.0-2".to_string(), url: "https://deb.debian.org/debian/pool/main/r/rust-sniffglue/librust-sniffglue-dev_0.14.0-2_amd64.deb".to_string(), }, PkgArtifact { name: "sniffglue".to_string(), version: "0.14.0-2".to_string(), url: "https://deb.debian.org/debian/pool/main/r/rust-sniffglue/sniffglue_0.14.0-2_amd64.deb".to_string(), } ], }, ]); assert_eq!(state, SyncState { groups }); } #[test] fn test_generate_group_courier() { let bytes = "Package: courier-base Source: courier (1.0.16-3) Version: 1.0.16-3+b1 Installed-Size: 743 Maintainer: Markus Wanner Architecture: amd64 Replaces: courier-ssl (<< 0.75.0-1) Depends: adduser, courier-authdaemon, courier-authlib (>= 0.66.1), courier-authlib-userdb, debconf (>= 0.5) | debconf-2.0, gnutls-bin, lsb-base, sysvinit-utils (>= 2.88dsf-50), perl:any, libc6 (>= 2.15), libcourier-unicode4 (>= 2.1.2), libgamin0 | libfam0, libgdbm6 (>= 1.16), libgnutls30 (>= 3.7.0), libidn12 (>= 1.13), libpcre3 Breaks: courier-authdaemon (<< 0.66.4-4~), courier-ssl (<< 0.75.0-1) Description: Courier mail server - base system Homepage: http://www.courier-mta.org/ Description-md5: 555818a698d6dfec6122cd45f5263ef2 Tag: interface::daemon, mail::transport-agent, network::server, role::program, works-with::mail Section: mail Priority: optional Filename: pool/main/c/courier/courier-base_1.0.16-3+b1_amd64.deb Size: 328148 MD5sum: 06d0be1d5211f0d425803633806663a5 SHA256: 688b7c11b8ec92514929d37e207681e4b9ac754db9e8cf0ab0632374433eed7e Package: courier-doc Source: courier Version: 1.0.16-3 Installed-Size: 1625 Maintainer: Markus Wanner Architecture: all Description: Courier mail server - additional documentation Homepage: http://www.courier-mta.org/ Description-md5: 5dcceca21b36719b84d5685c5dd14e9c Tag: interface::daemon, made-of::html, mail::transport-agent, role::documentation, role::program, works-with::mail Section: doc Priority: optional Filename: pool/main/c/courier/courier-doc_1.0.16-3_all.deb Size: 413660 MD5sum: efcc397d2590c11408ef0bd14f009fc7 SHA256: 8606f9cffd01b510d6f4135670b1c78fb1a9198e192cb13a9434a674702efdbc Package: courier-faxmail Source: courier (1.0.16-3) Version: 1.0.16-3+b1 Installed-Size: 188 Maintainer: Markus Wanner Architecture: amd64 Depends: courier-mta (= 1.0.16-3+b1), ghostscript, groff, mgetty-fax Recommends: netpbm Suggests: courier-doc Breaks: courier-webadmin (<< 1.0.14-2~) Description: Courier mail server - Fax<->mail gateway Homepage: http://www.courier-mta.org/ Description-md5: 1235807fe94191d8d0d1e41e90ae7d93 Tag: hardware::modem, interface::daemon, network::server, role::program, use::converting, works-with::fax, works-with::mail Section: mail Priority: optional Filename: pool/main/c/courier/courier-faxmail_1.0.16-3+b1_amd64.deb Size: 137492 MD5sum: 24f9a41c6380ea2ca7559ce9e6f6f54a SHA256: 6cb78e731f845dd98ab792c43fc01a6dc3416140b08d2db00e7415eff5973527 Package: courier-imap Source: courier (1.0.16-3) Version: 5.0.13+1.0.16-3+b1 Installed-Size: 593 Maintainer: Markus Wanner Architecture: amd64 Replaces: courier-imap-ssl (<< 4.16.2+0.75.0-1~), imap-server Provides: imap-server Depends: courier-base (= 1.0.16-3+b1), debconf | debconf-2.0, gamin, default-mta | mail-transport-agent, sysvinit-utils (>= 2.88dsf-50) | init-d-script, courier-authlib (>= 0.71), libc6 (>= 2.15), libcourier-unicode4 (>= 2.1.2), libgamin0 | libfam0, libgdbm6 (>= 1.16), libidn12 (>= 1.13) Suggests: courier-doc, imap-client Conflicts: imap-server Breaks: courier-imap-ssl (<< 4.16.2+0.75.0-1~) Description: Courier mail server - IMAP server Homepage: http://www.courier-mta.org/ Description-md5: aedad44242f18297b70663ef077f0e63 Tag: interface::daemon, mail::imap, network::server, network::service, protocol::imap, role::program, works-with::mail Section: mail Priority: optional Filename: pool/main/c/courier/courier-imap_5.0.13+1.0.16-3+b1_amd64.deb Size: 277952 MD5sum: f8eb4b0c42f191581189b2aee4c31793 SHA256: 67acfd8593f6c0a12a2681906e43dfe2872a694bd74e5438726646ec0e2af0a6 Package: courier-ldap Source: courier (1.0.16-3) Version: 1.0.16-3+b1 Installed-Size: 205 Maintainer: Markus Wanner Architecture: amd64 Replaces: courier-imap-authldap Depends: courier-authlib-ldap, courier-base (= 1.0.16-3+b1), debconf | debconf-2.0, sysvinit-utils (>= 2.88dsf-50) | init-d-script, courier-authlib (>= 0.71), libc6 (>= 2.15), libldap-2.4-2 (>= 2.4.7) Suggests: courier-doc Conflicts: courier-imap-authldap Description: Courier mail server - LDAP support Homepage: http://www.courier-mta.org/ Description-md5: 59e644146a903a5cf765b1a1794c77bc Tag: interface::daemon, network::server, protocol::ldap, role::program, security::authentication, works-with::db, works-with::mail Section: mail Priority: optional Filename: pool/main/c/courier/courier-ldap_1.0.16-3+b1_amd64.deb Size: 142284 MD5sum: fda5c8d7f98633778de1beb7197d257c SHA256: 733c1e1f620b416fb107e115fc8fa3cbe511d1e47ce1e171e1ffb8b5b1cecd05 Package: courier-mlm Source: courier (1.0.16-3) Version: 1.0.16-3+b1 Installed-Size: 982 Maintainer: Markus Wanner Architecture: amd64 Replaces: sqwebmail (<< 0.75.0-1~) Depends: courier-base (= 1.0.16-3+b1), maildrop, sysvinit-utils (>= 2.88dsf-50) | init-d-script, libc6 (>= 2.15), libcourier-unicode4 (>= 2.1.2), libgcc-s1 (>= 3.0), libgdbm6 (>= 1.16), libidn12 (>= 1.13), libstdc++6 (>= 5.2) Suggests: courier-doc Breaks: sqwebmail (<< 0.75.0-1~) Description: Courier mail server - mailing list manager Homepage: http://www.courier-mta.org/ Description-md5: fb8213625648c3fbce12df9752b51d0f Tag: interface::daemon, mail::list, network::server, role::program, works-with::mail Section: mail Priority: optional Filename: pool/main/c/courier/courier-mlm_1.0.16-3+b1_amd64.deb Size: 390264 MD5sum: 4f8cc681fee4364d1a89e118c16bb5a7 SHA256: 209018400fd2dfa4caf4ede13a8865a110a9dec1c387e8eb9e45e2cd0550b771 Package: courier-mta Source: courier (1.0.16-3) Version: 1.0.16-3+b1 Installed-Size: 2439 Maintainer: Markus Wanner Architecture: amd64 Replaces: courier-mta-ssl (<< 0.75.0-1~), mail-transport-agent Provides: mail-transport-agent Depends: courier-base (= 1.0.16-3+b1), debconf (>= 0.5) | debconf-2.0, libnet-cidr-perl, sysvinit-utils (>= 2.88dsf-50) | init-d-script, wget, courier-authlib (>= 0.71), libc6 (>= 2.15), libcourier-unicode4 (>= 2.1.2), libgcc-s1 (>= 3.0), libgdbm6 (>= 1.16), libidn12 (>= 1.13), libperl5.32 (>= 5.32.0~rc1), libstdc++6 (>= 5.2), perl:any Suggests: courier-doc, courier-filter-perl, couriergrey, mail-reader Conflicts: mail-transport-agent Breaks: courier-mta-ssl (<< 0.75.0-1~) Description: Courier mail server - ESMTP daemon Homepage: http://www.courier-mta.org/ Description-md5: 88c67d6433b0af4789d4e8a4fd1ecc42 Tag: interface::daemon, mail::transport-agent, network::server, network::service, protocol::smtp, role::program, works-with::mail Section: mail Priority: optional Filename: pool/main/c/courier/courier-mta_1.0.16-3+b1_amd64.deb Size: 634364 MD5sum: 788546e04c005d285cc084c1dea6b2ab SHA256: a05a38e8aa0986067b40d1f82dbf59732c6f4697ea91d8717ef0ea88b388ae6a Package: courier-pcp Source: courier (1.0.16-3) Version: 1.0.16-3+b1 Installed-Size: 245 Maintainer: Markus Wanner Architecture: amd64 Depends: sqwebmail, courier-authlib (>= 0.71), libc6 (>= 2.15) Suggests: courier-doc Breaks: courier-webadmin (<< 1.0.14-2~) Description: Courier mail server - PCP server Homepage: http://www.courier-mta.org/ Description-md5: 2607844768fa146876c3a6247b36dad9 Tag: interface::daemon, network::server, role::program, use::organizing, works-with::mail, works-with::pim Section: mail Priority: optional Filename: pool/main/c/courier/courier-pcp_1.0.16-3+b1_amd64.deb Size: 169328 MD5sum: 16d6b5a9f33b6da3e8cbe0fb52105aa5 SHA256: 7b118060d17983ff0a070825819a5b6ac46bad0262288e5f63c7bd0baefcf72d Package: courier-pop Source: courier (1.0.16-3) Version: 1.0.16-3+b1 Installed-Size: 315 Maintainer: Markus Wanner Architecture: amd64 Replaces: courier-pop-ssl (<< 0.75.0-1~), pop3-server Provides: pop3-server Depends: courier-base (= 1.0.16-3+b1), debconf | debconf-2.0, default-mta | mail-transport-agent, sysvinit-utils (>= 2.88dsf-50) | init-d-script, courier-authlib (>= 0.71), libc6 (>= 2.15), libcourier-unicode4 (>= 2.1.2), libidn12 (>= 1.13) Suggests: courier-doc, mail-reader Conflicts: pop3-server Breaks: courier-pop-ssl (<< 0.75.0-1~) Description: Courier mail server - POP3 server Homepage: http://www.courier-mta.org/ Description-md5: 89ea9794c711647b9c31923297fd27c5 Tag: interface::daemon, mail::pop, network::server, network::service, protocol::pop3, role::program, works-with::mail Section: mail Priority: optional Filename: pool/main/c/courier/courier-pop_1.0.16-3+b1_amd64.deb Size: 179872 MD5sum: 97bbb2d0a27f34d1b48482cfd003b081 SHA256: efc865b63f19efda4feb15917789b9390667d973ac18d7aa6e641290a7ba8461 Package: courier-webadmin Source: courier (1.0.16-3) Version: 1.0.16-3+b1 Installed-Size: 250 Maintainer: Markus Wanner Architecture: amd64 Depends: apache2 | httpd, courier-base (= 1.0.16-3+b1), libcgi-pm-perl, debconf (>= 0.5) | debconf-2.0, libc6 (>= 2.3.4), perl:any Suggests: courier-doc Description: Courier mail server - web-based administration frontend Homepage: http://www.courier-mta.org/ Description-md5: 9d1561eee0fd4d2c370758c8fbebd3a8 Tag: admin::configuring, interface::web, role::program, use::configuring, web::application Section: mail Priority: optional Filename: pool/main/c/courier/courier-webadmin_1.0.16-3+b1_amd64.deb Size: 147916 MD5sum: 146605f7e774c98d94da493cc3c19c4e SHA256: bc65ecb8eac668c0c5fe18c6784217dd67541d2347899e0096b4b2f9f2ab0059 Package: sqwebmail Source: courier (1.0.16-3) Version: 6.0.5+1.0.16-3+b1 Installed-Size: 1356 Maintainer: Markus Wanner Architecture: amd64 Depends: apache2 | httpd-cgi, courier-base (= 1.0.16-3+b1), cron, debconf (>= 0.5) | debconf-2.0, default-mta | mail-transport-agent, expect, iamerican | ispell-dictionary, ispell, maildrop, sysvinit-utils (>= 2.88dsf-50) | init-d-script, courier-authlib (>= 0.71), libc6 (>= 2.15), libcourier-unicode4 (>= 2.1.2), libgamin0 | libfam0, libgdbm6 (>= 1.16), libidn12 (>= 1.13), libldap-2.4-2 (>= 2.4.7), libpcre3, perl:any Recommends: apache2 (>= 2.4.6-4~) | httpd, courier-pcp Suggests: courier-doc, gnupg Description: Courier mail server - webmail server Homepage: http://www.courier-mta.org/ Description-md5: ba58b55a2bbe8efe6abfe55d02dd61cc Tag: interface::web, role::program, works-with::mail Section: mail Priority: optional Filename: pool/main/c/courier/sqwebmail_6.0.5+1.0.16-3+b1_amd64.deb Size: 496944 MD5sum: 5fa070104394a53254b244b16685508e SHA256: 51ebf109a5257b34a521a68967db5b328d2301ad9e7585ccf797dfb549ed5e6e "; let cursor = Cursor::new(bytes); let bin_pkgs = extract_pkgs_uncompressed::(cursor).unwrap(); let bytes = "Package: courier Binary: courier-base, courier-mlm, courier-mta, courier-faxmail, courier-webadmin, sqwebmail, courier-pcp, courier-pop, courier-imap, courier-ldap, courier-doc Version: 1.0.16-3 Maintainer: Markus Wanner Build-Depends: automake, courier-authlib-dev (>= 0.66.4-5~), debhelper-compat (= 13), default-libmysqlclient-dev, dh-exec, dh-apache2, expect, ghostscript, gnupg2, gnutls-bin, groff-base, libcourier-unicode-dev (>= 2.1-3~), libgamin-dev, libgcrypt-dev, libgdbm-dev | libgdbmg1-dev, libgnutls28-dev, libidn11-dev, libldap2-dev, libpam0g-dev, libpcre3-dev, libperl-dev, libpq-dev, libsasl2-dev | libsasl-dev, libtool-bin | libtool, mgetty-fax, mime-support, netpbm, po-debconf, procps, wget, zlib1g-dev Build-Conflicts: automake1.4 Architecture: any all Standards-Version: 4.5.1 Format: 3.0 (quilt) Files: dc395743184bd43c6bef647e29907439 3874 courier_1.0.16-3.dsc 25f1c97a9ee74b7b264402b52d424ea9 7644196 courier_1.0.16.orig.tar.bz2 f421e270aa2bb0eef69883b8dfc67661 866 courier_1.0.16.orig.tar.bz2.asc d82c935aa59897dc40adf85d8cc951b0 108396 courier_1.0.16-3.debian.tar.xz Vcs-Browser: https://salsa.debian.org/debian/courier Vcs-Git: https://salsa.debian.org/debian/courier.git Checksums-Sha256: dd89bad1059adfba65b6f06be895b97c7d3d28d4f177d6a4f055407d374ef683 3874 courier_1.0.16-3.dsc 87fc35ddff4f273aa04f43fdffc73f9236abf39bc3234a449eab88742d885ebb 7644196 courier_1.0.16.orig.tar.bz2 e2d574353654d2a3e473d481a1354f2d8eb6412e77277a489d6545ef41e6122d 866 courier_1.0.16.orig.tar.bz2.asc 565912449f530457892ccee787585184d644bac76f7055698d7f41600308519f 108396 courier_1.0.16-3.debian.tar.xz Homepage: http://www.courier-mta.org/ Package-List: courier-base deb mail optional arch=any courier-doc deb doc optional arch=all courier-faxmail deb mail optional arch=any courier-imap deb mail optional arch=any courier-ldap deb mail optional arch=any courier-mlm deb mail optional arch=any courier-mta deb mail optional arch=any courier-pcp deb mail optional arch=any courier-pop deb mail optional arch=any courier-webadmin deb mail optional arch=any sqwebmail deb mail optional arch=any Testsuite: autopkgtest Testsuite-Triggers: default-mta Directory: pool/main/c/courier Priority: source Section: mail "; let cursor = Cursor::new(bytes); let src_pkgs = extract_pkgs_uncompressed::(cursor).unwrap(); let mut sources = SourcePkgBucket::new(); for pkg in src_pkgs { sources.push(pkg); } let mut state = SyncState::new(); for bin in bin_pkgs { let src = sources.get(&bin).unwrap(); state.push( &src, bin, "https://deb.debian.org/debian", "debian".to_string(), "main".to_string(), ); } let mut groups = HashMap::new(); groups.insert("courier".to_string(), vec![ PkgGroup { name: "courier".to_string(), version: "1.0.16-3+b1".to_string(), distro: "debian".to_string(), suite: "main".to_string(), architecture: "amd64".to_string(), input_url: Some("https://buildinfos.debian.net/buildinfo-pool/c/courier/courier_1.0.16-3+b1_amd64.buildinfo".to_string()), artifacts: vec![ PkgArtifact { name: "courier-base".to_string(), version: "1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-base_1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "courier-faxmail".to_string(), version: "1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-faxmail_1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "courier-imap".to_string(), version: "5.0.13+1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-imap_5.0.13+1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "courier-ldap".to_string(), version: "1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-ldap_1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "courier-mlm".to_string(), version: "1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-mlm_1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "courier-mta".to_string(), version: "1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-mta_1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "courier-pcp".to_string(), version: "1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-pcp_1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "courier-pop".to_string(), version: "1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-pop_1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "courier-webadmin".to_string(), version: "1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-webadmin_1.0.16-3+b1_amd64.deb".to_string(), }, PkgArtifact { name: "sqwebmail".to_string(), version: "6.0.5+1.0.16-3+b1".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/sqwebmail_6.0.5+1.0.16-3+b1_amd64.deb".to_string(), }, ], }, PkgGroup { name: "courier".to_string(), version: "1.0.16-3".to_string(), distro: "debian".to_string(), suite: "main".to_string(), architecture: "all".to_string(), input_url: Some("https://buildinfos.debian.net/buildinfo-pool/c/courier/courier_1.0.16-3_all.buildinfo".to_string()), artifacts: vec![ PkgArtifact { name: "courier-doc".to_string(), version: "1.0.16-3".to_string(), url: "https://deb.debian.org/debian/pool/main/c/courier/courier-doc_1.0.16-3_all.deb".to_string(), } ], }, ]); assert_eq!(state, SyncState { groups }); } #[test] fn test_extra_source_only() { let packages_bytes = "Package: python3-buildlog-consultant Source: buildlog-consultant Version: 0.0.37-1 Installed-Size: 6972 Maintainer: Jelmer Vernooij Architecture: amd64 Depends: python3-debian, python3-requirement-parser, python3-yaml, python3 (<< 3.13), python3 (>= 3.11~), python3:any, libc6 (>= 2.34), libgcc-s1 (>= 4.2) Description: build log parser and analyser Homepage: https://github.com/jelmer/buildlog-consultant Description-md5: 03628aeae53788e68d12a1d9646fbb72 Section: python Priority: optional Filename: pool/main/b/buildlog-consultant/python3-buildlog-consultant_0.0.37-1_amd64.deb Size: 1079688 MD5sum: 56a82bbe8d7b730c7eeb0f59e7fad6a6 SHA256: 23d9edc63238b104b42c58a82937e1e06e7351ed7df5a938029d335b3bec8e4a Package: buildlog-consultant Source: rust-buildlog-consultant (0.0.44-1) Version: 0.0.44-1+b1 Installed-Size: 17441 Maintainer: Debian Rust Maintainers Architecture: amd64 Depends: libc6 (>= 2.34), libgcc-s1 (>= 4.2) Description: build log parser and analyser Multi-Arch: allowed Homepage: https://github.com/jelmer/buildlog-consultant Built-Using: rust-lazy-regex (= 2.5.0-3), rustc (= 1.81.0+dfsg1-2) Description-md5: 03628aeae53788e68d12a1d9646fbb72 Static-Built-Using: rust-aho-corasick (= 1.1.3-1), rust-anstream (= 0.6.15-1), rust-anstyle (= 1.0.8-1), rust-anstyle-parse (= 0.2.1-1), rust-anstyle-query (= 1.0.0-1), rust-bit-set (= 0.5.2-1), rust-bit-vec (= 0.6.3-1), rust-chrono (= 0.4.38-2), rust-clap (= 4.5.16-1), rust-clap-builder (= 4.5.15-2), rust-clap-lex (= 0.7.2-2), rust-colorchoice (= 1.0.0-1), rust-countme (= 3.0.1-1), rust-deb822-lossless (= 0.2.1-1), rust-debian-control (= 0.1.38-1), rust-debversion (= 0.4.3-2), rust-env-logger (= 0.10.2-2), rust-equivalent (= 1.0.1-1), rust-fancy-regex (= 0.11.0-2), rust-form-urlencoded (= 1.2.1-1), rust-hashbrown (= 0.14.5-5), rust-humantime (= 2.1.0-1), rust-iana-time-zone (= 0.1.60-1), rust-idna (= 0.4.0-1), rust-indexmap (= 2.2.6-1), rust-inventory (= 0.3.2-1), rust-itoa (= 1.0.9-1), rust-lazy-regex (= 2.5.0-3), rust-lazy-static (= 1.4.0-2), rust-log (= 0.4.22-1), rust-maplit (= 1.0.2-1), rust-memchr (= 2.7.4-1), rust-num-traits (= 0.2.19-2), rust-once-cell (= 1.20.2-1), rust-pep440-rs (= 0.6.6-1), rust-pep508-rs (= 0.6.1-2), rust-percent-encoding (= 2.3.1-1), rust-regex (= 1.10.6-1), rust-regex-automata (= 0.4.7-1), rust-regex-syntax (= 0.8.2-1), rust-rowan (= 0.15.16-1), rust-rustc-hash (= 1.1.0-1), rust-ryu (= 1.0.15-1), rust-serde (= 1.0.210-2), rust-serde-json (= 1.0.128-1), rust-serde-yaml (= 0.9.34-1), rust-shlex (= 1.3.0-1), rust-smallvec (= 1.13.2-1), rust-smawk (= 0.3.2-1), rust-strsim-0.10 (= 0.10.0-3), rust-termcolor (= 1.4.1-1), rust-text-size (= 1.1.1-1), rust-textwrap (= 0.16.1-1), rust-thiserror (= 1.0.59-1), rust-unicode-bidi (= 0.3.13-1), rust-unicode-linebreak (= 0.1.4-2), rust-unicode-normalization (= 0.1.22-1), rust-unicode-width (= 0.1.14-1), rust-unsafe-libyaml (= 0.2.11-1), rust-unscanny (= 0.1.0-1), rust-url (= 2.5.0-1), rust-urlencoding (= 2.1.3-1), rust-utf8parse (= 0.2.1-1), rustc (= 1.81.0+dfsg1-2) Section: devel Priority: optional Filename: pool/main/r/rust-buildlog-consultant/buildlog-consultant_0.0.44-1+b1_amd64.deb Size: 2155184 MD5sum: f396e8745f571aa6eb27ddbaf52594ad SHA256: 7dfba1f88be2f8bdf7480085dd018333d0159ac40462daf3679f3757347262c4 "; let sources_bytes = "Package: buildlog-consultant Binary: python3-buildlog-consultant Version: 0.0.37-1 Maintainer: Jelmer Vernooij Build-Depends: debhelper-compat (= 13), dh-sequence-python3, librust-debversion-dev, librust-fancy-regex-dev, librust-pyo3-dev, librust-pyo3-file-dev, librust-pyo3-filelike-dev, librust-pyo3-log-dev, librust-shlex-dev, librust-text-size-dev, librust-textwrap-dev, python3-all, python3-debian, python3-requirement-parser, python3-setuptools, python3-setuptools-rust, python3-yaml Architecture: any Standards-Version: 4.6.2 Format: 3.0 (quilt) Files: 6ad424f44b03af2394502b51004e715e 1999 buildlog-consultant_0.0.37-1.dsc 94bc4b065b25128d6c2df7549ba0ce14 106321 buildlog-consultant_0.0.37.orig.tar.gz 505fb064e8b97e075566cf654f6cd916 2784 buildlog-consultant_0.0.37-1.debian.tar.xz Vcs-Browser: https://salsa.debian.org/jelmer/buildlog-consultant Vcs-Git: https://salsa.debian.org/jelmer/buildlog-consultant.git Checksums-Sha256: 92ce9e76fb268de73a1fa627cc9f64d97b670fed9d77ea2bbb0b7e17e33512be 1999 buildlog-consultant_0.0.37-1.dsc 53deb11bf4e83e9f40e2df906215f55a4c6bd8299fdc07897d87ddd15f56d65a 106321 buildlog-consultant_0.0.37.orig.tar.gz 93ae05557c211d2091cfabcc545d4a625f75c8ac3390a019c087d73528b86f4a 2784 buildlog-consultant_0.0.37-1.debian.tar.xz Homepage: https://github.com/jelmer/buildlog-consultant Package-List: python3-buildlog-consultant deb python optional arch=any Extra-Source-Only: yes Directory: pool/main/b/buildlog-consultant Priority: optional Section: misc Package: rust-buildlog-consultant Binary: librust-buildlog-consultant-dev, buildlog-consultant Version: 0.0.44-1 Maintainer: Debian Rust Maintainers Uploaders: Jelmer Vernooij Build-Depends: debhelper-compat (= 13), dh-cargo (>= 25), cargo:native, rustc:native, libstd-rust-dev, librust-chrono-0.4+default-dev (>= 0.4.31-~~), librust-clap-4+default-dev, librust-clap-4+derive-dev, librust-debian-control-0.1+default-dev (>= 0.1.18-~~), librust-debversion-0.4+default-dev, librust-debversion-0.4+serde-dev, librust-env-logger+default-dev (>= 0.10-~~), librust-fancy-regex-0.11+default-dev, librust-inventory-0.3+default-dev, librust-lazy-regex+default-dev (>= 2-~~), librust-lazy-static-1+default-dev, librust-log-0.4+default-dev (>= 0.4.20-~~), librust-maplit-1+default-dev (>= 1.0.2-~~), librust-pep440-rs-0.6+default-dev (>= 0.6.5-~~), librust-pep508-rs-0.6+default-dev (>= 0.6.1-~~), librust-regex-1+default-dev, librust-serde-1+default-dev, librust-serde-1+derive-dev, librust-serde-json-1+default-dev, librust-serde-yaml-0.9+default-dev, librust-shlex-1+default-dev, librust-text-size-1+default-dev (>= 1.1.1-~~), librust-textwrap-0.16+default-dev Architecture: any Standards-Version: 4.7.0 Format: 3.0 (quilt) Files: e96dc4dbabe2027ccfffb31a47f167dd 2912 rust-buildlog-consultant_0.0.44-1.dsc d6de700387b2ae8ca5afb34bd9d3424d 111058 rust-buildlog-consultant_0.0.44.orig.tar.gz 8ec7a5e281352f6401db2d75dceb8de6 3624 rust-buildlog-consultant_0.0.44-1.debian.tar.xz Vcs-Browser: https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/buildlog-consultant Vcs-Git: https://salsa.debian.org/rust-team/debcargo-conf.git [src/buildlog-consultant] Checksums-Sha256: 0baa39785abfe865a70e456b8de6eaf48578e4bade493807e768a2026ec8ae1f 2912 rust-buildlog-consultant_0.0.44-1.dsc 488ee699c8b6d02bde8ee3a7cb8eb9b1377f638fb34cfb6ea5a74f45d54748d9 111058 rust-buildlog-consultant_0.0.44.orig.tar.gz d32092503606597d71d9f39d36afd295cc675e2bf0f64f209691d50020c47061 3624 rust-buildlog-consultant_0.0.44-1.debian.tar.xz Homepage: https://github.com/jelmer/buildlog-consultant Package-List: buildlog-consultant deb devel optional arch=any librust-buildlog-consultant-dev deb rust optional arch=any Testsuite: autopkgtest Testsuite-Triggers: dh-cargo, librust-maplit-1+default-dev, rustc Directory: pool/main/r/rust-buildlog-consultant Priority: optional Section: misc Package: rust-buildlog-consultant Binary: librust-buildlog-consultant-dev, buildlog-consultant Version: 0.1.0-1 Maintainer: Debian Rust Maintainers Uploaders: Jelmer Vernooij Build-Depends: debhelper-compat (= 13), dh-sequence-cargo, cargo:native, rustc:native, libstd-rust-dev, librust-chrono-0.4+default-dev (>= 0.4.31-~~), librust-clap-4+default-dev, librust-clap-4+derive-dev, librust-debian-control-0.1+default-dev (>= 0.1.18-~~), librust-debversion-0.4+default-dev, librust-debversion-0.4+serde-dev, librust-env-logger+default-dev (>= 0.10-~~), librust-fancy-regex-0.11+default-dev, librust-inventory-0.3+default-dev, librust-lazy-regex+default-dev (>= 2-~~), librust-lazy-static-1+default-dev, librust-log-0.4+default-dev (>= 0.4.20-~~), librust-maplit-1+default-dev (>= 1.0.2-~~), librust-pep508-rs-0.9+default-dev (>= 0.9.1-~~), librust-regex-1+default-dev, librust-serde-1+default-dev, librust-serde-1+derive-dev, librust-serde-json-1+default-dev, librust-serde-yaml-0.9+default-dev, librust-shlex-1+default-dev, librust-text-size-1+default-dev (>= 1.1.1-~~), librust-textwrap-0.16+default-dev Architecture: any Standards-Version: 4.7.0 Format: 3.0 (quilt) Files: 7f4d52474fdeb91fd28b30265c2951a0 2881 rust-buildlog-consultant_0.1.0-1.dsc 780a2b95f0b58b8607811f8c2a3ed5b3 112422 rust-buildlog-consultant_0.1.0.orig.tar.gz a83d2bdc040e133428a3d08d1beb6511 3716 rust-buildlog-consultant_0.1.0-1.debian.tar.xz Vcs-Browser: https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/buildlog-consultant Vcs-Git: https://salsa.debian.org/rust-team/debcargo-conf.git [src/buildlog-consultant] Checksums-Sha256: d866b60e266258cd49cc0b5e0eef4328469ac2001c5d470564ac8aca37768539 2881 rust-buildlog-consultant_0.1.0-1.dsc e18d1855ddb4376d5dc6e34c6e1ae818c46437092d56ea5c559358548d5be842 112422 rust-buildlog-consultant_0.1.0.orig.tar.gz 54bbbec4464f413d059406c93ffe3fa92e1a7b3385c8dfbcf5ce7d0b2a236c93 3716 rust-buildlog-consultant_0.1.0-1.debian.tar.xz Homepage: https://github.com/jelmer/buildlog-consultant Package-List: buildlog-consultant deb devel optional arch=any librust-buildlog-consultant-dev deb rust optional arch=any Testsuite: autopkgtest Testsuite-Triggers: dh-cargo, librust-maplit-1+default-dev, rustc Directory: pool/main/r/rust-buildlog-consultant Priority: optional Section: misc "; let mut sources = SourcePkgBucket::new(); for pkg in extract_pkgs_uncompressed::(sources_bytes.as_bytes()).unwrap() { sources.push(pkg); } let pkgs = extract_pkgs_uncompressed::(packages_bytes.as_bytes()).unwrap(); let mut pkgs = pkgs.into_iter(); // test first package (with Extra-Source-Only) let pkg = pkgs.next().unwrap(); let src = sources.get(&pkg).unwrap(); assert_eq!( src, DebianSourcePkg { base: "buildlog-consultant".to_string(), binary: vec!["python3-buildlog-consultant".to_string(),], version: "0.0.37-1".to_string(), directory: "pool/main/b/buildlog-consultant".to_string(), architecture: "any".to_string(), uploaders: vec![], } ); // test second package (without Extra-Source-Only) let pkg = pkgs.next().unwrap(); let src = sources.get(&pkg).unwrap(); assert_eq!( src, DebianSourcePkg { base: "rust-buildlog-consultant".to_string(), binary: vec![ "librust-buildlog-consultant-dev".to_string(), "buildlog-consultant".to_string(), ], version: "0.0.44-1+b1".to_string(), directory: "pool/main/r/rust-buildlog-consultant".to_string(), architecture: "any".to_string(), uploaders: vec!["Jelmer Vernooij ".to_string()], } ); assert_eq!(pkgs.next(), None); } } rebuildctl-0.22.1/src/schedule/fedora.rs000064400000000000000000000551301046102023000162340ustar 00000000000000use crate::args::PkgsSync; use crate::decompress; use crate::schedule::{fetch_url_or_path, Pkg}; use rebuilderd_common::errors::*; use rebuilderd_common::http; use rebuilderd_common::{PkgArtifact, PkgGroup}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::io::Read; pub async fn sync(http: &http::Client, sync: &PkgsSync) -> Result> { if sync.releases.len() > 1 { bail!("Tracking multiple releases in the same rebuilder is currently unsupported"); } let mut bases: HashMap<_, PkgGroup> = HashMap::new(); for release in &sync.releases { for arch in &sync.architectures { let url = format!("{}/{}/{}/{}/os/", sync.source, release, sync.suite, arch); let bytes = fetch_url_or_path(http, &format!("{url}repodata/repomd.xml")).await?; let location = get_primary_location_from_xml(&bytes)?; let bytes = fetch_url_or_path(http, &format!("{url}{location}")).await?; info!("Parsing index ({} bytes)...", bytes.len()); let comp = decompress::detect_compression(&bytes); let data = decompress::stream(comp, &bytes)?; let packages = parse_package_index(data)?; for pkg in packages { if !pkg.matches(sync) { continue; } let url = format!("{url}{}", pkg.location.href); let version = format!("{}-{}", pkg.version.ver, pkg.version.rel); let artifact = PkgArtifact { name: pkg.name, version, url, }; if let Some(group) = bases.get_mut(&pkg.format.sourcerpm) { group.add_artifact(artifact); } else { let mut group = PkgGroup::new( pkg.format.sourcerpm.clone(), format!("{}-{}", pkg.version.ver, pkg.version.rel), sync.distro.to_string(), sync.suite.to_string(), pkg.arch, None, ); group.add_artifact(artifact); bases.insert(pkg.format.sourcerpm, group); } } } } Ok(bases.into_values().collect()) } #[derive(Debug, Serialize, Deserialize)] pub struct RepomdXml { #[serde(rename = "$value")] pub data: Vec, } #[derive(Debug, Serialize, Deserialize)] pub struct RepomdXmlItem { #[serde(rename = "type")] pub item_type: Option, pub location: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct RepomdXmlLocation { pub href: String, } fn get_primary_location_from_xml(bytes: &[u8]) -> Result { let list = serde_xml_rs::from_reader::<_, RepomdXml>(bytes)?; let primary = list .data .into_iter() .find(|x| x.item_type.as_deref() == Some("primary")) .context("Failed to find 'primary' in repomd file")?; let location = primary .location .context("Failed to find 'location' attribute")?; Ok(location.href) } fn parse_package_index(r: R) -> Result> { let list = serde_xml_rs::from_reader::<_, PackagesXml>(r)?; Ok(list.packages) } #[derive(Debug, Serialize, Deserialize)] pub struct PackagesXml { #[serde(rename = "$value")] pub packages: Vec, } #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct PackagesXmlItem { pub name: String, pub arch: String, pub version: PackagesXmlItemVersion, pub packager: String, pub location: PackagesXmlItemLocation, pub format: PackagesXmlItemMetadata, } impl Pkg for PackagesXmlItem { fn pkg_name(&self) -> &str { &self.name } fn by_maintainer(&self, maintainers: &[String]) -> bool { maintainers.iter().any(|m| self.packager.starts_with(m)) } } #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct PackagesXmlItemVersion { pub epoch: String, pub ver: String, pub rel: String, } #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct PackagesXmlItemLocation { pub href: String, } #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct PackagesXmlItemMetadata { #[serde(rename = "sourcerpm")] pub sourcerpm: String, } #[cfg(test)] mod tests { use super::*; #[test] fn test_parse_repomd_primary_location() -> Result<()> { let bytes = br#" 1681418230 f6dee453a7f86804214e402ad2e444b989f044f0b16fa7ba74e5a27a8a49cd07 7f2fdf1ef2d90b5a7223cee806e2cd1652b6086b3f747a3986352b48d4be638f 1681418141 18320782 167638461 131fa4fcd206fd3a718e4765983c8b7b276e7e634e45c226d9c465145f8e69e9 f02c846e6937f434f4800d58c9ff11f5b42076ea2081c9d94e0ad9f4ea949c06 1681418141 54340868 747611414 1c4bf077a2bdf4743a7cded3e2f72282dec5f8e4910692d193e371508552322a 8bce951885e14c3bcd16563a84077afa954d5ba39149e9b2ae7755fc433538d8 1681418141 7374868 110707385 60bf45195ec1a08fb8f269632660d98db897920ad3444478c4a2ce48bac6f8c5 1e721ade786dee7c1fd34ca44386a1879c192618c9353c90a89a5a694c909846 1681418198 28710824 169746432 10 da0f6cd3c50c54b4a0d1de4156483a84d952400ca6a1a9f18215e2f8153de53a 307d77854cb35d06937ab7c096e180bb2e00131a488b64f8b90a2994a10d65d1 1681418227 45336776 347639808 10 e0dee9e0e57a903c855ac065ee2ecf213352136c5f0b84f693ed313ab6900569 c3f167024efc8f66d199bd836ae49155eed857659d6811939316689f805f7136 1681418164 10661728 94199808 10 dfa2aec8d2e83459677d698542f1a190d92815888668d027b21dfd46fb86ce01 7f2fdf1ef2d90b5a7223cee806e2cd1652b6086b3f747a3986352b48d4be638f 34d4d0da333f4e5935ee08100f5fe9dd78de016444839e1cfc8776aeb527fbc2 1681418141 33215921 167638461 541899 5f86dfe1903316d6b25d494616cf18352204fe70c529b4c97859df6faecd493f f02c846e6937f434f4800d58c9ff11f5b42076ea2081c9d94e0ad9f4ea949c06 73a46a4969de23c71eb8bbc364bfa7b1380672fb26828de14723783dcc6745ea 1681418141 51796916 747611414 545530 dfe295aec5a168406ec81db7a5d1e4f8df75cfb9fa11be9ed2a8b17d8f9ced18 8bce951885e14c3bcd16563a84077afa954d5ba39149e9b2ae7755fc433538d8 ea63e740b565e42a5eafda8514c1b1e20d18ff00a12869539fdfd292f72c05f6 1681418141 15491666 110707385 541197 1ab074f803c33a54eac36ffee514cfe9a60a927416b3ddc34defeaf4b1d63776 1681417845 1826355 5a8d7109590bf585b77781785ca3cfc4ad835e23700fdf5c28b256486c3182a1 1681418141 265548 49e47bfcdc5d63156c36b4ab0028c39def5002bcef03cb6e024f12a0b3200df7 5a8d7109590bf585b77781785ca3cfc4ad835e23700fdf5c28b256486c3182a1 928cb71330c7e6cc99138d5cb8c6cd5fd3bd07a0d479bf49421883c9f6d1f1f9 1681418230 496815 265548 1203 "#; let location = get_primary_location_from_xml(bytes)?; assert_eq!(location, "repodata/f6dee453a7f86804214e402ad2e444b989f044f0b16fa7ba74e5a27a8a49cd07-primary.xml.gz"); Ok(()) } #[test] fn test_parse_repomd_package_list() -> Result<()> { let bytes = br#" 0ad x86_64 6df9f2af65c505b47d42bd8183091e6c04b9a13290712937b3fdbc67c46f9e95 Cross-Platform RTS Game of Ancient Warfare 0 A.D. (pronounced "zero ey-dee") is a free, open-source, cross-platform real-time strategy (RTS) game of ancient warfare. In short, it is a historically-based war/economy game that allows players to relive or rewrite the history of Western civilizations, focusing on the years between 500 B.C. and 500 A.D. The project is highly ambitious, involving state-of-the-art 3D graphics, detailed artwork, sound, and a flexible and powerful custom-built game engine. The game has been in development by Wildfire Games (WFG), a group of volunteer, hobbyist game developers, since 2001. Fedora Project http://play0ad.com 0ad-data noarch 9d4882481909c8c5cdd4b59988f17fc015d8703f5fbc587d07bd44038fbdb9ac The Data Files for 0 AD 0 A.D. (pronounced "zero ey-dee") is a free, open-source, cross-platform real-time strategy (RTS) game of ancient warfare. In short, it is a historically-based war/economy game that allows players to relive or rewrite the history of Western civilizations, focusing on the years between 500 B.C. and 500 A.D. The project is highly ambitious, involving state-of-the-art 3D graphics, detailed artwork, sound, and a flexible and powerful custom-built game engine. This package contains the 0ad data files. Fedora Project http://play0ad.com 0xFFFF x86_64 77fbc5a6edd3091c45c171e84081a20a755498e865ccab3726bf3e52c5a82733 The Open Free Fiasco Firmware Flasher The 'Open Free Fiasco Firmware Flasher' aka 0xFFFF utility implements a free (GPL3) userspace handler for the NOLO bootloader and related utilities for the Nokia Internet Tablets like flashing setting device options, packing/unpacking FIASCO firmware format and more. Fedora Project https://talk.maemo.org/showthread.php?t=87996 "#; let list = parse_package_index(&bytes[..])?; assert_eq!( list, &[ PackagesXmlItem { name: "0ad".to_string(), arch: "x86_64".to_string(), version: PackagesXmlItemVersion { epoch: "0".to_string(), ver: "0.0.26".to_string(), rel: "7.fc38".to_string(), }, packager: "Fedora Project".to_string(), location: PackagesXmlItemLocation { href: "Packages/0/0ad-0.0.26-7.fc38.x86_64.rpm".to_string(), }, format: PackagesXmlItemMetadata { sourcerpm: "0ad-0.0.26-7.fc38.src.rpm".to_string(), } }, PackagesXmlItem { name: "0ad-data".to_string(), arch: "noarch".to_string(), version: PackagesXmlItemVersion { epoch: "0".to_string(), ver: "0.0.26".to_string(), rel: "2.fc38".to_string(), }, packager: "Fedora Project".to_string(), location: PackagesXmlItemLocation { href: "Packages/0/0ad-data-0.0.26-2.fc38.noarch.rpm".to_string(), }, format: PackagesXmlItemMetadata { sourcerpm: "0ad-data-0.0.26-2.fc38.src.rpm".to_string(), } }, PackagesXmlItem { name: "0xFFFF".to_string(), arch: "x86_64".to_string(), version: PackagesXmlItemVersion { epoch: "0".to_string(), ver: "0.10".to_string(), rel: "2.fc38".to_string(), }, packager: "Fedora Project".to_string(), location: PackagesXmlItemLocation { href: "Packages/0/0xFFFF-0.10-2.fc38.x86_64.rpm".to_string(), }, format: PackagesXmlItemMetadata { sourcerpm: "0xFFFF-0.10-2.fc38.src.rpm".to_string(), } }, ] ); Ok(()) } } rebuildctl-0.22.1/src/schedule/mod.rs000064400000000000000000000160361046102023000155550ustar 00000000000000use crate::args::PkgsSync; use glob::Pattern; use rebuilderd_common::errors::*; use rebuilderd_common::http; use std::fs; pub async fn fetch_url_or_path(client: &http::Client, path: &str) -> Result> { let bytes = if path.starts_with("https://") || path.starts_with("http://") { info!("Downloading {:?}...", path); client.get(path).send().await?.bytes().await?.to_vec() } else { info!("Reading {:?}...", path); fs::read(path)? }; Ok(bytes) } pub trait Pkg { fn pkg_name(&self) -> &str; fn matches(&self, sync: &PkgsSync) -> bool { if self.match_name(&sync.excludes) { return false; } if sync.maintainers.is_empty() && sync.pkgs.is_empty() { true } else { self.by_maintainer(&sync.maintainers) || self.match_name(&sync.pkgs) } } fn by_maintainer(&self, maintainers: &[String]) -> bool; fn match_name(&self, patterns: &[Pattern]) -> bool { patterns.iter().any(|p| p.matches(self.pkg_name())) } } pub mod archlinux; pub mod debian; pub mod fedora; pub mod tails; #[cfg(test)] mod tests { use super::*; use crate::schedule::archlinux::ArchPkg; struct Filter { maintainers: Vec, pkgs: Vec, excludes: Vec, } fn to_patterns(patterns: Vec) -> Vec { patterns.iter().map(|f| Pattern::new(f).unwrap()).collect() } fn gen_filter(f: Filter) -> PkgsSync { PkgsSync { distro: "archlinux".to_string(), sync_method: None, suite: "community".to_string(), architectures: vec!["x86_64".to_string()], source: "https://ftp.halifax.rwth-aachen.de/archlinux/$repo/os/$arch".to_string(), releases: Vec::new(), print_json: false, maintainers: f.maintainers, pkgs: to_patterns(f.pkgs), excludes: to_patterns(f.excludes), } } fn gen_pkg() -> ArchPkg { ArchPkg { name: "rebuilderd".to_string(), base: "rebuilderd".to_string(), filename: "rebuilderd-0.2.1-1-x86_64.pkg.tar.zst".to_string(), version: "0.2.1-1".to_string(), architecture: "x86_64".to_string(), packager: "kpcyrd ".to_string(), } } #[test] fn no_filter_always_matches() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: Vec::new(), excludes: Vec::new(), })); assert!(m); } #[test] fn maintainer_matches() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: vec!["kpcyrd ".to_string()], pkgs: Vec::new(), excludes: Vec::new(), })); assert!(m); } #[test] fn maintainer_does_not_match() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: vec!["Levente Polyak ".to_string()], pkgs: Vec::new(), excludes: Vec::new(), })); assert!(!m); } #[test] fn pkg_name_matches() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: vec!["rebuilderd".to_string()], excludes: Vec::new(), })); assert!(m); } #[test] fn pkg_name_does_not_match() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: vec!["asdf".to_string()], excludes: Vec::new(), })); assert!(!m); } #[test] fn pkg_name_and_maintainer_matches() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: vec!["kpcyrd ".to_string()], pkgs: vec!["rebuilderd".to_string()], excludes: Vec::new(), })); assert!(m); } #[test] fn pkg_name_and_maintainer_does_not_match() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: vec!["Levente Polyak ".to_string()], pkgs: vec!["linux-hardened".to_string()], excludes: Vec::new(), })); assert!(!m); } #[test] fn no_filter_but_excludes_match() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: Vec::new(), excludes: vec!["rebuilderd".to_string()], })); assert!(!m); } #[test] fn no_filter_and_no_excludes_match() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: Vec::new(), excludes: vec!["asdf".to_string()], })); assert!(m); } #[test] fn pkg_name_and_maintainer_match_and_no_excludes_match() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: vec!["kpcyrd ".to_string()], pkgs: vec!["rebuilderd".to_string()], excludes: vec!["asdf".to_string()], })); assert!(m); } #[test] fn pkg_name_and_maintainer_match_but_excludes_match() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: vec!["kpcyrd ".to_string()], pkgs: vec!["rebuilderd".to_string()], excludes: vec!["rebuilderd".to_string()], })); assert!(!m); } #[test] fn regular_string_matches_exact() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: vec!["rebuilderd".to_string()], excludes: Vec::new(), })); assert!(m); } #[test] fn regular_string_matches_only_exact() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: vec!["build".to_string()], excludes: Vec::new(), })); assert!(!m); } #[test] fn pattern_matches_prefix() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: vec!["*builderd".to_string()], excludes: Vec::new(), })); assert!(m); } #[test] fn pattern_matches_suffix() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: vec!["rebuild*".to_string()], excludes: Vec::new(), })); assert!(m); } #[test] fn pattern_matches_prefix_and_suffix() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: vec!["*build*".to_string()], excludes: Vec::new(), })); assert!(m); } #[test] fn pattern_matches_empty_string() { let m = gen_pkg().matches(&gen_filter(Filter { maintainers: Vec::new(), pkgs: vec!["rebuilder*".to_string()], excludes: Vec::new(), })); assert!(m); } } rebuildctl-0.22.1/src/schedule/tails.rs000064400000000000000000000035471046102023000161150ustar 00000000000000use crate::args::PkgsSync; use rebuilderd_common::errors::*; use rebuilderd_common::http; use rebuilderd_common::{PkgArtifact, PkgGroup}; use regex::Regex; use url::Url; pub async fn sync(http: &http::Client, sync: &PkgsSync) -> Result> { let source = sync .source .parse::() .context("Failed to parse source as url")?; let mut url = source.clone(); url.path_segments_mut() .map_err(|_| anyhow!("cannot be base"))? .pop_if_empty() .push(&sync.suite); info!("Downloading directory list from {}", url); let directory_list = http .get(url) .send() .await? .error_for_status()? .text() .await?; info!("Detecting tails versions"); let re = Regex::new(r"tails-amd64-([0-9a-z~\.]+)/").unwrap(); let cap = re .captures_iter(&directory_list) .next() .ok_or_else(|| anyhow!("Regular expression didn't match any versions"))?; let version = &cap[1]; info!("Detected tails version: {:?}", version); let mut group = PkgGroup::new( "tails".to_string(), version.to_string(), "tails".to_string(), sync.suite.to_string(), "amd64".to_string(), None, ); for ext in &["img", "iso"] { let filename = format!("tails-amd64-{}.{}", version, ext); let mut url = source.clone(); url.path_segments_mut() .map_err(|_| anyhow!("cannot be base"))? .pop_if_empty() .extend(&[&sync.suite, &format!("tails-amd64-{}", version), &filename]); let url = url.to_string(); info!("Artifact url: {:?}", url); let artifact = PkgArtifact { name: filename, version: version.to_string(), url, }; group.add_artifact(artifact); } Ok(vec![group]) }