diff --git a/.gitignore b/.gitignore index 7a6353d..2e4d4ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .envrc +**/target/ diff --git a/images/gitea/.dockerignore b/images/gitea/.dockerignore new file mode 100644 index 0000000..456a7a8 --- /dev/null +++ b/images/gitea/.dockerignore @@ -0,0 +1,3 @@ +.git/ +target/ +README.adoc diff --git a/images/gitea/Cargo.lock b/images/gitea/Cargo.lock new file mode 100644 index 0000000..9c6e145 --- /dev/null +++ b/images/gitea/Cargo.lock @@ -0,0 +1,1584 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bstr" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytes" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" + +[[package]] +name = "cc" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", + "unicase", + "unicode-width", +] + +[[package]] +name = "clap_derive" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.76", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "cli-table" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b53f9241f288a7b12c56565f04aaeaeeab6b8923d42d99255d4ca428b4d97f89" +dependencies = [ + "cli-table-derive", + "csv", + "termcolor", + "unicode-width", +] + +[[package]] +name = "cli-table-derive" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e83a93253aaae7c74eb7428ce4faa6e219ba94886908048888701819f82fb94" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "git+https://github.com/sclu1034/color-eyre.git?branch=fork#162d5e766f9414a5e8d72d5212ff5d81f0d06b68" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "gitea" +version = "0.1.2" +dependencies = [ + "clap", + "cli-table", + "color-eyre", + "globwalk", + "reqwest", + "serde", + "serde_json", + "time", + "url", +] + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "object" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-native-certs", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[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.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.209" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.209" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.76", +] + +[[package]] +name = "serde_json" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.39.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.76", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.76", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] diff --git a/images/gitea/Cargo.toml b/images/gitea/Cargo.toml new file mode 100644 index 0000000..7ec1d78 --- /dev/null +++ b/images/gitea/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "gitea" +version = "0.1.2" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "4.2.0", features = ["cargo", "color", "unicode", "std", "derive"] } +color-eyre = "0.6.2" +reqwest = { version = "0.11.16", default-features = false, features = ["blocking", "json", "rustls-tls-native-roots"] } +serde_json = "1.0.95" +serde = { version = "1.0.159", features = ["derive"] } +time = { version = "0.3.20", features = ["formatting", "parsing", "serde"] } +url = { version = "2.3.1", features = ["serde"] } +cli-table = "0.4.7" +globwalk = "0.8.1" + +[profile.release] +strip = "debuginfo" +lto = true + +[profile.dev.package.backtrace] +opt-level = 3 + +[patch.crates-io] +color-eyre = { git = "https://github.com/sclu1034/color-eyre.git", branch = "fork" } diff --git a/images/gitea/Dockerfile b/images/gitea/Dockerfile new file mode 100644 index 0000000..e2daaa6 --- /dev/null +++ b/images/gitea/Dockerfile @@ -0,0 +1,29 @@ +FROM rust:1.80.1-alpine3.20 AS builder + +RUN apk add --no-cache musl-dev; + +WORKDIR /app +COPY . . + +RUN --mount=type=cache,id=cargo-registry,target=/usr/local/cargo/registry \ + --mount=type=cache,id=cargo-target,target=/app/target \ + set -e; \ + cargo build --color always --release --locked; \ + # The cache will disappear after this directive, so we + # need to copy the binary to a persistent place. + cp target/release/gitea /app/gitea; + +FROM alpine:3.20.2 AS final + +RUN apk add --no-cache ca-certificates; + +ENV RUST_BACKTRACE=1 +ENV RUST_LOG=info + +COPY --from=builder /app/gitea /bin/ + +# Put this last, as it's the only thing that's different between variants. +# This way, the previous layers can all be shared. + +ARG VARIANT="missing build arg 'VARIANT'" +COPY ./shims/${VARIANT}/* /opt/resource/ diff --git a/images/gitea/README.adoc b/images/gitea/README.adoc new file mode 100644 index 0000000..b65b7ed --- /dev/null +++ b/images/gitea/README.adoc @@ -0,0 +1,23 @@ += Gitea Concourse Resource + +== Actions + +[source,yaml] +---- +- name: prs + type: gitea-pr + icon: git + source: + access_token: ((my_cred.token)) + repo: some-repo + owner: some_user_or_org + hostname: https://example.com +---- + +=== `check` + +Returns the list of currently active pull requests + +=== `in` + +Writes information about the currently active pull requests to `$1/prs.json`, which can be consumed by a `load_var` step. diff --git a/images/gitea/shims/package/check b/images/gitea/shims/package/check new file mode 100755 index 0000000..82430e1 --- /dev/null +++ b/images/gitea/shims/package/check @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea package check "$@" diff --git a/images/gitea/shims/package/in b/images/gitea/shims/package/in new file mode 100755 index 0000000..48c8805 --- /dev/null +++ b/images/gitea/shims/package/in @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea package in "$@" diff --git a/images/gitea/shims/package/out b/images/gitea/shims/package/out new file mode 100755 index 0000000..0ea48e9 --- /dev/null +++ b/images/gitea/shims/package/out @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea package out "$@" diff --git a/images/gitea/shims/pr/check b/images/gitea/shims/pr/check new file mode 100755 index 0000000..9bdeef2 --- /dev/null +++ b/images/gitea/shims/pr/check @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea pr check "$@" diff --git a/images/gitea/shims/pr/in b/images/gitea/shims/pr/in new file mode 100755 index 0000000..b30fefb --- /dev/null +++ b/images/gitea/shims/pr/in @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea pr in "$@" diff --git a/images/gitea/shims/pr/out b/images/gitea/shims/pr/out new file mode 100755 index 0000000..719df67 --- /dev/null +++ b/images/gitea/shims/pr/out @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea pr out "$@" diff --git a/images/gitea/shims/status/check b/images/gitea/shims/status/check new file mode 100755 index 0000000..05c370e --- /dev/null +++ b/images/gitea/shims/status/check @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea status check "$@" diff --git a/images/gitea/shims/status/in b/images/gitea/shims/status/in new file mode 100755 index 0000000..c652bb8 --- /dev/null +++ b/images/gitea/shims/status/in @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea status in "$@" diff --git a/images/gitea/shims/status/out b/images/gitea/shims/status/out new file mode 100755 index 0000000..af0e7e5 --- /dev/null +++ b/images/gitea/shims/status/out @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/gitea status out "$@" diff --git a/images/gitea/src/cmd/package.rs b/images/gitea/src/cmd/package.rs new file mode 100644 index 0000000..d82d765 --- /dev/null +++ b/images/gitea/src/cmd/package.rs @@ -0,0 +1,286 @@ +use std::fs; +use std::io::{self, Read, Write}; +use std::path::Path; + +use cli_table::format::Justify; +use cli_table::{Cell, Style, Table}; +use color_eyre::eyre::{self, Context}; +use color_eyre::{Help, Report, Result}; +use globwalk::{DirEntry, GlobWalkerBuilder}; +use reqwest::StatusCode; +use serde::{Deserialize, Serialize}; +use serde_json::json; +use time::format_description::well_known::Iso8601; +use url::Url; + +use crate::types::{Package, PackageType}; +use crate::util::make_client; +use crate::Action; + +#[derive(Deserialize, Serialize, Debug)] +struct Source { + access_token: String, + owner: String, + url: Url, + r#type: PackageType, + name: String, +} + +#[derive(Deserialize, Serialize, Debug)] +struct Version { + version: String, +} + +#[derive(Deserialize, Serialize, Debug)] +struct Params { + version: String, + globs: Vec, + #[serde(default)] + fail_fast: bool, + #[serde(default)] + r#override: bool, +} + +#[derive(Deserialize, Serialize, Debug)] +struct Config { + /// Resource configuration. + /// Passed verbatim from the definition in the pipeline. + source: Source, + /// For 'check': + /// Previous version of this resource. + /// Will be empty for the very first request. + /// For 'in': + /// The version metadata to create this as. + version: Option, + params: Option, +} + +fn action_check(conf: Config) -> Result<()> { + let client = make_client(&conf.source.access_token)?; + let url = conf + .source + .url + .join(&format!("api/v1/packages/{}", conf.source.owner)) + .wrap_err("Invalid URL")?; + + let mut pkgs: Vec = client + .get(url) + .query(&[ + ("type", conf.source.r#type.to_string()), + ("q", conf.source.name), + ]) + .send()? + .json()?; + + if pkgs.is_empty() { + return io::stdout().write_all(b"[]").map_err(From::from); + } + + pkgs.sort_unstable_by_key(|pkg| pkg.created_at); + + let table: Vec<_> = pkgs + .iter() + .map(|pkg| { + vec![ + pkg.id.cell().justify(Justify::Center), + pkg.name.clone().cell(), + pkg.owner.login.clone().cell(), + pkg.version.clone().cell(), + pkg.created_at + .format(&Iso8601::DEFAULT) + .unwrap_or_default() + .cell(), + ] + }) + .collect(); + + let table = table + .table() + .title(vec![ + "#".cell().bold(true), + "Name".cell().bold(true), + "Owner".cell().bold(true), + "Version".cell().bold(true), + "Created At".cell().bold(true), + ]) + .bold(true); + + let _ = cli_table::print_stderr(table); + + let newest = pkgs + .last() + .expect("List of packages should not be empty.") + .version + .clone(); + + let out = if let Some(prev) = conf.version { + if prev.version == newest { + vec![prev] + } else { + vec![prev, Version { version: newest }] + } + } else { + vec![Version { version: newest }] + }; + + serde_json::to_writer_pretty(io::stdout(), &out) + .wrap_err("Failed to write result to stdout")?; + + Ok(()) +} + +fn action_out(conf: Config, dir: impl AsRef) -> Result<()> { + let dir = dir + .as_ref() + .canonicalize() + .wrap_err_with(|| format!("Invalid file path '{}'", dir.as_ref().display()))?; + + let Some(params) = conf.params else { + eyre::bail!("Missing params"); + }; + + if params.globs.is_empty() { + eyre::bail!("`params.globs` must not be empty"); + } + + let client = make_client(&conf.source.access_token)?; + let url = conf + .source + .url + .join(&format!( + // The trailing slash is required, to make sure this entire URL is used + // when `join`ing the file name later. Otherwise, the last component + // would be considered a "file" part itself, and replaced by a future `join`. + "api/packages/{}/{}/{}/{}/", + conf.source.owner, conf.source.r#type, conf.source.name, params.version + )) + .wrap_err("Invalid URL")?; + + let walker = GlobWalkerBuilder::from_patterns(dir, ¶ms.globs) + .max_depth(3) + .file_type(globwalk::FileType::FILE) + .build() + .wrap_err("Failed to create glob walker")?; + + let handle_glob = |entry| { + let entry: DirEntry = entry?; + + let name = entry.file_name(); + let path = entry.path(); + let url = url.join(&name.to_string_lossy()).wrap_err("Invalid url")?; + + if params.r#override { + client + .delete(url.clone()) + .send() + .wrap_err_with(|| format!("Failed request 'DELETE {}'", &url))?; + } + + let data = fs::read(path) + .wrap_err_with(|| format!("Failed to read package file '{}'", path.display()))?; + + let res = client + .put(url.clone()) + .body(data) + .send() + .wrap_err_with(|| format!("Failed request 'PUT {}'", &url))?; + + match res.status() { + StatusCode::CREATED => { + eprintln!( + "Uploaded file '{}', version={}, package={}", + name.to_string_lossy(), + params.version, + conf.source.name + ); + } + StatusCode::BAD_REQUEST => { + eyre::bail!( + "Package, version or file name are invalid. package={}, version={}, file={}", + conf.source.name, + params.version, + name.to_string_lossy(), + ); + } + StatusCode::CONFLICT => { + eyre::bail!( + "File '{}' already exists. version={}, package={}", + name.to_string_lossy(), + params.version, + conf.source.name + ); + } + StatusCode::INTERNAL_SERVER_ERROR => { + eyre::bail!( + "Internal server error: {} {}", + res.status(), + res.text().unwrap_or_default() + ); + } + code => { + eyre::bail!("Unexpected status code {}\ntext = {:?}", code, res.text()); + } + } + + Ok::<_, Report>(()) + }; + + let mut has_entry = false; + + let mut errors = Vec::new(); + for entry in walker { + has_entry = true; + if let Err(err) = handle_glob(entry) { + errors.push(err); + if params.fail_fast { + break; + } + } + } + + if !errors.is_empty() { + let mut err = eyre::eyre!("Failed to upload package with {} errors", errors.len()); + + for e in errors { + err = err.report(e); + } + + return Err(err); + } + + if !has_entry { + eyre::bail!("Globs didn't produce any files"); + } + + let out = json!({ + "version": { + "version": params.version + } + }); + + serde_json::to_writer_pretty(io::stdout(), &out) + .wrap_err("Failed to write result to stdout")?; + + Ok(()) +} + +pub(crate) fn run(action: &Action) -> Result<()> { + let config: Config = { + let mut buf = String::new(); + io::stdin() + .read_to_string(&mut buf) + .wrap_err("Failed to read from stdin")?; + + if buf.is_empty() { + eyre::bail!("No data received on stdin"); + } + + serde_json::from_str(&buf).wrap_err("Failed to parse stdin")? + }; + + match action { + Action::Check => action_check(config), + Action::In { dest: _ } => Ok(()), + Action::Out { src } => action_out(config, src), + } +} diff --git a/images/gitea/src/cmd/pr.rs b/images/gitea/src/cmd/pr.rs new file mode 100644 index 0000000..a20f39a --- /dev/null +++ b/images/gitea/src/cmd/pr.rs @@ -0,0 +1,171 @@ +use std::fs; +use std::io::{self, Read}; +use std::path::Path; + +use cli_table::format::Justify; +use cli_table::{print_stderr, Cell, Style, Table}; +use color_eyre::eyre::{self, Context}; +use color_eyre::Result; +use reqwest::blocking::Response; +use serde::{Deserialize, Serialize}; +use serde_json::json; +use time::OffsetDateTime; +use url::Url; + +use crate::types::PullRequest; +use crate::util::make_client; +use crate::Action; + +#[derive(Deserialize, Serialize, Debug)] +struct Source { + access_token: String, + owner: String, + repo: String, + url: Url, +} + +#[derive(Deserialize, Serialize, Debug)] +struct Version { + prs: String, + #[serde(with = "time::serde::iso8601")] + timestamp: OffsetDateTime, +} + +impl<'a, I: Iterator> From for Version { + fn from(prs: I) -> Self { + Self { + prs: prs.fold(String::new(), |mut s, pr| { + if !s.is_empty() { + s.push(','); + } + s.push_str(&pr.number.to_string()); + s + }), + timestamp: OffsetDateTime::now_utc(), + } + } +} + +#[derive(Deserialize, Serialize, Debug)] +struct Config { + /// Resource configuration. + /// Passed verbatim from the definition in the pipeline. + source: Source, + /// For 'check': + /// Previous version of this resource. + /// Will be empty for the very first request. + /// For 'in': + /// The version metadata to create this as. + version: Option, +} + +fn fetch(src: &Source) -> Result { + let client = make_client(&src.access_token).wrap_err("Failed to create HTTP client")?; + let url = src + .url + .join(&format!("api/v1/repos/{}/{}/pulls", src.owner, src.repo)) + .wrap_err("Invalid URL")?; + + client + .get(url) + .query(&[("sort", "oldest"), ("state", "open")]) + .send() + .map_err(From::from) +} + +fn action_check(conf: Config) -> Result<()> { + let prs: Vec = fetch(&conf.source)?.json()?; + let version = Version::from(prs.iter()); + + let out = if let Some(prev) = conf.version { + if prev.prs == version.prs { + vec![prev] + } else { + vec![prev, version] + } + } else { + vec![version] + }; + + let table: Vec<_> = prs + .iter() + .map(|pr| { + vec![ + pr.number.cell().justify(Justify::Center), + pr.title.clone().cell(), + pr.user.login.clone().cell(), + pr.base.r#ref.clone().cell(), + pr.head.r#ref.clone().cell(), + ] + }) + .collect(); + + let table = table + .table() + .title(vec![ + "#".cell().bold(true), + "Title".cell().bold(true), + "User".cell().bold(true), + "Base".cell().bold(true), + "Head".cell().bold(true), + ]) + .bold(true); + + let _ = print_stderr(table); + + serde_json::to_writer_pretty(io::stdout(), &out) + .wrap_err("Failed to write result to stdout")?; + + Ok(()) +} + +fn action_in(conf: Config, dest: impl AsRef) -> Result<()> { + let old_version = if let Some(version) = conf.version { + version + } else { + eyre::bail!("Version missing in 'in' action."); + }; + + let bytes = fetch(&conf.source)?.bytes()?; + let prs: Vec = serde_json::from_slice(&bytes)?; + let version = Version::from(prs.iter()); + + { + if version.prs != old_version.prs { + eyre::bail!("Version to fetch does not match current resource."); + } + } + + let path = dest.as_ref().join("prs.json"); + let _ = fs::create_dir_all(dest); + fs::write(&path, &bytes)?; + + let out = json!({ + "version": version, + }); + + serde_json::to_writer_pretty(io::stdout(), &out)?; + + Ok(()) +} + +pub(crate) fn run(action: &Action) -> Result<()> { + let config: Config = { + let mut buf = String::new(); + io::stdin() + .read_to_string(&mut buf) + .wrap_err("Failed to read from stdin")?; + + if buf.is_empty() { + eyre::bail!("No data received on stdin"); + } + + serde_json::from_str(&buf).wrap_err("Failed to parse stdin")? + }; + + match action { + Action::Check => action_check(config), + Action::In { dest } => action_in(config, dest), + Action::Out { src: _ } => Ok(()), + } +} diff --git a/images/gitea/src/cmd/status.rs b/images/gitea/src/cmd/status.rs new file mode 100644 index 0000000..5533bae --- /dev/null +++ b/images/gitea/src/cmd/status.rs @@ -0,0 +1,154 @@ +use color_eyre::eyre; +use color_eyre::eyre::WrapErr; +use color_eyre::Help; +use color_eyre::Result; +use color_eyre::SectionExt; +use reqwest::StatusCode; +use serde::Deserialize; +use serde::Serialize; +use serde_json::json; +use std::io; +use std::io::Read; +use std::path::Path; +use url::Url; + +use crate::util::make_client; +use crate::Action; + +#[derive(Deserialize, Serialize, Debug)] +struct Source { + access_token: String, + owner: String, + url: Url, + repo: String, + sha: String, + context: String, + description: Option, + target_url: Option, +} + +#[derive(Deserialize, Serialize, Debug, Copy, Clone)] +#[serde(rename_all = "snake_case")] +enum State { + Pending, + Success, + Error, + Failure, + Warning, +} + +impl std::fmt::Display for State { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + State::Pending => write!(f, "pending"), + State::Success => write!(f, "success"), + State::Error => write!(f, "error"), + State::Failure => write!(f, "failure"), + State::Warning => write!(f, "warning"), + } + } +} + +#[derive(Deserialize, Serialize, Debug)] +struct Params { + state: State, + description: Option, +} + +#[derive(Deserialize, Serialize, Debug)] +struct Config { + /// Resource configuration. + /// Passed verbatim from the definition in the pipeline. + source: Source, + params: Params, +} + +fn action_out(conf: Config, _dir: impl AsRef) -> Result<()> { + let params = conf.params; + let description = params.description.or(conf.source.description); + + let client = make_client(&conf.source.access_token)?; + let url = conf + .source + .url + .join(&format!( + // The trailing slash is required, to make sure this entire URL is used + // when `join`ing the file name later. Otherwise, the last component + // would be considered a "file" part itself, and replaced by a future `join`. + "api/v1/repos/{}/{}/statuses/{}", + conf.source.owner, conf.source.repo, conf.source.sha + )) + .wrap_err("Invalid URL")?; + + let body = json!({ + "context": conf.source.context, + "description": description, + "state": params.state, + "target_url": conf.source.target_url, + }); + + let res = client + .post(url.clone()) + .json(&body) + .send() + .wrap_err_with(|| format!("Failed to send request 'POST {}'", url))?; + + match res.status() { + StatusCode::CREATED => { + eprintln!( + "Created status '{}' on commit '{}'", + params.state, conf.source.sha + ); + } + StatusCode::BAD_REQUEST => { + eyre::bail!( + "Invalid request: {:?}. state={}, context={}, description={:?}, target_url={:?}", + res.text(), + params.state, + conf.source.context, + description, + conf.source.target_url + ) + } + code => { + eyre::bail!("Unexpected status code {}\ntext = {:?}", code, res.text()); + } + } + + println!("{{ \"version\": {{}} }}"); + Ok(()) +} + +pub(crate) fn run(action: &Action) -> Result<()> { + // TODO: Gitea does actually support fetching statuses, making `check` and `in` viable, + // theoretically. But it also doesn't make much sense to implement them. + match action { + Action::Check => { + // Dummy implemented that always reports nothing. + println!("[]"); + Ok(()) + } + Action::In { dest: _ } => { + println!("{{}}"); + Ok(()) + } + Action::Out { src } => { + let config: Config = { + let mut buf = String::new(); + io::stdin() + .read_to_string(&mut buf) + .wrap_err("Failed to read from stdin")?; + + if buf.is_empty() { + eyre::bail!("No data received on stdin"); + } + + serde_json::from_str(&buf) + .wrap_err("Failed to parse stdin") + .with_section(|| buf.header("JSON"))? + }; + + action_out(config, src) + } + } +} diff --git a/images/gitea/src/main.rs b/images/gitea/src/main.rs new file mode 100644 index 0000000..23a608d --- /dev/null +++ b/images/gitea/src/main.rs @@ -0,0 +1,56 @@ +use std::path::PathBuf; + +use clap::{Parser, Subcommand}; +use color_eyre::Result; + +static USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); + +#[derive(Debug, Parser)] +#[command(author, version, about, long_about = None)] +#[command(propagate_version = true)] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Clone, Debug, Subcommand)] +enum Commands { + Pr { + #[command(subcommand)] + action: Action, + }, + Package { + #[command(subcommand)] + action: Action, + }, + Status { + #[command(subcommand)] + action: Action, + }, +} + +#[derive(Clone, Debug, Subcommand)] +pub(crate) enum Action { + Check, + In { dest: PathBuf }, + Out { src: PathBuf }, +} + +mod types; +mod util; +mod cmd { + pub mod package; + pub mod pr; + pub mod status; +} + +fn main() -> Result<()> { + color_eyre::install()?; + let cli = Cli::parse(); + + match &cli.command { + Commands::Pr { action } => cmd::pr::run(action), + Commands::Package { action } => cmd::package::run(action), + Commands::Status { action } => cmd::status::run(action), + } +} diff --git a/images/gitea/src/types.rs b/images/gitea/src/types.rs new file mode 100644 index 0000000..23d7b6a --- /dev/null +++ b/images/gitea/src/types.rs @@ -0,0 +1,46 @@ +use serde::{Deserialize, Serialize}; +use time::OffsetDateTime; + +#[derive(Clone, Debug, Deserialize)] +pub struct Ref { + pub r#ref: String, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct User { + pub login: String, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct PullRequest { + pub number: u64, + pub title: String, + pub user: User, + pub base: Ref, + pub head: Ref, +} + +#[derive(Copy, Clone, Deserialize, Serialize, Debug)] +#[serde(rename_all = "snake_case")] +pub enum PackageType { + Generic, +} + +impl std::fmt::Display for PackageType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PackageType::Generic => write!(f, "generic"), + } + } +} + +#[derive(Clone, Debug, Deserialize)] +pub struct Package { + #[serde(with = "time::serde::iso8601")] + pub created_at: OffsetDateTime, + pub id: u64, + pub name: String, + pub owner: User, + pub r#type: PackageType, + pub version: String, +} diff --git a/images/gitea/src/util.rs b/images/gitea/src/util.rs new file mode 100644 index 0000000..825c978 --- /dev/null +++ b/images/gitea/src/util.rs @@ -0,0 +1,19 @@ +use color_eyre::Result; +use reqwest::blocking::Client; +use reqwest::header::HeaderMap; + +use crate::USER_AGENT; + +pub(crate) fn make_client(access_token: impl AsRef) -> Result { + let mut headers = HeaderMap::new(); + headers.insert( + "Authorization", + format!("token {}", access_token.as_ref()).try_into()?, + ); + + Client::builder() + .default_headers(headers) + .user_agent(USER_AGENT) + .build() + .map_err(From::from) +} diff --git a/images/gitea/test.sh b/images/gitea/test.sh new file mode 100755 index 0000000..1dbfc6a --- /dev/null +++ b/images/gitea/test.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +set -e + +cargo build + +run() { +./target/debug/gitea package "$1" <