refactor: Use askama crate for compile-time template type checking
This commit is contained in:
parent
039c5f9659
commit
d663b7574b
9 changed files with 364 additions and 778 deletions
548
Cargo.lock
generated
548
Cargo.lock
generated
|
|
@ -80,6 +80,52 @@ version = "1.0.77"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9"
|
||||
|
||||
[[package]]
|
||||
name = "askama"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28"
|
||||
dependencies = [
|
||||
"askama_derive",
|
||||
"askama_escape",
|
||||
"humansize",
|
||||
"num-traits",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_derive"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ccf09143e56923c12e027b83a9553210a3c58322ed8419a53461b14a4dccd85"
|
||||
dependencies = [
|
||||
"askama_parser",
|
||||
"basic-toml",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_escape"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||
|
||||
[[package]]
|
||||
name = "askama_parser"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "262eb9cf7be51269c5f2951eeda9ccd14d6934e437457f47b4f066bf55a6770d"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
|
|
@ -87,10 +133,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
name = "basic-toml"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
checksum = "2f2139706359229bfa8f19142ac1155b4b80beafb7a60471ac5dd109d4a19778"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
|
|
@ -98,20 +147,12 @@ version = "2.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blue-build"
|
||||
version = "0.3.9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"cfg-if",
|
||||
"chrono",
|
||||
"clap",
|
||||
|
|
@ -123,20 +164,9 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"tera",
|
||||
"typed-builder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.14.0"
|
||||
|
|
@ -172,28 +202,6 @@ dependencies = [
|
|||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono-tz"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91d7b79e99bfaa0d47da0687c43aa3b7381938a62ad3a6498599039321f660b7"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz-build",
|
||||
"phf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono-tz-build"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f"
|
||||
dependencies = [
|
||||
"parse-zoneinfo",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ci_info"
|
||||
version = "0.10.2"
|
||||
|
|
@ -265,56 +273,6 @@ version = "0.8.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.4"
|
||||
|
|
@ -381,22 +339,6 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deunicode"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.1"
|
||||
|
|
@ -448,16 +390,6 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1fd087255f739f4f1aeea69f11b72f8080e9c2e7645cd06955dad4a178a49e3"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
|
|
@ -467,41 +399,6 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[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 = "hashbrown"
|
||||
version = "0.12.3"
|
||||
|
|
@ -570,22 +467,6 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "747ad1b4ae841a78e8aba0d63adbfbeaea26b517b63705d47856b73015d27060"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"globset",
|
||||
"log",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"same-file",
|
||||
"walkdir",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
|
|
@ -632,12 +513,6 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.151"
|
||||
|
|
@ -668,12 +543,44 @@ version = "2.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nias"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
|
|
@ -689,110 +596,12 @@ version = "1.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "parse-zoneinfo"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.71"
|
||||
|
|
@ -811,36 +620,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
|
|
@ -876,7 +655,7 @@ version = "0.38.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
|
|
@ -901,15 +680,6 @@ version = "1.0.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
|
||||
[[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 = "serde"
|
||||
version = "1.0.193"
|
||||
|
|
@ -954,33 +724,6 @@ dependencies = [
|
|||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "slug"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4"
|
||||
dependencies = [
|
||||
"deunicode",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
|
|
@ -1009,28 +752,6 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tera"
|
||||
version = "1.19.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"globwalk",
|
||||
"humansize",
|
||||
"lazy_static",
|
||||
"percent-encoding",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"slug",
|
||||
"unic-segment",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.0"
|
||||
|
|
@ -1040,26 +761,6 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
|
|
@ -1090,65 +791,12 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
name = "unicase"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-property"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
|
||||
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
|
||||
dependencies = [
|
||||
"unic-char-range",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-range"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
|
||||
|
||||
[[package]]
|
||||
name = "unic-common"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
|
||||
|
||||
[[package]]
|
||||
name = "unic-segment"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23"
|
||||
dependencies = [
|
||||
"unic-ucd-segment",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-ucd-segment"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700"
|
||||
dependencies = [
|
||||
"unic-char-property",
|
||||
"unic-char-range",
|
||||
"unic-ucd-version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-ucd-version"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
|
||||
dependencies = [
|
||||
"unic-common",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1181,22 +829,6 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[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.89"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ categories = ["command-line-utilities"]
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.75"
|
||||
askama = { version = "0.12.1", features = ["serde-json"] }
|
||||
cfg-if = "1.0.0"
|
||||
chrono = "0.4.31"
|
||||
clap = { version = "4.4.4", features = ["derive"] }
|
||||
|
|
@ -21,7 +22,6 @@ log = "0.4.20"
|
|||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
serde_json = "1.0.107"
|
||||
serde_yaml = "0.9.25"
|
||||
tera = "1.19.1"
|
||||
typed-builder = "0.18.0"
|
||||
|
||||
[features]
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ use clap::Args;
|
|||
use log::{debug, error, info, trace, warn};
|
||||
use typed_builder::TypedBuilder;
|
||||
|
||||
use crate::{module_recipe::Recipe, ops, template::TemplateCommand};
|
||||
use crate::{
|
||||
ops,
|
||||
template::{Recipe, TemplateCommand},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Args, TypedBuilder)]
|
||||
pub struct BuildCommand {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,5 @@ pub mod init;
|
|||
#[cfg(feature = "build")]
|
||||
pub mod build;
|
||||
|
||||
pub mod module_recipe;
|
||||
mod ops;
|
||||
pub mod template;
|
||||
|
|
|
|||
|
|
@ -1,119 +1 @@
|
|||
use std::{collections::HashMap, env};
|
||||
|
||||
use chrono::Local;
|
||||
use log::{debug, info, trace, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Value;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Recipe {
|
||||
pub name: String,
|
||||
|
||||
pub description: String,
|
||||
|
||||
#[serde(alias = "base-image")]
|
||||
pub base_image: String,
|
||||
|
||||
#[serde(alias = "image-version")]
|
||||
pub image_version: String,
|
||||
|
||||
pub modules: Vec<Module>,
|
||||
|
||||
pub containerfiles: Option<Containerfiles>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub extra: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
impl Recipe {
|
||||
pub fn generate_tags(&self) -> Vec<String> {
|
||||
debug!("Generating image tags for {}", &self.name);
|
||||
trace!("Recipe::generate_tags()");
|
||||
|
||||
let mut tags: Vec<String> = Vec::new();
|
||||
let image_version = &self.image_version;
|
||||
let timestamp = Local::now().format("%Y%m%d").to_string();
|
||||
|
||||
if let (Ok(commit_branch), Ok(default_branch), Ok(commit_sha), Ok(pipeline_source)) = (
|
||||
env::var("CI_COMMIT_REF_NAME"),
|
||||
env::var("CI_DEFAULT_BRANCH"),
|
||||
env::var("CI_COMMIT_SHORT_SHA"),
|
||||
env::var("CI_PIPELINE_SOURCE"),
|
||||
) {
|
||||
trace!("CI_COMMIT_REF_NAME={commit_branch}, CI_DEFAULT_BRANCH={default_branch},CI_COMMIT_SHORT_SHA={commit_sha}, CI_PIPELINE_SOURCE={pipeline_source}");
|
||||
warn!("Detected running in Gitlab, pulling information from CI variables");
|
||||
|
||||
if let Ok(mr_iid) = env::var("CI_MERGE_REQUEST_IID") {
|
||||
trace!("CI_MERGE_REQUEST_IID={mr_iid}");
|
||||
if pipeline_source == "merge_request_event" {
|
||||
debug!("Running in a MR");
|
||||
tags.push(format!("mr-{mr_iid}-{image_version}"));
|
||||
}
|
||||
}
|
||||
|
||||
if default_branch != commit_branch {
|
||||
debug!("Running on branch {commit_branch}");
|
||||
tags.push(format!("{commit_branch}-{image_version}"));
|
||||
} else {
|
||||
debug!("Running on the default branch");
|
||||
tags.push(image_version.to_string());
|
||||
tags.push(format!("{image_version}-{timestamp}"));
|
||||
tags.push(timestamp.to_string());
|
||||
}
|
||||
|
||||
tags.push(format!("{commit_sha}-{image_version}"));
|
||||
} else if let (
|
||||
Ok(github_event_name),
|
||||
Ok(github_event_number),
|
||||
Ok(github_sha),
|
||||
Ok(github_ref_name),
|
||||
) = (
|
||||
env::var("GITHUB_EVENT_NAME"),
|
||||
env::var("PR_EVENT_NUMBER"),
|
||||
env::var("GITHUB_SHA"),
|
||||
env::var("GITHUB_REF_NAME"),
|
||||
) {
|
||||
trace!("GITHUB_EVENT_NAME={github_event_name},PR_EVENT_NUMBER={github_event_number},GITHUB_SHA={github_sha},GITHUB_REF_NAME={github_ref_name}");
|
||||
warn!("Detected running in Github, pulling information from GITHUB variables");
|
||||
|
||||
let mut short_sha = github_sha.clone();
|
||||
short_sha.truncate(7);
|
||||
|
||||
if github_event_name == "pull_request" {
|
||||
debug!("Running in a PR");
|
||||
tags.push(format!("pr-{github_event_number}-{image_version}"));
|
||||
} else if github_ref_name == "live" {
|
||||
tags.push(image_version.to_owned());
|
||||
tags.push(format!("{image_version}-{timestamp}"));
|
||||
tags.push("latest".to_string());
|
||||
} else {
|
||||
tags.push(format!("br-{github_ref_name}-{image_version}"));
|
||||
}
|
||||
tags.push(format!("{short_sha}-{image_version}"));
|
||||
} else {
|
||||
warn!("Running locally");
|
||||
tags.push(format!("{image_version}-local"));
|
||||
}
|
||||
info!("Finished generating tags!");
|
||||
debug!("Tags: {tags:#?}");
|
||||
tags
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Module {
|
||||
#[serde(rename = "type")]
|
||||
pub module_type: Option<String>,
|
||||
|
||||
#[serde(rename = "from-file")]
|
||||
pub from_file: Option<String>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub config: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Containerfiles {
|
||||
pub pre: Option<Vec<String>>,
|
||||
pub post: Option<Vec<String>>,
|
||||
}
|
||||
|
|
|
|||
352
src/template.rs
352
src/template.rs
|
|
@ -6,15 +6,139 @@ use std::{
|
|||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use askama::Template;
|
||||
use chrono::Local;
|
||||
use clap::Args;
|
||||
use log::{debug, error, info, trace};
|
||||
use tera::{Context, Tera};
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Value;
|
||||
use typed_builder::TypedBuilder;
|
||||
|
||||
use crate::module_recipe::Recipe;
|
||||
#[derive(Debug, Clone, Template, TypedBuilder)]
|
||||
#[template(path = "Containerfile")]
|
||||
pub struct ContainerFileTemplate<'a> {
|
||||
recipe: &'a Recipe,
|
||||
recipe_path: &'a Path,
|
||||
|
||||
pub const DEFAULT_CONTAINERFILE: &str = include_str!("../templates/Containerfile.tera");
|
||||
pub const EXPORT_SCRIPT: &str = include_str!("../templates/export.sh");
|
||||
#[builder(default)]
|
||||
export_script: ExportsTemplate,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Template)]
|
||||
#[template(path = "export.sh", escape = "none")]
|
||||
pub struct ExportsTemplate;
|
||||
|
||||
#[derive(Serialize, Clone, Deserialize, Debug)]
|
||||
pub struct Recipe {
|
||||
pub name: String,
|
||||
|
||||
pub description: String,
|
||||
|
||||
#[serde(alias = "base-image")]
|
||||
pub base_image: String,
|
||||
|
||||
#[serde(alias = "image-version")]
|
||||
pub image_version: String,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub modules_ext: ModuleExt,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub extra: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
impl Recipe {
|
||||
pub fn generate_tags(&self) -> Vec<String> {
|
||||
debug!("Generating image tags for {}", &self.name);
|
||||
trace!("Recipe::generate_tags()");
|
||||
|
||||
let mut tags: Vec<String> = Vec::new();
|
||||
let image_version = &self.image_version;
|
||||
let timestamp = Local::now().format("%Y%m%d").to_string();
|
||||
|
||||
if let (Ok(commit_branch), Ok(default_branch), Ok(commit_sha), Ok(pipeline_source)) = (
|
||||
env::var("CI_COMMIT_REF_NAME"),
|
||||
env::var("CI_DEFAULT_BRANCH"),
|
||||
env::var("CI_COMMIT_SHORT_SHA"),
|
||||
env::var("CI_PIPELINE_SOURCE"),
|
||||
) {
|
||||
trace!("CI_COMMIT_REF_NAME={commit_branch}, CI_DEFAULT_BRANCH={default_branch},CI_COMMIT_SHORT_SHA={commit_sha}, CI_PIPELINE_SOURCE={pipeline_source}");
|
||||
warn!("Detected running in Gitlab, pulling information from CI variables");
|
||||
|
||||
if let Ok(mr_iid) = env::var("CI_MERGE_REQUEST_IID") {
|
||||
trace!("CI_MERGE_REQUEST_IID={mr_iid}");
|
||||
if pipeline_source == "merge_request_event" {
|
||||
debug!("Running in a MR");
|
||||
tags.push(format!("mr-{mr_iid}-{image_version}"));
|
||||
}
|
||||
}
|
||||
|
||||
if default_branch != commit_branch {
|
||||
debug!("Running on branch {commit_branch}");
|
||||
tags.push(format!("{commit_branch}-{image_version}"));
|
||||
} else {
|
||||
debug!("Running on the default branch");
|
||||
tags.push(image_version.to_string());
|
||||
tags.push(format!("{image_version}-{timestamp}"));
|
||||
tags.push(timestamp.to_string());
|
||||
}
|
||||
|
||||
tags.push(format!("{commit_sha}-{image_version}"));
|
||||
} else if let (
|
||||
Ok(github_event_name),
|
||||
Ok(github_event_number),
|
||||
Ok(github_sha),
|
||||
Ok(github_ref_name),
|
||||
) = (
|
||||
env::var("GITHUB_EVENT_NAME"),
|
||||
env::var("PR_EVENT_NUMBER"),
|
||||
env::var("GITHUB_SHA"),
|
||||
env::var("GITHUB_REF_NAME"),
|
||||
) {
|
||||
trace!("GITHUB_EVENT_NAME={github_event_name},PR_EVENT_NUMBER={github_event_number},GITHUB_SHA={github_sha},GITHUB_REF_NAME={github_ref_name}");
|
||||
warn!("Detected running in Github, pulling information from GITHUB variables");
|
||||
|
||||
let mut short_sha = github_sha.clone();
|
||||
short_sha.truncate(7);
|
||||
|
||||
if github_event_name == "pull_request" {
|
||||
debug!("Running in a PR");
|
||||
tags.push(format!("pr-{github_event_number}-{image_version}"));
|
||||
} else if github_ref_name == "live" {
|
||||
tags.push(image_version.to_owned());
|
||||
tags.push(format!("{image_version}-{timestamp}"));
|
||||
tags.push("latest".to_string());
|
||||
} else {
|
||||
tags.push(format!("br-{github_ref_name}-{image_version}"));
|
||||
}
|
||||
tags.push(format!("{short_sha}-{image_version}"));
|
||||
} else {
|
||||
warn!("Running locally");
|
||||
tags.push(format!("{image_version}-local"));
|
||||
}
|
||||
info!("Finished generating tags!");
|
||||
debug!("Tags: {tags:#?}");
|
||||
tags
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Deserialize, Debug, Template)]
|
||||
#[template(path = "Containerfile.module", escape = "none")]
|
||||
pub struct ModuleExt {
|
||||
pub modules: Vec<Module>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Module {
|
||||
#[serde(rename = "type")]
|
||||
pub module_type: Option<String>,
|
||||
|
||||
#[serde(rename = "from-file")]
|
||||
pub from_file: Option<String>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub config: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Args, TypedBuilder)]
|
||||
pub struct TemplateCommand {
|
||||
|
|
@ -50,14 +174,16 @@ impl TemplateCommand {
|
|||
fn template_file(&self) -> Result<()> {
|
||||
trace!("TemplateCommand::template_file()");
|
||||
|
||||
debug!("Setting up tera");
|
||||
let (tera, context) = self.setup_tera()?;
|
||||
debug!("Deserializing recipe");
|
||||
let recipe_de = serde_yaml::from_str::<Recipe>(fs::read_to_string(&self.recipe)?.as_str())?;
|
||||
trace!("recipe_de: {recipe_de:#?}");
|
||||
|
||||
trace!("tera: {tera:#?}");
|
||||
trace!("context: {context:#?}");
|
||||
let template = ContainerFileTemplate::builder()
|
||||
.recipe(&recipe_de)
|
||||
.recipe_path(&self.recipe)
|
||||
.build();
|
||||
|
||||
debug!("Rendering Containerfile");
|
||||
let output_str = tera.render("Containerfile", &context)?;
|
||||
let output_str = template.render()?;
|
||||
|
||||
match self.output.as_ref() {
|
||||
Some(output) => {
|
||||
|
|
@ -75,137 +201,83 @@ impl TemplateCommand {
|
|||
info!("Finished templating Containerfile");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_tera(&self) -> Result<(Tera, Context)> {
|
||||
trace!("TemplateCommand::setup_tera()");
|
||||
fn print_script(script_contents: &ExportsTemplate) -> String {
|
||||
trace!("print_script({script_contents})");
|
||||
|
||||
debug!("Deserializing recipe");
|
||||
let recipe_de = serde_yaml::from_str::<Recipe>(fs::read_to_string(&self.recipe)?.as_str())?;
|
||||
trace!("recipe_de: {recipe_de:#?}");
|
||||
format!(
|
||||
"\"{}\"",
|
||||
script_contents
|
||||
.render()
|
||||
.unwrap_or_else(|e| {
|
||||
error!("Failed to render export.sh script: {e}");
|
||||
process::exit(1);
|
||||
})
|
||||
.replace('\n', "\\n")
|
||||
.replace('\"', "\\\"")
|
||||
.replace('$', "\\$")
|
||||
)
|
||||
}
|
||||
|
||||
debug!("Building context");
|
||||
let mut context = Context::from_serialize(recipe_de)?;
|
||||
|
||||
trace!("add to context 'recipe': {}", self.recipe.display());
|
||||
context.insert("recipe", &self.recipe);
|
||||
|
||||
let mut tera = Tera::default();
|
||||
|
||||
match self.containerfile.as_ref() {
|
||||
Some(containerfile) => {
|
||||
debug!("Using {} as the template", containerfile.display());
|
||||
tera.add_raw_template("Containerfile", &fs::read_to_string(containerfile)?)?
|
||||
}
|
||||
None => tera.add_raw_template("Containerfile", DEFAULT_CONTAINERFILE)?,
|
||||
}
|
||||
|
||||
debug!("Registering function `print_containerfile`");
|
||||
tera.register_function(
|
||||
"print_containerfile",
|
||||
|args: &HashMap<String, tera::Value>| -> tera::Result<tera::Value> {
|
||||
trace!("tera fn print_containerfile({args:#?})");
|
||||
match args.get("containerfile") {
|
||||
Some(v) => match v.as_str() {
|
||||
Some(containerfile) => {
|
||||
debug!("Loading containerfile contents for {containerfile}");
|
||||
|
||||
let path =
|
||||
format!("config/containerfiles/{containerfile}/Containerfile");
|
||||
let path = Path::new(path.as_str());
|
||||
|
||||
let file = fs::read_to_string(path)?;
|
||||
|
||||
trace!("Containerfile contents {}:\n{file}", path.display());
|
||||
Ok(file.into())
|
||||
}
|
||||
None => Err("Arg containerfile wasn't a string".into()),
|
||||
},
|
||||
None => {
|
||||
Err("Needs the argument 'containerfile' for print_containerfile()".into())
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
debug!("Registering function `print_module_context`");
|
||||
tera.register_function(
|
||||
"print_module_context",
|
||||
|args: &HashMap<String, tera::Value>| -> tera::Result<tera::Value> {
|
||||
trace!("tera fn print_module_context({args:#?})");
|
||||
match args.get("module") {
|
||||
Some(v) => match serde_json::to_string(v) {
|
||||
Ok(s) => Ok(s.into()),
|
||||
Err(e) => Err(format!("Unable to serialize: {e}").into()),
|
||||
},
|
||||
None => Err("Needs the argument 'module' for print_module_context()".into()),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
debug!("Registering function `get_module_from_file`");
|
||||
tera.register_function(
|
||||
"get_module_from_file",
|
||||
|args: &HashMap<String, tera::Value>| -> tera::Result<tera::Value> {
|
||||
trace!("tera fn get_module_from_file({args:#?})");
|
||||
match args.get("file") {
|
||||
Some(v) => {
|
||||
let file = match v.as_str() {
|
||||
Some(s) => s,
|
||||
None => return Err("Property 'from-file' must be a string".into()),
|
||||
};
|
||||
|
||||
trace!("from-file: {file}");
|
||||
match serde_yaml::from_str::<tera::Value>(
|
||||
fs::read_to_string(format!("config/{file}"))?.as_str(),
|
||||
) {
|
||||
Ok(context) => {
|
||||
trace!("context: {context}");
|
||||
Ok(context)
|
||||
}
|
||||
Err(_) => Err(format!("Unable to deserialize file {file}").into()),
|
||||
}
|
||||
}
|
||||
None => Err("Needs the argument 'file' for get_module_from_file()".into()),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
debug!("Registering function `running_gitlab_actions`");
|
||||
tera.register_function(
|
||||
"running_gitlab_actions",
|
||||
|_: &HashMap<String, tera::Value>| -> tera::Result<tera::Value> {
|
||||
trace!("tera fn running_gitlab_actions()");
|
||||
|
||||
Ok(env::var("GITHUB_ACTIONS").is_ok_and(|e| e == "true").into())
|
||||
},
|
||||
);
|
||||
|
||||
debug!("Registering function `print_script`");
|
||||
tera.register_function(
|
||||
"print_script",
|
||||
|args: &HashMap<String, tera::Value>| -> tera::Result<tera::Value> {
|
||||
trace!("tera fn print_script({args:#?})");
|
||||
|
||||
let escape_script = |script_contents: &str| {
|
||||
format!(
|
||||
"\"{}\"",
|
||||
script_contents
|
||||
.replace('\n', "\\n")
|
||||
.replace('\"', "\\\"")
|
||||
.replace('$', "\\$")
|
||||
)
|
||||
};
|
||||
|
||||
match args.get("script") {
|
||||
Some(x) => match x.as_str().unwrap_or_default() {
|
||||
"export" => Ok(escape_script(EXPORT_SCRIPT).into()),
|
||||
_ => Err(format!("Script {x} doesn't exist").into()),
|
||||
},
|
||||
None => Err("Needs the argument 'script' for 'print_script()'".into()),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Ok((tera, context))
|
||||
fn get_containerfile_list(module: &Module) -> Option<Vec<String>> {
|
||||
if module.module_type.as_ref()? == "containerfile" {
|
||||
Some(
|
||||
module
|
||||
.config
|
||||
.get("containerfiles")?
|
||||
.as_sequence()?
|
||||
.iter()
|
||||
.filter_map(|t| Some(t.as_str()?.to_owned()))
|
||||
.collect(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn print_containerfile(containerfile: &str) -> String {
|
||||
trace!("print_containerfile({containerfile})");
|
||||
debug!("Loading containerfile contents for {containerfile}");
|
||||
|
||||
let path = format!("config/containerfiles/{containerfile}/Containerfile");
|
||||
|
||||
let file = fs::read_to_string(&path).unwrap_or_else(|e| {
|
||||
error!("Failed to read file {path}: {e}");
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
trace!("Containerfile contents {path}:\n{file}");
|
||||
|
||||
file
|
||||
}
|
||||
|
||||
fn get_module_from_file(file: &str) -> ModuleExt {
|
||||
trace!("get_module_from_file({file})");
|
||||
|
||||
serde_yaml::from_str(
|
||||
fs::read_to_string(format!("config/{file}").as_str())
|
||||
.unwrap_or_else(|e| {
|
||||
error!("Failed to read module {file}: {e}");
|
||||
process::exit(1);
|
||||
})
|
||||
.as_str(),
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
error!("Failed to parse {file}: {e}");
|
||||
process::exit(1);
|
||||
})
|
||||
}
|
||||
|
||||
fn print_module_context(module: &Module) -> String {
|
||||
serde_json::to_string(module).unwrap_or_else(|e| {
|
||||
error!("Failed to parse module: {e}");
|
||||
process::exit(1);
|
||||
})
|
||||
}
|
||||
|
||||
fn running_gitlab_actions() -> bool {
|
||||
trace!(" running_gitlab_actions()");
|
||||
|
||||
env::var("GITHUB_ACTIONS").is_ok_and(|e| e == "true")
|
||||
}
|
||||
|
|
|
|||
40
templates/Containerfile
Normal file
40
templates/Containerfile
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
FROM {{ recipe.base_image }}:{{ recipe.image_version }}
|
||||
|
||||
LABEL org.opencontainers.image.title="{{ recipe.name }}"
|
||||
LABEL org.opencontainers.image.version="{{ recipe.image_version }}"
|
||||
LABEL org.opencontainers.image.description="{{ recipe.description }}"
|
||||
LABEL io.artifacthub.package.readme-url=https://raw.githubusercontent.com/ublue-os/startingpoint/main/README.md
|
||||
LABEL io.artifacthub.package.logo-url=https://avatars.githubusercontent.com/u/120078124?s=200&v=4
|
||||
|
||||
ARG RECIPE={{ recipe_path.display() }}
|
||||
{%- if self::running_gitlab_actions() %}
|
||||
ARG IMAGE_REGISTRY=ghcr.io/ublue-os
|
||||
COPY cosign.pub /usr/share/ublue-os/cosign.pub
|
||||
{%- endif %}
|
||||
|
||||
# Copy the bling from ublue-os/bling into tmp, to be installed later by the bling module
|
||||
# Feel free to remove these lines if you want to speed up image builds and don't want any bling
|
||||
COPY --from=ghcr.io/ublue-os/bling:latest /rpms /tmp/bling/rpms
|
||||
COPY --from=ghcr.io/ublue-os/bling:latest /files /tmp/bling/files
|
||||
|
||||
COPY --from=docker.io/mikefarah/yq /usr/bin/yq /usr/bin/yq
|
||||
|
||||
COPY --from=gcr.io/projectsigstore/cosign /ko-app/cosign /usr/bin/cosign
|
||||
|
||||
COPY config /tmp/config/
|
||||
|
||||
# Copy modules
|
||||
# The default modules are inside ublue-os/bling
|
||||
COPY --from=ghcr.io/ublue-os/bling:latest /modules /tmp/modules/
|
||||
# Custom modules overwrite defaults
|
||||
COPY modules /tmp/modules/
|
||||
|
||||
RUN printf {{ self::print_script(export_script) }} >> /tmp/exports.sh && chmod +x /tmp/exports.sh
|
||||
|
||||
ARG CONFIG_DIRECTORY="/tmp/config"
|
||||
ARG IMAGE_NAME="{{ recipe.name }}"
|
||||
ARG BASE_IMAGE="{{ recipe.base_image }}"
|
||||
|
||||
{{ recipe.modules_ext }}
|
||||
|
||||
RUN rm -rf /tmp/* /var/* && ostree container commit
|
||||
17
templates/Containerfile.module
Normal file
17
templates/Containerfile.module
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{%- for module in modules %}
|
||||
{%- if let Some(type) = module.module_type %}
|
||||
{%- if type == "containerfile" %}
|
||||
{%- if let Some(containerfiles) = self::get_containerfile_list(module) %}
|
||||
{%- for c in containerfiles %}
|
||||
{{ self::print_containerfile(c) }}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- else %}
|
||||
RUN chmod +x /tmp/modules/{{ type }}/{{ type }}.sh && source /tmp/exports.sh && /tmp/modules/{{ type }}/{{ type }}.sh '{{ self::print_module_context(module) }}'
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- if let Some(from_file) = module.from_file %}
|
||||
{{ self::get_module_from_file(from_file).render().unwrap() }}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
FROM {{ base_image }}:{{ image_version }}
|
||||
|
||||
LABEL org.opencontainers.image.title="{{ name }}"
|
||||
LABEL org.opencontainers.image.version="{{ image_version }}"
|
||||
LABEL org.opencontainers.image.description="{{ description }}"
|
||||
LABEL io.artifacthub.package.readme-url=https://raw.githubusercontent.com/ublue-os/startingpoint/main/README.md
|
||||
LABEL io.artifacthub.package.logo-url=https://avatars.githubusercontent.com/u/120078124?s=200&v=4
|
||||
|
||||
ARG RECIPE={{ recipe }}
|
||||
{%- if running_gitlab_actions() %}
|
||||
ARG IMAGE_REGISTRY=ghcr.io/ublue-os
|
||||
COPY cosign.pub /usr/share/ublue-os/cosign.pub
|
||||
{%- endif %}
|
||||
|
||||
# Copy the bling from ublue-os/bling into tmp, to be installed later by the bling module
|
||||
# Feel free to remove these lines if you want to speed up image builds and don't want any bling
|
||||
COPY --from=ghcr.io/ublue-os/bling:latest /rpms /tmp/bling/rpms
|
||||
COPY --from=ghcr.io/ublue-os/bling:latest /files /tmp/bling/files
|
||||
|
||||
COPY --from=docker.io/mikefarah/yq /usr/bin/yq /usr/bin/yq
|
||||
|
||||
COPY --from=gcr.io/projectsigstore/cosign /ko-app/cosign /usr/bin/cosign
|
||||
|
||||
COPY config /tmp/config/
|
||||
|
||||
# Copy modules
|
||||
# The default modules are inside ublue-os/bling
|
||||
COPY --from=ghcr.io/ublue-os/bling:latest /modules /tmp/modules/
|
||||
# Custom modules overwrite defaults
|
||||
COPY modules /tmp/modules/
|
||||
|
||||
RUN printf {{ print_script(script = "export") }} >> /tmp/exports.sh && chmod +x /tmp/exports.sh
|
||||
|
||||
ARG CONFIG_DIRECTORY="/tmp/config"
|
||||
ARG IMAGE_NAME="{{ name }}"
|
||||
ARG BASE_IMAGE="{{ base_image }}"
|
||||
|
||||
{%- macro run_modules(module) %}
|
||||
{%- if module.type %}
|
||||
{%- if module.type == "containerfile" %}
|
||||
{%- for c in module.containerfiles %}
|
||||
{{ print_containerfile(containerfile = c ) }}
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
RUN chmod +x /tmp/modules/{{ module.type }}/{{ module.type }}.sh && source /tmp/exports.sh && /tmp/modules/{{ module.type }}/{{ module.type }}.sh '{{ print_module_context(module = module) }}'
|
||||
{%- endif %}
|
||||
{%- elif module["from-file"] %}
|
||||
{%- set extra_module = get_module_from_file(file = module["from-file"]) %}
|
||||
{%- for m in extra_module.modules %}
|
||||
{{ self::run_modules(module = m) }}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- endmacro run_modules %}
|
||||
|
||||
{%- for module in modules %}
|
||||
{{ self::run_modules(module = module) }}
|
||||
{%- endfor %}
|
||||
|
||||
RUN rm -rf /tmp/* /var/* && ostree container commit
|
||||
Loading…
Add table
Add a link
Reference in a new issue