debcargo-2.5.0/Cargo.lock0000644000001025450000000000100105700ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ "winapi", ] [[package]] name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] [[package]] name = "anyhow" version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" [[package]] name = "arrayvec" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", "winapi", ] [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitmaps" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" dependencies = [ "typenum", ] [[package]] name = "bstr" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "lazy_static", "memchr", "regex-automata", ] [[package]] name = "bytesize" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c58ec36aac5066d5ca17df51b3e70279f5670a72102f5752cb7e7c856adfc70" [[package]] name = "cargo" version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "519db9ad1bc3bf61f2e753cc204ac37903cf0f33f551a03c260208271c1f875b" dependencies = [ "anyhow", "atty", "bytesize", "cargo-platform", "cargo-util", "clap", "crates-io", "crossbeam-utils", "curl", "curl-sys", "env_logger", "filetime", "flate2", "fwdansi", "git2", "git2-curl", "glob", "hex 0.4.3", "home", "humantime", "ignore", "im-rc", "itertools", "jobserver", "lazy_static", "lazycell", "libc", "libgit2-sys", "log", "memchr", "num_cpus", "opener", "percent-encoding", "rustc-workspace-hack", "rustfix", "semver", "serde", "serde_ignored", "serde_json", "shell-escape", "strip-ansi-escapes", "tar", "tempfile", "termcolor", "toml", "unicode-width", "unicode-xid", "url", "walkdir", "winapi", ] [[package]] name = "cargo-platform" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" dependencies = [ "serde", ] [[package]] name = "cargo-util" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2bf633f7ad4e022f63c4197085047af9606a08a3df17badbb7bd3644dc7faeb" dependencies = [ "anyhow", "core-foundation", "crypto-hash", "filetime", "hex 0.4.3", "jobserver", "libc", "log", "miow", "same-file", "shell-escape", "tempfile", "walkdir", "winapi", ] [[package]] name = "cc" version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" dependencies = [ "jobserver", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ "libc", "num-integer", "num-traits", "time", "winapi", ] [[package]] name = "clap" version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term 0.11.0", "atty", "bitflags", "strsim", "textwrap 0.11.0", "unicode-width", "vec_map", ] [[package]] name = "commoncrypto" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" dependencies = [ "commoncrypto-sys", ] [[package]] name = "commoncrypto-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" dependencies = [ "libc", ] [[package]] name = "core-foundation" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "crates-io" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "217138863f33507d7a8edef10fc673c4911679ef7aeb9ff53ee7bb82dc7bf590" dependencies = [ "anyhow", "curl", "percent-encoding", "serde", "serde_json", "url", ] [[package]] name = "crc32fast" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-utils" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ "cfg-if", "lazy_static", ] [[package]] name = "crypto-hash" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a77162240fd97248d19a564a565eb563a3f592b386e4136fb300909e67dddca" dependencies = [ "commoncrypto", "hex 0.3.2", "openssl", "winapi", ] [[package]] name = "curl" version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877cc2f9b8367e32b6dabb9d581557e651cb3aa693a37f8679091bbf42687d5d" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", "socket2", "winapi", ] [[package]] name = "curl-sys" version = "0.4.50+curl-7.79.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4856b76919dd599f31236bb18db5f5bd36e2ce131e64f857ca5c259665b76171" dependencies = [ "cc", "libc", "libnghttp2-sys", "libz-sys", "openssl-sys", "pkg-config", "vcpkg", "winapi", ] [[package]] name = "debcargo" version = "2.5.0" dependencies = [ "ansi_term 0.12.1", "anyhow", "cargo", "chrono", "env_logger", "filetime", "flate2", "git2", "glob", "itertools", "log", "regex", "semver", "serde", "serde_derive", "structopt", "tar", "tempfile", "textwrap 0.14.2", "toml", "walkdir", ] [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" dependencies = [ "atty", "humantime", "log", "regex", "termcolor", ] [[package]] name = "filetime" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" dependencies = [ "cfg-if", "libc", "redox_syscall", "winapi", ] [[package]] name = "flate2" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ "cfg-if", "crc32fast", "libc", "libz-sys", "miniz_oxide", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ "foreign-types-shared", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ "matches", "percent-encoding", ] [[package]] name = "fwdansi" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c1f5787fe85505d1f7777268db5103d80a7a374d2316a7ce262e57baf8f208" dependencies = [ "memchr", "termcolor", ] [[package]] name = "getrandom" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "git2" version = "0.13.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a8057932925d3a9d9e4434ea016570d37420ddb1ceed45a174d577f24ed6700" dependencies = [ "bitflags", "libc", "libgit2-sys", "log", "openssl-probe", "openssl-sys", "url", ] [[package]] name = "git2-curl" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "883539cb0ea94bab3f8371a98cd8e937bbe9ee7c044499184aa4c17deb643a50" dependencies = [ "curl", "git2", "log", "url", ] [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" dependencies = [ "aho-corasick", "bstr", "fnv", "log", "regex", ] [[package]] name = "heck" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] [[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "hex" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "home" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" dependencies = [ "winapi", ] [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "idna" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ "matches", "unicode-bidi", "unicode-normalization", ] [[package]] name = "ignore" version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" dependencies = [ "crossbeam-utils", "globset", "lazy_static", "log", "memchr", "regex", "same-file", "thread_local", "walkdir", "winapi-util", ] [[package]] name = "im-rc" version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f" dependencies = [ "bitmaps", "rand_core 0.5.1", "rand_xoshiro", "sized-chunks", "typenum", "version_check", ] [[package]] name = "itertools" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" dependencies = [ "either", ] [[package]] name = "itoa" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "jobserver" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" dependencies = [ "libc", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" [[package]] name = "libgit2-sys" version = "0.12.24+1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddbd6021eef06fb289a8f54b3c2acfdd85ff2a585dfbb24b8576325373d2152c" dependencies = [ "cc", "libc", "libssh2-sys", "libz-sys", "openssl-sys", "pkg-config", ] [[package]] name = "libnghttp2-sys" version = "0.1.7+1.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57ed28aba195b38d5ff02b9170cbff627e336a20925e43b4945390401c5dc93f" dependencies = [ "cc", "libc", ] [[package]] name = "libssh2-sys" version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca" dependencies = [ "cc", "libc", "libz-sys", "openssl-sys", "pkg-config", "vcpkg", ] [[package]] name = "libz-sys" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" dependencies = [ "cc", "libc", "pkg-config", "vcpkg", ] [[package]] name = "log" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ "cfg-if", ] [[package]] name = "matches" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "miniz_oxide" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ "adler", "autocfg", ] [[package]] name = "miow" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ "winapi", ] [[package]] name = "num-integer" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ "autocfg", "num-traits", ] [[package]] name = "num-traits" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ "hermit-abi", "libc", ] [[package]] name = "once_cell" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "opener" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea3ebcd72a54701f56345f16785a6d3ac2df7e986d273eb4395c0b01db17952" dependencies = [ "bstr", "winapi", ] [[package]] name = "openssl" version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", "once_cell", "openssl-sys", ] [[package]] name = "openssl-probe" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "openssl-sys" version = "0.9.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6517987b3f8226b5da3661dad65ff7f300cc59fb5ea8333ca191fc65fde3edf" dependencies = [ "autocfg", "cc", "libc", "pkg-config", "vcpkg", ] [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pkg-config" version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" [[package]] name = "ppv-lite86" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" [[package]] name = "proc-macro-error" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", "syn", "version_check", ] [[package]] name = "proc-macro-error-attr" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", "version_check", ] [[package]] name = "proc-macro2" version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" dependencies = [ "unicode-xid", ] [[package]] name = "quote" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", "rand_chacha", "rand_core 0.6.3", "rand_hc", ] [[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 0.6.3", ] [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" [[package]] name = "rand_core" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom", ] [[package]] name = "rand_hc" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ "rand_core 0.6.3", ] [[package]] name = "rand_xoshiro" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004" dependencies = [ "rand_core 0.5.1", ] [[package]] name = "redox_syscall" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags", ] [[package]] name = "regex" version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "remove_dir_all" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ "winapi", ] [[package]] name = "rustc-workspace-hack" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb" [[package]] name = "rustfix" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f0be05fc0675ef4f47119dc39cfc46636bb77d4fc4ef1bd851b9c3f7697f32a" dependencies = [ "anyhow", "log", "serde", "serde_json", ] [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "schannel" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" dependencies = [ "lazy_static", "winapi", ] [[package]] name = "semver" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" dependencies = [ "serde", ] [[package]] name = "serde" version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_ignored" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c2c7d39d14f2f2ea82239de71594782f186fd03501ac81f0ce08e674819ff2f" dependencies = [ "serde", ] [[package]] name = "serde_json" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "shell-escape" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" [[package]] name = "sized-chunks" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" dependencies = [ "bitmaps", "typenum", ] [[package]] name = "smawk" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" [[package]] name = "socket2" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" dependencies = [ "libc", "winapi", ] [[package]] name = "strip-ansi-escapes" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8" dependencies = [ "vte", ] [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" dependencies = [ "clap", "lazy_static", "structopt-derive", ] [[package]] name = "structopt-derive" version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", "proc-macro2", "quote", "syn", ] [[package]] name = "syn" version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] [[package]] name = "tar" version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c" dependencies = [ "filetime", "libc", "xattr", ] [[package]] name = "tempfile" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if", "libc", "rand", "redox_syscall", "remove_dir_all", "winapi", ] [[package]] name = "termcolor" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ "winapi-util", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ "unicode-width", ] [[package]] name = "textwrap" version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" dependencies = [ "smawk", "unicode-linebreak", "unicode-width", ] [[package]] name = "thread_local" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" dependencies = [ "once_cell", ] [[package]] name = "time" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", "winapi", ] [[package]] name = "tinyvec" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "toml" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" dependencies = [ "serde", ] [[package]] name = "typenum" version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "unicode-bidi" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-linebreak" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f" dependencies = [ "regex", ] [[package]] name = "unicode-normalization" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "url" version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", "idna", "matches", "percent-encoding", ] [[package]] name = "utf8parse" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "vte" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" dependencies = [ "arrayvec", "utf8parse", "vte_generate_state_changes", ] [[package]] name = "vte_generate_state_changes" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" dependencies = [ "proc-macro2", "quote", ] [[package]] name = "walkdir" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", "winapi", "winapi-util", ] [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[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-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] [[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 = "xattr" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" dependencies = [ "libc", ] debcargo-2.5.0/Cargo.toml0000644000000032040000000000100106030ustar # 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 = "debcargo" version = "2.5.0" authors = ["Josh Triplett ", "Ximin Luo ", "Vasudev Kamath "] description = "Create a Debian package from a Cargo crate." license = "MIT/Apache-2.0" repository = "https://salsa.debian.org/rust-team/debcargo" resolver = "2" [dependencies.ansi_term] version = "0.12" [dependencies.anyhow] version = "1.0" [dependencies.cargo] version = "0.57" [dependencies.chrono] version = "0.4" [dependencies.env_logger] version = "0.9" [dependencies.filetime] version = "0.2" [dependencies.flate2] version = "1" [dependencies.git2] version = "0.13.23" [dependencies.glob] version = "0.3" [dependencies.itertools] version = "0.10" [dependencies.log] version = "0.4" [dependencies.regex] version = "1.0" [dependencies.semver] version = "1" [dependencies.serde] version = "1" [dependencies.serde_derive] version = "1" [dependencies.structopt] version = "0.3" features = ["color"] [dependencies.tar] version = "0.4" [dependencies.tempfile] version = "3" [dependencies.textwrap] version = "0.14" [dependencies.toml] version = "0.5" [dependencies.walkdir] version = "2" debcargo-2.5.0/Cargo.toml.orig000064400000000000000000000016160072674642500143210ustar 00000000000000[package] name = "debcargo" version = "2.5.0" authors = [ "Josh Triplett ", "Ximin Luo ", "Vasudev Kamath "] license = "MIT/Apache-2.0" repository = "https://salsa.debian.org/rust-team/debcargo" description = "Create a Debian package from a Cargo crate." edition = "2021" [dependencies] ansi_term = "0.12" anyhow = "1.0" cargo = "0.57" chrono = "0.4" env_logger = "0.9" filetime = "0.2" flate2 = "1" # Uncomment these if compiling non-Debian package on Debian as Debian's # libgit2 is too old - 1.1.0 vs 1.3.0 needed by newer git2 crates. #git2 = "= 0.13.21" #libgit2-sys = "= 0.12.22+1.1.0" git2 = "0.13.23" glob = "0.3" itertools = "0.10" log = "0.4" regex = "1.0" semver = "1" serde = "1" serde_derive = "1" structopt = { version = "0.3", features = ["color"] } tar = "0.4" textwrap = "0.14" tempfile = "3" toml = "0.5" walkdir = "2" debcargo-2.5.0/HACKING.md000064400000000000000000000050370072674642500130210ustar 00000000000000This file contains information about developing debcargo itself. ## Dependencies For testing: ```shell # Install dependencies for building (see README.md), then: $ cargo install cargo-tree # use https://github.com/infinity0/cargo-tree $ apt-get install dh-cargo lintian ``` For development: ```shell # As above, then: $ cargo install rustfmt cargo-graph cargo-outdated $ cargo graph | dot -T png > graph.png $ cargo outdated -R ``` ## Testing Whenever you make a major change, you should run: tests/sh/integrate.sh -kbr debcargo exa fd-find ripgrep in order to test it over a few hundred crates. Fix any build errors and important lintian errors that crop up. If you make a change that has wide-reaching implications, such as messing with the dependency logic, do a more thorough test: tests/sh/integrate.sh -kbR debcargo exa fd-find ripgrep mdbook sccache This will run the test over around a thousand crates. -R runs it over all the transitive dependencies of all the binary packages, which is needed for entry into Debian Testing. This is wider than -r, which runs the test over all the transitive build-dependencies of the source package, which is needed for entry into Debian Unstable. ### Details To test the `debcargo` produced packages, you can run the following script. ```shell $ tests/sh/integrate.sh crate[s] ``` where you can provide a list of crate names or local directories containing crates, and the script will run debcargo to create a source package (`.dsc`) and run lintian over it. If you find any issues, please add to the bugs in TODO.md file. ```shell $ tests/sh/integrate.sh -kb crate[s] ``` will additionally run [sbuild](https://wiki.debian.org/sbuild) on the source package to build binary Debian packages (`.deb`) and run lintian over that too. It will automatically pick up any extra .debs you already have in the output directory, if they are dependencies of what you're building. The `-k` flag tells the script not to wipe the directory before it does anything else. ```shell $ tests/sh/integrate.sh -r crate[s] ``` will run the script recursively over the listed crate(s) and all of their transitive dependencies, in dependency-order. However, sometimes this does not work properly because of sfackler/cargo-tree#34 and some dependencies will get skipped. In this case you can giving the `-z` flag which uses a slower but more accurate (for Debian) method for resolving dependencies. (This is noticeable mostly when building with `-kbr` because sbuild will fail complaining about missing dependencies.) See `-h` for other options. debcargo-2.5.0/README.md000064400000000000000000000034760072674642500127170ustar 00000000000000Crates.io to Debian =========================== `debcargo` creates Debian source package from the provided Rust crate. Create Debian source package from the downloaded crate which follows Rust teams crate packaging [policy](https://wiki.debian.org/Teams/RustPackaging/Policy). ## Features ## * Package specific versions of crates from crates.io. * Easy to customize, using config files and overlay directories. * Tries to auto-detect copyright information from metadata and actual crate source, used to guess appropriate values for `debian/copyright`. * Put `FIXME (hint)` strings where it can't detect full information, so user can provide an override/overlay or manually fix it. * Results in a lintian-clean Debian package in most cases. * Packages can be cross-compiled by `sbuild` assuming the crate doesn't include anything that breaks it (such as arch-specific build.rs scripts). ## Dependencies For building: ```shell $ apt-get build-dep cargo $ apt-get install libssl-dev libcurl4-gnutls-dev quilt $ cargo build debcargo ``` ## Examples ## To download and unpack the latest `clap` crate and prepare the source package: ```shell $ debcargo package clap ``` To download and unpack version `2.25.0` of `clap` crate and prepare the source package: ```shell $ debcargo package clap =2.25.0 ``` To provide additional packaging-specific config for downloading and packaging latest `clap` crate from crates.io: ```shell $ debcargo package --config clap-2/debian/debcargo.toml clap ``` See `debcargo.toml.example` for a sample TOML file. ### Long-term maintenance workflow See https://salsa.debian.org/rust-team/debcargo-conf/blob/master/README.rst for an example. ## License ## Debcargo is licensed under `MIT/Apache-2.0`. It is written by `Josh Triplett` and improved by members of **Debian Rust Maintainers team** debcargo-2.5.0/TODO.md000064400000000000000000000021750072674642500125220ustar 00000000000000See https://salsa.debian.org/groups/rust-team/-/issues See HACKING.md for development and testing instructions. ## Lower-priority tasks Minor issues - fs::rename cannot handle cross-device moves, e.g. if --directory is on a different partition from . then debcargo fails - the ? syntax loses the stack, use Result.expect() to give context, or use error-chain instead... - [ ] globset, ignore, termcolor: When generating d/copyright, failed to clone repository https://github.com/BurntSushi/ripgrep/tree/master/XXX: unexpected HTTP status code: 404; class=Net (12) Features for later - [ ] Integrate `apt-pkg-native` crate to check if the crate or its dependency is already in archive and display information. - [ ] Display first level dependency with equivalent Debian names at the end which are not yet packaged in Debian as a information to maintainer. - [ ] A `dependency` sub-command to print all the dependencies including first level and recursive using `cargo` API. - [ ] Employ `licensecheck` tool to look for license and copyright information. Currently we use regex to grep through sources. debcargo-2.5.0/debcargo.toml.example000064400000000000000000000256460072674642500155400ustar 00000000000000# Whether to generate a package for the binary crate. If omitted, defaults to # true unless semver_suffix (see below) is also true. #bin = true # Name for the binary crate. Defaults to "" which means the crate # name, with no "rust-" prefix and with underscores replaced by hyphens. #bin_name = "" # Add the semver to the package name, to allow co-installation with other # versions of the same crate. This should only be true for crates older than # the most up-to-date version in Debian, and only if they are needed as a # (direct or indirect) build dependency of another binary crate. # # If you set this to true, you should either omit "bin" or set it to false, # unless you are sure the old and new packages are co-installable. #semver_suffix = false # Overlay directory to copy on top of the generated one, given relative to the # directory that contains this config file. If any files conflict with the ones # generated by debcargo, the latter are moved to .debcargo.hint instead. # # For the special case of debian/changelog, generated entries will be prepended # to the top of the existing d/changelog (from the overlay), rather than stored # in debian/changelog.debcargo.hint. A further exception: if the distribution # of the top entry in the existing d/changelog is # UNRELEASED-FIXME-AUTOGENERATED-DEBCARGO then that whole entry will be # *replaced* with the generated entry, not prepended. # # Normally, any "hints" generated are written back to the overlay directory, # overwriting any hints that may have previously been stored there. For the # special case of debian/changelog, that is written-back as-is. Therefore, it # is strongly recommended that you keep the overlay directory tracked in # version control. To disable this behaviour, give --no-overlay-write-back on # the debcargo command line. # #overlay = "." # Local directory where crate can be found, instead of crates.io. Resolved # relative to the directory that contains this config file. Note: this is # currently experimental and only works for crates whose dependencies are all # published on crates.io. For example, not rustup. This limitation will # hopefully be fixed in the future. # #crate_src_path = "../.." # Paths from the crate tarball, to exclude from the orig tarball. # See https://docs.rs/glob/latest/glob/struct.Pattern.html for syntax #excludes = ["libgit2/**"] # Paths from the crate tarball, that have been manually reviewed to adhere to # Debian policy. debcargo has a crude method for detecting files that might not # fit within policy, and will give a fatal error if any are detected. In the # exceptional cases where the method gives a false-positive, add them here. #whitelist = ["libgit2/**"] # Whether to allow prerelease deps, by rewriting these to the released version. # This should only be enabled for certain crates if really necessary, and first # you should check that they can actually build when this is enabled. #allow_prerelease_deps = false # This is the stem of the short description for each binary package. By default # `debcargo` will try to auto-extract a description from `Cargo.toml` but # sometimes this may lead to a meaningless, weird short description. # # The full short description of each binary package is constructed using this # string plus an auto-generated suffix. The full string can be overridden by # the [packages.KEY].summary config key, see below. #summary = "PLACEHOLDER" # This is the stem of the long description for each binary package. By default # this is empty. # # The full long description of each binary package is constructed using this # string plus an auto-generated suffix. The full string can be overridden by # the [packages.KEY].description config key, see below. #description = """ #PLACEHOLDER #""" # Maintainer # # Defaults to pkg-rust-team, should only be overriden with care. If overridden, # vcs_* in [source] should also be overridden, otherwise they point the Rust # Team's salsa project. # #maintainer= "PLACEHOLDER" # Uploaders. This affects the Uploaders: field in debian/control as well as the # additional maintainers listed in debian/copyright. The naming is historical; # in Debian today for team-maintained packages, this is generally taken to mean # "the main individuals" responsible for the package - anyone on the team is # "morally allowed" to perform the upload as long as they specify "Team upload" # in debian/changelog; this is done automatically by debcargo. uploaders = [ "foo bar " ] [source] # Debian Standards-Version to use. By default debcargo uses latest policy version. #policy = "4.0.0" # Override or provide missing homepage for crate #homepage = "https://clap.rs" # Override the VCS entries. # By default this points to a relevant subdirectory underneath the main # repository for debcargo config files, owned by the Debian Rust Maintainers: # https://salsa.debian.org/rust-team/debcargo-conf/ # Please only override this if your package is truly special, e.g. it combines # lots of languages and/or there is not a crate at the top-level directory. In # most cases you should prefer packaging as part of the Debian Rust Team, see # https://wiki.debian.org/Teams/RustPackaging/Policy # #vcs_git = "https://salsa.debian.org/special_package/rust-special-0.1.git" #vcs_browser = "https://salsa.debian.org/special_package/rust-special-0.1" # Section override for the source package. Unless overridden here, library # crates get "rust" and non-library crates get a "FIXME". #section = "rust" # Extra Build-Depends on top of those generated by debcargo. # If you defined a custom d/rules that does extra stuff on top of dh-cargo, # then you may need to use this. # # OTOH, if your crate needs external development headers to build, these should # probably instead go in the [packages.lib] depends key rather than this key. # debcargo will then automatically add those into the package Build-Depends if # needed by dh-cargo; you don't have to add them here as well. #build_depends = ["PLACEHOLDER", "PLACEHOLDER"] # Build-Depends to subtract from those generated by debcargo. This should be # used when our default generated Build-Depends results in a cycle. For # example, this might happen if: # # - crate A's default-feature depends on crate B's no-default-features (which has no dependencies) # - crate B's default-feature depends on crate A's no-default-features (which has no dependencies) # # In these cases, you'll need to (for example) add "librustA+B-dev " # to build_depends_excludes in A's debcargo.toml to break the cycle, and also # add override_dh_auto_test to A's d/rules to avoid selecting the B feature # when running the test build. Depending on the exact situation, it should be # sufficient to do this override only for one of the packages in the cycle. # # Note that binary package Depends must be left alone in order to correctly # express the dependencies; these ought not to have cycles in anyway, even in # a case like the above example. # # This field should *not* be used to exclude arch-specific dependencies. We # want to include them to support cross-compiling, and they should cause no # problems since they are just source code. If our test "cargo build" fails for # one of those dependencies, it should be handled in that package by disabling # the failing test on the architectures that they are expected to fail on. #build_depends_excludes = ["PLACEHOLDER", "PLACEHOLDER"] # Binary package overrides. # # Different values for KEY selects different binary packages: # lib - the package for the library crate # "lib+FEATURE" - the metapackage for feature FEATURE # bin - the package for the binary crate # [packages.KEY] # Section override for the binary package. Use this if your crate is both a # library and a binary crate; in this case, omit source.section which will # default to "rust" and override this value for your binary package. #section = "PLACEHOLDER" # Short description for the package. If omitted, debcargo autogenerates this # using the top-level "summary" key plus a suffix describing the feature. #summary = "PLACEHOLDER" # Long description for the package. If omitted, debcargo autogenerates this # using the top-level "description" key plus a suffix describing the feature. #description = """ #PLACEHOLDER #""" # Additional Depends on top of the ones generated by debcargo. This should be # used to pull in system libraries for crates that need them to build. You'll # want the -dev versions of the library packages, since our crate packages are # development packages and not runtime packages. #depends = ["PLACEHOLDER", "PLACEHOLDER"] # We generate an autopkgtest (post-install test) for every feature, and also # run `cargo test` for the default feature set during build-time if there are # no additional dev-dependencies. # # However sometimes this may not work, e.g. if the crate is part of a larger # workspace and its tests require files from the workspace directory. Or if # the crate author is simply negligent and didn't ensure the test passes for # all features. In these cases, you can use this setting to mark the test as # "flaky" to ignore failures. Special cases for packages.KEY: # # packages."lib+@" - disables the test for the --all-features autopkgtest # # The effect is transitive to its reverse-dependencies, so e.g. if you specify # this for feature A, and feature B depends on feature A, then feature B also # implicitly has this set. To unset it on feature B (and its transitive rdeps), # explicit set this to false for feature B as well. # # So for example if the test breaks for the bare library (when running with # --no-default-features) but works when the std feature is enabled, set this to # true for [packages.lib] and false for [packages."lib+std"]. # # Note: debcargo will error if you set these in an inconsistent way. For # example if feature A depends on {B, C}, B says true and C says false, of # course we cannot determine what A should be. You can suppress the error by # explicitly giving A a value, either true or false. # #test_is_broken = false # Some tests depend on extra system tools or libraries, which need to be given # to autopkgtest. Like test_is_broken, the effect is transitive to its rdeps. #test_depends = [] # # Note: we do not (currently) support unsetting of this in indirect rdeps. This # would result in similar conflict issues as documented for test_is_broken. It # is possible to work around it similarly, by requiring manual resolution - but # cancelling dependencies is harder to implement than true/false so we avoid it # for now. Please file an issue if you have a real use-case for it. # More additional fields. This is mostly useful for binary packages that might # relate to other external programs, e.g. debcargo Recommends cargo. #recommends = ["PLACEHOLDER", "PLACEHOLDER"] #suggests = ["PLACEHOLDER", "PLACEHOLDER"] #provides = ["PLACEHOLDER", "PLACEHOLDER"] # Extra lines to include in the stanza, freeform. Use this to include things # that debcargo doesn't handle, such as Breaks, Conflicts, Replaces. #extra_lines = ["PLACEHOLDER", "PLACEHOLDER"] debcargo-2.5.0/src/bin/debcargo.rs000064400000000000000000000065710072674642500151120ustar 00000000000000use ansi_term::Colour::Red; use structopt::{ clap::{crate_version, AppSettings}, StructOpt, }; use debcargo::build_order::{build_order, BuildOrderArgs}; use debcargo::crates::{update_crates_io, CrateInfo}; use debcargo::debian::DebInfo; use debcargo::errors::Result; use debcargo::package::*; #[derive(Debug, Clone, StructOpt)] #[structopt(name = "debcargo", about = "Package Rust crates for Debian.")] enum Opt { /// Update the user's default crates.io index, outside of a workspace. Update, /// Print the Debian package name for a crate. DebSrcName { /// Name of the crate to package. crate_name: String, /// Version of the crate to package; may contain dependency operators. /// If empty string, resolves to the latest version. If given here, /// i.e. not omitted then print the package name as if the config /// option semver_suffix was set to true. version: Option, }, /// Extract only a crate, without any other transformations. Extract { #[structopt(flatten)] init: PackageInitArgs, #[structopt(flatten)] extract: PackageExtractArgs, }, /// Package a Rust crate for Debian. Package { #[structopt(flatten)] init: PackageInitArgs, #[structopt(flatten)] extract: PackageExtractArgs, #[structopt(flatten)] finish: PackageExecuteArgs, }, /// Print the transitive dependencies of a package in topological order. BuildOrder { #[structopt(flatten)] args: BuildOrderArgs, }, } fn real_main() -> Result<()> { let m = Opt::clap() .global_setting(AppSettings::ColoredHelp) .get_matches(); use Opt::*; match Opt::from_clap(&m) { Update => update_crates_io(), DebSrcName { crate_name, version, } => { let crate_info = CrateInfo::new_with_update(&crate_name, version.as_deref(), false)?; let deb_info = DebInfo::new(&crate_info, crate_version!(), version.is_some()); println!("{}", deb_info.package_name()); Ok(()) } Extract { init, extract } => { log::info!("preparing crate info"); let mut process = PackageProcess::init(init)?; log::info!("extracting crate"); process.extract(extract)?; Ok(()) } Package { init, extract, finish, } => { log::info!("preparing crate info"); let mut process = PackageProcess::init(init)?; log::info!("extracting crate"); process.extract(extract)?; log::info!("applying overlay and patches"); process.apply_overrides()?; log::info!("preparing orig tarball"); process.prepare_orig_tarball()?; log::info!("preparing debian folder"); process.prepare_debian_folder(finish)?; process.post_package_checks() } BuildOrder { args } => { let build_order = build_order(args)?; for v in &build_order { println!("{}", v); } Ok(()) } } } fn main() { env_logger::init(); if let Err(e) = real_main() { eprintln!("{}", Red.bold().paint(format!("debcargo failed: {:?}", e))); std::process::exit(1); } } debcargo-2.5.0/src/build_order.rs000064400000000000000000000242660072674642500150670ustar 00000000000000use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque}; use std::fmt; use std::path::{Path, PathBuf}; use anyhow::Context; use cargo::core::{Dependency, PackageId}; use structopt::{clap::arg_enum, StructOpt}; use crate::config::Config; use crate::crates::{crate_name_ver_to_dep, show_dep, transitive_deps, CrateDepInfo, CrateInfo}; use crate::debian::control::base_deb_name; use crate::errors::Result; use crate::package::{PackageExtractArgs, PackageProcess}; use crate::util; arg_enum! { #[derive(Debug, Clone, Copy)] pub enum ResolveType { SourceForDebianUnstable, BinaryAllForDebianTesting, } } #[derive(Debug, Clone, StructOpt)] pub struct BuildOrderArgs { /// Name of the crate to package. crate_name: String, /// Version of the crate to package; may contain dependency operators. version: Option, /// Directory for configs. The config subdirectory for a given crate is /// looked up by their crate name and version, from more specific to less /// specific, e.g. -1.2.3, then -1.2, then -1 and /// finally . The config file is read from the debian/debcargo.toml /// subpath of the looked-up subdirectory. #[structopt(long)] config_dir: Option, /// Resolution type, one of SourceForDebianUnstable | BinaryAllForDebianTesting #[structopt(long, default_value = "SourceForDebianUnstable")] resolve_type: ResolveType, /// Emulate resolution as if every package were built with --collapse-features. #[structopt(long)] emulate_collapse_features: bool, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] struct PackageIdFeat(PackageId, &'static str); impl fmt::Display for PackageIdFeat { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}@{}/{}", self.0.name(), self.0.version(), self.1) } } // First result: if somebody build-depends on us, what do they first need to build? // Second result: what other packages need to go into Debian Testing before us? fn get_build_deps( crate_details: &(CrateInfo, CrateDepInfo, Config), package: &PackageIdFeat, resolve_type: ResolveType, emulate_collapse_features: bool, ) -> Result<(Vec, Vec)> { let (_, crate_dep_info, config) = crate_details; let all_deps = crate_dep_info .iter() .map(|(_, v)| v.1.iter()) .flatten() .cloned() .collect::>(); let feature_deps: HashSet = HashSet::from_iter(transitive_deps(crate_dep_info, package.1).1); let additional_deps = if emulate_collapse_features || config.collapse_features { all_deps.clone() } else { // TODO: if build_depends_features is an override, use that instead of "default" // TODO: also deprecate build_depends_excludes HashSet::from_iter(transitive_deps(crate_dep_info, "default").1) }; let hard_deps = feature_deps .union(&additional_deps) .cloned() .collect::>(); use ResolveType::*; match resolve_type { SourceForDebianUnstable => Ok((hard_deps, vec![])), BinaryAllForDebianTesting => { let mut soft_deps = all_deps; for h in hard_deps.iter() { soft_deps.remove(h); } Ok((hard_deps, soft_deps.into_iter().collect::>())) } } } fn dep_features(dep: &Dependency) -> Vec<&'static str> { let mut feats = dep .features() .iter() .map(|x| x.as_str()) .collect::>(); if dep.uses_default_features() { feats.push("default") } feats.push(""); // bare-bones library with no features feats } fn find_config(config_dir: &Path, id: PackageId) -> Result<(Option, Config)> { let name = base_deb_name(&id.name()); let version = id.version(); let candidates = [ format!( "{}-{}.{}.{}", name, version.major, version.minor, version.patch ), format!("{}-{}.{}", name, version.major, version.minor), format!("{}-{}", name, version.major), name, ]; for c in candidates { let path = config_dir.join(c).join("debian").join("debcargo.toml"); if path.is_file() { let config = Config::parse(&path).context("failed to parse debcargo.toml")?; log::debug!("using config for {}: {:?}", id, path); return Ok((Some(path), config)); } } Ok((None, Config::default())) } fn resolve_info( infos: &mut BTreeMap, cache: &mut HashMap, config_dir: Option<&Path>, dependency: &Dependency, update: bool, ) -> Result { if let Some(id) = cache.get(dependency) { return Ok(*id); } // resolve dependency let info = CrateInfo::new_from_dependency(dependency, update)?; let id = info.package_id(); cache.insert(dependency.clone(), id); // insert info if it's not already there if let std::collections::btree_map::Entry::Vacant(e) = infos.entry(id) { let id = *e.key(); let default_config = Config::default(); let (config_path, config) = match config_dir { None => (None, default_config), Some(config_dir) => { let (config_path, config) = find_config(config_dir, id)?; match config_path { None => (None, default_config), Some(_) => (config_path, config), } } }; let (info, config) = match config_path { None => (info, config), Some(_) => { let mut process = PackageProcess::new(info, config_path, config)?; let tempdir = tempfile::Builder::new() .prefix("debcargo") .tempdir_in(".")?; process.extract(PackageExtractArgs { directory: Some(tempdir.path().to_path_buf()), })?; process.apply_overrides()?; (process.crate_info, process.config) } }; let dep_info = info.all_dependencies_and_features(); e.insert((info, dep_info, config)); }; Ok(id) } pub fn build_order(args: BuildOrderArgs) -> Result> { let crate_name = &args.crate_name; let version = args.version.as_deref(); let config_dir = args.config_dir.as_deref(); let mut infos = BTreeMap::new(); let mut cache = HashMap::new(); let seed_dep = crate_name_ver_to_dep(crate_name, version)?; let seed_id = resolve_info(&mut infos, &mut cache, config_dir, &seed_dep, true)?; let mut next = |idf: &PackageIdFeat| -> Result<(Vec, Vec)> { let (hard, soft) = get_build_deps( infos .get(&idf.0) .expect("build_order next called without crate info"), idf, args.resolve_type, args.emulate_collapse_features, )?; log::trace!("{} hard-dep: {}", idf, util::show_vec_with(&hard, show_dep)); if !soft.is_empty() { log::trace!("{} soft-dep: {}", idf, util::show_vec_with(&soft, show_dep)); } // note: we might resolve the same crate-version several times; // this is expected, since different dependencies (with different // version ranges) might resolve into the same crate-version let mut hard_p = Vec::new(); for dep in hard { let id = resolve_info(&mut infos, &mut cache, config_dir, &dep, false)?; for f in dep_features(&dep) { hard_p.push(PackageIdFeat(id, f)); } } let mut soft_p = Vec::new(); for dep in soft { let id = resolve_info(&mut infos, &mut cache, config_dir, &dep, false)?; for f in dep_features(&dep) { soft_p.push(PackageIdFeat(id, f)); } } log::trace!("{} hard-dep resolve: {}", idf, util::show_vec(&hard_p)); if !soft_p.is_empty() { log::trace!("{} soft-dep resolve: {}", idf, util::show_vec(&soft_p)); } Ok((hard_p, soft_p)) }; let mut i = 0; let mut log = |remaining: &VecDeque<_>, graph: &BTreeMap<_, _>| { i += 1; if i % 16 == 0 { debcargo_info!( "debcargo build-order: resolving dependencies: done: {}, todo: {}", graph.len(), remaining.len() ); } Ok(()) }; let succ_with_features = util::graph_from_succ([PackageIdFeat(seed_id, "")], &mut next, &mut log)?; log::trace!("succ_with_features: {:#?}", succ_with_features); let succ = util::succ_proj(&succ_with_features, |x| x.0); let pred = util::succ_to_pred(&succ); let roots = succ .iter() .filter_map(|(k, v)| if v.is_empty() { Some(*k) } else { None }) .collect::>(); // swap pred/succ for call to topo_sort since we want reverse topo order let build_order = match util::topo_sort(roots, pred.clone(), succ.clone()) { Ok(r) => r, Err(remain) => { log::error!( "topo_sort got cyclic graph: {:#?}", remain .into_iter() .map(|(k, vv)| ( k.to_string(), vv.into_iter() .map(|v| v.to_string()) .collect::>() )) .collect::>() ); debcargo_bail!( "topo_sort got cyclic graph; you'll need to patch the crate(s) to break the cycle." ) } }; // sanity check for p in build_order.iter() { if infos.remove(p).is_none() { log::error!("extra package in build-order not in infos: {}", p); } } for (p, _) in infos { log::error!( "leftover infos not used in build-order: {}, succ: {}, pred: {}", p, util::show_vec(succ.get(&p).into_iter().flatten()), util::show_vec(pred.get(&p).into_iter().flatten()), ); } Ok(build_order) } debcargo-2.5.0/src/config.rs000064400000000000000000000160770072674642500140430ustar 00000000000000use serde::Deserialize; use toml; use crate::errors::*; use std::collections::HashMap; use std::fs::File; use std::io::Read; use std::path::{Path, PathBuf}; pub const RUST_MAINT: &str = "Debian Rust Maintainers "; #[derive(Deserialize, Debug, Clone)] #[serde(default)] pub struct Config { pub bin: Option, pub bin_name: String, pub semver_suffix: bool, pub overlay: Option, pub excludes: Option>, pub whitelist: Option>, pub allow_prerelease_deps: bool, pub crate_src_path: Option, pub summary: Option, pub description: Option, pub maintainer: String, pub uploaders: Option>, pub collapse_features: bool, pub requires_root: Option, pub source: Option, pub packages: Option>, } #[derive(Deserialize, Debug, Clone, Default)] pub struct SourceOverride { section: Option, policy: Option, homepage: Option, vcs_git: Option, vcs_browser: Option, build_depends: Option>, build_depends_excludes: Option>, } #[derive(Deserialize, Debug, Clone, Default)] pub struct PackageOverride { section: Option, summary: Option, description: Option, depends: Option>, recommends: Option>, suggests: Option>, provides: Option>, extra_lines: Option>, test_is_broken: Option, test_depends: Option>, } impl Default for Config { fn default() -> Self { Config { bin: None, bin_name: "".to_string(), semver_suffix: false, overlay: None, excludes: None, whitelist: None, allow_prerelease_deps: false, crate_src_path: None, summary: None, description: None, maintainer: RUST_MAINT.to_string(), uploaders: None, collapse_features: false, source: None, packages: None, requires_root: None, } } } impl Config { pub fn parse(src: &Path) -> Result { let mut config_file = File::open(src)?; let mut content = String::new(); config_file.read_to_string(&mut content)?; Ok(toml::from_str(&content)?) } pub fn build_bin_package(&self) -> bool { match self.bin { None => !self.semver_suffix, Some(b) => b, } } pub fn overlay_dir(&self, config_path: Option<&Path>) -> Option { Some(config_path?.parent()?.join(self.overlay.as_ref()?)) } pub fn crate_src_path(&self, config_path: Option<&Path>) -> Option { Some(config_path?.parent()?.join(self.crate_src_path.as_ref()?)) } pub fn orig_tar_excludes(&self) -> Option<&Vec> { self.excludes.as_ref() } pub fn orig_tar_whitelist(&self) -> Option<&Vec> { self.whitelist.as_ref() } pub fn maintainer(&self) -> &str { self.maintainer.as_str() } pub fn uploaders(&self) -> Option<&Vec> { self.uploaders.as_ref() } pub fn requires_root(&self) -> Option<&String> { self.requires_root.as_ref() } // Source shortcuts pub fn section(&self) -> Option<&str> { Some(self.source.as_ref()?.section.as_ref()?) } pub fn policy_version(&self) -> Option<&str> { Some(self.source.as_ref()?.policy.as_ref()?) } pub fn homepage(&self) -> Option<&str> { Some(self.source.as_ref()?.homepage.as_ref()?) } pub fn vcs_git(&self) -> Option<&str> { Some(self.source.as_ref()?.vcs_git.as_ref()?) } pub fn vcs_browser(&self) -> Option<&str> { Some(self.source.as_ref()?.vcs_browser.as_ref()?) } pub fn build_depends(&self) -> Option<&Vec> { self.source.as_ref()?.build_depends.as_ref() } pub fn build_depends_excludes(&self) -> Option<&Vec> { self.source.as_ref()?.build_depends_excludes.as_ref() } // Packages shortcuts fn with_package<'a, T, F: FnOnce(&'a PackageOverride) -> Option>( &'a self, key: PackageKey, f: F, ) -> Option { self.packages .as_ref()? .get(&package_key_string(key)) .and_then(f) } pub fn package_section(&self, key: PackageKey) -> Option<&str> { self.with_package(key, |pkg| pkg.section.as_deref()) } pub fn package_summary(&self, key: PackageKey) -> Option<&str> { self.with_package(key, |pkg| pkg.summary.as_deref()) } pub fn package_description(&self, key: PackageKey) -> Option<&str> { self.with_package(key, |pkg| pkg.description.as_deref()) } pub fn package_depends(&self, key: PackageKey) -> Option<&Vec> { self.with_package(key, |pkg| pkg.depends.as_ref()) } pub fn package_recommends(&self, key: PackageKey) -> Option<&Vec> { self.with_package(key, |pkg| pkg.recommends.as_ref()) } pub fn package_suggests(&self, key: PackageKey) -> Option<&Vec> { self.with_package(key, |pkg| pkg.suggests.as_ref()) } pub fn package_provides(&self, key: PackageKey) -> Option<&Vec> { self.with_package(key, |pkg| pkg.provides.as_ref()) } pub fn package_extra_lines(&self, key: PackageKey) -> Option<&Vec> { self.with_package(key, |pkg| pkg.extra_lines.as_ref()) } pub fn package_test_is_broken(&self, key: PackageKey) -> Option { self.with_package(key, |pkg| pkg.test_is_broken) } pub fn package_test_depends(&self, key: PackageKey) -> Option<&Vec> { self.with_package(key, |pkg| pkg.test_depends.as_ref()) } } pub fn package_field_for_feature<'a>( get_field: &'a dyn Fn(PackageKey) -> Option<&'a Vec>, feature: PackageKey, f_provides: &[&str], ) -> Vec { Some(feature) .into_iter() .chain(f_provides.iter().map(|s| PackageKey::feature(s))) .map(move |f| get_field(f).into_iter().flatten()) .flatten() .map(|s| s.to_string()) .collect() } #[derive(Clone, Copy)] pub enum PackageKey<'a> { Bin, BareLib, FeatureLib(&'a str), } impl<'a> PackageKey<'a> { pub fn feature(f: &'a str) -> PackageKey<'a> { use self::PackageKey::*; if f.is_empty() { BareLib } else { FeatureLib(f) } } } fn package_key_string(key: PackageKey) -> String { use self::PackageKey::*; match key { Bin => "bin".to_string(), BareLib => "lib".to_string(), FeatureLib(feature) => format!("lib+{}", feature), } } pub fn testing_ignore_debpolv() -> bool { std::env::var("DEBCARGO_TESTING_IGNORE_DEBIAN_POLICY_VIOLATION") == Ok("1".to_string()) } pub fn testing_ruzt() -> bool { std::env::var("DEBCARGO_TESTING_RUZT") == Ok("1".to_string()) } debcargo-2.5.0/src/crates.rs000064400000000000000000000616300072674642500140520ustar 00000000000000use anyhow::{format_err, Error}; use cargo::{ core::manifest::ManifestMetadata, core::registry::PackageRegistry, core::source::MaybePackage, core::{ resolver::features::CliFeatures, Dependency, EitherManifest, FeatureValue, Manifest, Package, PackageId, Registry, Source, SourceId, Summary, Target, TargetKind, Workspace, }, ops, ops::{PackageOpts, Packages}, sources::registry::RegistrySource, util::{interning::InternedString, toml::read_manifest, FileLock}, Config, }; use filetime::{set_file_times, FileTime}; use flate2::read::GzDecoder; use glob::Pattern; use regex::Regex; use semver::Version; use tar::Archive; use tempfile; use std; use std::collections::{BTreeMap, HashSet}; use std::fs; use std::hash::{Hash, Hasher}; use std::io::{self, Read, Write}; use std::path::Path; use crate::config::testing_ignore_debpolv; use crate::errors::*; pub struct CrateInfo { // only used for to_registry_toml in extract_crate. DO NOT USE ELSEWHERE package: Package, // allows overriding package.manifest() e.g. via patches manifest: Manifest, crate_file: FileLock, config: Config, source_id: SourceId, excludes: Vec, includes: Vec, } pub type CrateDepInfo = BTreeMap< &'static str, // name of feature / optional dependency, // or "" for the base package w/ no default features, guaranteed to be in the map ( Vec<&'static str>, // dependencies: other features (of the current package) Vec, ), >; fn hash(hashable: &H) -> u64 { #![allow(deprecated)] let mut hasher = std::hash::SipHasher::new(); hashable.hash(&mut hasher); hasher.finish() } fn fetch_candidates(registry: &mut PackageRegistry, dep: &Dependency) -> Result> { let mut summaries = registry.query_vec(dep, false)?; summaries.sort_by(|a, b| b.package_id().partial_cmp(&a.package_id()).unwrap()); Ok(summaries) } pub fn update_crates_io() -> Result<()> { let config = Config::default()?; let _lock = config.acquire_package_cache_lock()?; let source_id = SourceId::crates_io(&config)?; let yanked_whitelist = HashSet::new(); let mut r = RegistrySource::remote(source_id, &yanked_whitelist, &config); r.update() } pub fn crate_name_ver_to_dep(crate_name: &str, version: Option<&str>) -> Result { // note: this forces a network call let config = Config::default()?; let source_id = SourceId::crates_io(&config)?; let version = version.and_then(|v| { if v.is_empty() { None } else if v.starts_with(|c: char| c.is_digit(10)) { Some(["=", v].concat()) } else { Some(v.to_string()) } }); Dependency::parse(crate_name, version.as_deref(), source_id) } pub fn show_dep(dep: &Dependency) -> String { format!("{} {}", dep.package_name(), dep.version_req()) } impl CrateInfo { pub fn new(crate_name: &str, version: Option<&str>) -> Result { CrateInfo::new_with_update(crate_name, version, true) } pub fn new_with_local_crate( crate_name: &str, version: Option<&str>, crate_path: &Path, ) -> Result { let config = Config::default()?; let crate_path = crate_path.canonicalize()?; let source_id = SourceId::for_path(&crate_path)?; let (package, crate_file) = { let yanked_whitelist = HashSet::new(); let mut source = source_id.load(&config, &yanked_whitelist)?; source.update()?; let package_id = match version { None | Some("") => { let dep = Dependency::parse(crate_name, None, source_id)?; let mut package_id: Option = None; source.query(&dep, &mut |p| package_id = Some(p.package_id()))?; package_id.unwrap() } Some(version) => PackageId::new(crate_name, version, source_id)?, }; let maybe_package = source.download(package_id)?; let package = match maybe_package { MaybePackage::Ready(p) => Ok(p), _ => Err(format_err!( "Failed to 'download' local crate {} from {}", crate_name, crate_path.display() )), }?; let crate_file = { let workspace = Workspace::ephemeral(package.clone(), &config, None, true)?; let opts = PackageOpts { config: &config, verify: false, list: false, check_metadata: true, allow_dirty: true, cli_features: CliFeatures::from_command_line(&[], true, false)?, jobs: None, targets: Vec::new(), to_package: Packages::Default, }; // as of cargo 0.41 this returns a FileLock with a temp path, instead of the one // it got renamed to if ops::package(&workspace, &opts)?.is_none() { return Err(format_err!( "Failed to assemble crate file for local crate {} at {}\n", crate_name, crate_path.display() )); } let filename = format!("{}-{}.crate", crate_name, package_id.version().to_string()); workspace .target_dir() .join("package") .open_rw(&filename, &config, "crate file")? }; (package, crate_file) }; let manifest = package.manifest().clone(); Ok(CrateInfo { package, manifest, crate_file, config, source_id, excludes: vec![], includes: vec![], }) } pub fn new_with_update( crate_name: &str, version: Option<&str>, update: bool, ) -> Result { let dep = crate_name_ver_to_dep(crate_name, version)?; Self::new_from_dependency(&dep, update) } pub fn new_from_dependency(dependency: &Dependency, update: bool) -> Result { let mut config = Config::default()?; if !update { // unfriendly API from cargo; we'll have to make do with it for // now as there is no other alternative config.configure( 0, false, None, config.frozen(), config.locked(), true, // offline &config.target_dir()?.map(|x| x.into_path_unlocked()), &[], &[], )?; } let source_id = dependency.source_id(); let registry_name = format!( "{}-{:016x}", source_id.url().host_str().unwrap_or(""), hash(&source_id).swap_bytes() ); let get_package_info = |config: &Config| -> Result<_> { let lock = config.acquire_package_cache_lock()?; let mut registry = PackageRegistry::new(config)?; registry.lock_patches(); let summaries = fetch_candidates(&mut registry, dependency)?; drop(lock); let pkgids = summaries .into_iter() .map(|s| s.package_id()) .collect::>(); let pkgid = pkgids.iter().max().ok_or_else(|| { format_err!( concat!( "Couldn't find any crate matching {}\n", "Try `debcargo update` to update the crates.io index." ), show_dep(dependency) ) })?; let pkgset = registry.get(pkgids.as_slice())?; let package = pkgset.get_one(*pkgid)?; let manifest = package.manifest(); for f in dependency.features() { // apparently, if offline is set then cargo sometimes selects // an offline-available version that doesn't satisfy the // requested features. this is dumb. if it happens, then we // retry with online allowed. if !manifest.summary().features().contains_key(f) { debcargo_bail!( "resolve ({} {}) -> ({}) failed to pick up required feature ({})\n\ This can happen with very old or yanked crates. Try patching one of \ its dependants, to drop or update the offending dependency.", dependency.package_name(), dependency.version_req(), pkgid, f, ) } } let filename = format!("{}-{}.crate", pkgid.name(), pkgid.version()); let crate_file = config .registry_cache_path() .join(®istry_name) .open_ro(&filename, config, &filename)?; Ok((package.clone(), manifest.clone(), crate_file)) }; // if update is false but the user never downloaded the crate then the // first call will error; re-try with online in that case let (package, manifest, crate_file) = get_package_info(&config).or_else(|_| get_package_info(&Config::default()?))?; Ok(CrateInfo { package, manifest, crate_file, config, source_id, excludes: vec![], includes: vec![], }) } pub fn crate_name(&self) -> &'static str { self.package_id().name().as_str() } pub fn version(&self) -> &Version { self.package_id().version() } pub fn semver(&self) -> String { match *self.package_id().version() { Version { major: 0, minor, .. } => format!("0.{}", minor), Version { major, .. } => format!("{}", major), } } pub fn manifest(&self) -> &Manifest { &self.manifest } pub fn replace_manifest(&mut self, path: &Path) -> Result<&Self> { if let (EitherManifest::Real(v), _) = read_manifest(path, self.source_id, &self.config)? { self.manifest = v; } Ok(self) } pub fn metadata(&self) -> &ManifestMetadata { self.manifest.metadata() } pub fn manifest_path(&self) -> &Path { self.package.manifest_path() } pub fn targets(&self) -> &[Target] { self.manifest.targets() } pub fn is_lib(&self) -> bool { let mut lib = false; for target in self.manifest.targets() { match *target.kind() { TargetKind::Lib(_) => { lib = true; break; } _ => continue, } } lib } pub fn get_binary_targets(&self) -> Vec<&str> { let mut bins = Vec::new(); for target in self.manifest.targets() { match *target.kind() { TargetKind::Bin => { bins.push(target.name()); } _ => continue, } } bins.sort_unstable(); bins } pub fn summary(&self) -> &Summary { self.manifest.summary() } pub fn checksum(&self) -> Option<&str> { self.manifest.summary().checksum() } pub fn package_id(&self) -> PackageId { self.manifest.summary().package_id() } pub fn crate_file(&self) -> &FileLock { &self.crate_file } pub fn dependencies(&self) -> &[Dependency] { self.manifest.dependencies() } pub fn dev_dependencies(&self) -> Vec { use cargo::core::dependency::DepKind; let mut deps = vec![]; for dep in self.dependencies() { if dep.kind() == DepKind::Development { deps.push(dep.clone()) } } deps } /// Collect information about the dependency structure of features and /// their external crate dependencies, in a simple output format. pub fn all_dependencies_and_features(&self) -> CrateDepInfo { use cargo::core::dependency::DepKind; let mut deps_by_name: BTreeMap<&str, Vec<&Dependency>> = BTreeMap::new(); for dep in self.dependencies() { // we treat build-dependencies also as dependencies in Debian if dep.kind() != DepKind::Development { let s = dep.name_in_toml().as_str(); deps_by_name.entry(s).or_default().push(dep); } } let deps_by_name = deps_by_name; let mut features_with_deps = BTreeMap::new(); // calculate dependencies of this crate's features for (feature, deps) in self.manifest.summary().features() { let mut feature_deps: Vec<&'static str> = vec![]; let mut other_deps: Vec = Vec::new(); for dep in deps { use self::FeatureValue::*; match dep { // another feature is a dependency Feature(dep_feature) => { feature_deps.push(InternedString::new(dep_feature).as_str()) } // another package is a dependency Dep { dep_name } => { // unwrap is ok, valid Cargo.toml files must have this for &dep in deps_by_name.get(dep_name.as_str()).unwrap() { other_deps.push(dep.clone()); } } // another package is a dependency DepFeature { dep_name, dep_feature, .. } => match deps_by_name.get(dep_name.as_str()) { // unwrap is ok, valid Cargo.toml files must have this Some(dd) => { for &dep in dd { let mut dep = dep.clone(); dep.set_features(vec![InternedString::new(dep_feature)]); dep.set_default_features(false); other_deps.push(dep); } } None => { let mut expected = false; for dep in self.dependencies() { if dep.kind() == DepKind::Development { let s = dep.name_in_toml().as_str(); if s == dep_name.as_str() { expected = true; } } } if expected { debcargo_warn!( "Ignoring \"{}\" feature \"{}\" as it depends on a \ dev-dependency \"{}\"", self.package_id(), feature, dep_name ); } else { panic!( "failed to account for dependency \"{}\" of \"{}\" feature \"{}\"", dep_name, self.package_id(), feature ); } } }, } } if feature_deps.is_empty() { // everything depends on bare library feature_deps.push(""); } features_with_deps.insert(feature.as_str(), (feature_deps, other_deps)); } // calculate dependencies of this crate's "optional dependencies", since they are also features let mut deps_required: Vec = Vec::new(); for deps in deps_by_name.values() { for &dep in deps { if dep.is_optional() { features_with_deps .insert(dep.name_in_toml().as_str(), (vec![""], vec![dep.clone()])); } else { deps_required.push(dep.clone()) } } } // implicit no-default-features features_with_deps.insert("", (vec![], deps_required)); // implicit default feature if !features_with_deps.contains_key("default") { features_with_deps.insert("default", (vec![""], vec![])); } features_with_deps } pub fn get_summary_description(&self) -> (Option, Option) { let (summary, description) = if let Some(ref description) = self.metadata().description { // Convention these days seems to be to do manual text // wrapping in crate descriptions, boo. \n\n is a real line break. let mut description = description .replace("\n\n", "\r") .replace("\n", " ") .replace("\r", "\n") .trim() .to_string(); // Trim off common prefixes let re = Regex::new(&format!( r"^(?i)({}|This(\s+\w+)?)(\s*,|\s+is|\s+provides)\s+", self.package_id().name() )) .unwrap(); description = re.replace(&description, "").to_string(); let re = Regex::new(r"^(?i)(a|an|the)\s+").unwrap(); description = re.replace(&description, "").to_string(); let re = Regex::new(r"^(?i)(rust\s+)?(implementation|library|tool|crate)\s+(of|to|for)\s+") .unwrap(); description = re.replace(&description, "").to_string(); // https://stackoverflow.com/questions/38406793/why-is-capitalizing-the-first-letter-of-a-string-so-convoluted-in-rust description = { let mut d = description.chars(); match d.next() { None => String::new(), Some(f) => f.to_uppercase().chain(d).collect::(), } }; // Use the first sentence or first line, whichever comes first, as the summary. let p1 = description.find('\n'); let p2 = description.find(". "); match p1.into_iter().chain(p2.into_iter()).min() { Some(p) => { let s = description[..p].trim_end_matches('.').to_string(); let d = description[p + 1..].trim(); if d.is_empty() { (Some(s), None) } else { (Some(s), Some(d.to_string())) } } None => (Some(description.trim_end_matches('.').to_string()), None), } } else { (None, None) }; (summary, description) } /// To be called before extract_crate. pub fn set_includes_excludes( &mut self, excludes: Option<&Vec>, includes: Option<&Vec>, ) { self.excludes = excludes .into_iter() .flatten() .map(|x| Pattern::new(&("*/".to_owned() + x)).unwrap()) .collect::>(); self.includes = includes .into_iter() .flatten() .map(|x| Pattern::new(&("*/".to_owned() + x)).unwrap()) .collect::>(); } pub fn filter_path(&self, path: &Path) -> ::std::result::Result { if self.excludes.iter().any(|p| p.matches_path(path)) { return Ok(true); } let suspicious = match path.extension() { Some(ext) => ext == "c" || ext == "a", _ => false, }; if suspicious { if self.includes.iter().any(|p| p.matches_path(path)) { debcargo_info!("Suspicious file, on whitelist so ignored: {:?}", path); Ok(false) } else if testing_ignore_debpolv() { debcargo_warn!("Suspicious file, ignoring as per override: {:?}", path); Ok(false) } else { Err(format!( "Suspicious file, should probably be excluded: {:?}", path )) } } else { Ok(false) } } pub fn extract_crate(&self, path: &Path) -> Result { let mut archive = Archive::new(GzDecoder::new(self.crate_file.file())); let tempdir = tempfile::Builder::new() .prefix("debcargo") .tempdir_in(".")?; let mut source_modified = false; let mut last_mtime = 0; let mut err = vec![]; for entry in archive.entries()? { let mut entry = entry?; match self.filter_path(&(entry.path()?)) { Err(e) => err.push(e), Ok(r) => { if r { source_modified = true; continue; } } } if !entry.unpack_in(tempdir.path())? { debcargo_bail!("Crate contained path traversals via '..'"); } if let Ok(mtime) = entry.header().mtime() { if mtime > last_mtime { last_mtime = mtime; } } } if !err.is_empty() { for e in err { debcargo_warn!("{}", e); } debcargo_bail!( "Suspicious files detected, aborting. Ask on #debian-rust if you are stuck." ) } let entries = tempdir.path().read_dir()?.collect::>>()?; if entries.len() != 1 || !entries[0].file_type()?.is_dir() { let pkgid = self.package_id(); debcargo_bail!( "{}-{}.crate did not unpack to a single top-level directory", pkgid.name(), pkgid.version() ); } if let Err(e) = fs::rename(entries[0].path(), &path) { return Err(Error::from(e).context(format!( concat!( "Could not create source directory {0}\n", "To regenerate, move or remove {0}" ), path.display() ))); } // Ensure that Cargo.toml is in standard form, e.g. does not contain // path dependencies, so can be built standalone (see #4030). let toml_path = path.join("Cargo.toml"); let ws = Workspace::new(&toml_path.canonicalize()?, &self.config)?; let registry_toml = self.package.to_registry_toml(&ws)?; let mut actual_toml = String::new(); fs::File::open(&toml_path)?.read_to_string(&mut actual_toml)?; if !actual_toml.contains("AUTOMATICALLY GENERATED BY CARGO") { // This logic should only fire for old crates, and that's what the // if-conditional is supposed to check; modern versions of cargo // already do this before uploading the crate and we shouldn't need // to handle it specially. let old_toml_path = path.join("Cargo.toml.orig"); fs::copy(&toml_path, &old_toml_path)?; fs::OpenOptions::new() .write(true) .truncate(true) .open(&toml_path)? .write_all(registry_toml.as_bytes())?; debcargo_info!( "Rewrote {:?} to canonical form\nOld backed up as {:?}", &toml_path, &old_toml_path, ); source_modified = true; // avoid lintian errors about package-contains-ancient-file // TODO: do we want to do this for unmodified tarballs? it would // force us to modify them, but otherwise we get that ugly warning let last_mtime = FileTime::from_unix_time(last_mtime as i64, 0); set_file_times(toml_path, last_mtime, last_mtime)?; } Ok(source_modified) } } /// Calculate all feature-dependencies and external-dependencies of a given /// feature, using the information previously generated by /// `all_dependencies_and_features`. pub fn transitive_deps<'a>( features_with_deps: &'a CrateDepInfo, feature: &str, ) -> (Vec<&'a str>, Vec) { let mut all_features = Vec::new(); let mut all_deps = Vec::new(); let &(ref ff, ref dd) = features_with_deps.get(feature).unwrap(); all_features.extend(ff.clone()); all_deps.extend(dd.clone()); for f in ff { let (ff1, dd1) = transitive_deps(features_with_deps, f); all_features.extend(ff1); all_deps.extend(dd1); } (all_features, all_deps) } debcargo-2.5.0/src/debian/changelog.rs000064400000000000000000000122030072674642500157320ustar 00000000000000use anyhow; use chrono::{DateTime, FixedOffset, Local, TimeZone}; use regex::Regex; use std::fmt; use std::str; pub const DEFAULT_DIST: &str = "UNRELEASED-FIXME-AUTOGENERATED-DEBCARGO"; pub const COMMENT_TEAM_UPLOAD: &str = " * Team upload."; pub struct ChangelogEntry { pub source: String, pub version: String, pub distribution: String, pub options: String, pub maintainer: String, pub date: DateTime, pub items: Vec, } pub fn local_now() -> DateTime { let now = Local::now(); let offset = now .timezone() .offset_from_local_datetime(&now.naive_local()) .unwrap(); now.with_timezone(&offset) } impl fmt::Display for ChangelogEntry { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!( f, "{} ({}) {}; {}\n", self.source, self.version, self.distribution, self.options )?; for entry in self.items.iter() { writeln!(f, "{}", entry)?; } writeln!(f, "\n -- {} {}", self.maintainer, self.date.to_rfc2822()) } } fn line_is_blank(s: &str) -> bool { s.chars().all(char::is_whitespace) } impl str::FromStr for ChangelogEntry { type Err = anyhow::Error; fn from_str(s: &str) -> Result { let mut lines = s.lines().collect::>(); // see https://manpages.debian.org/testing/dpkg-dev/deb-changelog.5.en.html // regexes adapted from /usr/share/perl5/Dpkg/Changelog/Entry/Debian.pm let firstline = lines[0]; let re1 = Regex::new(r"(?i)^(\w[-+0-9a-z.]*) \(([^\(\) \t]+)\)((?:\s+[-+0-9a-z.]+)+);(.*?)\s*$") .unwrap(); let matches1 = re1.captures(firstline).unwrap(); let mut i = 1; while line_is_blank(lines[i]) { i += 1; } lines = lines.split_off(i); while line_is_blank(lines.last().unwrap()) { lines.pop(); } let lastline = lines.pop().unwrap(); while line_is_blank(lines.last().unwrap()) { lines.pop(); } let re2 = Regex::new(r"^ \-\- ((?:.*) <(?:.*)>) ?(\w.*\S)\s*$").unwrap(); let matches2 = re2.captures(lastline).unwrap(); Ok(Self::new( matches1[1].to_string(), matches1[2].to_string(), matches1[3].to_string(), matches1[4].to_string(), matches2[1].to_string(), DateTime::parse_from_rfc2822(&matches2[2])?, lines.iter().map(|s| s.to_string()).collect(), )) } } impl ChangelogEntry { pub fn new( source: String, version: String, distribution: String, options: String, maintainer: String, date: DateTime, items: Vec, ) -> Self { ChangelogEntry { source, version, distribution, options, maintainer, date, items, } } pub fn maintainer_name(self: &ChangelogEntry) -> String { let re = Regex::new(r"^\s*(\S.*\S)\s*<.*>\s*$").unwrap(); let matches = re.captures(&self.maintainer).unwrap(); matches[1].to_string() } pub fn version_parts(self: &ChangelogEntry) -> (String, String) { let re = Regex::new(r"^(.*)-([^-]*)$").unwrap(); let matches = re.captures(&self.version).unwrap(); (matches[1].to_string(), matches[2].to_string()) } pub fn deb_version_suffix(self: &ChangelogEntry) -> String { let re = Regex::new(r".*-([^-]*)$").unwrap(); re.captures(&self.version).unwrap()[1].to_string() } pub fn deb_version_suffix_bump(self: &ChangelogEntry) -> String { let suf = self.deb_version_suffix(); let re = Regex::new(r"^((?:.*\D)?)(\d*)$").unwrap(); let matches = re.captures(&suf).unwrap(); if matches[2].is_empty() { format!("{}.1", &matches[1]) } else { format!( "{}{}", &matches[1], (matches[2].parse::().unwrap() + 1) ) } } } pub struct ChangelogIterator<'a> { input: &'a [u8], index: usize, } impl<'a> ChangelogIterator<'a> { pub fn from(input: &'a str) -> ChangelogIterator<'a> { ChangelogIterator { input: input.as_bytes(), index: 0, } } } impl<'a> Iterator for ChangelogIterator<'a> { type Item = &'a str; #[inline] fn next(&mut self) -> Option<&'a str> { let slice = &self.input[self.index..]; if slice.is_empty() { return None; } let mut result = slice; // ghetto parser; also hack around the fact rust's str doesn't // support proper indexing, boo for (i, c) in slice.iter().enumerate() { if *c != b'\n' { continue; } if i < (slice.len() - 1) && (slice[i + 1] as char).is_whitespace() { continue; } self.index += i + 1; result = &slice[..=i]; break; } Some(str::from_utf8(result).unwrap()) } } debcargo-2.5.0/src/debian/control.rs000064400000000000000000000460000072674642500154650ustar 00000000000000use std::env::{self, VarError}; use std::fmt::{self, Write}; use anyhow::{format_err, Error}; use semver::Version; use textwrap::fill; use crate::config::{self, Config, PackageKey}; use crate::errors::*; pub struct Source { name: String, section: String, priority: String, maintainer: String, uploaders: Vec, standards: String, build_deps: Vec, vcs_git: String, vcs_browser: String, homepage: String, x_cargo: String, requires_root: String, } pub struct Package { name: String, arch: String, multi_arch: String, section: Option, depends: Vec, recommends: Vec, suggests: Vec, provides: Vec, summary: Description, description: Description, extra_lines: Vec, } pub struct Description { pub prefix: String, pub suffix: String, } pub struct PkgTest { name: String, crate_name: String, feature: String, version: String, extra_test_args: Vec, depends: Vec, extra_restricts: Vec, } impl fmt::Display for Source { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "Source: {}", self.name)?; writeln!(f, "Section: {}", self.section)?; writeln!(f, "Priority: {}", self.priority)?; writeln!(f, "Build-Depends: {}", self.build_deps.join(",\n "))?; writeln!(f, "Maintainer: {}", self.maintainer)?; if !self.uploaders.is_empty() { writeln!(f, "Uploaders:\n {}", self.uploaders.join(",\n "))?; } writeln!(f, "Standards-Version: {}", self.standards)?; writeln!(f, "Vcs-Git: {}", self.vcs_git)?; writeln!(f, "Vcs-Browser: {}", self.vcs_browser)?; if !self.homepage.is_empty() { writeln!(f, "Homepage: {}", self.homepage)?; } if !self.x_cargo.is_empty() { writeln!(f, "X-Cargo-Crate: {}", self.x_cargo)?; } writeln!(f, "Rules-Requires-Root: {}", self.requires_root)?; Ok(()) } } impl fmt::Display for Package { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "Package: {}", self.name)?; writeln!(f, "Architecture: {}", self.arch)?; writeln!(f, "Multi-Arch: {}", self.multi_arch)?; if let Some(section) = &self.section { writeln!(f, "Section: {}", section)?; } if !self.depends.is_empty() { writeln!(f, "Depends:\n {}", self.depends.join(",\n "))?; } if !self.recommends.is_empty() { writeln!(f, "Recommends:\n {}", self.recommends.join(",\n "))?; } if !self.suggests.is_empty() { writeln!(f, "Suggests:\n {}", self.suggests.join(",\n "))?; } if !self.provides.is_empty() { writeln!(f, "Provides:\n {}", self.provides.join(",\n "))?; } for line in &self.extra_lines { writeln!(f, "{}", line)?; } self.write_description(f) } } impl fmt::Display for PkgTest { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!( f, "Test-Command: /usr/share/cargo/bin/cargo-auto-test {} {} --all-targets {}", self.crate_name, self.version, self.extra_test_args.join(" ") )?; writeln!(f, "Features: test-name={}:{}", &self.name, &self.feature)?; // TODO: drop the below workaround when rust-lang/cargo#5133 is fixed. // The downside of our present work-around is that more dependencies // must be installed, which makes it harder to actually run the tests let cargo_bug_fixed = false; let default_deps = if cargo_bug_fixed { &self.name } else { "@" }; if self.depends.is_empty() { writeln!(f, "Depends: dh-cargo (>= 18), {}", default_deps)?; } else { writeln!( f, "Depends: dh-cargo (>= 18), {}, {}", self.depends.join(", "), default_deps )?; } if self.extra_restricts.is_empty() { writeln!(f, "Restrictions: allow-stderr, skip-not-installable")?; } else { writeln!( f, "Restrictions: allow-stderr, skip-not-installable, {}", self.extra_restricts.join(", ") )?; } Ok(()) } } impl Source { pub fn pkg_prefix() -> &'static str { if config::testing_ruzt() { // avoid accidentally installing official packages during tests "ruzt" } else { "rust" } } #[allow(clippy::too_many_arguments)] pub fn new( basename: &str, name_suffix: Option<&str>, upstream_name: &str, home: &str, lib: bool, maintainer: String, uploaders: Vec, build_deps: Vec, _requires_root: String, ) -> Result { let pkgbase = match name_suffix { None => basename.to_string(), Some(suf) => format!("{}{}", basename, suf), }; let section = if lib { "rust" } else { "FIXME-IN-THE-SOURCE-SECTION" }; let priority = "optional".to_string(); let vcs_browser = format!( "https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/{}", pkgbase ); let vcs_git = format!( "https://salsa.debian.org/rust-team/debcargo-conf.git [src/{}]", pkgbase ); let cargo_crate = if upstream_name != base_deb_name(upstream_name) { upstream_name.to_string() } else { "".to_string() }; Ok(Source { name: dsc_name(&pkgbase), section: section.to_string(), priority, maintainer, uploaders, standards: "4.5.1".to_string(), build_deps, vcs_git, vcs_browser, homepage: home.to_string(), x_cargo: cargo_crate, requires_root: "no".to_string(), }) } pub fn name(&self) -> &str { &self.name } pub fn apply_overrides(&mut self, config: &Config) { if let Some(section) = config.section() { self.section = section.to_string(); } if let Some(policy) = config.policy_version() { self.standards = policy.to_string(); } self.build_deps.extend( config .build_depends() .into_iter() .flatten() .map(String::to_string), ); let bdeps_ex = config .build_depends_excludes() .map(Vec::as_slice) .unwrap_or(&[]); self.build_deps.retain(|x| !bdeps_ex.contains(x)); if let Some(homepage) = config.homepage() { self.homepage = homepage.to_string(); } if let Some(vcs_git) = config.vcs_git() { self.vcs_git = vcs_git.to_string(); } if let Some(vcs_browser) = config.vcs_browser() { self.vcs_browser = vcs_browser.to_string(); } if let Some(requires_root) = config.requires_root() { self.requires_root = requires_root.to_string(); } } } impl Package { pub fn pkg_prefix() -> &'static str { if config::testing_ruzt() { // avoid accidentally installing official packages during tests "libruzt" } else { "librust" } } #[allow(clippy::too_many_arguments)] pub fn new( basename: &str, name_suffix: Option<&str>, version: &Version, summary: Description, description: Description, feature: Option<&str>, f_deps: Vec<&str>, o_deps: Vec, f_provides: Vec<&str>, f_recommends: Vec<&str>, f_suggests: Vec<&str>, ) -> Result { let pkgbase = match name_suffix { None => basename.to_string(), Some(suf) => format!("{}{}", basename, suf), }; let deb_feature2 = &|p: &str, f: &str| { format!( "{} (= ${{binary:Version}})", match f { "" => deb_name(p), _ => deb_feature_name(p, f), } ) }; let deb_feature = &|f: &str| deb_feature2(&pkgbase, f); let filter_provides = &|x: Vec<&str>| { x.into_iter() .filter(|f| !f_provides.contains(f)) .map(deb_feature) .collect() }; let (recommends, suggests) = match feature { Some(_) => (vec![], vec![]), None => (filter_provides(f_recommends), filter_provides(f_suggests)), }; // Provides for all possible versions, see: // https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=901827#35 // https://wiki.debian.org/Teams/RustPackaging/Policy#Package_provides let mut provides = vec![]; let version_suffixes = vec![ "".to_string(), format!("-{}", version.major), format!("-{}.{}", version.major, version.minor), format!("-{}.{}.{}", version.major, version.minor, version.patch), ]; for suffix in version_suffixes.iter() { let p = format!("{}{}", basename, suffix); provides.push(deb_feature2(&p, feature.unwrap_or(""))); provides.extend(f_provides.iter().map(|f| deb_feature2(&p, f))); } let provides_self = deb_feature(feature.unwrap_or("")); // rust dropped Vec::remove_item for annoying reasons, the below is // an unofficial recommended replacement from the RFC #40062 let i = provides.iter().position(|x| *x == *provides_self); i.map(|i| provides.remove(i)); let mut depends = vec!["${misc:Depends}".to_string()]; if feature.is_some() && !f_deps.contains(&"") { // in dh-cargo we symlink /usr/share/doc/{$feature => $main} pkg // so we always need this direct dependency, even if the feature // only indirectly depends on the bare library via another depends.push(deb_feature("")); } depends.extend(f_deps.into_iter().map(deb_feature)); depends.extend(o_deps); Ok(Package { name: match feature { None => deb_name(&pkgbase), Some(f) => deb_feature_name(&pkgbase, f), }, arch: "any".to_string(), // This is the best but not ideal option for us. // // Currently Debian M-A spec has a deficiency where a package X that // build-depends on a (M-A:foreign+arch:all) package that itself // depends on an arch:any package Z, will pick up the BUILD_ARCH of // package Z instead of the HOST_ARCH. This is because we currently // have no way of telling dpkg to use HOST_ARCH when checking that the // dependencies of Y are satisfied, which is done at install-time // without any knowledge that we're about to do a cross-compile. It // is also problematic to tell dpkg to "accept any arch" because of // the presence of non-M-A:same packages in the archive, that are not // co-installable - different arches of Z might be depended-upon by // two conflicting chains. (dpkg has so far chosen not to add an // exception for the case where package Z is M-A:same co-installable). // // The recommended work-around for now from the dpkg developers is to // make our packages arch:any M-A:same even though this results in // duplicate packages in the Debian archive. For very large crates we // will eventually want to make debcargo generate -data packages that // are arch:all and have the arch:any -dev packages depend on it. multi_arch: "same".to_string(), section: None, depends, recommends, suggests, provides, summary, description, extra_lines: match (name_suffix, feature) { (Some(_), None) => { let fullpkg = format!("{}-{}", basename, version); vec![ format!("Replaces: {}", deb_name(&fullpkg)), format!("Breaks: {}", deb_name(&fullpkg)), ] } (_, _) => vec![], }, }) } pub fn new_bin( basename: &str, name_suffix: Option<&str>, section: Option<&str>, summary: Description, description: Description, ) -> Self { let (name, mut provides) = match name_suffix { None => (basename.to_string(), vec![]), Some(suf) => ( format!("{}{}", basename, suf), vec![format!("{} (= ${{binary:Version}})", basename)], ), }; provides.push("${cargo:Provides}".to_string()); Package { name, arch: "any".to_string(), multi_arch: "allowed".to_string(), section: section.map(|s| s.to_string()), depends: vec![ "${misc:Depends}".to_string(), "${shlibs:Depends}".to_string(), "${cargo:Depends}".to_string(), ], recommends: vec!["${cargo:Recommends}".to_string()], suggests: vec!["${cargo:Suggests}".to_string()], provides, summary, description, extra_lines: vec![ "Built-Using: ${cargo:Built-Using}".to_string(), "XB-X-Cargo-Built-Using: ${cargo:X-Cargo-Built-Using}".to_string(), ], } } pub fn name(&self) -> &str { self.name.as_str() } fn write_description(&self, out: &mut fmt::Formatter) -> fmt::Result { writeln!(out, "Description: {}", &self.summary)?; let description = format!("{}", &self.description); for line in fill(description.trim(), 79).lines() { let line = line.trim_end(); if line.is_empty() { writeln!(out, " .")?; } else if line.starts_with("- ") { writeln!(out, " {}", line)?; } else { writeln!(out, " {}", line)?; } } Ok(()) } #[allow(clippy::result_unit_err)] pub fn summary_check_len(&self) -> std::result::Result<(), ()> { if self.summary.prefix.len() <= 80 { Ok(()) } else { Err(()) } } pub fn apply_overrides(&mut self, config: &Config, key: PackageKey, f_provides: Vec<&str>) { if let Some(section) = config.package_section(key) { self.section = Some(section.to_string()); } self.summary .apply_overrides(&config.summary, config.package_summary(key)); self.description .apply_overrides(&config.description, config.package_description(key)); self.depends.extend(config::package_field_for_feature( &|x| config.package_depends(x), key, &f_provides, )); self.recommends.extend(config::package_field_for_feature( &|x| config.package_recommends(x), key, &f_provides, )); self.suggests.extend(config::package_field_for_feature( &|x| config.package_suggests(x), key, &f_provides, )); self.provides.extend(config::package_field_for_feature( &|x| config.package_provides(x), key, &f_provides, )); self.extra_lines.extend( config .package_extra_lines(key) .into_iter() .flatten() .map(|s| s.to_string()), ); } } impl Description { fn apply_overrides(&mut self, global: &Option, per_package: Option<&str>) { if let Some(per_package) = per_package { self.prefix = per_package.to_string(); self.suffix = "".to_string(); } else if let Some(global) = &global { self.prefix = global.into(); } } } impl fmt::Display for Description { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}{}", &self.prefix, self.suffix) } } impl PkgTest { pub fn new( name: &str, crate_name: &str, feature: &str, version: &str, extra_test_args: Vec<&str>, depends: &[String], extra_restricts: Vec<&str>, ) -> Result { Ok(PkgTest { name: name.to_string(), crate_name: crate_name.to_string(), feature: feature.to_string(), version: version.to_string(), extra_test_args: extra_test_args.iter().map(|x| x.to_string()).collect(), depends: depends.to_vec(), extra_restricts: extra_restricts.iter().map(|x| x.to_string()).collect(), }) } } /// Translates a semver into a Debian-format upstream version. /// Omits the build metadata, and uses a ~ before the prerelease version so it /// compares earlier than the subsequent release. pub fn deb_upstream_version(v: &Version) -> String { let mut s = format!("{}.{}.{}", v.major, v.minor, v.patch); if !v.pre.is_empty() { write!(s, "~{}", v.pre.as_str()).unwrap(); } s } pub fn base_deb_name(crate_name: &str) -> String { crate_name.replace('_', "-").to_lowercase() } pub fn dsc_name(name: &str) -> String { format!("{}-{}", Source::pkg_prefix(), base_deb_name(name)) } pub fn deb_name(name: &str) -> String { format!("{}-{}-dev", Package::pkg_prefix(), base_deb_name(name)) } pub fn deb_feature_name(name: &str, feature: &str) -> String { format!( "{}-{}+{}-dev", Package::pkg_prefix(), base_deb_name(name), base_deb_name(feature) ) } /// Retrieve one of a series of environment variables, and provide a friendly error message for /// non-UTF-8 values. fn get_envs(keys: &[&str]) -> Result> { for key in keys { match env::var(key) { Ok(val) => { return Ok(Some(val)); } Err(e @ VarError::NotUnicode(_)) => { return Err(Error::from(e) .context(format!("Environment variable ${} not valid UTF-8", key))); } Err(VarError::NotPresent) => {} } } Ok(None) } /// Determine a name and email address from environment variables. pub fn get_deb_author() -> Result { let name = get_envs(&["DEBFULLNAME", "NAME"])?.ok_or_else(|| { format_err!("Unable to determine your name; please set $DEBFULLNAME or $NAME") })?; let email = get_envs(&["DEBEMAIL", "EMAIL"])?.ok_or_else(|| { format_err!("Unable to determine your email; please set $DEBEMAIL or $EMAIL") })?; Ok(format!("{} <{}>", name, email)) } debcargo-2.5.0/src/debian/copyright/tests.rs000064400000000000000000000057420072674642500171670ustar 00000000000000use super::{debian_copyright, get_licenses}; use std::path::Path; use std::rc::Rc; use cargo::{ core::{package::Package, SourceId}, util::{config::Config, toml::TomlManifest}, }; use toml::toml; #[test] fn check_get_licenses() { let test_data: &[(&str, &[(&str, bool)])] = &[ ("AGPL-3.0", &[("AGPL-3.0", true)]), ("AcmeCorp-1.0", &[("AcmeCorp-1.0", false)]), ("AGPL-3.0-or-later", &[("AGPL-3.0-or-later", true)]), ("Apache-2.0/MIT", &[("Apache-2.0", true), ("MIT", true)]), ("Apache-2.0 or MIT", &[("Apache-2.0", true), ("MIT", true)]), ( "FooBar-1.0 AND MIT", &[("FooBar-1.0", false), ("MIT", true)], ), ]; for (name, expected) in test_data { let licenses = get_licenses(name).expect("getting licenses failed"); let found: Vec<_> = licenses .iter() .map(|l| (l.name.as_str(), !l.text.starts_with("FIXME"))) .collect(); assert_eq!(&found[..], &expected[..]); } } #[test] fn check_debian_copyright_authors() { let checks = vec![ ( vec![], vec!["FIXME (overlay) UNKNOWN-AUTHORS FIXME (overlay) UNKNOWN-YEARS"], ), ( vec!["Jordan Doe"], vec!["FIXME (overlay) UNKNOWN-YEARS Jordan Doe"], ), ( vec!["Jordan Doe", "Jane Doe"], vec![ "FIXME (overlay) UNKNOWN-YEARS Jordan Doe", "FIXME (overlay) UNKNOWN-YEARS Jane Doe", ], ), ]; for (input, expected_output) in checks.into_iter() { let package = build_package_with_authors(input); let srcdir = tempfile::tempdir().unwrap(); let copyright = debian_copyright( srcdir.path(), package.manifest(), package.manifest_path(), "Jordan Doe", &[], (2000, 2020), false, ) .unwrap(); let mut generated = false; for file in ©right.files { if file.files == "*" { assert_eq!(file.copyright, expected_output); generated = true; } } assert!(generated); } } fn build_package_with_authors(authors: Vec<&str>) -> Package { let authors: Vec = authors.into_iter().map(|s| s.to_string()).collect(); let toml = toml! { [package] name = "mypackage" version = "1.2.3" authors = authors license = "AGPLv3" }; let toml_manifest: Rc = Rc::new(toml::from_str(&toml::to_string(&toml).unwrap()).unwrap()); let source_id = SourceId::for_path(Path::new("/path/to/mypackage")).unwrap(); let package_root = Path::new("/path/to/mypackage"); let config = Config::default().unwrap(); let manifest = TomlManifest::to_real_manifest(&toml_manifest, source_id, package_root, &config) .unwrap() .0; Package::new(manifest, Path::new("/path/to/manifest")) } debcargo-2.5.0/src/debian/copyright.rs000064400000000000000000000324060072674642500160220ustar 00000000000000use cargo::core::manifest; use chrono::{DateTime, Datelike, NaiveDateTime, Utc}; use git2::Repository; use regex; use tempfile; use textwrap::fill; use walkdir; use std::cmp::Ordering; use std::collections::BTreeMap; use std::env; use std::fmt; use std::fs; use std::io::{BufRead, BufReader, Read}; use std::path::Path; use crate::errors::*; const DEB_COPYRIGHT_FORMAT: &str = "\ https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/"; macro_rules! format_para { ($fmt: expr, $text:expr) => {{ for line in $text.lines() { let line = line.trim_end(); if line.is_empty() { writeln!($fmt, " .")?; } else { writeln!($fmt, " {}", line)?; } } write!($fmt, "") }}; } struct UpstreamInfo { name: String, contacts: Vec, source: String, } #[derive(Clone)] pub struct Files { files: String, copyright: Vec, license: String, comment: String, } #[derive(Clone)] struct License { name: String, text: String, } pub struct DebCopyright { format: String, upstream: UpstreamInfo, files: Vec, licenses: Vec, } impl fmt::Display for DebCopyright { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "Format: {}", self.format)?; write!(f, "{}", self.upstream)?; for file in &self.files { write!(f, "\n{}", file)?; } for license in &self.licenses { write!(f, "\n{}", license)?; } Ok(()) } } impl DebCopyright { fn new(u: UpstreamInfo, f: &[Files], l: &[License]) -> DebCopyright { DebCopyright { format: DEB_COPYRIGHT_FORMAT.to_string(), upstream: u, files: f.to_vec(), licenses: l.to_vec(), } } } impl fmt::Display for UpstreamInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "Upstream-Name: {}", self.name)?; write!(f, "Upstream-Contact:")?; if self.contacts.len() > 1 { writeln!(f)?; } for contact in &self.contacts { writeln!(f, " {}", contact)?; } if !self.source.is_empty() { writeln!(f, "Source: {}", self.source)?; } Ok(()) } } impl UpstreamInfo { fn new(name: String, authors: &[String], repo: &str) -> UpstreamInfo { assert!(!authors.is_empty()); UpstreamInfo { name, contacts: authors.to_vec(), source: repo.to_string(), } } } impl fmt::Display for Files { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "Files: {}", self.files)?; write!(f, "Copyright:")?; if self.copyright.len() > 1 { writeln!(f)?; } for copyright in &self.copyright { writeln!(f, " {}", copyright)?; } writeln!(f, "License: {}", self.license)?; if !self.comment.is_empty() { writeln!(f, "Comment:")?; format_para!(f, &self.comment)?; } Ok(()) } } impl Files { pub fn new(name: &str, notice: &[T], license: &str, comment: &str) -> Files { assert!(!notice.is_empty()); Files { files: name.to_string(), copyright: notice.iter().map(|s| s.to_string()).collect(), license: license.to_string(), comment: comment.to_string(), } } pub fn files(&self) -> &str { &self.files } pub fn license(&self) -> &str { &self.license } } impl fmt::Display for License { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!(f, "License: {}", self.name)?; format_para!(f, &self.text)?; Ok(()) } } impl License { fn new(name: String, text: String) -> License { License { name, text } } } macro_rules! default_files { ($file:expr, $notice:expr) => {{ let comment = concat!( "FIXME (overlay): These notices are extracted from files. Please ", "review them before uploading to the archive." ); Files::new( $file, $notice, "UNKNOWN-LICENSE; FIXME (overlay)", &fill(comment, 79), ) }}; } fn gen_files(debsrcdir: &Path) -> Result> { let mut copyright_notices = BTreeMap::new(); let copyright_notice_re = regex::Regex::new(r"(?:[Cc]opyright|©)(?:\s|[©:,()Cc<])*\b(\d{4}\b.*)$")?; // Get current working directory and move inside the extracted source of // crate. This is necessary so as to capture correct path for files in // debian/copyright. let current_dir = env::current_dir()?; env::set_current_dir(debsrcdir)?; // Here we specifically use "." to avoid absolute paths. If we use // current_dir then we end up having absolute path from user home directory, // which again messes debian/copyright. // Use of . creates paths in format ./src/ which is acceptable. for entry in walkdir::WalkDir::new(".").sort_by(|a, b| a.file_name().cmp(b.file_name())) { let entry = entry?; if entry.file_type().is_file() { let copyright_file = entry.path().to_str().unwrap().to_string(); let file = fs::File::open(entry.path())?; let reader = BufReader::new(file); for line in reader.lines() { if let Ok(line) = line { if let Some(m) = copyright_notice_re.captures(&line) { let m = m.get(1).unwrap(); let start = m.start(); let end = m.end(); let notice = line[start..end] .trim_end() .trim_end_matches(". See the COPYRIGHT") .to_string(); if !copyright_notices.contains_key(©right_file) { copyright_notices.insert(copyright_file.clone(), vec![]); } copyright_notices .get_mut(©right_file) .unwrap() .push(notice); } } else { break; } } } } // Restore back to original working directory as we can continue without // problems. env::set_current_dir(current_dir.as_path())?; let mut notices: Vec = Vec::new(); for (filename, notice) in ©right_notices { notices.push(default_files!(filename, notice)); } Ok(notices) } fn get_licenses(license: &str) -> Result> { let mut licenses = BTreeMap::new(); let sep = regex::Regex::new(r"(?i:(\s(or|and)\s|/))")?; let known_licenses = vec![ ("agpl-3.0", include_str!("licenses/AGPL-3.0")), ("apache-2.0", include_str!("licenses/Apache-2.0")), ("bsd-2-clause", include_str!("licenses/BSD-2-Clause")), ("bsd-3-clause", include_str!("licenses/BSD-3-Clause")), ("cc0-1.0", include_str!("licenses/CC0-1.0")), ("gpl-2.0", include_str!("licenses/GPL-2.0")), ("gpl-3.0", include_str!("licenses/GPL-3.0")), ("isc", include_str!("licenses/ISC")), ("lgpl-2.0", include_str!("licenses/LGPL-2.0")), ("lgpl-2.1", include_str!("licenses/LGPL-2.1")), ("lgpl-3.0", include_str!("licenses/LGPL-3.0")), ("mit", include_str!("licenses/MIT")), ("mitnfa", include_str!("licenses/MITNFA")), ("mpl-1.1", include_str!("licenses/MPL-1.1")), ("mpl-2.0", include_str!("licenses/MPL-2.0")), ("unlicense", include_str!("licenses/Unlicense")), ("zlib", include_str!("licenses/Zlib")), ] .into_iter() .collect::>(); let lses: Vec<&str> = sep.split(license).filter(|s| !s.is_empty()).collect(); for ls in lses { let lname = ls .trim() .to_lowercase() .trim_end_matches('+') .trim_end_matches("-or-later") .to_string(); let text = match known_licenses.get(lname.as_str()) { Some(s) => s.to_string(), None => "FIXME (overlay): Unrecognized crate license, please find the \ full license text in the rest of the crate source code and \ copy-paste it here" .to_string(), }; licenses.insert(ls.trim().to_string(), text); } let mut lblocks: Vec = Vec::new(); if !licenses.is_empty() { for (l, t) in licenses { lblocks.push(License::new(l, t)); } } Ok(lblocks) } fn copyright_fromgit(repo_url: &str) -> Result { let tempdir = tempfile::Builder::new() .prefix("debcargo") .tempdir_in(".")?; let repo = Repository::clone(repo_url, tempdir.path())?; let mut revwalker = repo.revwalk()?; revwalker.push_head()?; // Get the latest and first commit id. This is bit ugly let latest_id = revwalker.next().unwrap()?; let first_id = revwalker.last().unwrap()?; // revwalker ends here is consumed by last let first_commit = repo.find_commit(first_id)?; let latest_commit = repo.find_commit(latest_id)?; let first_year = DateTime::::from_utc( NaiveDateTime::from_timestamp(first_commit.time().seconds(), 0), Utc, ) .year(); let latest_year = DateTime::::from_utc( NaiveDateTime::from_timestamp(latest_commit.time().seconds(), 0), Utc, ) .year(); let notice = match first_year.cmp(&latest_year) { Ordering::Equal => format!("{}", first_year), _ => format!("{}-{},", first_year, latest_year), }; Ok(notice) } pub fn debian_copyright( srcdir: &Path, manifest: &manifest::Manifest, manifest_path: &Path, maintainer: &str, uploaders: &[&str], year_range: (i32, i32), guess_harder: bool, ) -> Result { let meta = manifest.metadata().clone(); let repository = match meta.repository { None => "", Some(ref r) => r, }; // The Authors field is optional according to // https://rust-lang.github.io/rfcs/3052-optional-authors-field.html // and crates.io publishes crates without the field already. let unknown_authors = vec!["FIXME (overlay) UNKNOWN-AUTHORS".to_string()]; let authors = if meta.authors.is_empty() { &unknown_authors } else { &meta.authors }; let upstream = UpstreamInfo::new(manifest.name().to_string(), authors, repository); let mut licenses: Vec = Vec::new(); let mut crate_license: String = "".to_string(); if let Some(ref license_file_name) = meta.license_file { let license_file = manifest_path.with_file_name(license_file_name); let mut text = Vec::new(); fs::File::open(license_file)?.read_to_end(&mut text)?; licenses.reserve(1); let stext = String::from_utf8(text)?; licenses.push(License::new( "UNKNOWN-LICENSE; FIXME (overlay)".to_string(), stext, )); } else if let Some(ref license) = meta.license { licenses = get_licenses(license).unwrap(); crate_license = license .trim() .replace("/", " or ") .replace(" OR ", " or ") .replace(" AND ", " and "); } else { debcargo_bail!("Crate has no license or license_file"); } let mut files = gen_files(srcdir)?; let (y0, y1) = year_range; let years = if y0 == y1 { format!("{}", y0) } else { format!("{}-{}", y0, y1) }; let mut deb_notice = vec![format!("{} {}", years, maintainer)]; deb_notice.extend(uploaders.iter().map(|s| format!("{} {}", years, s))); files.push(Files::new("debian/*", &deb_notice, &crate_license, "")); // Insert catch all block as the first block of copyright file. Capture // copyright notice from git log of the upstream repository. let years = if guess_harder && !repository.is_empty() { match copyright_fromgit(repository) { Ok(x) => x, Err(e) => { debcargo_warn!( "Failed to generate d/copyright from git repository {}: {}\n", repository, e ); "FIXME (overlay) UNKNOWN-YEARS".to_string() } } } else { "FIXME (overlay) UNKNOWN-YEARS".to_string() }; let notice = match meta.authors.len() { 0 => vec![format!("FIXME (overlay) UNKNOWN-AUTHORS {}", years)], 1 => vec![format!("{} {}", years, &meta.authors[0])], _ => meta .authors .iter() .map(|s| format!("{} {}", years, s)) .collect(), }; let comment = concat!( "FIXME (overlay): Since upstream copyright years are not available ", "in Cargo.toml, they were extracted from the upstream Git ", "repository. This may not be correct information so you should ", "review and fix this before uploading to the archive." ); files.insert( 0, Files::new("*", notice.as_slice(), &crate_license, &fill(comment, 79)), ); Ok(DebCopyright::new(upstream, &files, &licenses)) } #[cfg(test)] mod tests; debcargo-2.5.0/src/debian/dependency.rs000064400000000000000000000246770072674642500161430ustar 00000000000000use cargo::core::Dependency; use itertools::Itertools; use std::cmp; use std::fmt; use crate::config::{testing_ignore_debpolv, Config}; use crate::debian::{self, control::base_deb_name, Package}; use crate::errors::*; #[derive(Eq, Clone)] #[allow(clippy::upper_case_acronyms)] enum V { M(u64), MM(u64, u64), MMP(u64, u64, u64), } impl V { fn new(p: &semver::Comparator) -> Result { use self::V::*; let mmp = match (p.minor, p.patch) { (None, None) => M(p.major), (Some(minor), None) => MM(p.major, minor), (Some(minor), Some(patch)) => MMP(p.major, minor, patch), (None, Some(_)) => debcargo_bail!("semver had patch without minor"), }; Ok(mmp) } fn inclast(&self) -> V { use self::V::*; match *self { M(major) => M(major + 1), MM(major, minor) => MM(major, minor + 1), MMP(major, minor, patch) => MMP(major, minor, patch + 1), } } fn mmp(&self) -> (u64, u64, u64) { use self::V::*; match *self { M(major) => (major, 0, 0), MM(major, minor) => (major, minor, 0), MMP(major, minor, patch) => (major, minor, patch), } } } impl cmp::Ord for V { fn cmp(&self, other: &V) -> cmp::Ordering { self.partial_cmp(other).unwrap() } } impl cmp::PartialOrd for V { fn partial_cmp(&self, other: &V) -> Option { self.mmp().partial_cmp(&other.mmp()) } } impl cmp::PartialEq for V { fn eq(&self, other: &V) -> bool { self.mmp() == other.mmp() } } impl fmt::Display for V { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::V::*; match *self { M(major) => write!(f, "{}", major), MM(major, minor) => write!(f, "{}.{}", major, minor), MMP(major, minor, patch) => write!(f, "{}.{}.{}", major, minor, patch), } } } struct VRange { ge: Option, lt: Option, } impl VRange { fn new() -> Self { VRange { ge: None, lt: None } } fn constrain_ge(&mut self, ge: V) -> &Self { match self.ge { Some(ref ge_) if &ge < ge_ => (), _ => self.ge = Some(ge), }; self } fn constrain_lt(&mut self, lt: V) -> &Self { match self.lt { Some(ref lt_) if < >= lt_ => (), _ => self.lt = Some(lt), }; self } fn to_deb_or_clause(&self, base: &str, suffix: &str) -> Result { use debian::dependency::V::*; match (&self.ge, &self.lt) { (None, None) => Ok(format!("{}{}", base, suffix)), (Some(ge), None) => Ok(format!("{}{} (>= {}-~~)", base, suffix, ge)), (None, Some(lt)) => Ok(format!("{}{} (<< {}-~~)", base, suffix, lt)), (Some(ge), Some(lt)) => { if ge >= lt { debcargo_bail!("bad version range: >= {}, << {}", ge, lt); } let mut ranges = vec![]; let (lt_maj, lt_min, lt_pat) = lt.mmp(); let (ge_maj, ge_min, ge_pat) = ge.mmp(); if ge_maj < lt_maj { ranges.push((M(ge_maj), Some((true, ge)))); ranges.extend((ge_maj + 1..lt_maj).map(|maj| (M(maj), None))); ranges.push((M(lt_maj), Some((false, lt)))); } else { assert!(ge_maj == lt_maj); if ge_min < lt_min { ranges.push((MM(ge_maj, ge_min), Some((true, ge)))); ranges.extend((ge_min + 1..lt_min).map(|min| (MM(ge_maj, min), None))); ranges.push((MM(lt_maj, lt_min), Some((false, lt)))); } else { assert!(ge_min == lt_min); ranges.push((MMP(ge_maj, ge_min, ge_pat), Some((true, ge)))); ranges.extend( (ge_pat + 1..lt_pat).map(|pat| (MMP(ge_maj, ge_min, pat), None)), ); ranges.push((MMP(lt_maj, lt_min, lt_pat), Some((false, lt)))); } }; // reverse the order so higher versions go first // this helps sbuild find build-deps, it does not resolve alternatives by default Ok(ranges .iter() .rev() .filter_map(|(ver, cons)| match cons { None => Some(format!("{}-{}{}", base, ver, suffix)), Some((true, c)) => { if c == &ver { // A-x >= x is redundant, drop the >= Some(format!("{}-{}{}", base, ver, suffix)) } else { Some(format!("{}-{}{} (>= {}-~~)", base, ver, suffix, c)) } } Some((false, c)) => { if c == &ver { // A-x << x is unsatisfiable, drop it None } else { Some(format!("{}-{}{} (<< {}-~~)", base, ver, suffix, c)) } } }) .join(" | ")) } } } } fn coerce_unacceptable_predicate<'a>( dep: &Dependency, p: &'a semver::Comparator, allow_prerelease_deps: bool, ) -> Result<&'a semver::Op> { let mmp = &V::new(p)?; // Cargo/semver and Debian handle pre-release versions quite // differently, so a versioned Debian dependency cannot properly // handle pre-release crates. This might be OK most of the time, // coerce it to the non-pre-release version. if !p.pre.is_empty() { if allow_prerelease_deps || testing_ignore_debpolv() { debcargo_warn!( "Coercing removal of prerelease part of dependency: {} {:?}", dep.package_name(), p ) } else { debcargo_bail!( "Cannot represent prerelease part of dependency: {} {:?}", dep.package_name(), p ) } } use debian::dependency::V::M; use semver::Op::*; match (&p.op, mmp) { (&Greater, &M(0)) => Ok(&p.op), (&GreaterEq, &M(0)) => { debcargo_warn!( "Coercing unrepresentable dependency version predicate 'GtEq 0' to 'Gt 0': {} {:?}", dep.package_name(), p ); Ok(&Greater) } // TODO: This will prevent us from handling wildcard dependencies with // 0.0.0* so for now commenting this out. // (_, &M(0)) => debcargo_bail!( // "Unrepresentable dependency version predicate: {} {:?}", // dep.package_name(), // p // ), (_, _) => Ok(&p.op), } } fn generate_version_constraints( vr: &mut VRange, dep: &Dependency, p: &semver::Comparator, op: &semver::Op, ) -> Result<()> { let mmp = V::new(p)?; use debian::dependency::V::*; use semver::Op::*; // see https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html // and https://docs.rs/semver/1/semver/enum.Op.html for semantics match (*op, &mmp) { (Less, &M(0)) | (Less, &MM(0, 0)) | (Less, &MMP(0, 0, 0)) => debcargo_bail!( "Unrepresentable dependency version predicate: {} {:?}", dep.package_name(), p ), (Less, _) => { vr.constrain_lt(mmp); } (LessEq, _) => { vr.constrain_lt(mmp.inclast()); } (Greater, _) => { vr.constrain_ge(mmp.inclast()); } (GreaterEq, _) => { vr.constrain_ge(mmp); } (Exact, _) | (Wildcard, _) => { vr.constrain_lt(mmp.inclast()); vr.constrain_ge(mmp); } (Tilde, &M(_)) | (Tilde, &MM(_, _)) => { vr.constrain_lt(mmp.inclast()); vr.constrain_ge(mmp); } (Tilde, &MMP(major, minor, _)) => { vr.constrain_lt(MM(major, minor + 1)); vr.constrain_ge(mmp); } (Caret, &MMP(0, 0, _)) => { vr.constrain_lt(mmp.inclast()); vr.constrain_ge(mmp); } (Caret, &MMP(0, minor, _)) | (Caret, &MM(0, minor)) => { vr.constrain_lt(MM(0, minor + 1)); vr.constrain_ge(mmp); } (Caret, &MMP(major, _, _)) | (Caret, &MM(major, _)) | (Caret, &M(major)) => { vr.constrain_lt(M(major + 1)); vr.constrain_ge(mmp); } (_, _) => { // https://github.com/dtolnay/semver/issues/262 panic!("Op is non-exhuastive for some reason"); } } Ok(()) } /// Translates a Cargo dependency into a Debian package dependency. pub fn deb_dep(config: &Config, dep: &Dependency) -> Result> // result is a AND-clause { let dep_dashed = base_deb_name(&dep.package_name()); let mut suffixes = Vec::new(); if dep.uses_default_features() { suffixes.push("+default-dev".to_string()); } for feature in dep.features() { suffixes.push(format!("+{}-dev", base_deb_name(feature))); } if suffixes.is_empty() { suffixes.push("-dev".to_string()); } let req = semver::VersionReq::parse(&dep.version_req().to_string()).unwrap(); let mut deps = Vec::new(); for suffix in suffixes { let base = format!("{}-{}", Package::pkg_prefix(), dep_dashed); let mut vr = VRange::new(); for p in &req.comparators { let op = coerce_unacceptable_predicate(dep, p, config.allow_prerelease_deps)?; generate_version_constraints(&mut vr, dep, p, op)?; } deps.push(vr.to_deb_or_clause(&base, &suffix)?); } Ok(deps) } pub fn deb_deps(config: &Config, cdeps: &[Dependency]) -> Result> // result is a AND-clause { let mut deps = Vec::new(); for dep in cdeps { deps.extend(deb_dep(config, dep)?.iter().map(String::to_string)); } deps.sort(); deps.dedup(); Ok(deps) } pub fn deb_dep_add_nocheck(x: &str) -> String { x.to_string() .split('|') .map(|x| x.trim_end().to_string() + " ") .join("|") .trim_end() .to_string() } debcargo-2.5.0/src/debian/licenses/AGPL-3.0000064400000000000000000001033300072674642500162100ustar 00000000000000 GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . debcargo-2.5.0/src/debian/licenses/Apache-2.0000064400000000000000000000001270072674642500166450ustar 00000000000000Debian systems provide the Apache 2.0 license in /usr/share/common-licenses/Apache-2.0 debcargo-2.5.0/src/debian/licenses/BSD-2-Clause000064400000000000000000000023240072674642500171510ustar 00000000000000Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. debcargo-2.5.0/src/debian/licenses/BSD-3-Clause000064400000000000000000000026240072674642500171550ustar 00000000000000Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. debcargo-2.5.0/src/debian/licenses/CC0-1.0000064400000000000000000000001330072674642500160250ustar 00000000000000Debian systems provide the CC0 1.0 Universal License in /usr/share/common-licenses/CC0-1.0 debcargo-2.5.0/src/debian/licenses/GPL-2.0000064400000000000000000000001070072674642500161040ustar 00000000000000Debian systems provide the GPL 2.0 in /usr/share/common-licenses/GPL-2 debcargo-2.5.0/src/debian/licenses/GPL-3.0000064400000000000000000000001070072674642500161050ustar 00000000000000Debian systems provide the GPL 3.0 in /usr/share/common-licenses/GPL-3 debcargo-2.5.0/src/debian/licenses/ISC000064400000000000000000000012710072674642500156060ustar 00000000000000Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. debcargo-2.5.0/src/debian/licenses/LGPL-2.0000064400000000000000000000001110072674642500162130ustar 00000000000000Debian systems provide the LGPL 2.0 in /usr/share/common-licenses/LGPL-2 debcargo-2.5.0/src/debian/licenses/LGPL-2.1000064400000000000000000000001130072674642500162160ustar 00000000000000Debian systems provide the LGPL 2.1 in /usr/share/common-licenses/LGPL-2.1 debcargo-2.5.0/src/debian/licenses/LGPL-3.0000064400000000000000000000001110072674642500162140ustar 00000000000000Debian systems provide the LGPL 3.0 in /usr/share/common-licenses/LGPL-3 debcargo-2.5.0/src/debian/licenses/MIT000064400000000000000000000020000072674642500156100ustar 00000000000000Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. debcargo-2.5.0/src/debian/licenses/MITNFA000064400000000000000000000027730072674642500161560ustar 00000000000000Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. Distributions of all or part of the Software intended to be used by the recipients as they would use the unmodified Software, containing modifications that substantially alter, remove, or disable functionality of the Software, outside of the documented configuration mechanisms provided by the Software, shall be modified such that the Original Author's bug reporting email addresses and urls are either replaced with the contact information of the parties responsible for the changes, or removed entirely. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. debcargo-2.5.0/src/debian/licenses/MPL-1.1000064400000000000000000000001110072674642500161050ustar 00000000000000Debian systems provide the MPL 1.1 in /usr/share/common-licenses/MPL-1.1 debcargo-2.5.0/src/debian/licenses/MPL-2.0000064400000000000000000000001110072674642500161050ustar 00000000000000Debian systems provide the MPL 2.0 in /usr/share/common-licenses/MPL-2.0 debcargo-2.5.0/src/debian/licenses/Unlicense000064400000000000000000000021740072674642500171200ustar 00000000000000This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. debcargo-2.5.0/src/debian/licenses/Zlib000064400000000000000000000014630072674642500160730ustar 00000000000000This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. debcargo-2.5.0/src/debian/mod.rs000064400000000000000000001301340072674642500145660ustar 00000000000000use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::fs; use std::io::{self, ErrorKind, Read, Seek, Write as IoWrite}; use std::os::unix::fs::PermissionsExt; use std::path::{Path, PathBuf}; use std::process::Command; use std::str::FromStr; use anyhow::format_err; use chrono::{self, Datelike}; use flate2::read::GzDecoder; use flate2::write::GzEncoder; use flate2::Compression; use regex::Regex; use tar::{Archive, Builder}; use tempfile; use crate::config::{package_field_for_feature, testing_ignore_debpolv, Config, PackageKey}; use crate::crates::{show_dep, transitive_deps, CrateDepInfo, CrateInfo}; use crate::errors::*; use crate::util::{self, copy_tree, expect_success, get_transitive_val, traverse_depth}; use self::changelog::{ChangelogEntry, ChangelogIterator}; use self::control::{base_deb_name, deb_upstream_version}; use self::control::{Description, Package, PkgTest, Source}; use self::copyright::debian_copyright; pub use self::dependency::{deb_dep_add_nocheck, deb_deps}; pub mod changelog; pub mod control; pub mod copyright; mod dependency; pub struct DebInfo { upstream_name: String, /// Debian package name without rust- prefix or any semver suffix base_package_name: String, /// Package name suffix after the base package name. /// Some implies semver_suffix, i.e. Some("") is different from None name_suffix: Option, uscan_version_pattern: Option, /// Debian package name without rust- prefix package_name: String, deb_upstream_version: String, debcargo_version: String, package_source_dir: PathBuf, orig_tarball_path: PathBuf, } impl DebInfo { pub fn new(crate_info: &CrateInfo, debcargo_version: &str, semver_suffix: bool) -> Self { let upstream_name = crate_info.package_id().name().to_string(); let name_dashed = base_deb_name(&upstream_name); let base_package_name = name_dashed.to_lowercase(); let (name_suffix, uscan_version_pattern, package_name) = if semver_suffix { let semver = crate_info.semver(); let name_suffix = format!("-{}", &semver); // See `man uscan` description of @ANY_VERSION@ on how these // regex patterns were built. let uscan = format!("[-_]?({}\\.\\d[\\-+\\.:\\~\\da-zA-Z]*)", &semver); let pkgname = format!("{}{}", base_package_name, &name_suffix); (Some(name_suffix), Some(uscan), pkgname) } else { (None, None, base_package_name.clone()) }; let deb_upstream_version = deb_upstream_version(crate_info.version()); let package_source_dir = PathBuf::from(format!( "{}-{}-{}", Source::pkg_prefix(), package_name, deb_upstream_version )); let orig_tarball_path = PathBuf::from(format!( "{}-{}_{}.orig.tar.gz", Source::pkg_prefix(), package_name, deb_upstream_version )); DebInfo { upstream_name, base_package_name, name_suffix, uscan_version_pattern, package_name, deb_upstream_version, debcargo_version: debcargo_version.to_string(), package_source_dir, orig_tarball_path, } } pub fn upstream_name(&self) -> &str { self.upstream_name.as_str() } pub fn base_package_name(&self) -> &str { self.base_package_name.as_str() } pub fn name_suffix(&self) -> Option<&str> { self.name_suffix.as_deref() } pub fn package_name(&self) -> &str { self.package_name.as_str() } pub fn deb_upstream_version(&self) -> &str { self.deb_upstream_version.as_str() } pub fn debcargo_version(&self) -> &str { self.debcargo_version.as_str() } pub fn package_source_dir(&self) -> &Path { self.package_source_dir.as_ref() } pub fn orig_tarball_path(&self) -> &Path { self.orig_tarball_path.as_ref() } } pub fn prepare_orig_tarball( crate_info: &CrateInfo, tarball: &Path, src_modified: bool, output_dir: &Path, ) -> Result<()> { let crate_file = crate_info.crate_file(); let tempdir = tempfile::Builder::new() .prefix("debcargo") .tempdir_in(".")?; let temp_archive_path = tempdir.path().join(tarball); let mut create = fs::OpenOptions::new(); create.write(true).create_new(true); if src_modified { debcargo_info!("crate tarball was modified; repacking for debian"); let mut f = crate_file.file(); f.seek(io::SeekFrom::Start(0))?; let mut archive = Archive::new(GzDecoder::new(f)); let mut new_archive = Builder::new(GzEncoder::new( create.open(&temp_archive_path)?, Compression::best(), )); for entry in archive.entries()? { let entry = entry?; let path = entry.path()?.into_owned(); if path.ends_with("Cargo.toml") && path.iter().count() == 2 { // Put the rewritten and original Cargo.toml back into the orig tarball let mut new_archive_append = |name: &str| { let mut header = entry.header().clone(); let srcpath = output_dir.join(name); header.set_path(path.parent().unwrap().join(name))?; header.set_size(fs::metadata(&srcpath)?.len()); header.set_cksum(); new_archive.append(&header, fs::File::open(&srcpath)?) }; new_archive_append("Cargo.toml")?; new_archive_append("Cargo.toml.orig")?; } else { match crate_info.filter_path(&entry.path()?) { Err(e) => debcargo_bail!(e), Ok(r) => { if !r { new_archive.append(&entry.header().clone(), entry)?; } else { writeln!( io::stderr(), "Filtered out files from .orig.tar.gz: {:?}", &entry.path()? )?; } } } } } new_archive.finish()?; } else { fs::copy(crate_file.path(), &temp_archive_path)?; } fs::rename(temp_archive_path, &tarball)?; Ok(()) } pub fn apply_overlay_and_patches( crate_info: &mut CrateInfo, config_path: Option<&Path>, config: &Config, output_dir: &Path, ) -> Result { let tempdir = tempfile::Builder::new() .prefix("debcargo") .tempdir_in(".")?; let overlay = config.overlay_dir(config_path); if let Some(p) = overlay.as_ref() { for anc in tempdir.path().ancestors() { if p.as_path() == anc { debcargo_bail!( "Aborting: refusing to copy an ancestor {} into a descendant {}", p.as_path().display(), tempdir.path().display(), ); } } copy_tree(p.as_path(), tempdir.path()).unwrap(); } if tempdir.path().join("control").exists() { debcargo_warn!( "Most of the time you shouldn't overlay debian/control, \ it's a maintenance burden. Use debcargo.toml instead." ) } if tempdir.path().join("patches").join("series").exists() { // apply patches to Cargo.toml in case they exist, and re-read it let output_dir = &fs::canonicalize(&output_dir)?; let stderr = || { // create a new owned handle to stderr fs::OpenOptions::new() .append(true) .open("/dev/stderr") .unwrap() }; expect_success( Command::new("quilt") .stdout(stderr()) .current_dir(&output_dir) .env("QUILT_PATCHES", tempdir.path().join("patches")) .args(&["push", "--quiltrc=-", "-a"]), "failed to apply patches", ); crate_info.replace_manifest(&output_dir.join("Cargo.toml"))?; expect_success( Command::new("quilt") .stdout(stderr()) .current_dir(&output_dir) .env("QUILT_PATCHES", tempdir.path().join("patches")) .args(&["pop", "--quiltrc=-", "-a"]), "failed to unapply patches", ); } Ok(tempdir) } #[allow(clippy::too_many_arguments)] pub fn prepare_debian_folder( crate_info: &mut CrateInfo, deb_info: &DebInfo, config_path: Option<&Path>, config: &Config, output_dir: &Path, tempdir: &tempfile::TempDir, changelog_ready: bool, copyright_guess_harder: bool, overlay_write_back: bool, ) -> Result<()> { let mut create = fs::OpenOptions::new(); create.write(true).create_new(true); let crate_name = crate_info.package_id().name(); let crate_version = crate_info.package_id().version(); let upstream_name = deb_info.upstream_name(); let maintainer = config.maintainer(); let uploaders: Vec<&str> = config .uploaders() .into_iter() .flatten() .map(String::as_str) .collect(); let mut new_hints = vec![]; let mut file = |name: &str| { let path = tempdir.path(); let f = path.join(name); fs::create_dir_all(f.parent().unwrap())?; create.open(&f).or_else(|e| match e.kind() { ErrorKind::AlreadyExists => { let hintname = name.to_owned() + util::HINT_SUFFIX; let hint = path.join(&hintname); if hint.exists() { fs::remove_file(&hint)?; } new_hints.push(hintname); create.open(&hint) } _ => Err(e), }) }; // debian/cargo-checksum.json { let checksum = crate_info .checksum() .unwrap_or("Could not get crate checksum"); let mut cargo_checksum_json = file("cargo-checksum.json")?; writeln!( cargo_checksum_json, r#"{{"package":"{}","files":{{}}}}"#, checksum )?; } // debian/compat { let mut compat = file("compat")?; writeln!(compat, "12")?; } // debian/copyright { let mut copyright = io::BufWriter::new(file("copyright")?); let year_range = if changelog_ready { // if changelog is ready, unconditionally read the year range from it changelog_first_last(tempdir.path())? } else { // otherwise use the first date if it exists let last = chrono::Local::now().year(); match changelog_first_last(tempdir.path()) { Ok((first, _)) => (first, last), Err(_) => (last, last), } }; let dep5_copyright = debian_copyright( output_dir, crate_info.manifest(), crate_info.manifest_path(), maintainer, &uploaders, year_range, copyright_guess_harder, )?; write!(copyright, "{}", dep5_copyright)?; } // debian/watch { let mut watch = file("watch")?; match config.crate_src_path(config_path) { Some(_) => write!(watch, "FIXME add uscan directive for local crate")?, None => { let uscan_version_pattern = deb_info .uscan_version_pattern .as_ref() .map_or_else(|| "@ANY_VERSION@".to_string(), |ref s| s.to_string()); writeln!(watch, "version=4")?; writeln!( watch, r"opts=filenamemangle=s/.*\/(.*)\/download/{name}-$1\.tar\.gz/g,\", name = upstream_name )?; writeln!( watch, r"uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)\d*)$/$1~$2/ \" )?; writeln!( watch, "https://qa.debian.org/cgi-bin/fakeupstream.cgi?upstream=crates.io/{name} \ .*/crates/{name}/{version_pattern}/download", name = upstream_name, version_pattern = uscan_version_pattern )?; } }; } // debian/source/format { fs::create_dir_all(tempdir.path().join("source"))?; let mut source_format = file("source/format")?; writeln!(source_format, "3.0 (quilt)")?; } // debian/control & debian/tests/control let (source, has_dev_depends, default_test_broken) = prepare_debian_control(deb_info, crate_info, config, &mut file)?; // for testing only, debian/debcargo_testing_bin/env if testing_ignore_debpolv() { fs::create_dir_all(tempdir.path().join("debcargo_testing_bin"))?; let mut env_hack = file("debcargo_testing_bin/env")?; env_hack.set_permissions(fs::Permissions::from_mode(0o777))?; // intercept calls to dh-cargo-built-using writeln!( env_hack, r#"#!/bin/sh case "$*" in */usr/share/cargo/bin/dh-cargo-built-using*) echo "debcargo testing: suppressing dh-cargo-built-using";; *) /usr/bin/env "$@";; esac "# )?; } // debian/rules { let mut rules = file("rules")?; rules.set_permissions(fs::Permissions::from_mode(0o777))?; if has_dev_depends || testing_ignore_debpolv() { // don't run any tests, we don't want extra B-D on dev-depends // this could potentially cause B-D cycles so we avoid it // // also don't run crate tests during integration testing since some // of them are brittle and fail; the purpose is to test debcargo // not the actual crates write!( rules, "{}", concat!( "#!/usr/bin/make -f\n", "%:\n", "\tdh $@ --buildsystem cargo\n" ) )?; // some crates need nightly to compile, annoyingly. only do this in // testing; outside of testing the user should explicitly override // debian/rules to do this if testing_ignore_debpolv() { writeln!(rules, "export RUSTC_BOOTSTRAP := 1")?; writeln!( rules, "export PATH := $(CURDIR)/debian/debcargo_testing_bin:$(PATH)" )?; } } else { write!( rules, "{}{}", concat!( "#!/usr/bin/make -f\n", "%:\n", "\tdh $@ --buildsystem cargo\n", "\n", "override_dh_auto_test:\n", ), // TODO: this logic is slightly brittle if another feature // "provides" the default feature. In this case, you need to // set test_is_broken explicitly on package."lib+default" and // not package."lib+theotherfeature". if default_test_broken { "\tdh_auto_test -- test --all || true\n" } else { "\tdh_auto_test -- test --all\n" }, )?; } } // debian/changelog if !changelog_ready { let author = control::get_deb_author()?; let crate_src = match config.crate_src_path(config_path) { Some(_) => "local source", None => "crates.io", }; let autogenerated_item = format!( " * Package {} {} from {} using debcargo {}", &crate_name, &crate_version, &crate_src, deb_info.debcargo_version() ); let autogenerated_re = Regex::new(&format!( r"^ \* Package (.*) (.*) from {} using debcargo (.*)$", &crate_src )) .unwrap(); // Special-case d/changelog: let (mut changelog, changelog_data) = changelog_or_new(tempdir.path())?; let (changelog_old, mut changelog_items, deb_version_suffix) = { let ver_bump = &|e: &Option<&str>| -> Result> { Ok(match e { Some(x) => { let e = ChangelogEntry::from_str(x)?; if e.version_parts().0 == deb_info.deb_upstream_version() { Some(e.deb_version_suffix_bump()) } else { None } } None => None, }) }; let mut chit = ChangelogIterator::from(&changelog_data); let e1 = chit.next(); match e1 { // If the first entry has changelog::DEFAULT_DIST then write over it smartly Some(x) if x.contains(changelog::DEFAULT_DIST) => { let mut e = ChangelogEntry::from_str(x)?; if author == e.maintainer { if let Some(pos) = e.items.iter().position(|x| autogenerated_re.is_match(x)) { e.items[pos] = autogenerated_item; } else { e.items.push(autogenerated_item); } } else { // If unreleased changelog is by someone else, preserve their entries e.items.insert(0, autogenerated_item); e.items.insert(1, "".to_string()); let ename = e.maintainer_name(); e.items.insert(2, format!(" [ {} ]", ename)); } (&changelog_data[x.len()..], e.items, ver_bump(&chit.next())?) } // Otherwise prepend a new entry to the existing entries _ => ( changelog_data.as_str(), vec![autogenerated_item], ver_bump(&e1)?, ), } }; let source_deb_version = format!( "{}-{}", deb_info.deb_upstream_version(), &deb_version_suffix.unwrap_or_else(|| "1".to_string()) ); if !uploaders.contains(&author.as_str()) { debcargo_warn!( "You ({}) are not in Uploaders; adding \"Team upload\" to d/changelog", author ); if !changelog_items.contains(&changelog::COMMENT_TEAM_UPLOAD.to_string()) { changelog_items.insert(0, changelog::COMMENT_TEAM_UPLOAD.to_string()); } } let changelog_new_entry = ChangelogEntry::new( source.name().to_string(), source_deb_version, changelog::DEFAULT_DIST.to_string(), "urgency=medium".to_string(), author, changelog::local_now(), changelog_items, ); changelog.seek(io::SeekFrom::Start(0))?; if changelog_old.is_empty() { write!(changelog, "{}", changelog_new_entry)?; } else { write!(changelog, "{}\n{}", changelog_new_entry, changelog_old)?; } // the new file might be shorter, truncate it to the current cursor position let pos = changelog.seek(io::SeekFrom::Current(0))?; changelog.set_len(pos)?; } if overlay_write_back { let overlay = config.overlay_dir(config_path); if let Some(p) = overlay.as_ref() { if !changelog_ready { // Special-case d/changelog: // Always write it back, this is safe because of our prepending logic new_hints.push("changelog".to_string()); } for hint in &new_hints { let newpath = tempdir.path().join(hint); let oldpath = p.join(hint); fs::copy(newpath, oldpath).expect("could not write back"); debcargo_info!("Wrote back file to overlay: {}", hint); } } } fs::rename(tempdir.path(), output_dir.join("debian"))?; Ok(()) } fn prepare_debian_control std::result::Result>( deb_info: &DebInfo, crate_info: &CrateInfo, config: &Config, mut file: F, ) -> Result<(Source, bool, bool)> { let crate_name = crate_info.crate_name(); let deb_upstream_version = deb_info.deb_upstream_version(); let base_pkgname = deb_info.base_package_name(); let name_suffix = deb_info.name_suffix(); let lib = crate_info.is_lib(); let mut bins = crate_info.get_binary_targets(); if lib && !bins.is_empty() && !config.build_bin_package() { bins.clear(); } let bin_name = if config.bin_name.eq(&Config::default().bin_name) { let default_bin_name = deb_info.base_package_name(); if !bins.is_empty() { debcargo_info!( "Generate binary crate with default name '{}', set bin_name to override or bin = false to disable.", &default_bin_name ); } default_bin_name } else { config.bin_name.as_str() }; let maintainer = config.maintainer(); let requires_root = config.requires_root(); let uploaders: Vec<&str> = config .uploaders() .into_iter() .flatten() .map(String::as_str) .collect(); let features_with_deps = crate_info.all_dependencies_and_features(); let dev_depends = deb_deps(config, &crate_info.dev_dependencies())?; log::trace!( "features_with_deps: {:?}", features_with_deps .iter() .map(|(&f, &(ref ff, ref dd))| { (f, (ff, dd.iter().map(show_dep).collect::>())) }) .collect::>() ); let meta = crate_info.metadata(); // debian/tests/control, preparation let test_is_marked_broken = |f: &str| config.package_test_is_broken(PackageKey::feature(f)); let test_is_broken = |f: &str| { let getparents = |f: &str| features_with_deps.get(f).map(|(d, _)| d); match get_transitive_val(&getparents, &test_is_marked_broken, f) { Err((k, vv)) => debcargo_bail!( "{} {}: {}: {:?}", "error trying to recursively determine test_is_broken for", k, "dependencies have inconsistent config values", vv ), Ok(v) => Ok(v.unwrap_or(false)), } }; let build_deps = { let build_deps = ["debhelper (>= 12)", "dh-cargo (>= 25)"] .iter() .map(|x| x.to_string()); // note: please keep this in sync with build_order::dep_features let (default_features, default_deps) = transitive_deps(&features_with_deps, "default"); //debcargo_info!("default_features: {:?}", default_features); //debcargo_info!("default_deps: {:?}", deb_deps(config, &default_deps)?); let extra_override_deps = package_field_for_feature( &|x| config.package_depends(x), PackageKey::feature("default"), &default_features, ); let build_deps_extra = ["cargo:native", "rustc:native", "libstd-rust-dev"] .iter() .map(|s| s.to_string()) .chain(deb_deps(config, &default_deps)?) .chain(extra_override_deps); if !bins.is_empty() { build_deps.chain(build_deps_extra).collect() } else { assert!(lib); build_deps .chain(build_deps_extra.map(|d| deb_dep_add_nocheck(&d))) .collect() } }; let mut source = Source::new( base_pkgname, name_suffix, crate_name, if let Some(ref home) = meta.homepage { home } else { "" }, lib, maintainer.to_string(), uploaders.iter().map(|s| s.to_string()).collect(), build_deps, if requires_root.is_some() { requires_root.as_ref().unwrap().to_string() } else { "no".to_string() }, )?; // If source overrides are present update related parts. source.apply_overrides(config); let mut control = io::BufWriter::new(file("control")?); write!(control, "{}", source)?; // Summary and description generated from Cargo.toml let (crate_summary, crate_description) = crate_info.get_summary_description(); let summary_prefix = crate_summary.unwrap_or(format!("Rust crate \"{}\"", crate_name)); let description_prefix = { let tmp = crate_description.unwrap_or_else(|| "".to_string()); if tmp.is_empty() { tmp } else { format!("{}\n.\n", tmp) } }; if lib { // debian/tests/control let all_features_test_broken = Some(&"@") .into_iter() .chain(features_with_deps.keys()) .any(|f| test_is_marked_broken(f).unwrap_or(false)); let all_features_test_depends = Some(&"@") .into_iter() .chain(features_with_deps.keys()) .map(|f| { config .package_test_depends(PackageKey::feature(f)) .into_iter() .flatten() }) .flatten() .map(|s| s.to_string()) .chain(dev_depends.clone()) .collect::>(); let mut testctl = io::BufWriter::new(file("tests/control")?); write!( testctl, "{}", PkgTest::new( source.name(), crate_name, "@", deb_upstream_version, vec!["--all-features"], &all_features_test_depends, if all_features_test_broken { vec!["flaky"] } else { vec![] }, )? )?; // begin transforming dependencies let working_features_with_deps = features_with_deps.clone(); let working_features_with_deps = { let mut working_features_with_deps = working_features_with_deps; // Detect corner case with feature naming regarding _ vs -. // Debian does not support _ in package names. Cargo automatically // converts - in crate names to _, but features (including optional // dependencies) can have both _ and -. let potential_corner_case = working_features_with_deps .keys() .filter(|x| base_deb_name(x).as_str() != **x) .cloned() .collect::>(); for f in potential_corner_case { let f_ = base_deb_name(f); if let Some((df1, dd1)) = working_features_with_deps.remove(f_.as_str()) { // merge dependencies of f_ and f working_features_with_deps .entry(f) .and_modify(|(df0, dd0)| { let mut df = BTreeSet::from_iter(df0.drain(..)); df.extend(df1); df.remove(f_.as_str()); df.remove(f); let mut dd: HashSet = HashSet::from_iter(dd0.drain(..)); dd.extend(dd1); df0.extend(df); dd0.extend(dd); }); // go through other feature deps and change f_ to f for (_, (df, _)) in working_features_with_deps.iter_mut() { for feat in df.iter_mut() { if *feat == f_.as_str() { *feat = f; } } } // check we didn't create a cycle in features let dep_feats = traverse_depth( &|k: &&'static str| working_features_with_deps.get(k).map(|x| &x.0), f, ); if dep_feats.contains(f) { log::debug!("transitive deps of feature {}: {:?}", f, dep_feats); debcargo_bail!( "Tried to merge features {} and {} as they are not representable separately\n\ in Debian, but this resulted in a feature cycle. You need to manually patch the package.", f, f_); } else { debcargo_warn!( "Merged features {} and {} as they are not representable separately in Debian.\n\ We checked that this does not break the package in an obvious way (feature cycle), however\n\ if there is a more sophisticated breakage, you'll have to manually patch those \ features instead.", f, f_); } } } working_features_with_deps }; log::trace!( "working_features_with_deps: {:?}", working_features_with_deps .iter() .map(|(&f, &(ref ff, ref dd))| { (f, (ff, dd.iter().map(show_dep).collect::>())) }) .collect::>() ); let (mut provides, reduced_features_with_deps) = if config.collapse_features { debcargo_warn!( "You are using the collapse_features work-around, which makes the resulting" ); debcargo_warn!( "package uninstallable when (now or in the future) your crate dependencies" ); debcargo_warn!( "contain cyclic dependencies on the crate-level; this is because cargo only" ); debcargo_warn!("enforces acyclicity of dependencies on the per-feature level."); debcargo_warn!(""); debcargo_warn!( "By switching on collapse_features, you are telling debcargo to generate Debian" ); debcargo_warn!( "binary package on a per-crate-level basis and not a per-feature-level, meaning" ); debcargo_warn!( "that there is the chance of generating a dependency cycle on the Debian binary" ); debcargo_warn!("package level, which APT by default refuses to install."); debcargo_warn!(""); debcargo_warn!( "You should not be doing this just because \"somebody told you so\"; you should" ); debcargo_warn!( "understand the situation and be prepared to deal with future technical debt" ); debcargo_warn!("when the aforementioned cycles arise."); debcargo_warn!(""); debcargo_warn!( "Note that a long-term solution has been discussed with the FTP team and is in" ); debcargo_warn!( "progress - namely to move Debian rust packages into a separate section of the" ); debcargo_warn!( "archive, which will then have the stricter current NEW rules lifted, and then" ); debcargo_warn!("the collapse_features work around would no longer be necessary."); debcargo_warn!(""); debcargo_warn!("A basic example of the above would be:"); debcargo_warn!(""); debcargo_warn!("- crate A with feature AX depends on crate B with feature BY"); debcargo_warn!("- crate B with feature BX depends on crate A with feature AY"); debcargo_warn!(""); debcargo_warn!( "This is a perfectly valid situation in the rust+cargo ecosystem. Notice that" ); debcargo_warn!( "there is no dependency cycle on the per-feature level, and this is enforced by" ); debcargo_warn!( "cargo; but if collapse_features is used then package A+AX+AY would cyclicly" ); debcargo_warn!("depend on package B+BX+BY."); collapse_features(working_features_with_deps) } else { reduce_provides(working_features_with_deps) }; log::trace!( "reduced_features_with_deps: {:?}", reduced_features_with_deps .iter() .map(|(&f, &(ref ff, ref dd))| { (f, (ff, dd.iter().map(show_dep).collect::>())) }) .collect::>() ); // end transforming dependencies log::trace!("provides: {:?}", provides); let mut recommends = vec![]; let mut suggests = vec![]; for (&feature, features) in provides.iter() { if feature.is_empty() { continue; } else if feature == "default" || features.contains(&"default") { recommends.push(feature); } else { suggests.push(feature); } } for (feature, (f_deps, o_deps)) in reduced_features_with_deps.into_iter() { let pk = PackageKey::feature(feature); let f_provides = provides.remove(feature).unwrap(); let mut crate_features = f_provides.clone(); crate_features.push(feature); let summary_suffix = if feature.is_empty() { " - Rust source code".to_string() } else { match f_provides.len() { 0 => format!(" - feature \"{}\"", feature), _ => format!(" - feature \"{}\" and {} more", feature, f_provides.len()), } }; let description_suffix = if feature.is_empty() { format!( "This package contains the source for the \ Rust {} crate, packaged by debcargo for use \ with cargo and dh-cargo.", crate_name ) } else { format!( "This metapackage enables feature \"{}\" for the \ Rust {} crate, by pulling in any additional \ dependencies needed by that feature.{}", feature, crate_name, match f_provides.len() { 0 => "".to_string(), 1 => format!( "\n\nAdditionally, this package also provides the \ \"{}\" feature.", f_provides[0], ), _ => format!( "\n\nAdditionally, this package also provides the \ \"{}\", and \"{}\" features.", f_provides[..f_provides.len() - 1].join("\", \""), f_provides[f_provides.len() - 1], ), }, ) }; let mut package = Package::new( base_pkgname, name_suffix, crate_info.version(), Description { prefix: summary_prefix.clone(), suffix: summary_suffix.clone(), }, Description { prefix: description_prefix.clone(), suffix: description_suffix.clone(), }, if feature.is_empty() { None } else { Some(feature) }, f_deps, deb_deps(config, &o_deps)?, f_provides.clone(), if feature.is_empty() { recommends.clone() } else { vec![] }, if feature.is_empty() { suggests.clone() } else { vec![] }, )?; // If any overrides present for this package it will be taken care. package.apply_overrides(config, pk, f_provides); match package.summary_check_len() { Err(()) => writeln!( control, concat!( "\n", "# FIXME (packages.\"(name)\".section) debcargo ", "auto-generated summary for {} is very long, consider overriding" ), package.name(), )?, Ok(()) => {} }; write!(control, "\n{}", package)?; // Override pointless overzealous warnings from lintian if !feature.is_empty() { let mut overrides = io::BufWriter::new(file(&format!("{}.lintian-overrides", package.name()))?); write!( overrides, "{} binary: empty-rust-library-declares-provides *", package.name() )?; } // Generate tests for all features in this package for f in crate_features { let (feature_deps, _) = transitive_deps(&features_with_deps, f); // args let mut args = if f == "default" || feature_deps.contains(&"default") { vec![] } else { vec!["--no-default-features"] }; // --features default sometimes fails, see // https://github.com/rust-lang/cargo/issues/8164 if !f.is_empty() && f != "default" { args.push("--features"); args.push(f); } // deps let test_depends = Some(f) .into_iter() .chain(feature_deps) .map(|f| { config .package_test_depends(PackageKey::feature(f)) .into_iter() .flatten() }) .flatten() .map(|s| s.to_string()) .chain(dev_depends.clone()) .collect::>(); let pkgtest = PkgTest::new( package.name(), crate_name, f, deb_upstream_version, args, &test_depends, if test_is_broken(f)? { vec!["flaky"] } else { vec![] }, )?; write!(testctl, "\n{}", pkgtest)?; } } assert!(provides.is_empty()); // reduced_features_with_deps consumed by into_iter, no longer usable } if !bins.is_empty() { // adding " - binaries" is a bit redundant for users, so just leave as-is let summary_suffix = "".to_string(); let description_suffix = format!( "This package contains the following binaries built from the Rust crate\n\"{}\":\n - {}", crate_name, bins.join("\n - ") ); let mut bin_pkg = Package::new_bin( bin_name, name_suffix, // if not-a-lib then Source section is already FIXME if !lib { None } else { Some("FIXME-(packages.\"(name)\".section)") }, Description { prefix: summary_prefix, suffix: summary_suffix, }, Description { prefix: description_prefix, suffix: description_suffix, }, ); // Binary package overrides. bin_pkg.apply_overrides(config, PackageKey::Bin, vec![]); write!(control, "\n{}", bin_pkg)?; } Ok((source, !dev_depends.is_empty(), test_is_broken("default")?)) } fn collapse_features( orig_features_with_deps: CrateDepInfo, ) -> (BTreeMap<&'static str, Vec<&'static str>>, CrateDepInfo) { let (provides, deps) = orig_features_with_deps.iter().fold( (Vec::new(), Vec::new()), |(mut provides, mut deps), (f, (_, f_deps))| { if f != &"" { provides.push(*f); } deps.append(&mut f_deps.clone()); (provides, deps) }, ); let mut collapsed_provides = BTreeMap::new(); collapsed_provides.insert("", provides); let mut collapsed_features_with_deps = BTreeMap::new(); collapsed_features_with_deps.insert("", (Vec::new(), deps)); (collapsed_provides, collapsed_features_with_deps) } /// Calculate Provides: in an attempt to reduce the number of binaries. /// /// The algorithm is very simple and incomplete. e.g. it does not, yet /// simplify things like: /// f1 depends on f2, f3 /// f2 depends on f4 /// f3 depends on f4 /// into /// f4 provides f1, f2, f3 fn reduce_provides( mut features_with_deps: CrateDepInfo, ) -> (BTreeMap<&'static str, Vec<&'static str>>, CrateDepInfo) { // If any features have duplicate dependencies, deduplicate them by // making all of the subsequent ones depend on the first one. let mut features_rev_deps = HashMap::new(); for (&f, dep) in features_with_deps.iter() { if !features_rev_deps.contains_key(dep) { features_rev_deps.insert(dep.clone(), vec![]); } features_rev_deps.get_mut(dep).unwrap().push(f); } for (_, ff) in features_rev_deps.into_iter() { let f0 = ff[0]; for f in &ff[1..] { features_with_deps.insert(f, (vec![f0], vec![])); } } // Calculate provides by following 0- or 1-length dependency lists. let mut provides = BTreeMap::new(); let mut provided = Vec::new(); for (&f, (ref ff, ref dd)) in features_with_deps.iter() { //debcargo_info!("provides considering: {:?}", &f); if !dd.is_empty() { continue; } assert!(!ff.is_empty() || f.is_empty()); let k = if ff.len() == 1 { // if A depends on a single feature B, then B provides A. ff[0] } else { continue; }; //debcargo_info!("provides still considering: {:?}", &f); if !provides.contains_key(k) { provides.insert(k, vec![]); } provides.get_mut(k).unwrap().push(f); provided.push(f); } //debcargo_info!("provides-internal: {:?}", &provides); //debcargo_info!("provided-internal: {:?}", &provided); for p in provided { features_with_deps.remove(p); } let provides = features_with_deps .keys() .map(|k| { ( *k, traverse_depth(&|k: &&'static str| provides.get(k), k) .into_iter() .collect::>(), ) }) .collect::>(); (provides, features_with_deps) } fn changelog_or_new(tempdir: &Path) -> Result<(fs::File, String)> { let mut changelog = fs::OpenOptions::new() .read(true) .write(true) .create(true) .open(tempdir.join("changelog"))?; let mut changelog_data = String::new(); changelog.read_to_string(&mut changelog_data)?; Ok((changelog, changelog_data)) } fn changelog_first_last(tempdir: &Path) -> Result<(i32, i32)> { let mut changelog = fs::File::open(tempdir.join("changelog"))?; let mut changelog_data = String::new(); changelog.read_to_string(&mut changelog_data)?; let mut last = None; let mut first = None; for x in ChangelogIterator::from(&changelog_data) { let e = ChangelogEntry::from_str(x)?; if None == last { last = Some(e.date.year()); } first = Some(e.date.year()); } if None == last { Err(format_err!("changelog had no entries")) } else { Ok((first.unwrap(), last.unwrap())) } } debcargo-2.5.0/src/errors.rs000064400000000000000000000023350072674642500141020ustar 00000000000000use anyhow; pub type Result = ::std::result::Result; pub use anyhow::format_err; #[macro_export] macro_rules! debcargo_info { ($e:expr) => { { use ansi_term::Colour::Green; eprintln!("{}", Green.paint($e)); } }; ($fmt:expr, $( $arg:tt)+) => { { use ansi_term::Colour::Green; let print_string = format!($fmt, $($arg)+); eprintln!("{}", Green.paint(print_string)); } }; } #[macro_export] macro_rules! debcargo_warn { ($e:expr) => { { use ansi_term::Colour::RGB; eprintln!("{}", RGB(255,165,0).bold().paint($e)); } }; ($fmt:expr, $( $arg:tt)+) => { { use ansi_term::Colour::RGB; let print_string = RGB(255,165,0).bold().paint(format!($fmt, $($arg)+)); eprintln!("{}", print_string); } }; } #[macro_export] macro_rules! debcargo_bail { ($e:expr) => {{ return Err(::anyhow::format_err!("{}", $e)); }}; ($fmt:expr, $( $arg:tt)+) => { { let error_string = format!($fmt, $($arg)+); return Err(::anyhow::format_err!("{}", error_string)); } }; } debcargo-2.5.0/src/lib.rs000064400000000000000000000001760072674642500133350ustar 00000000000000#[macro_use] pub mod errors; pub mod config; pub mod crates; pub mod debian; mod util; pub mod build_order; pub mod package; debcargo-2.5.0/src/package.rs000064400000000000000000000201050072674642500141540ustar 00000000000000use std::path::PathBuf; use anyhow::Context; use structopt::{clap::crate_version, StructOpt}; use crate::config::Config; use crate::crates::CrateInfo; use crate::debian::{self, DebInfo}; use crate::errors::Result; use crate::util; pub struct PackageProcess { // below state is filled in during init pub crate_info: CrateInfo, pub deb_info: DebInfo, pub config_path: Option, pub config: Config, // below state is filled in during the process /// Output directory as specified by the user. pub output_dir: Option, pub source_modified: Option, /// Tempdir that contains a working copy of the eventual output. pub temp_output_dir: Option, pub orig_tarball: Option, } #[derive(Debug, Clone, StructOpt)] pub struct PackageInitArgs { /// Name of the crate to package. pub crate_name: String, /// Version of the crate to package; may contain dependency operators. /// If empty string or omitted, resolves to the latest version. pub version: Option, /// TOML file providing package-specific options. #[structopt(long)] pub config: Option, } #[derive(Debug, Clone, StructOpt)] pub struct PackageExtractArgs { /// Output directory for the package. The orig tarball is named according /// to Debian conventions in the parent directory of this directory. #[structopt(long)] pub directory: Option, } #[derive(Debug, Clone, StructOpt)] pub struct PackageExecuteArgs { /// Assume the changelog is already bumped, and leave it alone. #[structopt(long)] pub changelog_ready: bool, /// Guess extra values for d/copyright. Might be slow. #[structopt(long)] pub copyright_guess_harder: bool, /// Don't write back hint files or d/changelog to the source overlay directory. #[structopt(long)] pub no_overlay_write_back: bool, } impl PackageProcess { /// More fine-grained access. For normal usage see `Self::init` instead. pub fn new( mut crate_info: CrateInfo, config_path: Option, config: Config, ) -> Result { crate_info.set_includes_excludes(config.orig_tar_excludes(), config.orig_tar_whitelist()); let deb_info = DebInfo::new(&crate_info, crate_version!(), config.semver_suffix); Ok(Self { crate_info, deb_info, config_path, config, output_dir: None, source_modified: None, temp_output_dir: None, orig_tarball: None, }) } pub fn init(init_args: PackageInitArgs) -> Result { let crate_name = &init_args.crate_name; let version = init_args.version.as_deref(); let config = init_args.config; let (config_path, config) = match config { Some(path) => { let config = Config::parse(&path).context("failed to parse debcargo.toml")?; (Some(path), config) } None => (None, Config::default()), }; let crate_path = config.crate_src_path(config_path.as_deref()); let crate_info = match crate_path { Some(p) => CrateInfo::new_with_local_crate(crate_name, version, &p)?, None => CrateInfo::new(crate_name, version)?, }; Self::new(crate_info, config_path, config) } pub fn extract(&mut self, extract: PackageExtractArgs) -> Result<()> { assert!(self.output_dir.is_none()); assert!(self.source_modified.is_none()); let Self { crate_info, deb_info, .. } = self; // vars read; begin stage let output_dir = extract .directory .unwrap_or_else(|| deb_info.package_source_dir().to_path_buf()); let source_modified = crate_info.extract_crate(&output_dir)?; // stage finished; set vars self.output_dir = Some(output_dir); self.source_modified = Some(source_modified); Ok(()) } pub fn apply_overrides(&mut self) -> Result<()> { assert!(self.temp_output_dir.is_none()); let Self { crate_info, config_path, config, output_dir, .. } = self; let output_dir = output_dir.as_ref().unwrap(); // vars read; begin stage let temp_output_dir = debian::apply_overlay_and_patches( crate_info, config_path.as_deref(), config, output_dir, )?; // stage finished; set vars self.temp_output_dir = Some(temp_output_dir); Ok(()) } pub fn prepare_orig_tarball(&mut self) -> Result<()> { assert!(self.orig_tarball.is_none()); let Self { crate_info, deb_info, output_dir, source_modified, .. } = self; let output_dir = output_dir.as_ref().unwrap(); let source_modified = source_modified.as_ref().unwrap(); // vars read; begin stage let orig_tarball = output_dir .parent() .unwrap() .join(deb_info.orig_tarball_path()); debian::prepare_orig_tarball(crate_info, &orig_tarball, *source_modified, output_dir)?; // stage finished; set vars self.orig_tarball = Some(orig_tarball); Ok(()) } pub fn prepare_debian_folder(&mut self, args: PackageExecuteArgs) -> Result<()> { let Self { crate_info, deb_info, config_path, config, output_dir, temp_output_dir, .. } = self; let output_dir = output_dir.as_ref().unwrap(); let temp_output_dir = temp_output_dir.as_ref().unwrap(); // vars read; begin stage debian::prepare_debian_folder( crate_info, deb_info, config_path.as_deref(), config, output_dir, temp_output_dir, args.changelog_ready, args.copyright_guess_harder, !args.no_overlay_write_back, )?; // stage finished; set vars Ok(()) } pub fn post_package_checks(&self) -> Result<()> { let Self { config_path, config, output_dir, orig_tarball, .. } = self; let output_dir = output_dir.as_ref().unwrap(); let orig_tarball = orig_tarball.as_ref().unwrap(); let curdir = std::env::current_dir()?; debcargo_info!( concat!("Package Source: {}\n", "Original Tarball for package: {}\n"), util::rel_p(output_dir, &curdir), util::rel_p(orig_tarball, &curdir) ); let fixmes = util::lookup_fixmes(output_dir.join("debian").as_path())?; if !fixmes.is_empty() { debcargo_warn!("FIXME found in the following files."); for f in fixmes { if util::hint_file_for(&f).is_some() { debcargo_warn!("\t(•) {}", util::rel_p(&f, &curdir)); } else { debcargo_warn!("\t • {}", util::rel_p(&f, &curdir)); } } debcargo_warn!(""); debcargo_warn!("To fix, try combinations of the following: "); match config_path.as_deref() { None => debcargo_warn!("\t • Write a config file and use it with --config"), Some(c) => { debcargo_warn!("\t • Add or edit overrides in your config file:"); debcargo_warn!("\t {}", util::rel_p(c, &curdir)); } }; match config.overlay_dir(config_path.as_deref()) { None => debcargo_warn!("\t • Create an overlay directory and add it to your config file with overlay = \"/path/to/overlay\""), Some(p) => { debcargo_warn!("\t • Add or edit files in your overlay directory:"); debcargo_warn!("\t {}", util::rel_p(&p, &curdir)); } } } Ok(()) } } debcargo-2.5.0/src/util.rs000064400000000000000000000160210072674642500135400ustar 00000000000000use std::collections::{BTreeMap, BTreeSet, VecDeque}; use std::ffi::OsStr; use std::fmt; use std::fs; use std::io::{BufRead, BufReader, Error}; use std::iter::Iterator; use std::os::unix::ffi::OsStrExt; use std::os::unix::fs::symlink; use std::path::{Path, PathBuf}; use std::process::Command; use itertools::Itertools; use walkdir::WalkDir; pub const HINT_SUFFIX: &str = ".debcargo.hint"; pub fn hint_file_for(file: &Path) -> Option<&Path> { let file = file.as_os_str().as_bytes(); if file.len() >= HINT_SUFFIX.len() && &file[file.len() - HINT_SUFFIX.len()..] == HINT_SUFFIX.as_bytes() { Some(Path::new(OsStr::from_bytes( &file[..file.len() - HINT_SUFFIX.len()], ))) } else { None } } pub fn lookup_fixmes(srcdir: &Path) -> Result, Error> { let mut fixmes = BTreeSet::new(); for entry in WalkDir::new(srcdir) { let entry = entry?; if entry.file_type().is_file() { let file = fs::File::open(entry.path())?; let reader = BufReader::new(file); // If we find one FIXME we break the loop and check next file. Idea // is only to find files with FIXME strings in it. for line in reader.lines().flatten() { if line.contains("FIXME") { fixmes.insert(entry.path().to_path_buf()); break; } } } } // ignore hint files whose non-hint partners exists and don't have a FIXME let fixmes = fixmes .iter() .filter(|f| match hint_file_for(f) { Some(ff) => fixmes.contains(ff) || !ff.exists(), None => true, }) .cloned() .collect::>(); Ok(fixmes) } pub fn rel_p<'a>(path: &'a Path, base: &'a Path) -> &'a str { path.strip_prefix(base).unwrap_or(path).to_str().unwrap() } pub fn copy_tree(oldtree: &Path, newtree: &Path) -> Result<(), Error> { for entry in WalkDir::new(oldtree) { let entry = entry?; if entry.depth() == 0 { continue; } let oldpath = entry.path(); let newpath = newtree.join(oldpath.strip_prefix(&oldtree).unwrap()); let ftype = entry.file_type(); if ftype.is_dir() { fs::create_dir(newpath)?; } else if ftype.is_file() { fs::copy(oldpath, newpath)?; } else if ftype.is_symlink() { symlink(fs::read_link(oldpath)?, newpath)?; } } Ok(()) } pub fn show_vec_with<'a, T, F>(it: impl IntoIterator, f: F) -> String where T: 'a, F: FnMut(&T) -> String, { Itertools::intersperse(it.into_iter().map(f), ", ".to_string()).collect::() } pub fn show_vec<'a, T>(it: impl IntoIterator) -> String where T: fmt::Display + 'a, { show_vec_with(it, std::string::ToString::to_string) } pub fn expect_success(cmd: &mut Command, err: &str) { match cmd.status() { Ok(status) => { if !status.success() { panic!("{}", err); } } Err(e) => { panic!("{}", e); } } } pub(crate) fn traverse_depth<'a, V, F>(succ: &'a F, key: V) -> BTreeSet where V: Ord + Copy + 'a, F: Fn(&V) -> Option<&'a Vec>, { let mut remain = VecDeque::from_iter([key]); let mut seen = BTreeSet::new(); while let Some(v) = remain.pop_front() { for v_ in succ(&v).into_iter().flatten() { if !seen.contains(v_) { seen.insert(*v_); remain.push_back(*v_); } } } seen } /// Get a value that might be set at a key or any of its ancestor keys, /// whichever is closest. Error if there are conflicting definitions. #[allow(clippy::type_complexity)] pub(crate) fn get_transitive_val< 'a, P: Fn(K) -> Option<&'a Vec>, F: Fn(K) -> Option, K: 'a + Ord + Copy, V: Eq + Ord, >( getparents: &'a P, f: &F, key: K, ) -> Result, (K, Vec<(K, V)>)> { let here = f(key); if here.is_some() { // value overrides anything from parents Ok(here) } else { let mut candidates = Vec::new(); for par in getparents(key).into_iter().flatten() { if let Some(v) = get_transitive_val(getparents, f, *par)? { candidates.push((*par, v)) } } if candidates.is_empty() { Ok(None) // here is None } else { let mut values = candidates.iter().map(|(_, v)| v).collect::>(); values.sort(); values.dedup(); if values.len() == 1 { Ok(candidates.pop().map(|(_, v)| v)) } else { Err((key, candidates)) // handle conflict } } } } pub fn graph_from_succ( seed: impl IntoIterator, succ: &mut FV, log: &mut FL, ) -> Result>, E> where V: Ord + Clone, FV: FnMut(&V) -> Result<(Vec, Vec), E>, FL: FnMut(&VecDeque, &BTreeMap>) -> Result<(), E>, { let mut seen = BTreeSet::from_iter(seed); let mut graph = BTreeMap::new(); let mut remain = VecDeque::from_iter(seen.iter().cloned()); while let Some(v) = remain.pop_front() { log(&remain, &graph)?; let (hard, soft) = succ(&v)?; for v_ in hard.iter().chain(soft.iter()) { if !seen.contains(v_) { seen.insert(v_.clone()); remain.push_back(v_.clone()); } } graph.insert(v, BTreeSet::from_iter(hard)); } Ok(graph) } pub fn succ_proj(succ: &BTreeMap>, proj: F) -> BTreeMap> where F: Fn(&S) -> T, S: Ord, T: Ord + Clone, { let mut succ_proj: BTreeMap> = BTreeMap::new(); for (s, ss) in succ { let e = succ_proj.entry(proj(s)).or_default(); for s_ in ss { e.insert(proj(s_)); } } succ_proj } pub fn succ_to_pred(succ: &BTreeMap>) -> BTreeMap> where V: Ord + Clone, { let mut pred: BTreeMap> = BTreeMap::new(); for (v, vv) in succ { for v_ in vv { pred.entry(v_.clone()).or_default().insert(v.clone()); } } pred } pub fn topo_sort( seed: impl IntoIterator, succ: BTreeMap>, mut pred: BTreeMap>, ) -> Result, BTreeMap>> where V: Ord + Clone, { let empty = BTreeSet::new(); let mut remain = VecDeque::from_iter(seed); let mut sort = Vec::new(); while let Some(v) = remain.pop_front() { sort.push(v.clone()); for v_ in succ.get(&v).unwrap_or(&empty) { let par = pred.entry(v_.clone()).or_default(); par.remove(&v); if par.is_empty() { remain.push_back(v_.clone()); } } } pred.retain(|_, v| !v.is_empty()); if !pred.is_empty() { Err(pred) } else { Ok(sort) } } debcargo-2.5.0/tests/clap_override.toml000064400000000000000000000013220072674642500163010ustar 00000000000000uploaders = ["Sylvestre Ledru ", "Ximin Luo " ] [source] policy = "4.0.0" homepage = "https://clap.rs" [packages.lib] summary = "Simple, efficient and full featured Command line argument parser - source" description = """ clap is used to parse and validate string of command line arguments provided by user at runtime. It provides help and version flags by default and additionally provide help subcommands in addition to traditional flags. This package provides clap with following default features. * suggestions: provides did you mean suggestions on typos * color: turns on colored error messages. * wrap_help: Wrap the help at actual terminal width when available. """ debcargo-2.5.0/tests/config_tests.rs000064400000000000000000000045620072674642500156340ustar 00000000000000extern crate debcargo; use debcargo::config::{Config, PackageKey}; use std::path::Path; #[test] fn source_package_override() { let filepath = Path::new("tests/clap_override.toml"); let config = Config::parse(filepath); assert!(config.is_ok()); let config = config.unwrap(); assert!(config.source.is_some()); assert!(config.packages.is_some()); let policy = config.policy_version(); assert!(policy.is_some()); assert_eq!(policy.unwrap(), "4.0.0"); let homepage = config.homepage(); assert!(homepage.is_some()); assert_eq!(homepage.unwrap(), "https://clap.rs"); assert!(config.section().is_none()); assert!(config.build_depends().is_none()); let filepath = Path::new("tests/debcargo_override.toml"); let config = Config::parse(filepath); assert!(config.is_ok()); let config = config.unwrap(); assert!(config.source.is_some()); let section = config.section(); assert!(section.is_some()); assert_eq!(section.unwrap(), "rust"); assert!(config.packages.is_some()); let sd = config.package_summary(PackageKey::Bin); assert!(sd.is_some()); if let Some(s) = sd { assert_eq!(s, "Tool to create Debian package from Rust crate"); } let sd = config.package_description(PackageKey::Bin); assert!(sd.is_some()); if let Some(d) = sd { assert_eq!( d, "\ This package provides debcargo a tool to create Debian source package from \ Rust crate. The package created by this tool is as per the packaging policy \ set by Debian Rust team. " ); } } #[test] fn sd_top_level() { let filepath = Path::new("tests/debcargo_override_top_level.toml"); let config = Config::parse(filepath); assert!(config.is_ok()); let config = config.unwrap(); assert!(config.source.is_some()); let section = config.section(); assert!(section.is_some()); assert_eq!(section.unwrap(), "rust"); assert_eq!( config.summary.unwrap(), "Tool to create Debian package from Rust crate" ); assert_eq!( config.description.unwrap(), "\ This package provides debcargo a tool to create Debian source package from \ Rust crate. The package created by this tool is as per the packaging policy \ set by Debian Rust team. " ); } debcargo-2.5.0/tests/configs/aesni/debian/debcargo.toml000064400000000000000000000000430072674642500212010ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/aesni/debian/rules000064400000000000000000000003640072674642500176210ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # crate requires builder to set custom RUSTFLAGS # we can't do that in Debian due to architecture baselines override_dh_auto_test: dh_auto_test || true debcargo-2.5.0/tests/configs/aesni-0.10/debian/debcargo.toml000064400000000000000000000000430072674642500215550ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/aesni-0.10/debian/rules000064400000000000000000000003640072674642500201750ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # crate requires builder to set custom RUSTFLAGS # we can't do that in Debian due to architecture baselines override_dh_auto_test: dh_auto_test || true debcargo-2.5.0/tests/configs/afl-0.10/debian/debcargo.toml000064400000000000000000000002310072674642500212170ustar 00000000000000semver_suffix = true overlay = "." [source] build_depends = ["llvm", "lld", "clang"] [packages.lib] depends = ["libclang-dev", "llvm", "lld", "clang"] debcargo-2.5.0/tests/configs/afl-0.10/debian/rules000064400000000000000000000010320072674642500176310ustar 00000000000000#!/usr/bin/make -f %: dh $@ --buildsystem cargo export RUSTC_BOOTSTRAP := 1 export PATH := $(CURDIR)/debian/debcargo_testing_bin:$(PATH) # needed by build script export XDG_DATA_HOME := $(CURDIR)/debian/xdg-data-home export CXXFLAGS := -Wno-unused-command-line-argument export CFLAGS := -Wno-unused-command-line-argument override_dh_strip_nondeterminism: # dh_strip_nondeterminism can't parse these files rm -rf $(CURDIR)/debian/libruzt-afl-*-dev/usr/share/cargo/registry/afl-*/AFLplusplus/docs/vuln_samples dh_strip_nondeterminism debcargo-2.5.0/tests/configs/aom-sys-0.2/debian/debcargo.toml000064400000000000000000000000760072674642500217750ustar 00000000000000semver_suffix = true [packages.lib] depends = ["libaom-dev"] debcargo-2.5.0/tests/configs/ascii-0.8/debian/debcargo.toml000064400000000000000000000000430072674642500214750ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/ascii-0.8/debian/patches/fix-old-dep.patch000064400000000000000000000007500072674642500236170ustar 00000000000000Crate authors like to put dev-dependencies in dependencies due to https://github.com/rust-lang/cargo/issues/1596 Then due to lack of maintenance this pollutes the dependency set with old crates that no longer compile. Here, quickcheck 0.4 eventually depends on simd which no longer compiles. --- a/Cargo.toml +++ b/Cargo.toml @@ -22,9 +22,6 @@ [[test]] name = "tests" path = "tests.rs" -[dependencies.quickcheck] -version = "0.4.1" -optional = true [features] default = ["std"] debcargo-2.5.0/tests/configs/ascii-0.8/debian/patches/series000064400000000000000000000000220072674642500216730ustar 00000000000000fix-old-dep.patch debcargo-2.5.0/tests/configs/broken-lto/debian/debcargo.toml000064400000000000000000000000430072674642500221560ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/broken-lto/debian/rules000064400000000000000000000003710072674642500205740ustar 00000000000000#!/usr/bin/make -f %: dh $@ --buildsystem cargo export RUSTC_BOOTSTRAP := 1 export PATH := $(CURDIR)/debian/debcargo_testing_bin:$(PATH) override_dh_dwz: # Don't do anything. fails because of the # https://github.com/rust-lang/rust/issues/66118 debcargo-2.5.0/tests/configs/broken-upstream/debian/debcargo.toml000064400000000000000000000000430072674642500232200ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/broken-upstream/debian/rules000064400000000000000000000022350072674642500216370ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/brotli-decompressor-2/debian/debcargo.toml000064400000000000000000000000430072674642500242370ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/brotli-decompressor-2/debian/rules000064400000000000000000000003710072674642500226550ustar 00000000000000#!/usr/bin/make -f %: dh $@ --buildsystem cargo export RUSTC_BOOTSTRAP := 1 export PATH := $(CURDIR)/debian/debcargo_testing_bin:$(PATH) override_dh_dwz: # Don't do anything. fails because of the # https://github.com/rust-lang/rust/issues/66118 debcargo-2.5.0/tests/configs/clang-sys/debian/debcargo.toml000064400000000000000000000002120072674642500220000ustar 00000000000000semver_suffix = true overlay = "." [source] build_depends = ["llvm", "clang"] [packages.lib] depends = ["libclang-dev", "lld", "clang"] debcargo-2.5.0/tests/configs/clang-sys-0.23/debian/debcargo.toml000064400000000000000000000002120072674642500223600ustar 00000000000000semver_suffix = true overlay = "." [source] build_depends = ["llvm", "clang"] [packages.lib] depends = ["libclang-dev", "lld", "clang"] debcargo-2.5.0/tests/configs/clang-sys-0.26/debian/debcargo.toml000064400000000000000000000002120072674642500223630ustar 00000000000000semver_suffix = true overlay = "." [source] build_depends = ["llvm", "clang"] [packages.lib] depends = ["libclang-dev", "lld", "clang"] debcargo-2.5.0/tests/configs/clang-sys-1/debian/debcargo.toml000064400000000000000000000002120072674642500221360ustar 00000000000000semver_suffix = true overlay = "." [source] build_depends = ["llvm", "clang"] [packages.lib] depends = ["libclang-dev", "lld", "clang"] debcargo-2.5.0/tests/configs/clippy-0.0/debian/debcargo.toml000064400000000000000000000000430072674642500216750ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/clippy-0.0/debian/rules000064400000000000000000000011220072674642500203060ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # clippy upstream now errors on purpose with the message "clippy is no longer # available on crates.io". Many old crates depend on clippy even though it is # a dev-dependency because of [3] and there are far too many to patch. So just # make the build of clippy "succeed"; it does not actually get used in the # build of a reverse-dependency anyway. # # [1] https://github.com/rust-lang/cargo/issues/1596 override_dh_auto_test: dh_auto_test || true override_dh_auto_install: dh_auto_install || true debcargo-2.5.0/tests/configs/cmake-0.1/debian/debcargo.toml000064400000000000000000000000710072674642500214570ustar 00000000000000semver_suffix = true [packages.lib] depends = ["cmake"] debcargo-2.5.0/tests/configs/compiler-builtins-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500240370ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/compiler-builtins-0.1/debian/rules000064400000000000000000000022350072674642500224560ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/compiler-error-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500233370ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/compiler-error-0.1/debian/rules000064400000000000000000000022350072674642500217560ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/compiletest-rs-0.3/debian/debcargo.toml000064400000000000000000000000430072674642500233520ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/compiletest-rs-0.3/debian/rules000064400000000000000000000002700072674642500217660ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # crate errors on the default feature by design override_dh_auto_test: dh_auto_test || true debcargo-2.5.0/tests/configs/core-arch-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500222410ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/core-arch-0.1/debian/rules000064400000000000000000000022350072674642500206600ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/core-error-0.0/debian/debcargo.toml000064400000000000000000000000430072674642500224540ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/core-error-0.0/debian/rules000064400000000000000000000022350072674642500210730ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/core-foundation-0.9/debian/debcargo.toml000064400000000000000000000000430072674642500235020ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/core-foundation-0.9/debian/rules000064400000000000000000000003310072674642500221140ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/core-graphics-0.22/debian/debcargo.toml000064400000000000000000000000430072674642500232070ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/core-graphics-0.22/debian/rules000064400000000000000000000003310072674642500216210ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/core-graphics-types-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500242660ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/core-graphics-types-0.1/debian/rules000064400000000000000000000003310072674642500227000ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/core-text-19/debian/debcargo.toml000064400000000000000000000000430072674642500222430ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/core-text-19/debian/rules000064400000000000000000000003310072674642500206550ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/cpp-demangle-0.3/debian/debcargo.toml000064400000000000000000000000410072674642500227320ustar 00000000000000semver_suffix = true bin = false debcargo-2.5.0/tests/configs/dav1d-sys-0.3/debian/debcargo.toml000064400000000000000000000001000072674642500222050ustar 00000000000000semver_suffix = true [packages.lib] depends = ["libdav1d-dev"] debcargo-2.5.0/tests/configs/diesel-1/debian/debcargo.toml000064400000000000000000000000430072674642500215050ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/diesel-1/debian/patches/fix-old-dep.patch000064400000000000000000000010140072674642500236210ustar 00000000000000Crate authors like to put dev-dependencies in dependencies due to https://github.com/rust-lang/cargo/issues/1596 Then due to lack of maintenance this pollutes the dependency set with old crates that no longer compile. Here, quickcheck 0.4 eventually depends on simd which no longer compiles. --- a/Cargo.toml +++ b/Cargo.toml @@ -76,10 +76,6 @@ version = ">=0.3.0, <0.5.0" optional = true -[dependencies.quickcheck] -version = "0.4" -optional = true - [dependencies.r2d2] version = ">= 0.8, < 0.9" optional = true debcargo-2.5.0/tests/configs/diesel-1/debian/patches/series000064400000000000000000000000220072674642500217030ustar 00000000000000fix-old-dep.patch debcargo-2.5.0/tests/configs/dwrote-0.11/debian/debcargo.toml000064400000000000000000000000430072674642500217630ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/dwrote-0.11/debian/rules000064400000000000000000000003350072674642500204010ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on windows override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-pc-windows-gnu) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/fd-find-8/debian/debcargo.toml000064400000000000000000000000430072674642500215560ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/fd-find-8/debian/rules000064400000000000000000000003710072674642500201740ustar 00000000000000#!/usr/bin/make -f %: dh $@ --buildsystem cargo export RUSTC_BOOTSTRAP := 1 export PATH := $(CURDIR)/debian/debcargo_testing_bin:$(PATH) override_dh_dwz: # Don't do anything. fails because of the # https://github.com/rust-lang/rust/issues/66118 debcargo-2.5.0/tests/configs/fsevent-0.4/debian/debcargo.toml000064400000000000000000000000430072674642500220530ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/fsevent-0.4/debian/rules000064400000000000000000000003310072674642500204650ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/fsevent-sys-2/debian/debcargo.toml000064400000000000000000000000430072674642500225270ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/fsevent-sys-2/debian/rules000064400000000000000000000003310072674642500211410ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/heapsize-plugin-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500235020ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/heapsize-plugin-0.1/debian/rules000064400000000000000000000022350072674642500221210ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/http-types-2/debian/debcargo.toml000064400000000000000000000000430072674642500223620ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/http-types-2/debian/patches/fix-features.patch000064400000000000000000000004110072674642500247700ustar 00000000000000--- a/Cargo.toml +++ b/Cargo.toml @@ -83,7 +83,7 @@ version = "0.2.0" [features] -async_std = ["fs"] +async_std = ["async-std"] # replaces fs with deps of fs cookie-secure = ["cookies", "cookie/secure"] cookies = ["cookie"] default = ["fs", "cookie-secure"] debcargo-2.5.0/tests/configs/http-types-2/debian/patches/series000064400000000000000000000000230072674642500225610ustar 00000000000000fix-features.patch debcargo-2.5.0/tests/configs/jetscii-0.3/debian/debcargo.toml000064400000000000000000000000430072674642500220320ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/jetscii-0.3/debian/rules000064400000000000000000000022350072674642500204510ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/nasm-rs-0.2/debian/debcargo.toml000064400000000000000000000000700072674642500217570ustar 00000000000000semver_suffix = true [packages.lib] depends = ["nasm"] debcargo-2.5.0/tests/configs/nodrop-union-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500230250ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/nodrop-union-0.1/debian/rules000064400000000000000000000022350072674642500214440ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/nom-4/debian/debcargo.toml000064400000000000000000000000430072674642500210340ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/nom-4/debian/rules000064400000000000000000000002670072674642500174560ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # crate declares benches outside of crate path override_dh_auto_test: dh_auto_test || true debcargo-2.5.0/tests/configs/old-version/debian/debcargo.toml000064400000000000000000000000250072674642500223430ustar 00000000000000semver_suffix = true debcargo-2.5.0/tests/configs/only-macos/debian/debcargo.toml000064400000000000000000000000430072674642500221630ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/only-macos/debian/rules000064400000000000000000000003310072674642500205750ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/only-windows/debian/debcargo.toml000064400000000000000000000000430072674642500225530ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/only-windows/debian/rules000064400000000000000000000003350072674642500211710ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on windows override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-pc-windows-gnu) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/openssl-sys-0.9/debian/debcargo.toml000064400000000000000000000000760072674642500227130ustar 00000000000000semver_suffix = true [packages.lib] depends = ["libssl-dev"] debcargo-2.5.0/tests/configs/packed-simd-0.3/debian/debcargo.toml000064400000000000000000000000430072674642500225610ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/packed-simd-0.3/debian/rules000064400000000000000000000022350072674642500212000ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/petgraph-0.4/debian/debcargo.toml000064400000000000000000000000430072674642500222130ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/petgraph-0.4/debian/patches/fix-old-dep.patch000064400000000000000000000017610072674642500243400ustar 00000000000000Crate authors like to put dev-dependencies in dependencies due to https://github.com/rust-lang/cargo/issues/1596 Then due to lack of maintenance this pollutes the dependency set with old crates that no longer compile. Here, quickcheck 0.4 eventually depends on simd which no longer compiles. --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ license = "MIT/Apache-2.0" repository = "https://github.com/bluss/petgraph" [package.metadata.docs.rs] -features = ["serde-1", "quickcheck"] +features = ["serde-1"] [package.metadata.release] no-dev-version = true @@ -40,11 +40,6 @@ version = "0.3.0" optional = true -[dependencies.quickcheck] -version = "0.4" -optional = true -default-features = false - [dependencies.serde] version = "1.0" optional = true @@ -66,7 +61,7 @@ version = "0.3" [features] -all = ["unstable", "quickcheck", "stable_graph", "graphmap"] +all = ["unstable", "stable_graph", "graphmap"] default = ["graphmap", "stable_graph"] generate = [] graphmap = ["ordermap"] debcargo-2.5.0/tests/configs/petgraph-0.4/debian/patches/series000064400000000000000000000000220072674642500224110ustar 00000000000000fix-old-dep.patch debcargo-2.5.0/tests/configs/phf-generator-0.10/debian/debcargo.toml000064400000000000000000000000410072674642500232150ustar 00000000000000semver_suffix = true bin = false debcargo-2.5.0/tests/configs/pkg-config-0.3/debian/debcargo.toml000064400000000000000000000000760072674642500224320ustar 00000000000000semver_suffix = true [packages.lib] depends = ["pkg-config"] debcargo-2.5.0/tests/configs/redis-0.17/debian/debcargo.toml000064400000000000000000000000430072674642500215730ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/redis-0.17/debian/rules000064400000000000000000000003130072674642500202050ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # crate is buggy; fails to declare "alloc" feature on futures-util override_dh_auto_test: dh_auto_test || true debcargo-2.5.0/tests/configs/redox-syscall-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500231670ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/redox-syscall-0.1/debian/rules000064400000000000000000000022350072674642500216060ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/redox-users-0.3/debian/debcargo.toml000064400000000000000000000000430072674642500226600ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/redox-users-0.3/debian/rules000064400000000000000000000022350072674642500212770ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/rhai-1/debian/debcargo.toml000064400000000000000000000000430072674642500211630ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/rhai-1/debian/rules000064400000000000000000000003710072674642500176010ustar 00000000000000#!/usr/bin/make -f %: dh $@ --buildsystem cargo export RUSTC_BOOTSTRAP := 1 export PATH := $(CURDIR)/debian/debcargo_testing_bin:$(PATH) override_dh_dwz: # Don't do anything. fails because of the # https://github.com/rust-lang/rust/issues/66118 debcargo-2.5.0/tests/configs/ring-0.13/debian/debcargo.toml000064400000000000000000000000430072674642500214200ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/ring-0.13/debian/rules000064400000000000000000000003520072674642500200350ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # crate is super-over-zealous with lint settings # overrides our cargo wrapper's --cap-lints warn override_dh_auto_test: dh_auto_test || true debcargo-2.5.0/tests/configs/ring-0.14/debian/debcargo.toml000064400000000000000000000000430072674642500214210ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/ring-0.14/debian/rules000064400000000000000000000003520072674642500200360ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # crate is super-over-zealous with lint settings # overrides our cargo wrapper's --cap-lints warn override_dh_auto_test: dh_auto_test || true debcargo-2.5.0/tests/configs/security-framework-2/debian/debcargo.toml000064400000000000000000000000430072674642500241030ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/security-framework-2/debian/rules000064400000000000000000000003310072674642500225150ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/security-framework-sys-2/debian/debcargo.toml000064400000000000000000000000430072674642500247170ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/security-framework-sys-2/debian/rules000064400000000000000000000003310072674642500233310ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on macos override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-apple-darwin) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/serde-qs-0.8/debian/debcargo.toml000064400000000000000000000000430072674642500221300ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/serde-qs-0.8/debian/patches/fix-actix-web-dep.patch000064400000000000000000000015300072674642500253540ustar 00000000000000actix-web eventually depends on actix-connect 1.0.2 actix-connect 1.0.2 depends on prerelease trust-dns-resolver 0.18.0-alpha.2, which declares broken deps on trust-dns-proto "0.18.0" - should be "=0.18.0-alpha.2" debcargo doesn't support prerelease versions because semver compatibility doesn't apply. So patching trust-dns-resolver to fix their bug is not an option for us here. So just disable actix-web 2 here. --- a/Cargo.toml +++ b/Cargo.toml @@ -30,12 +30,6 @@ default-features = false package = "actix-web" -[dependencies.actix-web2] -version = "2.0" -optional = true -default-features = false -package = "actix-web" - [dependencies.futures] version = "0.3" optional = true @@ -75,6 +69,5 @@ [features] actix = ["actix-web", "futures"] -actix2 = ["actix-web2", "futures"] default = [] warp = ["futures", "tracing", "warp-framework"] debcargo-2.5.0/tests/configs/serde-qs-0.8/debian/patches/series000064400000000000000000000000300072674642500223250ustar 00000000000000fix-actix-web-dep.patch debcargo-2.5.0/tests/configs/servo-fontconfig-sys-5/debian/debcargo.toml000064400000000000000000000001050072674642500243470ustar 00000000000000semver_suffix = true [packages.lib] depends = ["libfontconfig-dev"] debcargo-2.5.0/tests/configs/sleef-sys-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500223100ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/sleef-sys-0.1/debian/rules000064400000000000000000000022350072674642500207270ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/spin-0.4/debian/debcargo.toml000064400000000000000000000000430072674642500213520ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/spin-0.4/debian/rules000064400000000000000000000022350072674642500177710ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # code uses old rust feature that causes compiler error. override_dh_auto_test: dh_auto_test || true # This crate is actually broken; however there are several cases why this # override is OK and necessary for Debian: # # 1. The other crate depends on this broken crate in an architecture-specific # way i.e. with [target.$arch.*] in Cargo.toml # # cargo does not yet support omitting these dependencies on other arches [1] # and so we are forced to include it also in debcargo [2] # # [1] https://github.com/rust-lang/cargo/issues/5896 # [2] https://salsa.debian.org/rust-team/debcargo/-/issues/14 # # 2. The other crate depends on this broken crate only via one of its optional # features that most users of that crate, don't need. You generally run into # this situation when resolving via --resolve-type BinaryAllForDebianTesting # # If your situation does not fit into one of the above situations, you should # re-consider the override. If your override is incorrect, the build failure # will crop up again later, in the crate that depends on this broken crate. debcargo-2.5.0/tests/configs/tiny-keccak-2/debian/debcargo.toml000064400000000000000000000000430072674642500224430ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/tiny-keccak-2/debian/rules000064400000000000000000000002770072674642500210660ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # crate errors on purpose when no features are enabled override_dh_auto_test: dh_auto_test || true debcargo-2.5.0/tests/configs/vcpkg-0.2/debian/debcargo.toml000064400000000000000000000000610072674642500215110ustar 00000000000000semver_suffix = true excludes = ["test-data/**"] debcargo-2.5.0/tests/configs/wepoll-ffi-0.1/debian/debcargo.toml000064400000000000000000000000430072674642500224420ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/wepoll-ffi-0.1/debian/rules000064400000000000000000000003350072674642500210600ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on windows override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-pc-windows-gnu) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/winreg-0.6/debian/debcargo.toml000064400000000000000000000000430072674642500216760ustar 00000000000000semver_suffix = true overlay = "." debcargo-2.5.0/tests/configs/winreg-0.6/debian/rules000064400000000000000000000003350072674642500203140ustar 00000000000000#!/usr/bin/make -f include /usr/share/rustc/architecture.mk %: dh $@ --buildsystem cargo # only supported on windows override_dh_auto_test: case $(DEB_HOST_RUST_TYPE) in *-pc-windows-gnu) dh_auto_test;; *) true;; esac debcargo-2.5.0/tests/configs/zip-0.5/debian/debcargo.toml000064400000000000000000000001700072674642500212050ustar 00000000000000semver_suffix = true # tests purposefully contain invalid data that debian tools try to process excludes = ["tests/**"] debcargo-2.5.0/tests/debcargo_override.toml000064400000000000000000000007440072674642500171370ustar 00000000000000uploaders = ["Sylvestre Ledru ", "Ximin Luo " ] [source] section = "rust" build_depends = ["libssl-dev"] homepage = "https://salsa.debian.org/rust-team/debcargo-conf" [packages.bin] summary = "Tool to create Debian package from Rust crate" description = """ This package provides debcargo a tool to create Debian source package from Rust crate. The package created by this tool is as per the packaging policy set by Debian Rust team. """ debcargo-2.5.0/tests/debcargo_override_top_level.toml000064400000000000000000000007250072674642500212070ustar 00000000000000uploaders = ["Sylvestre Ledru ", "Ximin Luo " ] summary = "Tool to create Debian package from Rust crate" description = """ This package provides debcargo a tool to create Debian source package from Rust crate. The package created by this tool is as per the packaging policy set by Debian Rust team. """ [source] section = "rust" build_depends = ["libssl-dev"] homepage = "https://salsa.debian.org/rust-team/debcargo-conf" debcargo-2.5.0/tests/sh/integrate.sh000075500000000000000000000222640072674642500155310ustar 00000000000000#!/bin/bash set -e scriptdir="$(dirname "$0")" # outputs directory=tmp failures_file="" # inputs allow_failures="$scriptdir/build-allow-fail" lintian_suppress_tags="$scriptdir/lintian-suppress-tags" config_dir="$scriptdir/../configs" # tweaks run_lintian=true run_sbuild=false keepfiles=false resolve= extraargs= export DEBCARGO_TESTING_IGNORE_DEBIAN_POLICY_VIOLATION=1 export DEBCARGO_TESTING_RUZT=1 export DEB_HOST_ARCH=${DEB_HOST_ARCH:-$(dpkg-architecture -qDEB_HOST_ARCH)} while getopts 'd:f:a:l:c:bkrRux:zh?' o; do case $o in d ) directory=$OPTARG;; f ) failures_file=$OPTARG;; a ) allow_failures=$OPTARG;; c ) config_dir=$OPTARG;; b ) run_sbuild=true;; k ) keepfiles=true;; r ) resolve=SourceForDebianUnstable;; R ) resolve=BinaryAllForDebianTesting;; x ) extraargs="$extraargs $OPTARG";; h|\? ) cat >&2 <|) [..] Run debcargo, do a source-only build, and call lintian on the results. -h This help text. Options for output: -d DIR Output directory, default: $directory. Warning: this will be wiped at the start of the test! -f FILE File to output failed crates in, instead of exiting non-zero. Relative paths are taken relative to the output directory. Options for input: -a FILE File that lists crate names to ignore failures for, default: $allow_failures. -c DIR Path to config directory, default: $config_dir. Options to control running: -b Run sbuild on the resulting dsc package. -k Don't wipe the output directory at the start of the test, and don't rebuild a crate if its directory already exists. -r Operate on all transitive build-dependencies of the source package, needed for entry into Debian Unstable. -R Operate on all transitive dependencies of the binary packages, needed for entry into Debian Testing. -x ARG Give ARG as an extra argument to debcargo, e.g. like -x--copyright-guess-harder. eof exit 2;; esac done shift $(expr $OPTIND - 1) allow_fail() { local crate="$1" local version="$2" if ! test -f "${allow_failures}"; then return 1 elif grep -qx "${crate}" "${allow_failures}"; then echo >&2 "Allowing ${crate} to fail..." return 0 elif [ -n "$version" ] && grep -qx "${crate}-${version}" "${allow_failures}"; then echo >&2 "Allowing ${crate}-${version} to fail..." return 0 else return 1 fi } shouldbuild() { local dst="$1" local src="$2" test ! -e "$dst" -o "$src" -nt "$dst" } changelog_pkgname() {( local cratedir="$1" cd "$cratedir" # dpkg-parsechangelog is really slow when dealing with hundreds of crates #echo $(dpkg-parsechangelog -SSource)_$(dpkg-parsechangelog -SVersion) head -n1 debian/changelog | sed -nre 's/^(\S*) \((\S*)\).*/\1_\2/gp' )} run_lintian() {( local crate="$1" local version="$2" local cratedir="$crate${version:+-$version}" cd "$directory" allow_fail "$crate" $version && return 0 local base="$(changelog_pkgname "$cratedir")" local out="${base}.lintian.out" if ! ( shouldbuild "$out" "${base}_source.changes" \ || shouldbuild "$out" "${base}_${DEB_HOST_ARCH}.changes" ); then echo >&2 "skipping already-linted ${base}_*.changes in ${out}" return 0 fi echo >&2 "running lintian for ${base} into ${out}" rm -f "$out" "${out}.tmp" changes="${base}_source.changes" lintian --suppress-tags-from-file "$lintian_suppress_tags" -EIL +pedantic "$changes" | tee -a "${out}.tmp" changes="${base}_${DEB_HOST_ARCH}.changes" lintian --suppress-tags-from-file "$lintian_suppress_tags" -EIL +pedantic "$changes" | tee -a "${out}.tmp" mv "${out}.tmp" "$out" )} if [ -z "$CHROOT" ]; then if schroot -i -c "debcargo-unstable-${DEB_HOST_ARCH}-sbuild" >/dev/null 2>&1; then CHROOT="debcargo-unstable-${DEB_HOST_ARCH}-sbuild" else CHROOT=${CHROOT:-unstable-"$DEB_HOST_ARCH"-sbuild} fi fi GPG_KEY_ID="Debcargo Integration Test" run_sbuild() {( local crate="$1" local version="$2" local cratedir="$crate${version:+-$version}" cd "$directory" allow_fail "$crate" $version && return 0 local base="$(changelog_pkgname "$cratedir")" local dsc="${base}.dsc" local build="${base}_${DEB_HOST_ARCH}.build" local changes="${base}_${DEB_HOST_ARCH}.changes" if ! shouldbuild "$changes" "$dsc"; then echo >&2 "skipping already-built ${dsc} in ${changes}" return 0 fi if [ ! -f "signing-key.gpg" ]; then mkdir -p "$PWD/gpg" chmod 700 "$PWD/gpg" GNUPGHOME="$PWD/gpg" gpg --batch --pinentry-mode=loopback --passphrase "" --quick-gen-key "$GPG_KEY_ID" GNUPGHOME="$PWD/gpg" gpg --batch --export "$GPG_KEY_ID" > signing-key.gpg fi # Update the local repo apt-ftparchive packages . > Packages apt-ftparchive release . > Release GNUPGHOME="$PWD/gpg" gpg --batch -a --detach-sign -u "$GPG_KEY_ID" -o Release.gpg --yes Release # We use --build-dep-resolver=aspcud as both apt/aptitude fail to resolve # certain complex dependency situations e.g. bytes-0.4. For our official # Debian rust packages we patch those crates to have simpler dependencies; # but we don't want to maintain those patches for this integration test. # We also pass criteria to minimise the Rust packages we take from the # Debian archive, and maximise the ones generated by this test. echo >&2 "sbuild $dsc logging to $build" sbuild --arch-all --arch-any --no-run-lintian --build-dep-resolver=aspcud \ --aspcud-criteria="-removed,-changed,-new,+count(solution,APT-Release:=/o=sbuild-build-depends-archive/),-count(solution,APT-Release:=/o=Debian/)" \ --extra-repository="deb file:$(readlink -f "$directory") ./" --extra-repository-key="$PWD/signing-key.gpg" \ -c "$CHROOT" -d unstable $SBUILD_EXTRA_ARGS "$dsc" )} build_source() {( local crate="$1" local version="$2" local cratedir="$crate${version:+-$version}" cd "$directory" if [ -d "$cratedir" ]; then if [ -f "$cratedir/debian/changelog" ]; then local base="$(changelog_pkgname "$cratedir")" if ! shouldbuild "${base}_source.buildinfo" "$cratedir/debian/changelog"; then echo >&2 "skipping already-built ${cratedir}" return 0 fi fi rm -rf "$cratedir" fi local deb_src_name="$($debcargo deb-src-name "$crate" "$version")" local config="$config_dir/${deb_src_name}/debian/debcargo.toml" if [ -f "$config" ]; then option="--config $config" if ! grep -q 'semver_suffix = true' "$config"; then echo >&2 "bad config: $config must contain \"semver_suffix = true\"" return 1 fi echo >&2 "using config: $config" elif [ "$deb_src_name" != "$($debcargo deb-src-name "$crate" "")" ]; then config="$config_dir/old-version/debian/debcargo.toml" option="--config $config" echo >&2 "using config: $config" fi if ( set -x; $debcargo package $extraargs --no-overlay-write-back --directory $cratedir $option "${crate}" $version ); then : else local x=$? if allow_fail "$crate" $version; then return 0 fi echo >&2 "crate failed: $crate $version" if [ -n "$failures_file" ]; then echo "$crate" $version >> "$failures_file" return 0 else return $x fi fi cd "${cratedir}" mkdir -p debian/source dpkg-buildpackage -d -S --no-sign )} cargo_tree_rec() { local resolve="$1" shift local cache="$directory/z.${*/\//_}.$resolve.list" if [ ! -f "$cache" ]; then "$debcargo" build-order --resolve-type "$resolve" \ --config-dir "${config_dir}" "$@" > "$cache.tmp" mv "$cache.tmp" "$cache" fi cat "$cache" } run_x_or_deps() { local x="$1" shift case "$x" in *-[0-9]*) spec="${x%-[0-9]*} ${x##*-}" tree_args="${x%-[0-9]*}:${x##*-}" ;; *) spec="$x" tree_args="$x" ;; esac if [ -n "$resolve" ]; then set -o pipefail cargo_tree_rec "$resolve" $tree_args | while read pkg ver extra; do "$@" "$pkg" "${ver#v}" done set +o pipefail fi echo $spec | while read pkg ver extras; do "$@" "$pkg" "${ver#v}" done } # make all paths absolute so things don't mess up when we switch dirs allow_failures=$(readlink -f "$allow_failures") lintian_suppress_tags=$(readlink -f "$lintian_suppress_tags") config_dir=$(readlink -f "$config_dir") directory=$(readlink -f "$directory") scriptdir=$(readlink -f "$scriptdir") # ensure $directory exists and maybe wipe it if ! $keepfiles; then # don't rm the directory itself, in case it's a symlink rm -rf "$directory"/* fi mkdir -p "$directory" cargo build debcargo="$scriptdir/../../target/debug/debcargo" test -x $debcargo for i in "$@"; do run_x_or_deps "$i" true; done for i in "$@"; do run_x_or_deps "$i" build_source; done # sudo schroot -c source:debcargo-unstable-amd64-sbuild -- sh -c 'echo "deb [allow-insecure=yes] file:/home/infinity0/var/lib/rust/debcargo-tmp ./" > /etc/apt/sources.list.d/local-debcargo-integration-test.list' if $run_sbuild; then if ! schroot -i -c "$CHROOT" >/dev/null; then echo >&2 "create the $CHROOT schroot by running e.g.:" echo >&2 " sudo sbuild-createchroot unstable /srv/chroot/$CHROOT http://deb.debian.org/debian" echo >&2 " sudo schroot -c source:$CHROOT -- apt-get -y install dh-cargo" echo >&2 " sudo sbuild-update -udr $CHROOT" echo >&2 "See https://wiki.debian.org/sbuild for more details" exit 1 fi for i in "$@"; do run_x_or_deps "$i" run_sbuild; done fi if $run_lintian; then for i in "$@"; do run_x_or_deps "$i" run_lintian; done fi debcargo-2.5.0/tests/sh/lintian-suppress-tags000064400000000000000000000051030072674642500174000ustar 00000000000000## To be fixed by the package developer # copyright missing-license-paragraph-in-dep5-copyright space-in-std-shortname-in-dep5-copyright license-problem-undefined-license superfluous-file-pattern bad-exception-format-in-dep5-copyright # other source file-contains-fixme-placeholder synopsis-too-long description-synopsis-starts-with-article debian-changelog-line-too-long unknown-section spelling-error-in-binary rust-boilerplate no-manual-page ## To be fixed here in debcargo out-of-date-standards-version package-uses-old-debhelper-compat-version uses-debhelper-compat-file upstream-metadata-file-is-missing ## Cannot be fixed due to Rust crate conventions # crates don't generally have GPG signatures debian-watch-does-not-check-gpg-signature # crates don't always have a homepage no-homepage-field # crates don't always have tests missing-tests-control # crates sometimes just have long source lines very-long-line-length-in-source-file ## Not to be fixed, due to how we package Rust in Debian and lintian being presumptuous # we install the crate into /usr/share/cargo, including most docs package-contains-documentation-outside-usr-share-doc # we install the crate into /usr/share/cargo, lintian is overzealous repeated-path-segment # this is a result of how we have to do rust packaging - # see the comment relating to Multi-Arch in the debcargo source code package-contains-no-arch-dependent-files # Provides issue with FTP pending resolution field-too-long # bug 833608 version-substvar-for-external-package # our policy is not to file ITPs for library crates since there are so many initial-upload-closes-no-bugs ## Not to be fixed, due to our test setup unused-override # lintian doesn't recognise our test "ruzt" prefix wrong-section-according-to-package-name # we don't finalise changelogs for this integration test bad-distribution-in-changes-file distribution-and-changes-mismatch # this is because we don't bother with excluding embedded libs in this # integration test. they are not allowed in Debian and would be a FTP reject # but we don't care for the purposes of this integration test source-is-missing unpack-message-for-orig unpack-message-for-deb-data unpack-message-for-source arch-dependent-file-in-usr-share arch-dependent-file-not-in-arch-specific-directory arch-dep-package-has-big-usr-share embedded-library font-outside-font-dir font-in-non-font-package duplicate-font-file source-contains-autogenerated-gperf-data source-contains-prebuilt-javascript-object windows-devel-file-in-package executable-not-elf-or-script incorrect-path-for-interpreter hardening-no-fortify-functions debcargo-2.5.0/tests/sh/quick-build.sh000075500000000000000000000001750072674642500157550ustar 00000000000000#!/bin/bash set -e cargo build rm -rf rust-* target/debug/debcargo package "$@" nano rust-${1/_/-}-*/debian/${file:-control}