without autoescape
This commit is contained in:
parent
49089b3074
commit
319360968b
557
Cargo.lock
generated
557
Cargo.lock
generated
@ -2,6 +2,24 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7ed72e1635e121ca3e79420540282af22da58be50de153d36f81ddc6b83aa9e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
@ -44,6 +62,30 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
@ -59,6 +101,40 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono-tz"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29c39203181991a7dd4343b8005bd804e7a9a37afb8ac070e43771e8c820bbde"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz-build",
|
||||
"phf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono-tz-build"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f509c3a87b33437b05e2458750a0700e5bdd6956176773e6c7d6dd15a283a0c"
|
||||
dependencies = [
|
||||
"parse-zoneinfo",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.16"
|
||||
@ -83,6 +159,41 @@ dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.23"
|
||||
@ -106,11 +217,28 @@ dependencies = [
|
||||
"openssl",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"tera",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deunicode"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
@ -151,6 +279,12 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
@ -176,6 +310,16 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
@ -202,6 +346,30 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"fnv",
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "globwalk"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"ignore",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
@ -217,6 +385,25 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humansize"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf7d67cf4a22adc5be66e75ebdf769b3f2ea032041437a7061f97a63dad4b"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
@ -228,6 +415,24 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
"globset",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"memchr",
|
||||
"regex",
|
||||
"same-file",
|
||||
"thread_local",
|
||||
"walkdir",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
@ -253,6 +458,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -321,6 +535,31 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.13.0"
|
||||
@ -388,12 +627,104 @@ version = "6.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4"
|
||||
|
||||
[[package]]
|
||||
name = "parse-zoneinfo"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69486e2b8c2d2aeb9762db7b4e00b0331156393555cff467f4163ff06821eef8"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b13570633aff33c6d22ce47dd566b10a3b9122c2fe9d8e7501895905be532b91"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3c567e5702efdc79fb18859ea74c3eb36e14c43da7b8c1f098a4ed6514ec7a0"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eb32be5ee3bbdafa8c7a18b0a8a8d962b66cfa2ceee4037f49267a50ee821fe"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha-1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
"uncased",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
@ -406,6 +737,12 @@ version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
@ -424,6 +761,36 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
@ -444,6 +811,23 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
@ -503,6 +887,17 @@ dependencies = [
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.4"
|
||||
@ -512,6 +907,21 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
|
||||
|
||||
[[package]]
|
||||
name = "slug"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
|
||||
dependencies = [
|
||||
"deunicode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.9.0"
|
||||
@ -535,6 +945,28 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tera"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d4685e72cb35f0eb74319c8fe2d3b61e93da5609841cde2cb87fcc3bea56d20"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"globwalk",
|
||||
"humansize",
|
||||
"lazy_static",
|
||||
"percent-encoding",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"slug",
|
||||
"unic-segment",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
@ -665,6 +1097,77 @@ dependencies = [
|
||||
"tracing-serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c"
|
||||
|
||||
[[package]]
|
||||
name = "uncased"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-property"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
|
||||
dependencies = [
|
||||
"unic-char-range",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-range"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
|
||||
|
||||
[[package]]
|
||||
name = "unic-common"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
|
||||
|
||||
[[package]]
|
||||
name = "unic-segment"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23"
|
||||
dependencies = [
|
||||
"unic-ucd-segment",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-ucd-segment"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700"
|
||||
dependencies = [
|
||||
"unic-char-property",
|
||||
"unic-char-range",
|
||||
"unic-ucd-version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-ucd-version"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
|
||||
dependencies = [
|
||||
"unic-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.8"
|
||||
@ -749,6 +1252,60 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -18,3 +18,4 @@ tracing = "0.1.36"
|
||||
tracing-subscriber = { version = "0.3.15", features = ["json"] }
|
||||
log = { version = "0.4.17", features = ["std", "kv_unstable"] }
|
||||
openssl = {version = "0.10", features = ["vendored"]}
|
||||
tera = "1.17.0"
|
||||
|
@ -1 +1,78 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{
|
||||
actions::shell::ShellAction,
|
||||
model::{CuddleScript, CuddleShellScriptArg, CuddleVariable},
|
||||
};
|
||||
|
||||
pub mod shell;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct CuddleAction {
|
||||
pub script: CuddleScript,
|
||||
pub path: PathBuf,
|
||||
pub name: String,
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
impl CuddleAction {
|
||||
pub fn new(script: CuddleScript, path: PathBuf, name: String) -> Self {
|
||||
Self { script, path, name }
|
||||
}
|
||||
|
||||
pub fn execute(self, variables: Vec<CuddleVariable>) -> anyhow::Result<()> {
|
||||
match self.script {
|
||||
CuddleScript::Shell(s) => {
|
||||
let mut arg_variables: Vec<CuddleVariable> = vec![];
|
||||
if let Some(args) = s.args {
|
||||
for (k, v) in args {
|
||||
let var = match v {
|
||||
CuddleShellScriptArg::Env(e) => {
|
||||
let env_var = match std::env::var(e.key.clone()) {
|
||||
Ok(var) => var,
|
||||
Err(e) => {
|
||||
log::error!("env_variable not found: {}", k);
|
||||
return Err(anyhow::anyhow!(e));
|
||||
}
|
||||
};
|
||||
CuddleVariable::new(k.clone(), env_var)
|
||||
}
|
||||
};
|
||||
|
||||
arg_variables.push(var);
|
||||
}
|
||||
} else {
|
||||
arg_variables = vec![]
|
||||
};
|
||||
|
||||
let mut vars = variables.clone();
|
||||
vars.append(&mut arg_variables);
|
||||
|
||||
log::trace!("preparing to run action");
|
||||
|
||||
match ShellAction::new(
|
||||
self.name.clone(),
|
||||
format!(
|
||||
"{}/scripts/{}.sh",
|
||||
self.path
|
||||
.to_str()
|
||||
.expect("action doesn't have a name, this should never happen"),
|
||||
self.name
|
||||
),
|
||||
)
|
||||
.execute(vars)
|
||||
{
|
||||
Ok(()) => {
|
||||
log::trace!("finished running action");
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
CuddleScript::Dagger(_d) => Err(anyhow::anyhow!("not implemented yet!")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::{env::current_dir, path::PathBuf, process::Command};
|
||||
|
||||
use crate::cli::CuddleVariable;
|
||||
use crate::model::CuddleVariable;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct ShellAction {
|
||||
|
@ -1,314 +0,0 @@
|
||||
use std::{
|
||||
env::{self, current_dir},
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use clap::Command;
|
||||
use git2::Repository;
|
||||
|
||||
use crate::{
|
||||
actions,
|
||||
context::{CuddleContext, CuddleTreeType},
|
||||
model::{CuddleScript, CuddleShellScriptArg},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
struct CuddleAction {
|
||||
script: CuddleScript,
|
||||
path: PathBuf,
|
||||
name: String,
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
impl CuddleAction {
|
||||
pub fn new(script: CuddleScript, path: PathBuf, name: String) -> Self {
|
||||
Self { script, path, name }
|
||||
}
|
||||
|
||||
pub fn execute(self, variables: Vec<CuddleVariable>) -> anyhow::Result<()> {
|
||||
match self.script {
|
||||
CuddleScript::Shell(s) => {
|
||||
let mut arg_variables: Vec<CuddleVariable> = vec![];
|
||||
if let Some(args) = s.args {
|
||||
for (k, v) in args {
|
||||
let var = match v {
|
||||
CuddleShellScriptArg::Env(e) => {
|
||||
let env_var = match env::var(e.key.clone()) {
|
||||
Ok(var) => var,
|
||||
Err(e) => {
|
||||
log::error!("env_variable not found: {}", k);
|
||||
return Err(anyhow::anyhow!(e));
|
||||
}
|
||||
};
|
||||
CuddleVariable::new(k.clone(), env_var)
|
||||
}
|
||||
};
|
||||
|
||||
arg_variables.push(var);
|
||||
}
|
||||
} else {
|
||||
arg_variables = vec![]
|
||||
};
|
||||
|
||||
let mut vars = variables.clone();
|
||||
vars.append(&mut arg_variables);
|
||||
|
||||
log::trace!("preparing to run action");
|
||||
|
||||
match actions::shell::ShellAction::new(
|
||||
self.name.clone(),
|
||||
format!(
|
||||
"{}/scripts/{}.sh",
|
||||
self.path
|
||||
.to_str()
|
||||
.expect("action doesn't have a name, this should never happen"),
|
||||
self.name
|
||||
),
|
||||
)
|
||||
.execute(vars)
|
||||
{
|
||||
Ok(()) => {
|
||||
log::trace!("finished running action");
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
CuddleScript::Dagger(_d) => Err(anyhow::anyhow!("not implemented yet!")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct CuddleVariable {
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl CuddleVariable {
|
||||
pub fn new(name: String, value: String) -> Self {
|
||||
Self { name, value }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct GitCommit {
|
||||
commit_sha: String,
|
||||
}
|
||||
|
||||
impl GitCommit {
|
||||
fn new() -> anyhow::Result<GitCommit> {
|
||||
let repo = Repository::open(current_dir().expect("having current_dir available")).map_err(
|
||||
|e| {
|
||||
log::debug!("{}", e);
|
||||
anyhow::anyhow!("could not open repository")
|
||||
},
|
||||
)?;
|
||||
let head_ref = repo
|
||||
.head()
|
||||
.map_err(|e| {
|
||||
log::warn!("{}", e);
|
||||
anyhow::anyhow!("could not get HEAD")
|
||||
})?
|
||||
.target()
|
||||
.ok_or(anyhow::anyhow!(
|
||||
"could not extract head -> target to commit_sha"
|
||||
))?;
|
||||
|
||||
Ok(Self {
|
||||
commit_sha: head_ref.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CuddleCli<'a> {
|
||||
scripts: Vec<CuddleAction>,
|
||||
variables: Vec<CuddleVariable>,
|
||||
context: Arc<Mutex<Vec<CuddleContext>>>,
|
||||
command: Option<Command<'a>>,
|
||||
tmp_dir: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl<'a> CuddleCli<'a> {
|
||||
pub fn new(context: Arc<Mutex<Vec<CuddleContext>>>) -> anyhow::Result<CuddleCli<'a>> {
|
||||
let mut cli = CuddleCli {
|
||||
scripts: vec![],
|
||||
variables: vec![],
|
||||
context: context.clone(),
|
||||
command: None,
|
||||
tmp_dir: None,
|
||||
};
|
||||
|
||||
cli = cli
|
||||
.process_variables()
|
||||
.process_scripts()
|
||||
.process_templates()?
|
||||
.build_cli();
|
||||
|
||||
Ok(cli)
|
||||
}
|
||||
|
||||
fn process_variables(mut self) -> Self {
|
||||
if let Ok(context_iter) = self.context.clone().lock() {
|
||||
for ctx in context_iter.iter() {
|
||||
if let Some(variables) = ctx.plan.vars.clone() {
|
||||
for (name, var) in variables {
|
||||
self.variables.push(CuddleVariable::new(name, var))
|
||||
}
|
||||
}
|
||||
|
||||
if let CuddleTreeType::Root = ctx.node_type {
|
||||
let mut temp_path = ctx.path.clone();
|
||||
temp_path.push(".cuddle/tmp/");
|
||||
|
||||
self.variables.push(CuddleVariable::new(
|
||||
"tmp".into(),
|
||||
temp_path.clone().to_string_lossy().to_string(),
|
||||
));
|
||||
|
||||
self.tmp_dir = Some(temp_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match GitCommit::new() {
|
||||
Ok(commit) => self.variables.push(CuddleVariable::new(
|
||||
"commit_sha".into(),
|
||||
commit.commit_sha.clone(),
|
||||
)),
|
||||
Err(e) => {
|
||||
log::debug!("{}", e);
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn process_scripts(mut self) -> Self {
|
||||
if let Ok(context_iter) = self.context.clone().lock() {
|
||||
for ctx in context_iter.iter() {
|
||||
if let Some(scripts) = ctx.plan.scripts.clone() {
|
||||
for (name, script) in scripts {
|
||||
self.scripts
|
||||
.push(CuddleAction::new(script.clone(), ctx.path.clone(), name))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn process_templates(self) -> anyhow::Result<Self> {
|
||||
if let None = self.tmp_dir {
|
||||
log::debug!("cannot process template as bare bones cli");
|
||||
return Ok(self);
|
||||
}
|
||||
|
||||
// Make sure tmp_dir exists and clean it up first
|
||||
let tmp_dir = self
|
||||
.tmp_dir
|
||||
.clone()
|
||||
.ok_or(anyhow::anyhow!("tmp_dir does not exist aborting"))?;
|
||||
if tmp_dir.exists() && tmp_dir.ends_with("tmp") {
|
||||
std::fs::remove_dir_all(tmp_dir.clone())?;
|
||||
}
|
||||
std::fs::create_dir_all(tmp_dir.clone())?;
|
||||
// Handle all templating with variables and such.
|
||||
// TODO: use actual templating engine, for new we just copy templates to the final folder
|
||||
|
||||
if let Ok(context_iter) = self.context.clone().lock() {
|
||||
for ctx in context_iter.iter() {
|
||||
let mut template_path = ctx.path.clone();
|
||||
template_path.push("templates");
|
||||
|
||||
log::trace!("template path: {}", template_path.clone().to_string_lossy());
|
||||
|
||||
if !template_path.exists() {
|
||||
continue;
|
||||
}
|
||||
|
||||
for file in std::fs::read_dir(template_path)?.into_iter() {
|
||||
let f = file?;
|
||||
let mut dest_file = tmp_dir.clone();
|
||||
dest_file.push(f.file_name());
|
||||
|
||||
std::fs::copy(f.path(), dest_file)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn build_cli(mut self) -> Self {
|
||||
let mut root_cmd = Command::new("cuddle")
|
||||
.version("1.0")
|
||||
.author("kjuulh <contact@kasperhermansen.com>")
|
||||
.about("cuddle is your domain specific organization tool. It enabled widespread sharing through repositories, as well as collaborating while maintaining speed and integrity")
|
||||
.subcommand_required(true)
|
||||
.propagate_version(true);
|
||||
|
||||
if self.scripts.len() > 0 {
|
||||
let mut execute_cmd = Command::new("x").about("x is your entry into your domains scripts, scripts inherited from parents will also be present here").subcommand_required(true);
|
||||
|
||||
for script in self.scripts.iter() {
|
||||
let action_cmd = Command::new(script.name.clone());
|
||||
|
||||
// TODO: Some way to add an about for clap, requires conversion from String -> &str
|
||||
|
||||
execute_cmd = execute_cmd.subcommand(action_cmd);
|
||||
}
|
||||
|
||||
root_cmd = root_cmd.subcommand(execute_cmd);
|
||||
}
|
||||
|
||||
self.command = Some(root_cmd);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn execute(self) -> anyhow::Result<Self> {
|
||||
if let Some(mut cli) = self.command.clone() {
|
||||
let matches = cli.clone().get_matches();
|
||||
|
||||
let res = match matches.subcommand() {
|
||||
Some(("x", exe_submatch)) => {
|
||||
log::trace!("executing x");
|
||||
|
||||
match exe_submatch.subcommand() {
|
||||
Some((name, _action_matches)) => {
|
||||
log::trace!(action=name; "running action; name={}", name);
|
||||
match self.scripts.iter().find(|ele| ele.name == name) {
|
||||
Some(script) => {
|
||||
script.clone().execute(self.variables.clone())?;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(anyhow!("could not find a match")),
|
||||
}
|
||||
}
|
||||
_ => Err(anyhow!("could not find a match")),
|
||||
}
|
||||
}
|
||||
_ => Err(anyhow!("could not find a match")),
|
||||
};
|
||||
|
||||
match res {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
let _ = cli.print_long_help();
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
}
|
182
cuddle_cli/src/cli/mod.rs
Normal file
182
cuddle_cli/src/cli/mod.rs
Normal file
@ -0,0 +1,182 @@
|
||||
mod subcommands;
|
||||
|
||||
use std::{
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use clap::Command;
|
||||
|
||||
use crate::{
|
||||
actions::CuddleAction,
|
||||
context::{CuddleContext, CuddleTreeType},
|
||||
model::*,
|
||||
util::git::GitCommit,
|
||||
};
|
||||
|
||||
use self::subcommands::render_template::RenderTemplateCommand;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CuddleCli<'a> {
|
||||
scripts: Vec<CuddleAction>,
|
||||
variables: Vec<CuddleVariable>,
|
||||
context: Arc<Mutex<Vec<CuddleContext>>>,
|
||||
command: Option<Command<'a>>,
|
||||
tmp_dir: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl<'a> CuddleCli<'a> {
|
||||
pub fn new(context: Arc<Mutex<Vec<CuddleContext>>>) -> anyhow::Result<CuddleCli<'a>> {
|
||||
let mut cli = CuddleCli {
|
||||
scripts: vec![],
|
||||
variables: vec![],
|
||||
context: context.clone(),
|
||||
command: None,
|
||||
tmp_dir: None,
|
||||
};
|
||||
|
||||
cli = cli
|
||||
.process_variables()
|
||||
.process_scripts()
|
||||
.process_templates()?
|
||||
.build_cli();
|
||||
|
||||
Ok(cli)
|
||||
}
|
||||
|
||||
fn process_variables(mut self) -> Self {
|
||||
if let Ok(context_iter) = self.context.clone().lock() {
|
||||
for ctx in context_iter.iter() {
|
||||
if let Some(variables) = ctx.plan.vars.clone() {
|
||||
for (name, var) in variables {
|
||||
self.variables.push(CuddleVariable::new(name, var))
|
||||
}
|
||||
}
|
||||
|
||||
if let CuddleTreeType::Root = ctx.node_type {
|
||||
let mut temp_path = ctx.path.clone();
|
||||
temp_path.push(".cuddle/tmp");
|
||||
|
||||
self.variables.push(CuddleVariable::new(
|
||||
"tmp".into(),
|
||||
temp_path.clone().to_string_lossy().to_string(),
|
||||
));
|
||||
|
||||
self.tmp_dir = Some(temp_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match GitCommit::new() {
|
||||
Ok(commit) => self.variables.push(CuddleVariable::new(
|
||||
"commit_sha".into(),
|
||||
commit.commit_sha.clone(),
|
||||
)),
|
||||
Err(e) => {
|
||||
log::debug!("{}", e);
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn process_scripts(mut self) -> Self {
|
||||
if let Ok(context_iter) = self.context.clone().lock() {
|
||||
for ctx in context_iter.iter() {
|
||||
if let Some(scripts) = ctx.plan.scripts.clone() {
|
||||
for (name, script) in scripts {
|
||||
self.scripts
|
||||
.push(CuddleAction::new(script.clone(), ctx.path.clone(), name))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn process_templates(self) -> anyhow::Result<Self> {
|
||||
if let None = self.tmp_dir {
|
||||
log::debug!("cannot process template as bare bones cli");
|
||||
return Ok(self);
|
||||
}
|
||||
|
||||
// Make sure tmp_dir exists and clean it up first
|
||||
let tmp_dir = self
|
||||
.tmp_dir
|
||||
.clone()
|
||||
.ok_or(anyhow::anyhow!("tmp_dir does not exist aborting"))?;
|
||||
if tmp_dir.exists() && tmp_dir.ends_with("tmp") {
|
||||
std::fs::remove_dir_all(tmp_dir.clone())?;
|
||||
}
|
||||
std::fs::create_dir_all(tmp_dir.clone())?;
|
||||
// Handle all templating with variables and such.
|
||||
// TODO: use actual templating engine, for new we just copy templates to the final folder
|
||||
|
||||
if let Ok(context_iter) = self.context.clone().lock() {
|
||||
for ctx in context_iter.iter() {
|
||||
let mut template_path = ctx.path.clone();
|
||||
template_path.push("templates");
|
||||
|
||||
log::trace!("template path: {}", template_path.clone().to_string_lossy());
|
||||
|
||||
if !template_path.exists() {
|
||||
continue;
|
||||
}
|
||||
|
||||
for file in std::fs::read_dir(template_path)?.into_iter() {
|
||||
let f = file?;
|
||||
let mut dest_file = tmp_dir.clone();
|
||||
dest_file.push(f.file_name());
|
||||
|
||||
std::fs::copy(f.path(), dest_file)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn build_cli(mut self) -> Self {
|
||||
let mut root_cmd = Command::new("cuddle")
|
||||
.version("1.0")
|
||||
.author("kjuulh <contact@kasperhermansen.com>")
|
||||
.about("cuddle is your domain specific organization tool. It enabled widespread sharing through repositories, as well as collaborating while maintaining speed and integrity")
|
||||
.subcommand_required(true)
|
||||
.arg_required_else_help(true)
|
||||
.propagate_version(true);
|
||||
|
||||
root_cmd = subcommands::x::build_command(root_cmd, self.clone());
|
||||
root_cmd = subcommands::render_template::build_command(root_cmd);
|
||||
|
||||
self.command = Some(root_cmd);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn execute(self) -> anyhow::Result<Self> {
|
||||
if let Some(mut cli) = self.command.clone() {
|
||||
let matches = cli.clone().get_matches();
|
||||
|
||||
let res = match matches.subcommand() {
|
||||
Some(("x", exe_submatch)) => subcommands::x::execute_x(exe_submatch, self.clone()),
|
||||
Some(("render_template", sub_matches)) => {
|
||||
RenderTemplateCommand::from_matches(sub_matches, self.clone())
|
||||
.and_then(|cmd| cmd.execute())?;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(anyhow::anyhow!("could not find a match")),
|
||||
};
|
||||
|
||||
match res {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
let _ = cli.print_long_help();
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
}
|
2
cuddle_cli/src/cli/subcommands/mod.rs
Normal file
2
cuddle_cli/src/cli/subcommands/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod render_template;
|
||||
pub mod x;
|
150
cuddle_cli/src/cli/subcommands/render_template.rs
Normal file
150
cuddle_cli/src/cli/subcommands/render_template.rs
Normal file
@ -0,0 +1,150 @@
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
use clap::{Arg, ArgMatches, Command};
|
||||
|
||||
use crate::{cli::CuddleCli, model::CuddleVariable};
|
||||
|
||||
pub fn build_command<'a>(root_cmd: Command<'a>) -> Command<'a> {
|
||||
root_cmd.subcommand(
|
||||
Command::new("render_template")
|
||||
.about("renders a jinja compatible template")
|
||||
.args(&[
|
||||
Arg::new("template-file")
|
||||
.alias("template")
|
||||
.short('t')
|
||||
.long("template-file")
|
||||
.required(true)
|
||||
.action(clap::ArgAction::Set).long_help("template-file is the input file path of the .tmpl file (or inferred) that you would like to render"),
|
||||
Arg::new("destination")
|
||||
.alias("dest")
|
||||
.short('d')
|
||||
.long("destination")
|
||||
.required(true)
|
||||
.action(clap::ArgAction::Set)
|
||||
.long_help("destination is the output path of the template once done, but default .tmpl is stripped and the normal file extension is used. this can be overwritten if a file path is entered instead. I.e. (/some/file/name.txt)"),
|
||||
Arg::new("extra-var")
|
||||
.long("extra-var")
|
||||
.required(false)
|
||||
.action(clap::ArgAction::Set),
|
||||
]))
|
||||
}
|
||||
|
||||
pub struct RenderTemplateCommand {
|
||||
variables: Vec<CuddleVariable>,
|
||||
template_file: PathBuf,
|
||||
destination: PathBuf,
|
||||
}
|
||||
|
||||
impl RenderTemplateCommand {
|
||||
pub fn from_matches(matches: &ArgMatches, cli: CuddleCli) -> anyhow::Result<Self> {
|
||||
let template_file = matches
|
||||
.get_one::<String>("template-file")
|
||||
.ok_or(anyhow::anyhow!("template-file was not found"))
|
||||
.and_then(get_path_buf_and_check_exists)?;
|
||||
|
||||
let destination = matches
|
||||
.get_one::<String>("destination")
|
||||
.ok_or(anyhow::anyhow!("destination was not found"))
|
||||
.and_then(get_path_buf_and_check_dir_exists)
|
||||
.and_then(RenderTemplateCommand::transform_extension)?;
|
||||
|
||||
let mut extra_vars: Vec<CuddleVariable> =
|
||||
if let Some(extra_vars) = matches.get_many::<String>("extra-var") {
|
||||
let mut vars = Vec::with_capacity(extra_vars.len());
|
||||
for var in extra_vars.into_iter() {
|
||||
let parts: Vec<&str> = var.split("=").collect();
|
||||
if parts.len() != 2 {
|
||||
return Err(anyhow::anyhow!("extra-var: is not set correctly: {}", var));
|
||||
}
|
||||
|
||||
vars.push(CuddleVariable::new(parts[0].into(), parts[1].into()));
|
||||
}
|
||||
vars
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
extra_vars.append(&mut cli.variables.clone());
|
||||
|
||||
Ok(Self {
|
||||
variables: extra_vars,
|
||||
template_file,
|
||||
destination,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn execute(self) -> anyhow::Result<()> {
|
||||
// Prepare context
|
||||
let mut context = tera::Context::new();
|
||||
for var in self.variables {
|
||||
context.insert(
|
||||
var.name.to_lowercase().replace(" ", "_").replace("-", "_"),
|
||||
&var.value,
|
||||
)
|
||||
}
|
||||
|
||||
// Load source template
|
||||
let source = std::fs::read_to_string(self.template_file)?;
|
||||
|
||||
let output = tera::Tera::one_off(source.as_str(), &context, false)?;
|
||||
|
||||
// Put template in final destination
|
||||
std::fs::write(&self.destination, output)?;
|
||||
|
||||
log::info!(
|
||||
"finished writing template to: {}",
|
||||
&self.destination.to_string_lossy()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn transform_extension(template_path: PathBuf) -> anyhow::Result<PathBuf> {
|
||||
if template_path.is_file() {
|
||||
let ext = template_path.extension().ok_or(anyhow::anyhow!(
|
||||
"destination path does not have an extension"
|
||||
))?;
|
||||
if ext.to_string_lossy().ends_with("tmpl") {
|
||||
let template_dest = template_path
|
||||
.to_str()
|
||||
.and_then(|s| s.strip_suffix(".tmpl"))
|
||||
.ok_or(anyhow::anyhow!("string does not end in .tmpl"))?;
|
||||
|
||||
return PathBuf::from_str(template_dest).map_err(|e| anyhow::anyhow!(e));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(template_path)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_path_buf_and_check_exists(raw_path: &String) -> anyhow::Result<PathBuf> {
|
||||
match PathBuf::from_str(&raw_path) {
|
||||
Ok(pb) => {
|
||||
if pb.exists() {
|
||||
Ok(pb)
|
||||
} else {
|
||||
Err(anyhow::anyhow!(
|
||||
"path: {}, could not be found",
|
||||
pb.to_string_lossy()
|
||||
))
|
||||
}
|
||||
}
|
||||
Err(e) => Err(anyhow::anyhow!(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_path_buf_and_check_dir_exists(raw_path: &String) -> anyhow::Result<PathBuf> {
|
||||
match PathBuf::from_str(&raw_path) {
|
||||
Ok(pb) => {
|
||||
if pb.is_dir() && pb.exists() {
|
||||
Ok(pb)
|
||||
} else if pb.is_file() {
|
||||
Ok(pb)
|
||||
} else {
|
||||
Ok(pb)
|
||||
}
|
||||
}
|
||||
Err(e) => Err(anyhow::anyhow!(e)),
|
||||
}
|
||||
}
|
37
cuddle_cli/src/cli/subcommands/x.rs
Normal file
37
cuddle_cli/src/cli/subcommands/x.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use clap::{ArgMatches, Command};
|
||||
|
||||
use crate::cli::CuddleCli;
|
||||
|
||||
pub fn build_command<'a>(root_cmd: Command<'a>, cli: CuddleCli<'a>) -> Command<'a> {
|
||||
if cli.scripts.len() > 0 {
|
||||
let mut execute_cmd = Command::new("x").about("x is your entry into your domains scripts, scripts inherited from parents will also be present here").subcommand_required(true);
|
||||
|
||||
for script in cli.scripts.iter() {
|
||||
let action_cmd = Command::new(script.name.clone());
|
||||
|
||||
// TODO: Some way to add an about for clap, requires conversion from String -> &str
|
||||
|
||||
execute_cmd = execute_cmd.subcommand(action_cmd);
|
||||
}
|
||||
|
||||
root_cmd.subcommand(execute_cmd)
|
||||
} else {
|
||||
root_cmd
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_x(exe_submatch: &ArgMatches, cli: CuddleCli) -> anyhow::Result<()> {
|
||||
match exe_submatch.subcommand() {
|
||||
Some((name, _action_matches)) => {
|
||||
log::trace!(action=name; "running action; name={}", name);
|
||||
match cli.scripts.iter().find(|ele| ele.name == name) {
|
||||
Some(script) => {
|
||||
script.clone().execute(cli.variables.clone())?;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(anyhow::anyhow!("could not find a match")),
|
||||
}
|
||||
}
|
||||
_ => Err(anyhow::anyhow!("could not find a match")),
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ use envconfig::Envconfig;
|
||||
pub enum CuddleFetchPolicy {
|
||||
Always,
|
||||
Once,
|
||||
Never,
|
||||
}
|
||||
|
||||
#[derive(Envconfig, Clone)]
|
||||
@ -20,6 +21,7 @@ impl CuddleConfig {
|
||||
match self.fetch_policy.clone().to_lowercase().as_str() {
|
||||
"always" => Ok(CuddleFetchPolicy::Always),
|
||||
"once" => Ok(CuddleFetchPolicy::Once),
|
||||
"never" => Ok(CuddleFetchPolicy::Never),
|
||||
_ => Err(anyhow::anyhow!("could not parse fetch policy")),
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,3 @@
|
||||
use std::{
|
||||
env::current_dir,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use config::CuddleConfig;
|
||||
use tracing::Level;
|
||||
|
||||
@ -11,23 +6,15 @@ mod cli;
|
||||
mod config;
|
||||
mod context;
|
||||
mod model;
|
||||
mod util;
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
init_logging()?;
|
||||
|
||||
let config = CuddleConfig::from_env()?;
|
||||
|
||||
match git2::Repository::open(current_dir()?) {
|
||||
Ok(_) => {
|
||||
let context = context::extract_cuddle(config.clone())?;
|
||||
_ = cli::CuddleCli::new(context)?.execute()?;
|
||||
}
|
||||
Err(_) => {
|
||||
// Only build bare bones cli
|
||||
log::info!("was not opened in a repo with git, only showing bare-bones options");
|
||||
_ = cli::CuddleCli::new(Arc::new(Mutex::new(vec![])))?.execute()?;
|
||||
}
|
||||
}
|
||||
let context = context::extract_cuddle(config.clone())?;
|
||||
_ = cli::CuddleCli::new(context)?.execute()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -35,7 +22,7 @@ fn main() -> anyhow::Result<()> {
|
||||
fn init_logging() -> anyhow::Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.pretty()
|
||||
.with_max_level(Level::DEBUG)
|
||||
.with_max_level(Level::INFO)
|
||||
.init();
|
||||
|
||||
Ok(())
|
||||
|
@ -46,3 +46,16 @@ pub struct CuddlePlan {
|
||||
pub vars: Option<HashMap<String, String>>,
|
||||
pub scripts: Option<HashMap<String, CuddleScript>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct CuddleVariable {
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl CuddleVariable {
|
||||
pub fn new(name: String, value: String) -> Self {
|
||||
Self { name, value }
|
||||
}
|
||||
}
|
||||
|
33
cuddle_cli/src/util/git.rs
Normal file
33
cuddle_cli/src/util/git.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use std::env::current_dir;
|
||||
|
||||
use git2::Repository;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GitCommit {
|
||||
pub commit_sha: String,
|
||||
}
|
||||
|
||||
impl GitCommit {
|
||||
pub fn new() -> anyhow::Result<GitCommit> {
|
||||
let repo = Repository::open(current_dir().expect("having current_dir available")).map_err(
|
||||
|e| {
|
||||
log::debug!("{}", e);
|
||||
anyhow::anyhow!("could not open repository")
|
||||
},
|
||||
)?;
|
||||
let head_ref = repo
|
||||
.head()
|
||||
.map_err(|e| {
|
||||
log::warn!("{}", e);
|
||||
anyhow::anyhow!("could not get HEAD")
|
||||
})?
|
||||
.target()
|
||||
.ok_or(anyhow::anyhow!(
|
||||
"could not extract head -> target to commit_sha"
|
||||
))?;
|
||||
|
||||
Ok(Self {
|
||||
commit_sha: head_ref.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
1
cuddle_cli/src/util/mod.rs
Normal file
1
cuddle_cli/src/util/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod git;
|
14
examples/templates/cuddle.yaml
Normal file
14
examples/templates/cuddle.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
# yaml-language-server: $schema=../../schemas/base.json
|
||||
|
||||
base: false
|
||||
|
||||
vars:
|
||||
service: "some-service"
|
||||
|
||||
scripts:
|
||||
test_render_template:
|
||||
type: shell
|
||||
args:
|
||||
extravar:
|
||||
type: env
|
||||
key: "HOME"
|
6
examples/templates/scripts/test_render_template.sh
Executable file
6
examples/templates/scripts/test_render_template.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
CUDDLE_FETCH_POLICY=never cuddle_cli render_template \
|
||||
--template-file "$TMP/input.txt.tmpl" \
|
||||
--destination "$TMP/input.txt" \
|
||||
--extra-var "extravar=someextravar"
|
3
examples/templates/templates/input.txt.tmpl
Normal file
3
examples/templates/templates/input.txt.tmpl
Normal file
@ -0,0 +1,3 @@
|
||||
some {{ service }} name
|
||||
|
||||
- {{ extravar }}
|
Loading…
Reference in New Issue
Block a user