feat(baker/bake): implement all available decorators
This commit is contained in:
Generated
+472
-19
@@ -259,6 +259,28 @@ version = "1.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-rs"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00"
|
||||||
|
dependencies = [
|
||||||
|
"aws-lc-sys",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-sys"
|
||||||
|
version = "0.41.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cmake",
|
||||||
|
"dunce",
|
||||||
|
"fs_extra",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.7.9"
|
version = "0.7.9"
|
||||||
@@ -393,6 +415,15 @@ dependencies = [
|
|||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be"
|
||||||
|
dependencies = [
|
||||||
|
"hybrid-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block2"
|
name = "block2"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
@@ -527,6 +558,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
|
checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
|
"jobserver",
|
||||||
|
"libc",
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -637,12 +670,31 @@ version = "0.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
|
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cmake"
|
||||||
|
version = "0.1.58"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "combine"
|
||||||
|
version = "4.6.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "concurrent-queue"
|
name = "concurrent-queue"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -672,6 +724,12 @@ dependencies = [
|
|||||||
"yaml-rust2",
|
"yaml-rust2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-oid"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-random"
|
name = "const-random"
|
||||||
version = "0.1.18"
|
version = "0.1.18"
|
||||||
@@ -726,6 +784,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "criterion"
|
name = "criterion"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@@ -803,6 +870,15 @@ dependencies = [
|
|||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
|
||||||
|
dependencies = [
|
||||||
|
"hybrid-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deranged"
|
name = "deranged"
|
||||||
version = "0.5.5"
|
version = "0.5.5"
|
||||||
@@ -819,8 +895,19 @@ version = "0.10.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer 0.10.4",
|
||||||
"crypto-common",
|
"crypto-common 0.1.7",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer 0.12.0",
|
||||||
|
"const-oid",
|
||||||
|
"crypto-common 0.2.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -853,6 +940,12 @@ dependencies = [
|
|||||||
"const-random",
|
"const-random",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dunce"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "duration-str"
|
name = "duration-str"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
@@ -1046,6 +1139,12 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fs_extra"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@@ -1136,8 +1235,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1147,9 +1248,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"r-efi",
|
"r-efi",
|
||||||
"wasip2",
|
"wasip2",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1309,6 +1412,15 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hybrid-array"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
@@ -1382,6 +1494,7 @@ version = "0.1.19"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
|
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -1389,7 +1502,9 @@ dependencies = [
|
|||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"ipnet",
|
||||||
"libc",
|
"libc",
|
||||||
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1561,6 +1676,12 @@ dependencies = [
|
|||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipnet"
|
||||||
|
version = "2.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is-terminal"
|
name = "is-terminal"
|
||||||
version = "0.4.17"
|
version = "0.4.17"
|
||||||
@@ -1626,6 +1747,65 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jni"
|
||||||
|
version = "0.22.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"combine",
|
||||||
|
"jni-macros",
|
||||||
|
"jni-sys",
|
||||||
|
"log",
|
||||||
|
"simd_cesu8",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"walkdir",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jni-macros"
|
||||||
|
version = "0.22.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustc_version",
|
||||||
|
"simd_cesu8",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jni-sys"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
|
||||||
|
dependencies = [
|
||||||
|
"jni-sys-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jni-sys-macros"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jobserver"
|
||||||
|
version = "0.1.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.3.4",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.83"
|
version = "0.3.83"
|
||||||
@@ -1721,9 +1901,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.28"
|
version = "0.4.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru-slab"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchit"
|
name = "matchit"
|
||||||
@@ -1737,6 +1923,16 @@ version = "0.8.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "md-5"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"digest 0.11.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.6"
|
version = "2.7.6"
|
||||||
@@ -1769,9 +1965,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "1.1.0"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873"
|
checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi",
|
||||||
@@ -2205,7 +2401,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82"
|
checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest",
|
||||||
"sha2",
|
"sha2 0.10.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2398,6 +2594,62 @@ dependencies = [
|
|||||||
"prost",
|
"prost",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn"
|
||||||
|
version = "0.11.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"cfg_aliases",
|
||||||
|
"pin-project-lite",
|
||||||
|
"quinn-proto",
|
||||||
|
"quinn-udp",
|
||||||
|
"rustc-hash",
|
||||||
|
"rustls",
|
||||||
|
"socket2",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"web-time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn-proto"
|
||||||
|
version = "0.11.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
|
||||||
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
|
"bytes",
|
||||||
|
"getrandom 0.3.4",
|
||||||
|
"lru-slab",
|
||||||
|
"rand",
|
||||||
|
"ring",
|
||||||
|
"rustc-hash",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"slab",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"tinyvec",
|
||||||
|
"tracing",
|
||||||
|
"web-time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn-udp"
|
||||||
|
version = "0.5.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"socket2",
|
||||||
|
"tracing",
|
||||||
|
"windows-sys 0.60.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.42"
|
version = "1.0.42"
|
||||||
@@ -2535,6 +2787,41 @@ version = "0.8.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "reqwest"
|
||||||
|
version = "0.13.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper",
|
||||||
|
"hyper-rustls",
|
||||||
|
"hyper-util",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"quinn",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-platform-verifier",
|
||||||
|
"sync_wrapper",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls",
|
||||||
|
"tower",
|
||||||
|
"tower-http",
|
||||||
|
"tower-service",
|
||||||
|
"url",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.14"
|
version = "0.17.14"
|
||||||
@@ -2583,6 +2870,21 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
@@ -2602,6 +2904,7 @@ version = "0.23.35"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
|
checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"ring",
|
"ring",
|
||||||
@@ -2629,15 +2932,44 @@ version = "1.13.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282"
|
checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"web-time",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-platform-verifier"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"jni",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"rustls",
|
||||||
|
"rustls-native-certs",
|
||||||
|
"rustls-platform-verifier-android",
|
||||||
|
"rustls-webpki",
|
||||||
|
"security-framework",
|
||||||
|
"security-framework-sys",
|
||||||
|
"webpki-root-certs",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-platform-verifier-android"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.103.8"
|
version = "0.103.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
|
checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
@@ -2861,6 +3193,17 @@ dependencies = [
|
|||||||
"unsafe-libyaml",
|
"unsafe-libyaml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha1"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.3.0",
|
||||||
|
"digest 0.11.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.10.9"
|
version = "0.10.9"
|
||||||
@@ -2868,8 +3211,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"digest",
|
"digest 0.10.7",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.3.0",
|
||||||
|
"digest 0.11.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2894,6 +3248,22 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simd_cesu8"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version",
|
||||||
|
"simdutf8",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simdutf8"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.11"
|
version = "0.4.11"
|
||||||
@@ -2908,12 +3278,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.6.1"
|
version = "0.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
|
checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.60.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2956,6 +3326,9 @@ name = "sync_wrapper"
|
|||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "synstructure"
|
name = "synstructure"
|
||||||
@@ -3093,10 +3466,25 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tinyvec"
|
||||||
version = "1.48.0"
|
version = "1.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
|
checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.52.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -3111,9 +3499,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.6.0"
|
version = "2.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
|
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -3262,6 +3650,24 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-http"
|
||||||
|
version = "0.6.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.10.0",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tower",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-layer"
|
name = "tower-layer"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -3320,9 +3726,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.19.0"
|
version = "1.20.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ucd-trie"
|
name = "ucd-trie"
|
||||||
@@ -3488,6 +3894,19 @@ dependencies = [
|
|||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-futures"
|
||||||
|
version = "0.4.56"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.106"
|
version = "0.2.106"
|
||||||
@@ -3530,6 +3949,25 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-time"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-root-certs"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -3849,6 +4287,7 @@ dependencies = [
|
|||||||
"which",
|
"which",
|
||||||
"workshop-baker-params",
|
"workshop-baker-params",
|
||||||
"workshop-engine",
|
"workshop-engine",
|
||||||
|
"workshop-getterurl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3877,6 +4316,20 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "workshop-getterurl"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"md-5",
|
||||||
|
"reqwest",
|
||||||
|
"sha1",
|
||||||
|
"sha2 0.11.0",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"tokio",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "writeable"
|
name = "writeable"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ privdrop = "0.5.6"
|
|||||||
which = "8.0.2"
|
which = "8.0.2"
|
||||||
globset = "0.4.18"
|
globset = "0.4.18"
|
||||||
axum = "0.7"
|
axum = "0.7"
|
||||||
|
workshop-getterurl = { path = "../workshop-getterurl" }
|
||||||
workshop-baker-params = { version = "0.1.0", path = "../workshop-baker-params" }
|
workshop-baker-params = { version = "0.1.0", path = "../workshop-baker-params" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
+216
-36
@@ -1,4 +1,5 @@
|
|||||||
use crate::bake::constant::{DEFAULT_WORKSPACE, TRIVIAL_SCRIPT_NAME};
|
use crate::bake::builder::RenderMode;
|
||||||
|
use crate::bake::constant::DEFAULT_WORKSPACE;
|
||||||
use crate::bake::error::BakeError;
|
use crate::bake::error::BakeError;
|
||||||
use crate::bake::parser::Function;
|
use crate::bake::parser::Function;
|
||||||
use crate::cli::Cli;
|
use crate::cli::Cli;
|
||||||
@@ -6,8 +7,12 @@ use crate::prebake;
|
|||||||
use crate::prebake::PrebakeConfig;
|
use crate::prebake::PrebakeConfig;
|
||||||
use crate::prebake::security::get_drop_after;
|
use crate::prebake::security::get_drop_after;
|
||||||
use crate::prebake::stage::PrebakeStage;
|
use crate::prebake::stage::PrebakeStage;
|
||||||
|
use std::future::Future;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use workshop_engine::{Engine, EventSender, ExecutionContext};
|
use std::pin::Pin;
|
||||||
|
use std::time::Duration;
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
use workshop_engine::{Engine, EventSender, ExecutionContext, ExecutionError};
|
||||||
|
|
||||||
mod builder;
|
mod builder;
|
||||||
pub mod constant;
|
pub mod constant;
|
||||||
@@ -15,6 +20,13 @@ mod decorator;
|
|||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
mod schedule;
|
mod schedule;
|
||||||
|
pub mod trivial;
|
||||||
|
|
||||||
|
/// Completion event sent from a spawned task to the batch consumer loop.
|
||||||
|
struct TaskCompletion {
|
||||||
|
name: String,
|
||||||
|
result: Result<(), BakeError>,
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn bake(
|
pub async fn bake(
|
||||||
script_path: &Path,
|
script_path: &Path,
|
||||||
@@ -39,8 +51,8 @@ pub async fn bake(
|
|||||||
.iter()
|
.iter()
|
||||||
.any(|d| matches!(d, decorator::Decorator::Pipeline))
|
.any(|d| matches!(d, decorator::Decorator::Pipeline))
|
||||||
});
|
});
|
||||||
let trivial = false;
|
// TODO: if PIP(pipeline implicit parameter).trivial is set, always use RenderMode::Off
|
||||||
let use_template = true;
|
let render_mode = RenderMode::Full;
|
||||||
|
|
||||||
let engine = Engine::new();
|
let engine = Engine::new();
|
||||||
if let Some(env) = &prebake.envvars
|
if let Some(env) = &prebake.envvars
|
||||||
@@ -49,31 +61,97 @@ pub async fn bake(
|
|||||||
ctx.env_vars.extend(prebake_env.clone());
|
ctx.env_vars.extend(prebake_env.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
if !has_pipeline || trivial {
|
if !has_pipeline {
|
||||||
let function = Function {
|
trivial::run_trivial(
|
||||||
name: TRIVIAL_SCRIPT_NAME.to_string(),
|
&script_content,
|
||||||
decorators: vec![],
|
|
||||||
body: script_content,
|
|
||||||
};
|
|
||||||
let script =
|
|
||||||
builder::build_script(&function, bake_base_path, &workspace, None, use_template)?;
|
|
||||||
let result = engine.execute_script(&script, ctx, &event_tx).await;
|
|
||||||
result?;
|
|
||||||
} else {
|
|
||||||
let sorted_functions = schedule::sort_function(functions.pipeline_functions)?;
|
|
||||||
let remaining = functions.remaining_code;
|
|
||||||
for func in sorted_functions {
|
|
||||||
let mut modified_func = func.clone();
|
|
||||||
modified_func.body = remaining.clone() + &func.body;
|
|
||||||
let script = builder::build_script(
|
|
||||||
&modified_func,
|
|
||||||
bake_base_path,
|
bake_base_path,
|
||||||
&workspace,
|
&workspace,
|
||||||
None,
|
&engine,
|
||||||
use_template,
|
ctx,
|
||||||
)?;
|
&event_tx,
|
||||||
let result = engine.execute_script(&script, ctx, &event_tx).await;
|
render_mode,
|
||||||
result?;
|
)
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
let remaining = functions.remaining_code;
|
||||||
|
let (mut dag, func_map) = schedule::build_dag(functions.pipeline_functions)?;
|
||||||
|
|
||||||
|
while !dag.is_empty() {
|
||||||
|
let ready: Vec<String> = dag.peek_all().into_iter().cloned().collect();
|
||||||
|
if ready.is_empty() {
|
||||||
|
let remaining_nodes: Vec<String> = dag.clone().into_iter().collect();
|
||||||
|
return Err(BakeError::CircularDependency(remaining_nodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Separate @parallel from sequential (consume ready for owned names)
|
||||||
|
let (sequential, parallel): (Vec<String>, Vec<String>) = ready.into_iter()
|
||||||
|
.partition(|name| {
|
||||||
|
let f = &func_map[name.as_str()];
|
||||||
|
!f.decorators
|
||||||
|
.iter()
|
||||||
|
.any(|d| matches!(d, decorator::Decorator::Parallel))
|
||||||
|
});
|
||||||
|
|
||||||
|
// Execute sequential functions first
|
||||||
|
for name in &sequential {
|
||||||
|
execute_one(
|
||||||
|
&engine,
|
||||||
|
&func_map[name.as_str()],
|
||||||
|
ctx,
|
||||||
|
&event_tx,
|
||||||
|
&workspace,
|
||||||
|
&remaining,
|
||||||
|
bake_base_path,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute @parallel functions concurrently
|
||||||
|
if !parallel.is_empty() {
|
||||||
|
let handles: Vec<_> = parallel
|
||||||
|
.iter()
|
||||||
|
.map(|name| {
|
||||||
|
let func = func_map[name.as_str()].clone();
|
||||||
|
let mut ctx_local = ctx.clone();
|
||||||
|
let et = event_tx.clone();
|
||||||
|
let ws = workspace.clone();
|
||||||
|
let rem = remaining.clone();
|
||||||
|
let bb = bake_base_path.to_path_buf();
|
||||||
|
let n = name.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let eng = Engine::new();
|
||||||
|
(
|
||||||
|
n,
|
||||||
|
execute_one(&eng, &func, &mut ctx_local, &et, &ws, &rem, &bb)
|
||||||
|
.await,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for handle in handles {
|
||||||
|
let (name, result) = handle.await.map_err(|_| {
|
||||||
|
BakeError::ScriptExecutionError(ExecutionError::ExecutionFailed(
|
||||||
|
"parallel task panicked".to_string(),
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
let func = &func_map[name.as_str()];
|
||||||
|
let is_fallible = func
|
||||||
|
.decorators
|
||||||
|
.iter()
|
||||||
|
.any(|d| matches!(d, decorator::Decorator::Fallible));
|
||||||
|
match result {
|
||||||
|
Err(e) if !is_fallible => return Err(e),
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("'{}' failed (fallible, non-fatal): {}", name, e);
|
||||||
|
}
|
||||||
|
Ok(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit the entire batch — all nodes completed (or fallible-failed)
|
||||||
|
dag.pop_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,16 +183,118 @@ fn privileged(prebake_config: &PrebakeConfig) -> bool {
|
|||||||
PrebakeStage::Never == drop_after
|
PrebakeStage::Never == drop_after
|
||||||
}
|
}
|
||||||
|
|
||||||
type TaskResult = Result<(), BakeError>;
|
// ── Execution helpers ──
|
||||||
|
|
||||||
type TaskFn = Box<dyn FnOnce() -> TaskResult + Send>;
|
async fn execute_one(
|
||||||
|
engine: &Engine,
|
||||||
|
func: &Function,
|
||||||
|
ctx: &mut ExecutionContext,
|
||||||
|
event_tx: &EventSender,
|
||||||
|
workspace: &Path,
|
||||||
|
remaining: &str,
|
||||||
|
bake_base: &Path,
|
||||||
|
) -> Result<(), BakeError> {
|
||||||
|
// Extract combinators preserving original order
|
||||||
|
let combos: Vec<&decorator::Decorator> = func
|
||||||
|
.decorators
|
||||||
|
.iter()
|
||||||
|
.filter(|d| decorator::is_combinator(d))
|
||||||
|
.collect();
|
||||||
|
|
||||||
// TODO: Learn closure and continue
|
// Build the script
|
||||||
// async fn run<F>(f:F) -> TaskFn {
|
let mut modified = func.clone();
|
||||||
// let engine = Engine::new();
|
modified.body = remaining.to_string() + &func.body;
|
||||||
// engine.execute_script
|
let script = builder::build_script(
|
||||||
// }
|
&modified, bake_base, workspace, None, RenderMode::Full,
|
||||||
|
)?;
|
||||||
|
|
||||||
// fn with_timeout<F>(f: F, duration: i32) -> TaskFn {
|
// Execute with combinator chain
|
||||||
|
execute_with_combos(engine, &script, ctx, event_tx, &combos).await
|
||||||
|
}
|
||||||
|
|
||||||
// }
|
async fn execute_with_combos(
|
||||||
|
engine: &Engine,
|
||||||
|
script: &PathBuf,
|
||||||
|
ctx: &ExecutionContext,
|
||||||
|
event_tx: &EventSender,
|
||||||
|
combos: &[&decorator::Decorator],
|
||||||
|
) -> Result<(), BakeError> {
|
||||||
|
build_combinator_chain(engine, script, ctx, event_tx, combos, 0).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds a combinator execution chain using `Box::pin` to avoid infinite-sized async fn recursion.
|
||||||
|
/// Each combinator wraps the inner future: processed outermost (idx=0) → innermost (baseline).
|
||||||
|
fn build_combinator_chain<'a>(
|
||||||
|
engine: &'a Engine,
|
||||||
|
script: &'a PathBuf,
|
||||||
|
ctx: &'a ExecutionContext,
|
||||||
|
event_tx: &'a EventSender,
|
||||||
|
combos: &'a [&'a decorator::Decorator],
|
||||||
|
idx: usize,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<(), BakeError>> + Send + 'a>> {
|
||||||
|
use decorator::Decorator;
|
||||||
|
|
||||||
|
// Baseline: no more combinators — execute the script once
|
||||||
|
if idx >= combos.len() {
|
||||||
|
return Box::pin(async move {
|
||||||
|
engine.execute_script(script, ctx, event_tx).await?;
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
match combos[idx] {
|
||||||
|
Decorator::Loop(count) => Box::pin(async move {
|
||||||
|
for i in 0..*count {
|
||||||
|
log::debug!("Loop {}/{}", i + 1, count);
|
||||||
|
build_combinator_chain(engine, script, ctx, event_tx, combos, idx + 1).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}),
|
||||||
|
Decorator::Timeout(secs) => Box::pin(async move {
|
||||||
|
tokio::time::timeout(
|
||||||
|
Duration::from_secs(*secs as u64),
|
||||||
|
build_combinator_chain(engine, script, ctx, event_tx, combos, idx + 1),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|_| BakeError::ScriptExecutionError(ExecutionError::Timeout))?
|
||||||
|
}),
|
||||||
|
Decorator::Retry(retries, delay_secs) => Box::pin(async move {
|
||||||
|
let max_attempts = *retries as usize + 1;
|
||||||
|
let delay = Duration::from_secs(*delay_secs as u64);
|
||||||
|
let mut last_err = None;
|
||||||
|
for attempt in 0..max_attempts {
|
||||||
|
match build_combinator_chain(
|
||||||
|
engine, script, ctx, event_tx, combos, idx + 1,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => return Ok(()),
|
||||||
|
Err(e) => {
|
||||||
|
// Timeout should not be retried
|
||||||
|
if matches!(&e, BakeError::ScriptExecutionError(ExecutionError::Timeout)) {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
if attempt < max_attempts - 1 {
|
||||||
|
last_err = Some(e);
|
||||||
|
log::warn!(
|
||||||
|
"Retry {}/{} after {}s",
|
||||||
|
attempt + 1,
|
||||||
|
retries,
|
||||||
|
delay_secs
|
||||||
|
);
|
||||||
|
tokio::time::sleep(delay).await;
|
||||||
|
} else {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(last_err.unwrap())
|
||||||
|
}),
|
||||||
|
// Non-combinator decorators: skip (shouldn't reach here if filtered correctly)
|
||||||
|
_ => build_combinator_chain(engine, script, ctx, event_tx, combos, idx + 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── AI Coding Agent marker ──
|
||||||
|
// Code in this module PARTIALLY or FULLY utilized AI Coding Agent
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::bake::constant::{PIPELINE_SKIP_ERRORCODE, TRIVIAL_SCRIPT_NAME};
|
use crate::bake::constant::PIPELINE_SKIP_ERRORCODE;
|
||||||
use crate::bake::decorator::Decorator;
|
use crate::bake::decorator::Decorator;
|
||||||
use crate::bake::error::BakeError;
|
use crate::bake::error::BakeError;
|
||||||
use crate::bake::parser::Function;
|
use crate::bake::parser::Function;
|
||||||
@@ -9,24 +9,45 @@ use std::path::Path;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
/// Template for use_template=false, which just executes the main body without any wrapping.
|
/// Three-level rendering control.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum RenderMode {
|
||||||
|
/// No template, hardcoded "{{ main }}". Debug escape hatch.
|
||||||
|
Off,
|
||||||
|
/// Uses bake_base.sh with essential execution skeleton only.
|
||||||
|
Minimal,
|
||||||
|
/// Uses bake_base.sh with helpers (logs, colors, etc.).
|
||||||
|
Full,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderMode {
|
||||||
|
pub fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
RenderMode::Off => "off",
|
||||||
|
RenderMode::Minimal => "minimal",
|
||||||
|
RenderMode::Full => "full",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hardcoded template for RenderMode::Off.
|
||||||
const TRIVIAL_TEMPLATE: &str = "{{ main }}";
|
const TRIVIAL_TEMPLATE: &str = "{{ main }}";
|
||||||
|
|
||||||
/// Renders a `Function` into an executable shell script using a minijinja template.
|
/// Renders a `Function` into an executable shell script using a minijinja template.
|
||||||
/// If `use_template` is true, wraps the body in `bake_base`; otherwise uses a trivial template.
|
///
|
||||||
|
/// `render_mode` controls the template source:
|
||||||
|
/// - `Off`: hardcoded `{{ main }}`, no bake_base file needed.
|
||||||
|
/// - `Minimal` / `Full`: reads bake_base.sh; the template distinguishes the two
|
||||||
|
/// via the `render_mode` context variable.
|
||||||
pub fn build_script(
|
pub fn build_script(
|
||||||
function: &Function,
|
function: &Function,
|
||||||
bake_base: &Path,
|
bake_base: &Path,
|
||||||
target_dir: &Path,
|
target_dir: &Path,
|
||||||
temp_path: Option<PathBuf>,
|
temp_path: Option<PathBuf>,
|
||||||
use_template: bool,
|
render_mode: RenderMode,
|
||||||
) -> Result<PathBuf, BakeError> {
|
) -> Result<PathBuf, BakeError> {
|
||||||
let name = &function.name;
|
let name = &function.name;
|
||||||
let trivial = name == TRIVIAL_SCRIPT_NAME;
|
|
||||||
let body = &function.body;
|
let body = &function.body;
|
||||||
let export = function
|
|
||||||
.find_decorator(|d| matches!(d, Decorator::Export).then_some(()))
|
|
||||||
.is_some();
|
|
||||||
let condition = function.find_decorator(|d| {
|
let condition = function.find_decorator(|d| {
|
||||||
if let Decorator::If(content) = d {
|
if let Decorator::If(content) = d {
|
||||||
Some(content.clone())
|
Some(content.clone())
|
||||||
@@ -38,13 +59,14 @@ pub fn build_script(
|
|||||||
let filename = format!("bakefn_{}.sh", name);
|
let filename = format!("bakefn_{}.sh", name);
|
||||||
let target = target_dir.join(filename);
|
let target = target_dir.join(filename);
|
||||||
|
|
||||||
let bake_base_content = if use_template {
|
let template_content = match render_mode {
|
||||||
|
RenderMode::Off => TRIVIAL_TEMPLATE.to_string(),
|
||||||
|
RenderMode::Minimal | RenderMode::Full => {
|
||||||
std::fs::read_to_string(bake_base).map_err(|e| BakeError::ScriptGenerationFailed {
|
std::fs::read_to_string(bake_base).map_err(|e| BakeError::ScriptGenerationFailed {
|
||||||
script: bake_base.display().to_string(),
|
script: bake_base.display().to_string(),
|
||||||
reason: e.to_string(),
|
reason: e.to_string(),
|
||||||
})?
|
})?
|
||||||
} else {
|
}
|
||||||
TRIVIAL_TEMPLATE.to_string()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let condition_code = match condition {
|
let condition_code = match condition {
|
||||||
@@ -57,30 +79,22 @@ pub fn build_script(
|
|||||||
None => String::new(),
|
None => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut preexport_code = String::new();
|
// preexport/export: stubs for the future IPC-based @export.
|
||||||
let mut export_code = String::new();
|
let preexport_code = String::new();
|
||||||
if !trivial {
|
let export_code = String::new();
|
||||||
if export {
|
|
||||||
preexport_code = format!("declare -xp > /dev/shm/bakeenv.before.{}\n", name);
|
|
||||||
export_code = format!(
|
|
||||||
"declare -xp > /dev/shm/bakeenv.after.{}\ndiff -w --new-line-format='%L' --old-line-format='' --unchanged-line-format='' /dev/shm/bakeenv.before.{} /dev/shm/bakeenv.after.{} > /dev/shm/bakeexport.{}\n",
|
|
||||||
name, name, name, name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
preexport_code.push_str(format!(". /dev/shm/bakeexport.{}\n", name).as_str());
|
|
||||||
export_code.push_str(format!("rm -f /dev/shm/bakeenv.*.{}\n", name).as_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut env = Environment::new();
|
let mut env = Environment::new();
|
||||||
env.add_template("script", bake_base_content.as_str())?;
|
env.add_template("script", &template_content)?;
|
||||||
let script = env.get_template("script")?;
|
let rendered = env.get_template("script")?.render(
|
||||||
let rendered = if use_template {
|
context! {
|
||||||
script.render(
|
main => body,
|
||||||
context! {main => body,condition => condition_code, preexport => preexport_code, name => name, export => export_code},
|
condition => condition_code,
|
||||||
)?
|
preexport => preexport_code,
|
||||||
} else {
|
name => name,
|
||||||
script.render(context! {main => body})?
|
export => export_code,
|
||||||
};
|
render_mode => render_mode.as_str(),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut temp_file =
|
let mut temp_file =
|
||||||
NamedTempFile::new_in(&temp_path).map_err(|e| BakeError::ScriptGenerationFailed {
|
NamedTempFile::new_in(&temp_path).map_err(|e| BakeError::ScriptGenerationFailed {
|
||||||
@@ -114,7 +128,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_build_script_with_template() {
|
fn test_build_script_full_mode() {
|
||||||
let temp_dir = tempfile::tempdir().unwrap();
|
let temp_dir = tempfile::tempdir().unwrap();
|
||||||
let bake_base = temp_dir.path().join("bake_base.sh");
|
let bake_base = temp_dir.path().join("bake_base.sh");
|
||||||
|
|
||||||
@@ -125,7 +139,9 @@ mod tests {
|
|||||||
decorators: vec![],
|
decorators: vec![],
|
||||||
body: "echo 'hello world'".to_string(),
|
body: "echo 'hello world'".to_string(),
|
||||||
};
|
};
|
||||||
let result = build_script(&function, &bake_base, temp_dir.path(), None, true);
|
let result = build_script(
|
||||||
|
&function, &bake_base, temp_dir.path(), None, RenderMode::Full,
|
||||||
|
);
|
||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
let script_path = result.unwrap();
|
let script_path = result.unwrap();
|
||||||
@@ -134,10 +150,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_build_script_trivial_mode() {
|
fn test_build_script_off_mode() {
|
||||||
let temp_dir = tempfile::tempdir().unwrap();
|
let temp_dir = tempfile::tempdir().unwrap();
|
||||||
let function = Function {
|
let function = Function {
|
||||||
name: "trivial".to_string(),
|
name: "test".to_string(),
|
||||||
decorators: vec![],
|
decorators: vec![],
|
||||||
body: "echo 'direct output'".to_string(),
|
body: "echo 'direct output'".to_string(),
|
||||||
};
|
};
|
||||||
@@ -147,7 +163,7 @@ mod tests {
|
|||||||
Path::new("/nonexistent"),
|
Path::new("/nonexistent"),
|
||||||
temp_dir.path(),
|
temp_dir.path(),
|
||||||
None,
|
None,
|
||||||
false,
|
RenderMode::Off,
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ use crate::bake::error::BakeError;
|
|||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
// "# @decorator" or "# @decorator(parameters)"
|
// "# @decorator" or "# @decorator(parameters)"
|
||||||
static ref DECORATOR_REGEX: Regex = Regex::new(r"^\s*#\s+@(\w+)\s?(\((.*)\))?").unwrap()
|
static ref DECORATOR_REGEX: Regex = Regex::new(r"^\s*#\s+@(\w+)\s?(\((.*)\))?").unwrap();
|
||||||
;
|
|
||||||
static ref UNEXPECTED_ARGUMENT: &'static str = "decorator does not accept arguments";
|
static ref UNEXPECTED_ARGUMENT: &'static str = "decorator does not accept arguments";
|
||||||
static ref MISSING_ARGUMENT: &'static str = "decorator requires an argument";
|
static ref MISSING_ARGUMENT: &'static str = "decorator requires an argument";
|
||||||
static ref UNKNOWN_DECORATOR: &'static str = "unknown decorator";
|
static ref UNKNOWN_DECORATOR: &'static str = "unknown decorator";
|
||||||
@@ -46,6 +45,31 @@ pub enum Decorator {
|
|||||||
Health(String),
|
Health(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the decorator is a flag (position-independent, consumed after execution).
|
||||||
|
pub fn is_flag(d: &Decorator) -> bool {
|
||||||
|
matches!(
|
||||||
|
d,
|
||||||
|
Decorator::Pipeline
|
||||||
|
| Decorator::Fallible
|
||||||
|
| Decorator::Export
|
||||||
|
| Decorator::If(_)
|
||||||
|
| Decorator::After(_)
|
||||||
|
| Decorator::Parallel
|
||||||
|
| Decorator::Health(_)
|
||||||
|
| Decorator::Unknown
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the decorator is a combinator (position-dependent, nestable).
|
||||||
|
pub fn is_combinator(d: &Decorator) -> bool {
|
||||||
|
matches!(d, Decorator::Loop(_) | Decorator::Timeout(_) | Decorator::Retry(..))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the decorator is a mode (at most one, alters what gets executed).
|
||||||
|
pub fn is_mode(d: &Decorator) -> bool {
|
||||||
|
matches!(d, Decorator::Pipe(_) | Decorator::Daemon)
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Decorator {
|
impl Display for Decorator {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ pub enum BakeError {
|
|||||||
|
|
||||||
#[error("Script execution error: {0}")]
|
#[error("Script execution error: {0}")]
|
||||||
ScriptExecutionError(#[from] ExecutionError),
|
ScriptExecutionError(#[from] ExecutionError),
|
||||||
|
|
||||||
|
#[error("Incompatible decorators on function '{function}': {reason}")]
|
||||||
|
IncompatibleDecorators { function: String, reason: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasExitCode for BakeError {
|
impl HasExitCode for BakeError {
|
||||||
@@ -47,6 +50,7 @@ impl HasExitCode for BakeError {
|
|||||||
BakeError::YamlParseError(_) => EXITCODE_PARSE_ERROR,
|
BakeError::YamlParseError(_) => EXITCODE_PARSE_ERROR,
|
||||||
BakeError::DecoratorParseError { .. } => EXITCODE_PARSE_ERROR,
|
BakeError::DecoratorParseError { .. } => EXITCODE_PARSE_ERROR,
|
||||||
BakeError::ScriptExecutionError(e) => e.exit_code(),
|
BakeError::ScriptExecutionError(e) => e.exit_code(),
|
||||||
|
BakeError::IncompatibleDecorators { .. } => EXITCODE_PARSE_ERROR,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,13 @@ use crate::bake::error::BakeError;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use topological_sort::TopologicalSort;
|
use topological_sort::TopologicalSort;
|
||||||
|
|
||||||
/// Topologically sorts functions by explicit `@after` dependencies and implicit ordering
|
/// Builds a DAG from functions using `@after` dependencies and implicit ordering
|
||||||
/// for consecutive `@pipeline` functions (each pipeline function implicitly depends on
|
/// for consecutive `@pipeline` functions. Returns the sorted DAG and a name→Function map.
|
||||||
/// the previous one unless it has an explicit `@after`).
|
/// The caller should use `peek_all()` (non-destructive) to get ready nodes, execute them,
|
||||||
pub fn sort_function(functions: Vec<Function>) -> Result<Vec<Function>, BakeError> {
|
/// then `pop()` each completed node to advance the DAG.
|
||||||
|
pub fn build_dag(
|
||||||
|
functions: Vec<Function>,
|
||||||
|
) -> Result<(TopologicalSort<String>, HashMap<String, Function>), BakeError> {
|
||||||
let function_mapped = functions
|
let function_mapped = functions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| (f.name.as_str(), f))
|
.map(|f| (f.name.as_str(), f))
|
||||||
@@ -31,9 +34,11 @@ pub fn sort_function(functions: Vec<Function>) -> Result<Vec<Function>, BakeErro
|
|||||||
|
|
||||||
// Add implicit @after for pipeline functions that don't have explicit @after
|
// Add implicit @after for pipeline functions that don't have explicit @after
|
||||||
if is_pipeline {
|
if is_pipeline {
|
||||||
if !has_after && let Some(ref last) = last_pipeline {
|
if !has_after {
|
||||||
|
if let Some(ref last) = last_pipeline {
|
||||||
ts.add_dependency(last, function.name.clone());
|
ts.add_dependency(last, function.name.clone());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
last_pipeline = Some(function.name.clone());
|
last_pipeline = Some(function.name.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,18 +60,12 @@ pub fn sort_function(functions: Vec<Function>) -> Result<Vec<Function>, BakeErro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut functions_sorted = Vec::<Function>::new();
|
let owned_map: HashMap<String, Function> = functions
|
||||||
while let Some(name) = ts.pop() {
|
.into_iter()
|
||||||
let function = function_mapped[name.as_str()];
|
.map(|f| (f.name.clone(), f))
|
||||||
functions_sorted.push(function.clone());
|
.collect();
|
||||||
}
|
|
||||||
|
|
||||||
if !ts.is_empty() {
|
Ok((ts, owned_map))
|
||||||
let remaining: Vec<String> = ts.collect();
|
|
||||||
return Err(BakeError::CircularDependency(remaining));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(functions_sorted)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -81,10 +80,28 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper: drain the DAG and return sorted order (for backward-compatible tests)
|
||||||
|
fn drain_dag(functions: Vec<Function>) -> Result<Vec<Function>, BakeError> {
|
||||||
|
let (mut dag, func_map) = build_dag(functions)?;
|
||||||
|
let mut result = Vec::new();
|
||||||
|
while !dag.is_empty() {
|
||||||
|
let batch = dag.pop_all();
|
||||||
|
if batch.is_empty() {
|
||||||
|
// Cycle detected: remaining nodes form a circular dependency
|
||||||
|
let remaining: Vec<String> = dag.into_iter().collect();
|
||||||
|
return Err(BakeError::CircularDependency(remaining));
|
||||||
|
}
|
||||||
|
for name in batch {
|
||||||
|
result.push(func_map[&name].clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_functions() {
|
fn test_empty_functions() {
|
||||||
let functions = vec![];
|
let functions = vec![];
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
assert!(result.is_empty());
|
assert!(result.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +110,7 @@ mod tests {
|
|||||||
let function = create_function("func1", vec![], "body1");
|
let function = create_function("func1", vec![], "body1");
|
||||||
let functions = vec![function.clone()];
|
let functions = vec![function.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 1);
|
assert_eq!(result.len(), 1);
|
||||||
assert_eq!(result[0].name, "func1");
|
assert_eq!(result[0].name, "func1");
|
||||||
@@ -106,7 +123,7 @@ mod tests {
|
|||||||
let function3 = create_function("func3", vec![], "body3");
|
let function3 = create_function("func3", vec![], "body3");
|
||||||
let functions = vec![function1.clone(), function2.clone(), function3.clone()];
|
let functions = vec![function1.clone(), function2.clone(), function3.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
let names: Vec<String> = result.iter().map(|f| f.name.clone()).collect();
|
let names: Vec<String> = result.iter().map(|f| f.name.clone()).collect();
|
||||||
@@ -125,7 +142,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![function1.clone(), function2.clone()];
|
let functions = vec![function1.clone(), function2.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 2);
|
assert_eq!(result.len(), 2);
|
||||||
assert_eq!(result[0].name, "func1");
|
assert_eq!(result[0].name, "func1");
|
||||||
@@ -147,7 +164,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![function1.clone(), function2.clone(), function3.clone()];
|
let functions = vec![function1.clone(), function2.clone(), function3.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
assert_eq!(result[0].name, "func1");
|
assert_eq!(result[0].name, "func1");
|
||||||
@@ -179,7 +196,7 @@ mod tests {
|
|||||||
function4.clone(),
|
function4.clone(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 4);
|
assert_eq!(result.len(), 4);
|
||||||
|
|
||||||
@@ -212,7 +229,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![function1.clone(), function2.clone()];
|
let functions = vec![function1.clone(), function2.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 2);
|
assert_eq!(result.len(), 2);
|
||||||
assert_eq!(result[0].name, "func1");
|
assert_eq!(result[0].name, "func1");
|
||||||
@@ -233,7 +250,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![function1.clone(), function2.clone(), function3.clone()];
|
let functions = vec![function1.clone(), function2.clone(), function3.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
|
|
||||||
@@ -270,7 +287,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![function1.clone(), function2.clone()];
|
let functions = vec![function1.clone(), function2.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 2);
|
assert_eq!(result.len(), 2);
|
||||||
let names: Vec<String> = result.iter().map(|f| f.name.clone()).collect();
|
let names: Vec<String> = result.iter().map(|f| f.name.clone()).collect();
|
||||||
@@ -285,7 +302,7 @@ mod tests {
|
|||||||
let func3 = create_function("func3", vec![Decorator::Pipeline], "body3");
|
let func3 = create_function("func3", vec![Decorator::Pipeline], "body3");
|
||||||
let functions = vec![func1.clone(), func2.clone(), func3.clone()];
|
let functions = vec![func1.clone(), func2.clone(), func3.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
assert_eq!(result[0].name, "func1");
|
assert_eq!(result[0].name, "func1");
|
||||||
@@ -298,7 +315,7 @@ mod tests {
|
|||||||
let func1 = create_function("func1", vec![Decorator::Pipeline], "body1");
|
let func1 = create_function("func1", vec![Decorator::Pipeline], "body1");
|
||||||
let functions = vec![func1.clone()];
|
let functions = vec![func1.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 1);
|
assert_eq!(result.len(), 1);
|
||||||
assert_eq!(result[0].name, "func1");
|
assert_eq!(result[0].name, "func1");
|
||||||
@@ -315,7 +332,7 @@ mod tests {
|
|||||||
let func3 = create_function("func3", vec![Decorator::Pipeline], "body3");
|
let func3 = create_function("func3", vec![Decorator::Pipeline], "body3");
|
||||||
let functions = vec![func1.clone(), func2.clone(), func3.clone()];
|
let functions = vec![func1.clone(), func2.clone(), func3.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
let positions: std::collections::HashMap<String, usize> = result
|
let positions: std::collections::HashMap<String, usize> = result
|
||||||
@@ -336,7 +353,7 @@ mod tests {
|
|||||||
let func4 = create_function("func4", vec![Decorator::Pipeline], "body4");
|
let func4 = create_function("func4", vec![Decorator::Pipeline], "body4");
|
||||||
let functions = vec![func1.clone(), func2.clone(), func3.clone(), func4.clone()];
|
let functions = vec![func1.clone(), func2.clone(), func3.clone(), func4.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
|
|
||||||
assert_eq!(result.len(), 4);
|
assert_eq!(result.len(), 4);
|
||||||
let positions: std::collections::HashMap<String, usize> = result
|
let positions: std::collections::HashMap<String, usize> = result
|
||||||
@@ -353,7 +370,7 @@ mod tests {
|
|||||||
let func1 = create_function("func1", vec![Decorator::Pipeline], "body1");
|
let func1 = create_function("func1", vec![Decorator::Pipeline], "body1");
|
||||||
let functions = vec![func1.clone()];
|
let functions = vec![func1.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
assert_eq!(result.len(), 1);
|
assert_eq!(result.len(), 1);
|
||||||
assert_eq!(result[0].name, "func1");
|
assert_eq!(result[0].name, "func1");
|
||||||
}
|
}
|
||||||
@@ -364,7 +381,7 @@ mod tests {
|
|||||||
let func2 = create_function("func2", vec![Decorator::Pipeline], "body2");
|
let func2 = create_function("func2", vec![Decorator::Pipeline], "body2");
|
||||||
let functions = vec![func1.clone(), func2.clone()];
|
let functions = vec![func1.clone(), func2.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
assert_eq!(result.len(), 2);
|
assert_eq!(result.len(), 2);
|
||||||
let positions: std::collections::HashMap<String, usize> = result
|
let positions: std::collections::HashMap<String, usize> = result
|
||||||
.iter()
|
.iter()
|
||||||
@@ -385,7 +402,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![func1.clone(), func2.clone(), func3.clone()];
|
let functions = vec![func1.clone(), func2.clone(), func3.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
let positions: std::collections::HashMap<String, usize> = result
|
let positions: std::collections::HashMap<String, usize> = result
|
||||||
.iter()
|
.iter()
|
||||||
@@ -411,7 +428,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![func1.clone(), func2.clone()];
|
let functions = vec![func1.clone(), func2.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions);
|
let result = drain_dag(functions);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
result.unwrap_err(),
|
result.unwrap_err(),
|
||||||
@@ -428,7 +445,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![func1.clone()];
|
let functions = vec![func1.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions);
|
let result = drain_dag(functions);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
result.unwrap_err(),
|
result.unwrap_err(),
|
||||||
@@ -458,7 +475,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let functions = vec![func1.clone(), func2.clone()];
|
let functions = vec![func1.clone(), func2.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
assert_eq!(result.len(), 2);
|
assert_eq!(result.len(), 2);
|
||||||
let positions: std::collections::HashMap<String, usize> = result
|
let positions: std::collections::HashMap<String, usize> = result
|
||||||
.iter()
|
.iter()
|
||||||
@@ -483,7 +500,7 @@ mod tests {
|
|||||||
func5.clone(),
|
func5.clone(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
assert_eq!(result.len(), 5);
|
assert_eq!(result.len(), 5);
|
||||||
let positions: std::collections::HashMap<String, usize> = result
|
let positions: std::collections::HashMap<String, usize> = result
|
||||||
.iter()
|
.iter()
|
||||||
@@ -503,7 +520,7 @@ mod tests {
|
|||||||
let func3 = create_function("func3", vec![Decorator::Pipeline], "body3");
|
let func3 = create_function("func3", vec![Decorator::Pipeline], "body3");
|
||||||
let functions = vec![func1.clone(), func2.clone(), func3.clone()];
|
let functions = vec![func1.clone(), func2.clone(), func3.clone()];
|
||||||
|
|
||||||
let result = sort_function(functions).unwrap();
|
let result = drain_dag(functions).unwrap();
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
let positions: std::collections::HashMap<String, usize> = result
|
let positions: std::collections::HashMap<String, usize> = result
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use crate::bake::builder::{build_script, RenderMode};
|
||||||
|
use crate::bake::constant::TRIVIAL_SCRIPT_NAME;
|
||||||
|
use crate::bake::error::BakeError;
|
||||||
|
use crate::bake::parser::Function;
|
||||||
|
use std::path::Path;
|
||||||
|
use workshop_engine::{Engine, EventSender, ExecutionContext};
|
||||||
|
|
||||||
|
/// Executes `script_content` as a single function in trivial mode.
|
||||||
|
///
|
||||||
|
/// Two entry paths lead here:
|
||||||
|
/// - **Auto-detection** (`!has_pipeline`): bake.sh has no `@pipeline` functions,
|
||||||
|
/// the entire content is treated as one trivial function.
|
||||||
|
/// - **Explicit PIP** (future): `trivial` parameter forces trivial mode even
|
||||||
|
/// when `@pipeline` functions exist, typically with `RenderMode::Off`.
|
||||||
|
pub async fn run_trivial(
|
||||||
|
script_content: &str,
|
||||||
|
bake_base_path: &Path,
|
||||||
|
workspace: &Path,
|
||||||
|
engine: &Engine,
|
||||||
|
ctx: &mut ExecutionContext,
|
||||||
|
event_tx: &EventSender,
|
||||||
|
render_mode: RenderMode,
|
||||||
|
) -> Result<(), BakeError> {
|
||||||
|
let function = Function {
|
||||||
|
name: TRIVIAL_SCRIPT_NAME.to_string(),
|
||||||
|
decorators: vec![],
|
||||||
|
body: script_content.to_string(),
|
||||||
|
};
|
||||||
|
let script = build_script(&function, bake_base_path, workspace, None, render_mode)?;
|
||||||
|
engine.execute_script(&script, ctx, event_tx).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
use crate::monitor::UsageStats;
|
|
||||||
use cgroups_rs;
|
|
||||||
use cgroups_rs::fs::Cgroup;
|
|
||||||
use cgroups_rs::fs::{cpu::CpuController, memory::MemController, pid::PidController};
|
|
||||||
use log;
|
|
||||||
use std::time::{Duration, Instant};
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub fn get_usage(
|
|
||||||
name: &String,
|
|
||||||
usage_prev: crate::monitor::UsageStats,
|
|
||||||
) -> anyhow::Result<crate::monitor::UsageStats> {
|
|
||||||
let hierarchy = cgroups_rs::fs::hierarchies::auto();
|
|
||||||
if !hierarchy.v2() {
|
|
||||||
return Err(anyhow::anyhow!(
|
|
||||||
"Unsupported cgroup hierarchy, cgroups v2 required."
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let cgroup = Cgroup::load(hierarchy, name);
|
|
||||||
let mut cpu_usage_us: u64 = 0;
|
|
||||||
let mut cpu_usage_percent: f64 = 0.0;
|
|
||||||
let mut memory_usage_bytes: u64 = 0;
|
|
||||||
let mut memory_limit_bytes: i64 = 0;
|
|
||||||
let mut process_count: u64 = 0;
|
|
||||||
|
|
||||||
if let Some(cpu) = cgroup.controller_of::<CpuController>() {
|
|
||||||
let stats = parse_cpustat(cpu.cpu().stat.as_str())?;
|
|
||||||
cpu_usage_us = stats.usage_usec;
|
|
||||||
} else {
|
|
||||||
log::warn!("Failed to fetch CPU usage info!");
|
|
||||||
}
|
|
||||||
|
|
||||||
let current = Instant::now();
|
|
||||||
let delta_usage = cpu_usage_us - usage_prev.cpu_usage_us;
|
|
||||||
let delta_wall = current - usage_prev._timestamp;
|
|
||||||
if usage_prev._timestamp > current {
|
|
||||||
log::warn!("Usage stats are from the future!");
|
|
||||||
} else if usage_prev.cpu_usage_us == 0 {
|
|
||||||
log::info!("Previous CPU usage is zero, probably a fresh start.");
|
|
||||||
} else if delta_wall < Duration::from_millis(1) {
|
|
||||||
log::warn!("Usage stats are too close together!");
|
|
||||||
} else {
|
|
||||||
cpu_usage_percent = delta_usage as f64 / delta_wall.as_micros() as f64 * 100.0;
|
|
||||||
// dbg!(&delta_usage, &delta_wall);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(mem) = cgroup.controller_of::<MemController>() {
|
|
||||||
let stats = mem.memory_stat();
|
|
||||||
memory_usage_bytes = stats.usage_in_bytes;
|
|
||||||
memory_limit_bytes = stats.limit_in_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(proc) = cgroup.controller_of::<PidController>() {
|
|
||||||
process_count = proc.get_pid_current()?;
|
|
||||||
}
|
|
||||||
Ok(UsageStats {
|
|
||||||
cpu_usage_us,
|
|
||||||
cpu_usage_percent,
|
|
||||||
memory_usage_bytes,
|
|
||||||
// memory_usage_percent: 0.0,
|
|
||||||
memory_limit_bytes,
|
|
||||||
process_count,
|
|
||||||
_timestamp: Instant::now(),
|
|
||||||
})
|
|
||||||
|
|
||||||
// todo!();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
pub struct CgroupCpuStat {
|
|
||||||
pub usage_usec: u64,
|
|
||||||
pub user_usec: u64,
|
|
||||||
pub system_usec: u64,
|
|
||||||
pub nice_usec: u64,
|
|
||||||
pub core_sched_force_idle_usec: u64,
|
|
||||||
pub nr_periods: u64,
|
|
||||||
pub nr_throttled: u64,
|
|
||||||
pub throttled_usec: u64,
|
|
||||||
pub nr_bursts: u64,
|
|
||||||
pub burst_usec: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_cpustat(stat: &str) -> anyhow::Result<CgroupCpuStat> {
|
|
||||||
let mut cpu_stat = CgroupCpuStat::default();
|
|
||||||
for line in stat.lines() {
|
|
||||||
let line = line.trim();
|
|
||||||
if line.is_empty() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (key, value_str) = line
|
|
||||||
.split_once(' ')
|
|
||||||
.ok_or_else(|| anyhow::anyhow!("Invalid format:{}", line))?;
|
|
||||||
|
|
||||||
let value = value_str.parse::<u64>().map_err(|e| {
|
|
||||||
anyhow::anyhow!(
|
|
||||||
"Cannot convert value {}({}) into integer: {}",
|
|
||||||
key,
|
|
||||||
value_str,
|
|
||||||
e
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
match key {
|
|
||||||
"usage_usec" => cpu_stat.usage_usec = value,
|
|
||||||
"user_usec" => cpu_stat.user_usec = value,
|
|
||||||
"system_usec" => cpu_stat.system_usec = value,
|
|
||||||
"nice_usec" => cpu_stat.nice_usec = value,
|
|
||||||
"core_sched.force_idle_usec" => cpu_stat.core_sched_force_idle_usec = value,
|
|
||||||
"nr_periods" => cpu_stat.nr_periods = value,
|
|
||||||
"nr_throttled" => cpu_stat.nr_throttled = value,
|
|
||||||
"throttled_usec" => cpu_stat.throttled_usec = value,
|
|
||||||
"nr_bursts" => cpu_stat.nr_bursts = value,
|
|
||||||
"burst_usec" => cpu_stat.burst_usec = value,
|
|
||||||
_unknown_key => {} // Ignore unknown keys
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(cpu_stat)
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub fn get_usage() -> anyhow::Result<f64> {
|
|
||||||
unimplemented!("Not supporting windows JobObject at this time!");
|
|
||||||
}
|
|
||||||
@@ -139,17 +139,11 @@ pub fn resolve_template(
|
|||||||
_standalone: bool,
|
_standalone: bool,
|
||||||
server_templates: Option<&HashMap<String, NotificationTemplateDef>>,
|
server_templates: Option<&HashMap<String, NotificationTemplateDef>>,
|
||||||
) -> Result<NotificationTemplateDef, NotifyError> {
|
) -> Result<NotificationTemplateDef, NotifyError> {
|
||||||
// 1. Try the initial schema directly
|
let mut schema_next = if schema.is_none() {
|
||||||
if let Some(schema_name) = schema.as_deref() {
|
resolve_template_next_schema(schema)
|
||||||
if let Some(template) =
|
} else {
|
||||||
resolve_template_by_schema(schema_name, method_name, templates, server_templates)
|
schema.clone()
|
||||||
{
|
};
|
||||||
return Ok(template);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Walk the fallback chain
|
|
||||||
let mut schema_next = resolve_template_next_schema(schema);
|
|
||||||
while let Some(ref schema_name) = schema_next {
|
while let Some(ref schema_name) = schema_next {
|
||||||
if let Some(template) =
|
if let Some(template) =
|
||||||
resolve_template_by_schema(schema_name, method_name, templates, server_templates)
|
resolve_template_by_schema(schema_name, method_name, templates, server_templates)
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ pub fn lookup_uid_by_name(username: &str) -> Result<u32, PrebakeError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: originally unsafe {pwent} here, maybe to check and remove
|
// NOTE: originally unsafe {pwent} here
|
||||||
// let pwent = pwent ;
|
// let pwent = pwent ;
|
||||||
if pwent.is_null() {
|
if pwent.is_null() {
|
||||||
if let Ok(uid) = username.parse::<u32>() {
|
if let Ok(uid) = username.parse::<u32>() {
|
||||||
|
|||||||
@@ -54,52 +54,50 @@ pub async fn bootstrap(
|
|||||||
let bootstrap_config = config.bootstrap.clone().unwrap_or_default();
|
let bootstrap_config = config.bootstrap.clone().unwrap_or_default();
|
||||||
|
|
||||||
if let Some(raw) = bootstrap_config.custom {
|
if let Some(raw) = bootstrap_config.custom {
|
||||||
match BootstrapSource::parse(&raw) {
|
// Workshop-specific schemes requiring bakerd infrastructure
|
||||||
BootstrapSource::Inline(script) => {
|
if let Some(rest) = raw.strip_prefix("workspace://") {
|
||||||
if ctx.dry_run {
|
log::info!("Custom bootstrap from workspace: {}", rest);
|
||||||
log::info!(
|
|
||||||
"[DRY_RUN] User provided inline bootstrap script:\n{}",
|
|
||||||
script
|
|
||||||
);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
log::debug!("Using inline bootstrap script ({} bytes)", script.len());
|
|
||||||
if ctx.standalone {
|
|
||||||
write_bootstrap_content(&bootstrap_path, script)?;
|
|
||||||
} else {
|
|
||||||
// Requires PIP(Pipeline Implicit Parameters) to be implemented
|
|
||||||
unimplemented!("Permission check is not implemented, failing...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BootstrapSource::Workspace(relpath) => {
|
|
||||||
// Project-relative path, resolved by bakerd against the project root.
|
|
||||||
// Routing path relpath through bakerd's workspace manager ensures
|
|
||||||
// proper sandboxing and access control.
|
|
||||||
log::info!("Custom bootstrap from workspace: {}", relpath);
|
|
||||||
unimplemented!("Workspace-relative bootstrap requires bakerd's workspace manager");
|
unimplemented!("Workspace-relative bootstrap requires bakerd's workspace manager");
|
||||||
}
|
} else if let Some(name) = raw.strip_prefix("server://") {
|
||||||
BootstrapSource::Server(name) => {
|
|
||||||
// Script provided by the bake server (bakerd), keyed by name.
|
|
||||||
// The server maintains a registry of trusted bootstrap scripts.
|
|
||||||
log::info!("Custom bootstrap from server: {}", name);
|
log::info!("Custom bootstrap from server: {}", name);
|
||||||
unimplemented!("Server-provided bootstrap requires bakerd's script registry");
|
unimplemented!("Server-provided bootstrap requires bakerd's script registry");
|
||||||
}
|
}
|
||||||
BootstrapSource::Http(url) => {
|
// Use getterURL for standard URL schemes: http, https, file, git, ...
|
||||||
// HTTP download, similar to finalize::plugin::fetch::fetch_http_plugin.
|
else if workshop_getterurl::GetterUrl::parse(&raw).is_ok() {
|
||||||
// Should support: checksum verification, retry, timeout.
|
log::info!("Fetching custom bootstrap via getterURL: {}", raw);
|
||||||
log::info!("Custom bootstrap from URL: {}", url);
|
if ctx.standalone {
|
||||||
log::info!(" Target: {}", bootstrap_path.display());
|
let temp_dir = tempfile::tempdir().map_err(BootstrapError::IOError)?;
|
||||||
unimplemented!(
|
let fetched = workshop_getterurl::fetch(&raw, temp_dir.path())
|
||||||
"HTTP bootstrap fetching requires bakerd-level network infrastructure"
|
.await
|
||||||
);
|
.map_err(|e| BootstrapError::InvalidConfig(e.to_string()))?;
|
||||||
|
if fetched.is_dir() {
|
||||||
|
return Err(BootstrapError::InvalidConfig(
|
||||||
|
format!("getterURL returned a directory, expected a single file: {}", fetched.display())
|
||||||
|
));
|
||||||
}
|
}
|
||||||
BootstrapSource::File(path) => {
|
let content = tokio::fs::read_to_string(&fetched)
|
||||||
// Local file copy. This is the simplest case — we can implement
|
|
||||||
// this directly without bakerd infrastructure.
|
|
||||||
log::info!("Custom bootstrap from local file: {}", path);
|
|
||||||
tokio::fs::copy(&path, &bootstrap_path)
|
|
||||||
.await
|
.await
|
||||||
.map_err(BootstrapError::IOError)?;
|
.map_err(BootstrapError::IOError)?;
|
||||||
|
if ctx.dry_run {
|
||||||
|
log::info!("[DRY_RUN] Fetched bootstrap script:\n{}", content);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
write_bootstrap_content(&bootstrap_path, content)?;
|
||||||
|
} else {
|
||||||
|
unimplemented!("Permission check is not implemented, failing...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Inline content (not a valid getterURL pattern)
|
||||||
|
else {
|
||||||
|
if ctx.dry_run {
|
||||||
|
log::info!("[DRY_RUN] User provided inline bootstrap script:\n{}", raw);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
log::debug!("Using inline bootstrap script ({} bytes)", raw.len());
|
||||||
|
if ctx.standalone {
|
||||||
|
write_bootstrap_content(&bootstrap_path, raw.to_string())?;
|
||||||
|
} else {
|
||||||
|
unimplemented!("Permission check is not implemented, failing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user