feat: add replay feature for recovery
- fix bug commit not update index Signed-off-by: Pakin <pakin.t@forth.co.th>
This commit is contained in:
parent
a69ef7b927
commit
2466472235
4 changed files with 693 additions and 140 deletions
460
Cargo.lock
generated
460
Cargo.lock
generated
|
|
@ -16,7 +16,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cipher",
|
"cipher",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -400,6 +400,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 = "brotli"
|
name = "brotli"
|
||||||
version = "8.0.2"
|
version = "8.0.2"
|
||||||
|
|
@ -439,6 +448,12 @@ version = "1.25.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
|
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder-lite"
|
name = "byteorder-lite"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
@ -478,6 +493,17 @@ 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 = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chacha20"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.3.0",
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.44"
|
version = "0.4.44"
|
||||||
|
|
@ -497,10 +523,16 @@ version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crypto-common",
|
"crypto-common 0.1.7",
|
||||||
"inout",
|
"inout",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cmov"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color_quant"
|
name = "color_quant"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
|
@ -552,6 +584,12 @@ dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-oid"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "constant_time_eq"
|
name = "constant_time_eq"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
@ -593,6 +631,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 = "crc"
|
name = "crc"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
|
|
@ -658,6 +705,24 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710"
|
||||||
|
dependencies = [
|
||||||
|
"hybrid-array",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctutils"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e"
|
||||||
|
dependencies = [
|
||||||
|
"cmov",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deflate64"
|
name = "deflate64"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
|
@ -690,11 +755,23 @@ 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",
|
||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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.1",
|
||||||
|
"ctutils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "displaydoc"
|
name = "displaydoc"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
|
|
@ -816,6 +893,12 @@ dependencies = [
|
||||||
"zune-inflate",
|
"zune-inflate",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-iterator"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "2.4.1"
|
version = "2.4.1"
|
||||||
|
|
@ -914,6 +997,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
|
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -977,7 +1061,7 @@ checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1001,6 +1085,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"r-efi 6.0.0",
|
"r-efi 6.0.0",
|
||||||
|
"rand_core 0.10.1",
|
||||||
"wasip2",
|
"wasip2",
|
||||||
"wasip3",
|
"wasip3",
|
||||||
]
|
]
|
||||||
|
|
@ -1032,9 +1117,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.4.13"
|
version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
|
checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic-waker",
|
"atomic-waker",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|
@ -1087,7 +1172,16 @@ version = "0.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest 0.10.7",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hmac"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f"
|
||||||
|
dependencies = [
|
||||||
|
"digest 0.11.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1135,6 +1229,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.9.0"
|
version = "1.9.0"
|
||||||
|
|
@ -1437,16 +1540,6 @@ version = "2.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
|
checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iri-string"
|
|
||||||
version = "0.7.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.2"
|
version = "1.70.2"
|
||||||
|
|
@ -1504,9 +1597,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.97"
|
version = "0.3.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf"
|
checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
|
@ -1593,7 +1686,7 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"libc",
|
"libc",
|
||||||
"plain",
|
"plain",
|
||||||
"redox_syscall 0.7.4",
|
"redox_syscall 0.7.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1621,7 +1714,7 @@ dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"log",
|
"log",
|
||||||
"quick-xml",
|
"quick-xml",
|
||||||
"rand",
|
"rand 0.9.4",
|
||||||
"rayon",
|
"rayon",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
@ -1685,7 +1778,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c60a23ffb90d527e23192f1246b14746e2f7f071cb84476dd879071696c18a4a"
|
checksum = "c60a23ffb90d527e23192f1246b14746e2f7f071cb84476dd879071696c18a4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc",
|
"crc",
|
||||||
"sha2",
|
"sha2 0.10.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1704,6 +1797,16 @@ dependencies = [
|
||||||
"rayon",
|
"rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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.8.0"
|
version = "2.8.0"
|
||||||
|
|
@ -1733,7 +1836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
|
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1795,9 +1898,9 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "no_std_io2"
|
name = "no_std_io2"
|
||||||
version = "0.9.3"
|
version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b51ed7824b6e07d354605f4abb3d9d300350701299da96642ee084f5ce631550"
|
checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
@ -1873,6 +1976,24 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-core-foundation"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-system-configuration"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7216bd11cbda54ccabcab84d523dc93b858ec75ecfb3a7d89513fa22464da396"
|
||||||
|
dependencies = [
|
||||||
|
"objc2-core-foundation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.4"
|
version = "1.21.4"
|
||||||
|
|
@ -1981,8 +2102,8 @@ version = "0.12.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest 0.10.7",
|
||||||
"hmac",
|
"hmac 0.12.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2003,19 +2124,38 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "phf"
|
||||||
version = "1.1.11"
|
version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517"
|
checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project"
|
||||||
|
version = "1.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-internal",
|
"pin-project-internal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-internal"
|
name = "pin-project-internal"
|
||||||
version = "1.1.11"
|
version = "1.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6"
|
checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -2068,6 +2208,35 @@ dependencies = [
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postgres-protocol"
|
||||||
|
version = "0.6.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56201207dac53e2f38e848e31b4b91616a6bb6e0c7205b77718994a7f49e70fc"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"fallible-iterator",
|
||||||
|
"hmac 0.13.0",
|
||||||
|
"md-5",
|
||||||
|
"memchr",
|
||||||
|
"rand 0.10.1",
|
||||||
|
"sha2 0.11.0",
|
||||||
|
"stringprep",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postgres-types"
|
||||||
|
version = "0.2.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8dc729a129e682e8d24170cd30ae1aa01b336b096cbb56df6d534ffec133d186"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"fallible-iterator",
|
||||||
|
"postgres-protocol",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "potential_utf"
|
name = "potential_utf"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
|
@ -2119,18 +2288,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "profiling"
|
name = "profiling"
|
||||||
version = "1.0.17"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
|
checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"profiling-procmacros",
|
"profiling-procmacros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "profiling-procmacros"
|
name = "profiling-procmacros"
|
||||||
version = "1.0.17"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b"
|
checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
|
@ -2232,9 +2401,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-xml"
|
name = "quick-xml"
|
||||||
version = "0.39.2"
|
version = "0.39.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d"
|
checksum = "721da970c312655cde9b4ffe0547f20a8494866a4af5ff51f18b7c633d0c870b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
@ -2267,7 +2436,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
|
checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"rand_core",
|
"rand_core 0.9.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
|
||||||
|
dependencies = [
|
||||||
|
"chacha20",
|
||||||
|
"getrandom 0.4.2",
|
||||||
|
"rand_core 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2277,7 +2457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.9.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2289,6 +2469,12 @@ dependencies = [
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rav1e"
|
name = "rav1e"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|
@ -2316,7 +2502,7 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"paste",
|
"paste",
|
||||||
"profiling",
|
"profiling",
|
||||||
"rand",
|
"rand 0.9.4",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"simd_helpers",
|
"simd_helpers",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
@ -2395,9 +2581,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.7.4"
|
version = "0.7.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a"
|
checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
@ -2676,8 +2862,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"digest",
|
"digest 0.10.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2693,8 +2879,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]]
|
||||||
|
|
@ -2728,6 +2925,12 @@ dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
|
@ -2762,6 +2965,17 @@ 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 = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stringprep"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
"unicode-properties",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
|
|
@ -2857,6 +3071,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-postgres",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tonic",
|
"tonic",
|
||||||
"tonic-prost",
|
"tonic-prost",
|
||||||
|
|
@ -2941,10 +3156,25 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tinyvec"
|
||||||
version = "1.52.1"
|
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 = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6"
|
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.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "110a78583f19d5cdb2c5ccf321d1290344e71313c6c37d43520d386027d18386"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -2978,6 +3208,32 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-postgres"
|
||||||
|
version = "0.7.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4dd8df5ef180f6364759a6f00f7aadda4fbbac86cdee37480826a6ff9f3574ce"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"fallible-iterator",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"parking_lot",
|
||||||
|
"percent-encoding",
|
||||||
|
"phf",
|
||||||
|
"pin-project-lite",
|
||||||
|
"postgres-protocol",
|
||||||
|
"postgres-types",
|
||||||
|
"rand 0.10.1",
|
||||||
|
"socket2",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"whoami",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-rustls"
|
name = "tokio-rustls"
|
||||||
version = "0.26.4"
|
version = "0.26.4"
|
||||||
|
|
@ -3014,9 +3270,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tonic"
|
name = "tonic"
|
||||||
version = "0.14.5"
|
version = "0.14.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec"
|
checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
|
|
@ -3043,9 +3299,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tonic-build"
|
name = "tonic-build"
|
||||||
version = "0.14.5"
|
version = "0.14.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734"
|
checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -3055,9 +3311,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tonic-prost"
|
name = "tonic-prost"
|
||||||
version = "0.14.5"
|
version = "0.14.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309"
|
checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"prost",
|
"prost",
|
||||||
|
|
@ -3066,9 +3322,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tonic-prost-build"
|
name = "tonic-prost-build"
|
||||||
version = "0.14.5"
|
version = "0.14.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a"
|
checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -3101,20 +3357,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-http"
|
name = "tower-http"
|
||||||
version = "0.6.8"
|
version = "0.6.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
|
checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"iri-string",
|
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3179,12 +3435,33 @@ version = "2.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.24"
|
version = "1.0.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-properties"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
|
@ -3280,6 +3557,15 @@ version = "0.11.1+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.14.7+wasi-0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
|
||||||
|
dependencies = [
|
||||||
|
"wasip2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasip2"
|
name = "wasip2"
|
||||||
version = "1.0.3+wasi-0.2.9"
|
version = "1.0.3+wasi-0.2.9"
|
||||||
|
|
@ -3299,10 +3585,19 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasite"
|
||||||
version = "0.2.120"
|
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 = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1"
|
checksum = "66fe902b4a6b8028a753d5424909b764ccf79b7a209eac9bf97e59cda9f71a42"
|
||||||
|
dependencies = [
|
||||||
|
"wasi 0.14.7+wasi-0.2.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.121"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
|
@ -3313,9 +3608,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-futures"
|
name = "wasm-bindgen-futures"
|
||||||
version = "0.4.70"
|
version = "0.4.71"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084"
|
checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
|
@ -3323,9 +3618,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.120"
|
version = "0.2.121"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103"
|
checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
|
|
@ -3333,9 +3628,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.120"
|
version = "0.2.121"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41"
|
checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -3346,9 +3641,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.120"
|
version = "0.2.121"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea"
|
checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
@ -3389,9 +3684,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.97"
|
version = "0.3.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602"
|
checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
|
@ -3403,6 +3698,19 @@ version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
|
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "whoami"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "998767ef88740d1f5b0682a9c53c24431453923962269c2db68ee43788c5a40d"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"libredox",
|
||||||
|
"objc2-system-configuration",
|
||||||
|
"wasite",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.11"
|
version = "0.1.11"
|
||||||
|
|
@ -3817,7 +4125,7 @@ dependencies = [
|
||||||
"deflate64",
|
"deflate64",
|
||||||
"flate2",
|
"flate2",
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"hmac",
|
"hmac 0.12.1",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"lzma-rust2",
|
"lzma-rust2",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ tokio-util = { version = "0.7.18", features = ["io"] }
|
||||||
tonic = { version = "0.14.2", features = ["transport"] }
|
tonic = { version = "0.14.2", features = ["transport"] }
|
||||||
tonic-prost = "0.14.2"
|
tonic-prost = "0.14.2"
|
||||||
uuid = { version = "1.20.0", features = ["v4"] }
|
uuid = { version = "1.20.0", features = ["v4"] }
|
||||||
|
tokio-postgres = "0.7.17"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tonic-prost-build = "0.14.2"
|
tonic-prost-build = "0.14.2"
|
||||||
|
|
|
||||||
371
src/app.rs
371
src/app.rs
|
|
@ -1,10 +1,16 @@
|
||||||
use std::{collections::HashMap, io::Cursor, sync::Arc, time::Duration};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
io::Cursor,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
sync::Arc,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
use async_compression::tokio::bufread::BrotliEncoder;
|
use async_compression::tokio::bufread::BrotliEncoder;
|
||||||
use axum::{
|
use axum::{
|
||||||
Json, Router,
|
Json, Router,
|
||||||
body::Body,
|
body::Body,
|
||||||
extract::{Query, State},
|
extract::{DefaultBodyLimit, Query, State},
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
};
|
};
|
||||||
|
|
@ -22,7 +28,7 @@ use image::load_from_memory;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use redis::{AsyncTypedCommands, Connection, TypedCommands, aio::MultiplexedConnection};
|
use redis::{AsyncTypedCommands, Connection, TypedCommands, aio::MultiplexedConnection};
|
||||||
use reqwest::header;
|
use reqwest::header;
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{Value, json};
|
use serde_json::{Value, json};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncReadExt, BufReader},
|
io::{AsyncReadExt, BufReader},
|
||||||
|
|
@ -33,6 +39,7 @@ use tokio::{
|
||||||
task::JoinSet,
|
task::JoinSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use tokio_postgres::NoTls;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -58,11 +65,11 @@ pub struct AppState {
|
||||||
// cached_country_names: Vec<&'static str>,
|
// cached_country_names: Vec<&'static str>,
|
||||||
configures: gcm::Configure,
|
configures: gcm::Configure,
|
||||||
repo: Arc<Mutex<Repository>>,
|
repo: Arc<Mutex<Repository>>,
|
||||||
|
// commit external db
|
||||||
|
postgres: Arc<Mutex<tokio_postgres::Client>>,
|
||||||
redis: RedisPool,
|
redis: RedisPool,
|
||||||
// save already fetched path, further calls should fetch from redis instead.
|
// save already fetched path, further calls should fetch from redis instead.
|
||||||
fetched: Vec<String>,
|
fetched: Vec<String>,
|
||||||
// queue
|
|
||||||
enqueue_tx: Sender<CacheJob>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
|
|
@ -349,12 +356,18 @@ struct Signature {
|
||||||
email: String,
|
email: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_handler]
|
|
||||||
async fn commit_handler(
|
async fn commit_handler(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
// request body as multipart/form-data
|
// request body as multipart/form-data
|
||||||
mut payload: Multipart,
|
mut payload: Multipart,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
// operate on repo
|
||||||
|
let op_repo = state
|
||||||
|
.get_config("GIT_REPO_LOCAL_DEST")
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.replace("./", "");
|
||||||
|
|
||||||
// Extract multipart fields
|
// Extract multipart fields
|
||||||
let mut path: Option<String> = None;
|
let mut path: Option<String> = None;
|
||||||
let mut signature_username: Option<String> = None;
|
let mut signature_username: Option<String> = None;
|
||||||
|
|
@ -362,6 +375,8 @@ async fn commit_handler(
|
||||||
let mut message: Option<String> = None;
|
let mut message: Option<String> = None;
|
||||||
let mut file_bytes: Option<Vec<u8>> = None;
|
let mut file_bytes: Option<Vec<u8>> = None;
|
||||||
|
|
||||||
|
let mut ref_message: Option<String> = None;
|
||||||
|
|
||||||
let mut file_mappings: HashMap<String, Vec<u8>> = HashMap::new();
|
let mut file_mappings: HashMap<String, Vec<u8>> = HashMap::new();
|
||||||
let mut filex_map: HashMap<String, Vec<u8>> = HashMap::new();
|
let mut filex_map: HashMap<String, Vec<u8>> = HashMap::new();
|
||||||
let mut pathx_map: HashMap<String, String> = HashMap::new();
|
let mut pathx_map: HashMap<String, String> = HashMap::new();
|
||||||
|
|
@ -420,7 +435,8 @@ async fn commit_handler(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
"file" => {
|
"file" => {
|
||||||
file_bytes = Some(match field.bytes().await {
|
let _file_bytes = field.bytes().await;
|
||||||
|
file_bytes = Some(match _file_bytes {
|
||||||
Ok(b) => b.to_vec(),
|
Ok(b) => b.to_vec(),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -430,6 +446,17 @@ async fn commit_handler(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
"ref" => {
|
||||||
|
ref_message = Some(match field.text().await {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => {
|
||||||
|
return (
|
||||||
|
axum::http::StatusCode::BAD_REQUEST,
|
||||||
|
Json(json!({"error": format!("Failed to read ref field: {}", e)})),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
filex if name.starts_with("file") => match field.bytes().await {
|
filex if name.starts_with("file") => match field.bytes().await {
|
||||||
Ok(fx) => {
|
Ok(fx) => {
|
||||||
|
|
@ -495,8 +522,8 @@ async fn commit_handler(
|
||||||
|
|
||||||
// Create signature
|
// Create signature
|
||||||
let signature = Signature {
|
let signature = Signature {
|
||||||
username: signature_username,
|
username: signature_username.clone(),
|
||||||
email: signature_email,
|
email: signature_email.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("sig: {signature:?}");
|
info!("sig: {signature:?}");
|
||||||
|
|
@ -557,6 +584,44 @@ async fn commit_handler(
|
||||||
info!("commit success! [{commit_oid}]");
|
info!("commit success! [{commit_oid}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: save to db
|
||||||
|
|
||||||
|
let mut plock = state.postgres.lock().await;
|
||||||
|
let tx = match plock.transaction().await {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
axum::http::StatusCode::CREATED,
|
||||||
|
Json(
|
||||||
|
json!({"result": format!("{commit_oid}"), "reason": "CannotConnect_CommitMayBeLost"}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let insert_commit = tx.execute("INSERT INTO recovery_commit (commit_hash, commit_user, email, repo, ref) VALUES ($1, $2, $3, $4, $5)", &[
|
||||||
|
&commit_oid.to_string(),
|
||||||
|
&signature_username.clone(),
|
||||||
|
&signature_email.clone(),
|
||||||
|
&op_repo,
|
||||||
|
&ref_message.unwrap_or_default(),
|
||||||
|
]).await;
|
||||||
|
if insert_commit.is_ok() {
|
||||||
|
match tx.commit().await {
|
||||||
|
Ok(_) => {
|
||||||
|
info!("successfully inserted into postgres");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("commit postgres failed: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error!("failed to commit to postgres & rolling back ...");
|
||||||
|
if let Err(rollback_error) = tx.rollback().await {
|
||||||
|
error!("failed to rollback, {rollback_error}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
axum::http::StatusCode::OK,
|
axum::http::StatusCode::OK,
|
||||||
Json(json!({"result": format!("{commit_oid}")})),
|
Json(json!({"result": format!("{commit_oid}")})),
|
||||||
|
|
@ -712,11 +777,34 @@ async fn commit_file_content(
|
||||||
) -> Result<git2::Oid, Box<dyn std::error::Error>> {
|
) -> Result<git2::Oid, Box<dyn std::error::Error>> {
|
||||||
let repo_guard = repo.lock().await;
|
let repo_guard = repo.lock().await;
|
||||||
|
|
||||||
let blob_oid = repo_guard.blob(content)?;
|
let workdir = repo_guard.workdir().ok_or_else(|| {
|
||||||
|
git2::Error::from_str("Repository must have a working directory for this strategy")
|
||||||
|
})?;
|
||||||
|
|
||||||
let mut index = repo_guard.index()?;
|
let full_path = if Path::new(path).is_absolute() {
|
||||||
|
Path::new(path).to_path_buf()
|
||||||
|
} else {
|
||||||
|
workdir.join(path)
|
||||||
|
};
|
||||||
|
if let Some(parent) = full_path.parent() {
|
||||||
|
std::fs::create_dir_all(parent)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::fs::write(&full_path, content)?;
|
||||||
|
|
||||||
let target_ref = format!("refs/heads/{branch}");
|
let target_ref = format!("refs/heads/{branch}");
|
||||||
|
|
||||||
|
let relative_git_path = if full_path.is_absolute() {
|
||||||
|
full_path.strip_prefix(workdir).map_err(|_| {
|
||||||
|
git2::Error::from_str(
|
||||||
|
"The provided path is outside of the repository working directory",
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
} else {
|
||||||
|
Path::new(path)
|
||||||
|
};
|
||||||
|
let mut index = repo_guard.index()?;
|
||||||
|
|
||||||
let parent_commit = match repo_guard.find_reference(&target_ref) {
|
let parent_commit = match repo_guard.find_reference(&target_ref) {
|
||||||
Ok(reference) => {
|
Ok(reference) => {
|
||||||
let commit = reference.peel_to_commit()?;
|
let commit = reference.peel_to_commit()?;
|
||||||
|
|
@ -726,20 +814,8 @@ async fn commit_file_content(
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
index.add(&git2::IndexEntry {
|
index.add_path(relative_git_path)?;
|
||||||
ctime: git2::IndexTime::new(0, 0),
|
index.write()?;
|
||||||
mtime: git2::IndexTime::new(0, 0),
|
|
||||||
dev: 0,
|
|
||||||
ino: 0,
|
|
||||||
mode: 0o100644,
|
|
||||||
uid: 0,
|
|
||||||
gid: 0,
|
|
||||||
file_size: content.len() as u32,
|
|
||||||
id: blob_oid,
|
|
||||||
flags: 0,
|
|
||||||
flags_extended: 0,
|
|
||||||
path: path.as_bytes().to_vec(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let tree_oid = index.write_tree()?;
|
let tree_oid = index.write_tree()?;
|
||||||
let tree = repo_guard.find_tree(tree_oid)?;
|
let tree = repo_guard.find_tree(tree_oid)?;
|
||||||
|
|
@ -753,14 +829,17 @@ async fn commit_file_content(
|
||||||
|
|
||||||
let oid = repo_guard.commit(
|
let oid = repo_guard.commit(
|
||||||
//"refs/heads/master"
|
//"refs/heads/master"
|
||||||
Some(&target_ref),
|
None, &sig, &sig, message, &tree, &parents,
|
||||||
&sig,
|
|
||||||
&sig,
|
|
||||||
message,
|
|
||||||
&tree,
|
|
||||||
&parents,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
repo_guard.reference(&target_ref, oid, true, "api commit log update")?;
|
||||||
|
|
||||||
|
if let Ok(mut head) = repo_guard.head() {
|
||||||
|
if head.name() == Some(&target_ref) {
|
||||||
|
repo_guard.set_head(&target_ref)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info!("commit oid: {oid}");
|
info!("commit oid: {oid}");
|
||||||
|
|
||||||
Ok(oid)
|
Ok(oid)
|
||||||
|
|
@ -774,9 +853,59 @@ async fn commit_multiple_file_contents(
|
||||||
branch: String,
|
branch: String,
|
||||||
) -> Result<git2::Oid, Box<dyn std::error::Error>> {
|
) -> Result<git2::Oid, Box<dyn std::error::Error>> {
|
||||||
let repo_guard = repo.lock().await;
|
let repo_guard = repo.lock().await;
|
||||||
let mut index = repo_guard.index()?;
|
|
||||||
|
|
||||||
|
let workdir = repo_guard.workdir().ok_or_else(|| {
|
||||||
|
git2::Error::from_str("Repository must have a working directory for this strategy")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Pre-calculate and normalize paths into a standard vector so we don't have
|
||||||
|
// path-resolution discrepancies between loops.
|
||||||
|
// Keeps: (Absolute Path on Disk, Relative Path for Git Index, Content Buffer)
|
||||||
|
let mut processing_queue: Vec<(PathBuf, PathBuf, &[u8])> = Vec::new();
|
||||||
|
|
||||||
|
for (raw_path, content) in &file_mapping {
|
||||||
|
let path_obj = Path::new(raw_path);
|
||||||
|
|
||||||
|
// 1. Compute a clean, guaranteed absolute path for writing to disk
|
||||||
|
let full_path = if path_obj.is_absolute() {
|
||||||
|
path_obj.to_path_buf()
|
||||||
|
} else {
|
||||||
|
// This handles files starting with "./", "../", or raw filenames safely
|
||||||
|
workdir.join(path_obj)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Canonicalize or cleanly normalize the path syntax relative to the workdir
|
||||||
|
// to strip out relative quirks like "." or ".." components
|
||||||
|
let clean_full_path = match full_path.canonicalize() {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => full_path, // Fallback if file doesn't exist yet on disk
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. Compute a strict relative path matching how Git sees the workspace
|
||||||
|
let relative_git_path = clean_full_path
|
||||||
|
.strip_prefix(workdir)
|
||||||
|
.map_err(|_| {
|
||||||
|
git2::Error::from_str(
|
||||||
|
"A provided path lives outside the repository working directory",
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.to_path_buf();
|
||||||
|
|
||||||
|
processing_queue.push((clean_full_path, relative_git_path, content));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop 1: Safely write all processed files to disk first
|
||||||
|
for (full_path, _, content) in &processing_queue {
|
||||||
|
if let Some(parent) = full_path.parent() {
|
||||||
|
std::fs::create_dir_all(parent)?;
|
||||||
|
}
|
||||||
|
std::fs::write(full_path, content)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut index = repo_guard.index()?;
|
||||||
let target_ref = format!("refs/heads/{branch}");
|
let target_ref = format!("refs/heads/{branch}");
|
||||||
|
|
||||||
|
// Loop 2: Hydrate index from previous branch commit tree
|
||||||
let parent_commit = match repo_guard.find_reference(&target_ref) {
|
let parent_commit = match repo_guard.find_reference(&target_ref) {
|
||||||
Ok(reference) => {
|
Ok(reference) => {
|
||||||
let commit = reference.peel_to_commit()?;
|
let commit = reference.peel_to_commit()?;
|
||||||
|
|
@ -786,24 +915,15 @@ async fn commit_multiple_file_contents(
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (_, (path, file)) in file_mapping.iter().enumerate() {
|
// Loop 3: Stage all files using the matching pre-calculated relative path
|
||||||
let blob_oid = repo_guard.blob(file.as_slice())?;
|
for (_, relative_git_path, _) in &processing_queue {
|
||||||
index.add(&git2::IndexEntry {
|
index.add_path(relative_git_path)?;
|
||||||
ctime: git2::IndexTime::new(0, 0),
|
|
||||||
mtime: git2::IndexTime::new(0, 0),
|
|
||||||
dev: 0,
|
|
||||||
ino: 0,
|
|
||||||
mode: 0o100644,
|
|
||||||
uid: 0,
|
|
||||||
gid: 0,
|
|
||||||
file_size: file.len() as u32,
|
|
||||||
id: blob_oid,
|
|
||||||
flags: 0,
|
|
||||||
flags_extended: 0,
|
|
||||||
path: path.as_bytes().to_vec(),
|
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flush changes to .git/index
|
||||||
|
index.write()?;
|
||||||
|
|
||||||
|
// Create tree layout from updated index state
|
||||||
let tree_oid = index.write_tree()?;
|
let tree_oid = index.write_tree()?;
|
||||||
let tree = repo_guard.find_tree(tree_oid)?;
|
let tree = repo_guard.find_tree(tree_oid)?;
|
||||||
|
|
||||||
|
|
@ -814,17 +934,20 @@ async fn commit_multiple_file_contents(
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let oid = repo_guard.commit(
|
// Commit changes to the object database
|
||||||
//"refs/heads/master"
|
let oid = repo_guard.commit(None, &sig, &sig, message, &tree, &parents)?;
|
||||||
Some(&target_ref),
|
|
||||||
&sig,
|
|
||||||
&sig,
|
|
||||||
message,
|
|
||||||
&tree,
|
|
||||||
&parents,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
info!("commit oid: {oid}");
|
// Advance branch reference explicitly
|
||||||
|
repo_guard.reference(&target_ref, oid, true, "api multi-file commit update")?;
|
||||||
|
|
||||||
|
// Sync active workspace reference state if checking out the branch locally
|
||||||
|
if let Ok(head) = repo_guard.head() {
|
||||||
|
if head.name() == Some(&target_ref) {
|
||||||
|
repo_guard.set_head(&target_ref)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Multi-file transaction successfully committed. OID: {oid}");
|
||||||
|
|
||||||
Ok(oid)
|
Ok(oid)
|
||||||
}
|
}
|
||||||
|
|
@ -909,6 +1032,102 @@ async fn pull_handler(State(state): State<AppState>) -> impl IntoResponse {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct ReplayPayload {
|
||||||
|
commit_hashes: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn replay_handler(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Json(payload): Json<ReplayPayload>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let repo = state.repo.clone();
|
||||||
|
|
||||||
|
let commit_hashes: Vec<&str> = payload.commit_hashes.iter().map(|x| x.as_str()).collect();
|
||||||
|
|
||||||
|
if let Err(e) = replay(repo, &commit_hashes.as_slice()).await {
|
||||||
|
return (
|
||||||
|
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Json(json!({"error": e.to_string()})),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
axum::http::StatusCode::OK,
|
||||||
|
Json(json!({"result": "replay completed"})),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn replay(
|
||||||
|
repo: Arc<Mutex<Repository>>,
|
||||||
|
commit_hashes: &[&str],
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let repo_guard = repo.lock().await;
|
||||||
|
|
||||||
|
let initial_head = repo_guard.head()?.peel_to_commit()?;
|
||||||
|
info!(
|
||||||
|
"Starting transaction replay. Initial HEAD: {}",
|
||||||
|
initial_head.id()
|
||||||
|
);
|
||||||
|
|
||||||
|
for (index, hash) in commit_hashes.iter().enumerate() {
|
||||||
|
let oid = Oid::from_str(hash)?;
|
||||||
|
let commit_to_apply = repo_guard.find_commit(oid)?;
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"#[{}/{}] Doing {} - \"{}\"",
|
||||||
|
index + 1,
|
||||||
|
commit_hashes.len(),
|
||||||
|
&hash[0..7],
|
||||||
|
commit_to_apply.summary().unwrap_or("[No summary]")
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut cherrypick_opts = git2::CherrypickOptions::new();
|
||||||
|
repo_guard.cherrypick(&commit_to_apply, Some(&mut cherrypick_opts))?;
|
||||||
|
|
||||||
|
let mut repo_index = repo_guard.index()?;
|
||||||
|
|
||||||
|
if repo_index.has_conflicts() {
|
||||||
|
error!("[CONFLICTED] at commit {}, aborting ...", &hash[0..7]);
|
||||||
|
let current_head_commit = repo_guard.head()?.peel_to_commit()?;
|
||||||
|
repo_guard.reset(current_head_commit.as_object(), ResetType::Hard, None)?;
|
||||||
|
return Err(format!("index_{}/conflicted", index).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let tree_id = repo_index.write_tree()?;
|
||||||
|
let tree = repo_guard.find_tree(tree_id)?;
|
||||||
|
|
||||||
|
let original_author = commit_to_apply.author();
|
||||||
|
|
||||||
|
let author = git2::Signature::now(
|
||||||
|
original_author.name().unwrap_or("Transaction Processor"),
|
||||||
|
original_author
|
||||||
|
.email()
|
||||||
|
.unwrap_or("processor@local.internal"),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let current_head = repo_guard.head()?.peel_to_commit()?;
|
||||||
|
let _new_commit_oid = repo_guard.commit(
|
||||||
|
Some("HEAD"),
|
||||||
|
&author,
|
||||||
|
&author,
|
||||||
|
&format!(
|
||||||
|
"Replay transaction: {}",
|
||||||
|
commit_to_apply.summary().unwrap_or("")
|
||||||
|
),
|
||||||
|
&tree,
|
||||||
|
&[¤t_head],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
repo_guard.cleanup_state()?;
|
||||||
|
info!("applied success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("all transaction applied successfully!");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Pull is fetch + merge
|
// Pull is fetch + merge
|
||||||
async fn pull(
|
async fn pull(
|
||||||
config: gcm::Configure,
|
config: gcm::Configure,
|
||||||
|
|
@ -971,10 +1190,6 @@ async fn health_handler(State(_): State<AppState>) -> impl IntoResponse {
|
||||||
|
|
||||||
pub async fn run(config: gcm::Configure) -> gcm::StandardResult {
|
pub async fn run(config: gcm::Configure) -> gcm::StandardResult {
|
||||||
// REDIS POOL
|
// REDIS POOL
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
let manager = RedisConnectionManager::new(format!(
|
let manager = RedisConnectionManager::new(format!(
|
||||||
"redis://{}:{}",
|
"redis://{}:{}",
|
||||||
config.get("REDIS_URI").unwrap_or(&"".to_string()),
|
config.get("REDIS_URI").unwrap_or(&"".to_string()),
|
||||||
|
|
@ -987,7 +1202,33 @@ pub async fn run(config: gcm::Configure) -> gcm::StandardResult {
|
||||||
.await
|
.await
|
||||||
.expect("failed to build redis pool");
|
.expect("failed to build redis pool");
|
||||||
|
|
||||||
let (enqueue_tx, enqueue_rx) = channel::<CacheJob>(8);
|
// let connect_str = "host=localhost user=postgres password=my_password dbname=my_database";
|
||||||
|
let connect_str = config
|
||||||
|
.get("POSTGRES_CONN")
|
||||||
|
.expect("failed to connect postgres");
|
||||||
|
info!("connect config: {connect_str}");
|
||||||
|
let (mut client, connection) = tokio_postgres::connect(connect_str, NoTls).await?;
|
||||||
|
tokio::spawn(async move {
|
||||||
|
if let Err(e) = connection.await {
|
||||||
|
error!("connection postgres error: {e}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
info!("Creating 'commit' table ...");
|
||||||
|
client
|
||||||
|
.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS recovery_commit (
|
||||||
|
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
|
commit_hash TEXT NOT NULL,
|
||||||
|
commit_user TEXT NOT NULL,
|
||||||
|
email TEXT NOT NULL,
|
||||||
|
repo TEXT NOT NULL,
|
||||||
|
ref TEXT NOT NULL,
|
||||||
|
commit_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
expire_at TIMESTAMPTZ DEFAULT NOW() + interval '1 hour'
|
||||||
|
)",
|
||||||
|
&[],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let state = AppState {
|
let state = AppState {
|
||||||
// cached_country_names: common::valid_country_name(),
|
// cached_country_names: common::valid_country_name(),
|
||||||
|
|
@ -995,9 +1236,9 @@ pub async fn run(config: gcm::Configure) -> gcm::StandardResult {
|
||||||
repo: Arc::new(Mutex::new(Repository::open(
|
repo: Arc::new(Mutex::new(Repository::open(
|
||||||
config.get("GIT_REPO_LOCAL_DEST").unwrap_or(&"".to_string()),
|
config.get("GIT_REPO_LOCAL_DEST").unwrap_or(&"".to_string()),
|
||||||
)?)),
|
)?)),
|
||||||
|
postgres: Arc::new(Mutex::new(client)),
|
||||||
redis: redis_pool.clone(),
|
redis: redis_pool.clone(),
|
||||||
fetched: Vec::new(),
|
fetched: Vec::new(),
|
||||||
enqueue_tx: enqueue_tx.clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
|
|
@ -1007,6 +1248,8 @@ pub async fn run(config: gcm::Configure) -> gcm::StandardResult {
|
||||||
.route("/push", get(push_handler))
|
.route("/push", get(push_handler))
|
||||||
.route("/pull", get(pull_handler))
|
.route("/pull", get(pull_handler))
|
||||||
.route("/health", get(health_handler))
|
.route("/health", get(health_handler))
|
||||||
|
.route("/replay", post(replay_handler))
|
||||||
|
.layer(DefaultBodyLimit::max(100 * 1024 * 1024))
|
||||||
// .route("/healthz", get(reg::health))
|
// .route("/healthz", get(reg::health))
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ async fn main() -> gcm::StandardResult {
|
||||||
.get("CONFIG_VERSION")
|
.get("CONFIG_VERSION")
|
||||||
.expect("config version not defined")
|
.expect("config version not defined")
|
||||||
);
|
);
|
||||||
|
info!("RUNNING: {:?}", config.get("PUBLIC_PORT"));
|
||||||
app::run(config.clone()).await?;
|
app::run(config.clone()).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue