Compare commits
2 Commits
experiment
...
main
Author | SHA1 | Date | |
---|---|---|---|
5027930d36 | |||
c4c1288fe9 |
4
.drone.yml
Normal file
4
.drone.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
kind: template
|
||||||
|
load: bust_gobin_default_template.yaml
|
||||||
|
name: char
|
||||||
|
data: {}
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
target/
|
dist/
|
||||||
.vscode/
|
|
||||||
|
729
Cargo.lock
generated
729
Cargo.lock
generated
@ -1,729 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "addr2line"
|
|
||||||
version = "0.19.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
|
|
||||||
dependencies = [
|
|
||||||
"gimli",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "adler"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace"
|
|
||||||
version = "0.3.67"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
|
|
||||||
dependencies = [
|
|
||||||
"addr2line",
|
|
||||||
"cc",
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"miniz_oxide",
|
|
||||||
"object",
|
|
||||||
"rustc-demangle",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitflags"
|
|
||||||
version = "1.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bytes"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.0.79"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "char_cli"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"clap",
|
|
||||||
"color-eyre",
|
|
||||||
"eyre",
|
|
||||||
"tokio",
|
|
||||||
"tracing",
|
|
||||||
"tracing-subscriber",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "char_plan"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"char_sdk",
|
|
||||||
"char_sdk_derive",
|
|
||||||
"eyre",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "char_sdk"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"clap",
|
|
||||||
"eyre",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "char_sdk_derive"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap"
|
|
||||||
version = "4.1.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"clap_lex",
|
|
||||||
"is-terminal",
|
|
||||||
"strsim",
|
|
||||||
"termcolor",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap_lex"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
|
|
||||||
dependencies = [
|
|
||||||
"os_str_bytes",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "color-eyre"
|
|
||||||
version = "0.6.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
|
|
||||||
dependencies = [
|
|
||||||
"backtrace",
|
|
||||||
"color-spantrace",
|
|
||||||
"eyre",
|
|
||||||
"indenter",
|
|
||||||
"once_cell",
|
|
||||||
"owo-colors",
|
|
||||||
"tracing-error",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "color-spantrace"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
"owo-colors",
|
|
||||||
"tracing-core",
|
|
||||||
"tracing-error",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "errno"
|
|
||||||
version = "0.2.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
|
||||||
dependencies = [
|
|
||||||
"errno-dragonfly",
|
|
||||||
"libc",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "errno-dragonfly"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "eyre"
|
|
||||||
version = "0.6.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
|
|
||||||
dependencies = [
|
|
||||||
"indenter",
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gimli"
|
|
||||||
version = "0.27.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hermit-abi"
|
|
||||||
version = "0.2.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hermit-abi"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "indenter"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "io-lifetimes"
|
|
||||||
version = "1.0.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"windows-sys 0.45.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "is-terminal"
|
|
||||||
version = "0.4.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi 0.3.1",
|
|
||||||
"io-lifetimes",
|
|
||||||
"rustix",
|
|
||||||
"windows-sys 0.45.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazy_static"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.139"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linux-raw-sys"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lock_api"
|
|
||||||
version = "0.4.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.4.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "miniz_oxide"
|
|
||||||
version = "0.6.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
|
||||||
dependencies = [
|
|
||||||
"adler",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mio"
|
|
||||||
version = "0.8.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"log",
|
|
||||||
"wasi",
|
|
||||||
"windows-sys 0.45.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nu-ansi-term"
|
|
||||||
version = "0.46.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
|
||||||
dependencies = [
|
|
||||||
"overload",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num_cpus"
|
|
||||||
version = "1.15.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi 0.2.6",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "object"
|
|
||||||
version = "0.30.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell"
|
|
||||||
version = "1.17.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "os_str_bytes"
|
|
||||||
version = "6.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "overload"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "owo-colors"
|
|
||||||
version = "3.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
|
||||||
dependencies = [
|
|
||||||
"lock_api",
|
|
||||||
"parking_lot_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot_core"
|
|
||||||
version = "0.9.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"redox_syscall",
|
|
||||||
"smallvec",
|
|
||||||
"windows-sys 0.45.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project-lite"
|
|
||||||
version = "0.2.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.51"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.2.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc-demangle"
|
|
||||||
version = "0.1.21"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustix"
|
|
||||||
version = "0.36.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"errno",
|
|
||||||
"io-lifetimes",
|
|
||||||
"libc",
|
|
||||||
"linux-raw-sys",
|
|
||||||
"windows-sys 0.45.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sharded-slab"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook-registry"
|
|
||||||
version = "1.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smallvec"
|
|
||||||
version = "1.10.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "socket2"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strsim"
|
|
||||||
version = "0.10.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.107"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "termcolor"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thread_local"
|
|
||||||
version = "1.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio"
|
|
||||||
version = "1.25.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"bytes",
|
|
||||||
"libc",
|
|
||||||
"memchr",
|
|
||||||
"mio",
|
|
||||||
"num_cpus",
|
|
||||||
"parking_lot",
|
|
||||||
"pin-project-lite",
|
|
||||||
"signal-hook-registry",
|
|
||||||
"socket2",
|
|
||||||
"tokio-macros",
|
|
||||||
"windows-sys 0.42.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio-macros"
|
|
||||||
version = "1.8.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing"
|
|
||||||
version = "0.1.37"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"log",
|
|
||||||
"pin-project-lite",
|
|
||||||
"tracing-attributes",
|
|
||||||
"tracing-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-attributes"
|
|
||||||
version = "0.1.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-core"
|
|
||||||
version = "0.1.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
"valuable",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-error"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
|
|
||||||
dependencies = [
|
|
||||||
"tracing",
|
|
||||||
"tracing-subscriber",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-log"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
"log",
|
|
||||||
"tracing-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-subscriber"
|
|
||||||
version = "0.3.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
|
|
||||||
dependencies = [
|
|
||||||
"nu-ansi-term",
|
|
||||||
"sharded-slab",
|
|
||||||
"smallvec",
|
|
||||||
"thread_local",
|
|
||||||
"tracing-core",
|
|
||||||
"tracing-log",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "valuable"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu",
|
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-util"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm",
|
|
||||||
"windows_aarch64_msvc",
|
|
||||||
"windows_i686_gnu",
|
|
||||||
"windows_i686_msvc",
|
|
||||||
"windows_x86_64_gnu",
|
|
||||||
"windows_x86_64_gnullvm",
|
|
||||||
"windows_x86_64_msvc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.45.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.42.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm",
|
|
||||||
"windows_aarch64_msvc",
|
|
||||||
"windows_i686_gnu",
|
|
||||||
"windows_i686_msvc",
|
|
||||||
"windows_x86_64_gnu",
|
|
||||||
"windows_x86_64_gnullvm",
|
|
||||||
"windows_x86_64_msvc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.42.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.42.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.42.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.42.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.42.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.42.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.42.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
|
13
Cargo.toml
13
Cargo.toml
@ -1,13 +0,0 @@
|
|||||||
[workspace]
|
|
||||||
members = [
|
|
||||||
"examples/service/char_plan",
|
|
||||||
"crates/char_cli",
|
|
||||||
"crates/char_sdk",
|
|
||||||
"crates/char_sdk_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[workspace.dependencies]
|
|
||||||
eyre = "0.6.8"
|
|
||||||
color-eyre = "0.6.2"
|
|
||||||
tokio = { version = "1.25.0", features = ["full"] }
|
|
||||||
tracing = { version = "0.1.37", features = ["log"] }
|
|
26
README.md
Normal file
26
README.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Char
|
||||||
|
|
||||||
|
Char is an organizations best friend, it helps with code sharing when either
|
||||||
|
using a multi-repo strategy or mono repo. The goal of the project is to
|
||||||
|
facilitate sharing of presets and plugins to reduce the required complexity
|
||||||
|
developers have to take on.
|
||||||
|
|
||||||
|
This project is best suited with a standard library of plugins (which serves the
|
||||||
|
function of libraries), as well `kjuulh/bust` which is a platform agnostic
|
||||||
|
CI/task setup
|
||||||
|
|
||||||
|
This is in very early stages, and for now it officially supports scaffolding.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
The `examples` folder shows how to load plugins, though presets are still
|
||||||
|
pending.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# file: .char.yml
|
||||||
|
registry: git.front.kjuulh.io
|
||||||
|
plugins:
|
||||||
|
"kjuulh/char#/plugins/gocli":
|
||||||
|
vars:
|
||||||
|
name: "char"
|
||||||
|
```
|
67
cmd/char/do.go
Normal file
67
cmd/char/do.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package char
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/charcontext"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequiredArg struct {
|
||||||
|
Required bool
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDoCommand(charctx *charcontext.CharContext) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "do",
|
||||||
|
}
|
||||||
|
about, err := charctx.About(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range about {
|
||||||
|
for _, c := range a.Commands {
|
||||||
|
requiredArgs := make(map[string]*RequiredArg, len(c.Args))
|
||||||
|
for _, arg := range c.Args {
|
||||||
|
requiredArgs[arg] = &RequiredArg{
|
||||||
|
Required: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, required := range c.Required {
|
||||||
|
if _, ok := requiredArgs[required]; ok {
|
||||||
|
requiredArg := requiredArgs[required]
|
||||||
|
requiredArg.Required = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doCmd := &cobra.Command{
|
||||||
|
Use: c.Name,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if err := cmd.ParseFlags(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := charctx.Do(cmd.Context(), a.ClientName, c.Name, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for argName, argValue := range requiredArgs {
|
||||||
|
doCmd.PersistentFlags().StringVar(&argValue.Value, argName, "", "")
|
||||||
|
if argValue.Required {
|
||||||
|
doCmd.MarkPersistentFlagRequired(argName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(doCmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
13
cmd/char/limitedroot.go
Normal file
13
cmd/char/limitedroot.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package char
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewLimitedCharCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "char",
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
64
cmd/char/ls.go
Normal file
64
cmd/char/ls.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package char
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/charcontext"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewLsCommand(charctx *charcontext.CharContext) *cobra.Command {
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "ls",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
ctx := cmd.Context()
|
||||||
|
|
||||||
|
about, err := charctx.About(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range about {
|
||||||
|
fmt.Printf("plugin: %s\n", a.Name)
|
||||||
|
fmt.Printf("\tversion: %s\n", a.Version)
|
||||||
|
fmt.Printf("\tabout: %s\n", a.About)
|
||||||
|
if len(a.Vars) > 0 {
|
||||||
|
fmt.Println("\tVars:")
|
||||||
|
for _, av := range a.Vars {
|
||||||
|
fmt.Printf("\t\t%s\n", av)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(a.Commands) > 0 {
|
||||||
|
fmt.Println("\tCommands:")
|
||||||
|
for _, ac := range a.Commands {
|
||||||
|
fmt.Printf("\t\t%s\n", ac.Name)
|
||||||
|
if len(ac.Args) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Println("\t\tArgs")
|
||||||
|
for _, aca := range ac.Args {
|
||||||
|
isrequired := false
|
||||||
|
for _, acr := range ac.Required {
|
||||||
|
if acr == aca {
|
||||||
|
isrequired = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isrequired {
|
||||||
|
fmt.Printf("\t\t\t%s: required\n", aca)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("\t\t\t%s\n", aca)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
19
cmd/char/root.go
Normal file
19
cmd/char/root.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package char
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/charcontext"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCharCmd(charctx *charcontext.CharContext) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "char",
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(
|
||||||
|
NewLsCommand(charctx),
|
||||||
|
NewDoCommand(charctx),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "char_cli"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
|
|
||||||
eyre = { workspace = true }
|
|
||||||
tracing = { workspace = true }
|
|
||||||
color-eyre = { workspace = true }
|
|
||||||
tokio = { workspace = true }
|
|
||||||
tracing-subscriber = "0.3.16"
|
|
||||||
clap = "4.1.6"
|
|
@ -1,4 +0,0 @@
|
|||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "char_sdk"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
eyre = { workspace = true }
|
|
||||||
clap = "4.1.6"
|
|
@ -1,53 +0,0 @@
|
|||||||
pub mod std;
|
|
||||||
|
|
||||||
pub enum ActionArg<'a> {
|
|
||||||
Required { name: &'a str, description: &'a str },
|
|
||||||
Optional { name: &'a str, description: &'a str },
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct InputArg<'a> {
|
|
||||||
name: &'a str,
|
|
||||||
value: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ActionArgs<'a> {
|
|
||||||
pub name: &'a str,
|
|
||||||
pub args: Vec<ActionArg<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Action {
|
|
||||||
fn action<'a>(&self) -> ActionArgs<'a>;
|
|
||||||
fn execute(&self, args: &[&InputArg]) -> eyre::Result<()>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Plugin {}
|
|
||||||
|
|
||||||
pub struct CharBuilder {
|
|
||||||
actions: Vec<Box<dyn Action>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CharBuilder {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
CharBuilder {
|
|
||||||
actions: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_context<C>(mut self, context: C) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_action(mut self, action: impl Into<Box<dyn Action>>) -> Self {
|
|
||||||
self.actions.push(action.into());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_plugin(mut self, plugin: impl Plugin) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute(mut self) -> eyre::Result<()> {
|
|
||||||
//clap::Command::new("").arg(a)
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
pub struct Plugin {}
|
|
||||||
|
|
||||||
impl crate::Plugin for Plugin {}
|
|
||||||
|
|
||||||
impl Default for Plugin {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
pub struct Plugin {}
|
|
||||||
|
|
||||||
impl crate::Plugin for Plugin {}
|
|
||||||
|
|
||||||
impl Default for Plugin {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
pub mod dagger;
|
|
||||||
pub mod k8s;
|
|
@ -1,12 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "char_sdk_derive"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
syn = "1.0.107"
|
|
||||||
quote = "1.0.23"
|
|
||||||
[lib]
|
|
||||||
proc-macro = true
|
|
@ -1,24 +0,0 @@
|
|||||||
extern crate proc_macro;
|
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
|
||||||
use quote::quote;
|
|
||||||
|
|
||||||
#[proc_macro_derive(CharAction)]
|
|
||||||
pub fn derive_char_action_into_box(input: TokenStream) -> TokenStream {
|
|
||||||
let ast = syn::parse(input).unwrap();
|
|
||||||
|
|
||||||
// Build the trait implementation
|
|
||||||
impl_hello_macro(&ast)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|
||||||
let name = &ast.ident;
|
|
||||||
let gen = quote! {
|
|
||||||
impl Into<Box<dyn char_sdk::Action>> for #name {
|
|
||||||
fn into(self) -> Box<dyn char_sdk::Action> {
|
|
||||||
Box::new(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
gen.into()
|
|
||||||
}
|
|
4
examples/basic/.char.yml
Normal file
4
examples/basic/.char.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
registry: git.front.kjuulh.io
|
||||||
|
plugins:
|
||||||
|
"kjuulh/char#plugins/gocli": {}
|
||||||
|
"kjuulh/char#plugins/rust": {}
|
2
examples/basic/.gitignore
vendored
Normal file
2
examples/basic/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.char/plugins/
|
||||||
|
char
|
21
examples/basic/benchmark.sh
Executable file
21
examples/basic/benchmark.sh
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
go build -o char ../../main.go
|
||||||
|
|
||||||
|
function devcharls() {
|
||||||
|
CHAR_DEV_MODE=true ./char ls 2&> /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
function charls() {
|
||||||
|
./char ls 2&> /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "scratch"
|
||||||
|
time devcharls
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "ready"
|
||||||
|
time charls
|
||||||
|
echo ""
|
7
examples/basic/test.sh
Executable file
7
examples/basic/test.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
go build -o char ../../main.go
|
||||||
|
|
||||||
|
CHAR_DEV_MODE=true ./char ls
|
13
examples/basic/testdo.sh
Executable file
13
examples/basic/testdo.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
go build -o char ../../main.go
|
||||||
|
|
||||||
|
echo "base"
|
||||||
|
CHAR_DEV_MODE=true ./char do -h
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "--------"
|
||||||
|
echo "local_up"
|
||||||
|
CHAR_DEV_MODE=false ./char do local_up --fish something
|
@ -1,8 +0,0 @@
|
|||||||
[char]
|
|
||||||
plan = "plans/base/"
|
|
||||||
|
|
||||||
[config.docker]
|
|
||||||
something = "something"
|
|
||||||
|
|
||||||
[config.k8s]
|
|
||||||
something = "else"
|
|
7
examples/service/char_plan/Cargo.lock
generated
7
examples/service/char_plan/Cargo.lock
generated
@ -1,7 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "char"
|
|
||||||
version = "0.1.0"
|
|
@ -1,13 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "char_plan"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
char_sdk = { path = "../../../crates/char_sdk" }
|
|
||||||
char_sdk_derive = { path = "../../../crates/char_sdk_derive" }
|
|
||||||
|
|
||||||
eyre = { workspace = true }
|
|
||||||
tokio = { workspace = true }
|
|
@ -1,43 +0,0 @@
|
|||||||
use char_sdk_derive::CharAction;
|
|
||||||
|
|
||||||
#[derive(CharAction)]
|
|
||||||
struct Run;
|
|
||||||
|
|
||||||
impl char_sdk::Action for Run {
|
|
||||||
fn action<'a>(&self) -> char_sdk::ActionArgs<'a> {
|
|
||||||
char_sdk::ActionArgs {
|
|
||||||
name: "run",
|
|
||||||
args: vec![char_sdk::ActionArg::Required {
|
|
||||||
name: "profile",
|
|
||||||
description: "which release profile to use, takes ['release', 'test']",
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute(&self, args: &[&char_sdk::InputArg]) -> eyre::Result<()> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(CharAction)]
|
|
||||||
struct Build;
|
|
||||||
|
|
||||||
impl char_sdk::Action for Build {
|
|
||||||
fn action<'a>(&self) -> char_sdk::ActionArgs<'a> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute(&self, args: &[&char_sdk::InputArg]) -> eyre::Result<()> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
char_sdk::CharBuilder::new()
|
|
||||||
.add_action(Run {})
|
|
||||||
.add_action(Build {})
|
|
||||||
.add_plugin(char_sdk::std::dagger::Plugin::default())
|
|
||||||
.add_plugin(char_sdk::std::k8s::Plugin::default())
|
|
||||||
.execute()
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
[char]
|
|
||||||
|
|
||||||
[plan]
|
|
||||||
|
|
||||||
name = "base"
|
|
31
go.mod
Normal file
31
go.mod
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
module git.front.kjuulh.io/kjuulh/char
|
||||||
|
|
||||||
|
go 1.19
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0
|
||||||
|
github.com/hashicorp/go-plugin v1.4.9
|
||||||
|
github.com/spf13/cobra v1.7.0
|
||||||
|
github.com/stretchr/testify v1.8.2
|
||||||
|
golang.org/x/sync v0.2.0
|
||||||
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/fatih/color v1.13.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.3.4 // indirect
|
||||||
|
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect
|
||||||
|
github.com/oklog/run v1.0.0 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
|
||||||
|
golang.org/x/text v0.3.0 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 // indirect
|
||||||
|
google.golang.org/grpc v1.27.1 // indirect
|
||||||
|
)
|
133
go.sum
Normal file
133
go.sum
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||||
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||||
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
|
||||||
|
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
|
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU=
|
||||||
|
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||||
|
github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo=
|
||||||
|
github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
|
github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I=
|
||||||
|
github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
|
github.com/hashicorp/go-plugin v1.4.5 h1:oTE/oQR4eghggRg8VY7PAz3dr++VwDNBGCcOfIvHpBo=
|
||||||
|
github.com/hashicorp/go-plugin v1.4.5/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
|
||||||
|
github.com/hashicorp/go-plugin v1.4.6 h1:MDV3UrKQBM3du3G7MApDGvOsMYy3JQJ4exhSoKBAeVA=
|
||||||
|
github.com/hashicorp/go-plugin v1.4.6/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
|
||||||
|
github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU=
|
||||||
|
github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
|
||||||
|
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
|
||||||
|
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
||||||
|
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||||
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||||
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
||||||
|
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
|
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
|
||||||
|
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||||
|
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||||
|
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||||
|
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||||
|
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||||
|
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||||
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||||
|
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
|
||||||
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
|
||||||
|
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||||
|
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
1
go.work.sum
Normal file
1
go.work.sum
Normal file
@ -0,0 +1 @@
|
|||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
29
main.go
Normal file
29
main.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/cmd/char"
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/charcontext"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
charctx, err := charcontext.NewCharContext(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, charcontext.ErrNoContextFound) {
|
||||||
|
log.Print("you are not in a char context, as such you will be presented with limited options")
|
||||||
|
if err := char.NewLimitedCharCmd().Execute(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defer charctx.Close()
|
||||||
|
|
||||||
|
if err := char.NewCharCmd(charctx).Execute(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
70
pkg/charcontext/char_context.go
Normal file
70
pkg/charcontext/char_context.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package charcontext
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/plugins/provider"
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/register"
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CharContext struct {
|
||||||
|
contextPath string
|
||||||
|
pluginRegister *register.PluginRegister
|
||||||
|
schema *schema.CharSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCharContext(ctx context.Context) (*CharContext, error) {
|
||||||
|
localPath, err := FindLocalRoot(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
gpp := provider.NewGitPluginProvider()
|
||||||
|
|
||||||
|
s, err := schema.ParseFile(ctx, ".char.yml")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins, err := s.GetPlugins(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gpp.FetchPlugins(ctx, s.Registry, plugins)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
builder := register.NewPluginRegisterBuilder()
|
||||||
|
|
||||||
|
for name, plugin := range plugins {
|
||||||
|
builder = builder.Add(name.Hash(), plugin.Opts.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := builder.Build(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CharContext{
|
||||||
|
contextPath: localPath,
|
||||||
|
pluginRegister: r,
|
||||||
|
schema: s,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc *CharContext) Close() {
|
||||||
|
if err := cc.pluginRegister.Close(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc *CharContext) About(ctx context.Context) ([]register.AboutItem, error) {
|
||||||
|
return cc.pluginRegister.About(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc *CharContext) Do(ctx context.Context, clientName string, commandName string, args map[string]string) error {
|
||||||
|
return cc.pluginRegister.Do(ctx, clientName, commandName, args)
|
||||||
|
}
|
57
pkg/charcontext/context_root.go
Normal file
57
pkg/charcontext/context_root.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package charcontext
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrNoContextFound = errors.New("could not find project root")
|
||||||
|
|
||||||
|
const CharFileName = ".char.yml"
|
||||||
|
|
||||||
|
func FindLocalRoot(ctx context.Context) (string, error) {
|
||||||
|
curdir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return recursiveFindLocalRoot(ctx, curdir)
|
||||||
|
|
||||||
|
//output, err := exec.Command("git", "rev-parse", "--show-toplevel").CombinedOutput()
|
||||||
|
//if err != nil {
|
||||||
|
// return "", err
|
||||||
|
//}
|
||||||
|
//if len(output) == 0 {
|
||||||
|
// return "", errors.New("could not find absolute path")
|
||||||
|
//}
|
||||||
|
//if _, err := os.Stat(string(output)); errors.Is(err, os.ErrNotExist) {
|
||||||
|
// return "", fmt.Errorf("path does not exist %s", string(output))
|
||||||
|
//}
|
||||||
|
|
||||||
|
//return string(output), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func recursiveFindLocalRoot(ctx context.Context, localpath string) (string, error) {
|
||||||
|
entries, err := os.ReadDir(localpath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
if entry.Name() == CharFileName {
|
||||||
|
return localpath, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if localpath == "/" {
|
||||||
|
return "", ErrNoContextFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return recursiveFindLocalRoot(ctx, path.Dir(localpath))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeToPath(_ context.Context, path string) error {
|
||||||
|
return os.Chdir(path)
|
||||||
|
}
|
107
pkg/plugins/provider/git.go
Normal file
107
pkg/plugins/provider/git.go
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GitPluginProvider struct{}
|
||||||
|
|
||||||
|
func NewGitPluginProvider() *GitPluginProvider {
|
||||||
|
return &GitPluginProvider{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gpp *GitPluginProvider) FetchPlugins(ctx context.Context, registry string, plugins schema.CharSchemaPlugins) error {
|
||||||
|
errgroup, ctx := errgroup.WithContext(ctx)
|
||||||
|
baseDir := ".char/plugins"
|
||||||
|
if os.Getenv("CHAR_DEV_MODE") == "true" {
|
||||||
|
if err := os.RemoveAll(baseDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(baseDir, 0755); err != nil {
|
||||||
|
return fmt.Errorf("path already exists cannot create: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for n, plugin := range plugins {
|
||||||
|
n, plugin := n, plugin
|
||||||
|
errgroup.Go(func() error {
|
||||||
|
dest := fmt.Sprintf(
|
||||||
|
"%s/%s",
|
||||||
|
strings.TrimRight(baseDir, "/"), n.Hash(),
|
||||||
|
)
|
||||||
|
fileinfo, err := os.Stat(dest)
|
||||||
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
log.Printf("fetching git plugin repo: %s", n)
|
||||||
|
return gpp.FetchPlugin(
|
||||||
|
ctx,
|
||||||
|
registry,
|
||||||
|
plugin,
|
||||||
|
dest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if fileinfo.ModTime().Add(time.Hour * 1).Before(time.Now()) {
|
||||||
|
log.Printf("fetching git plugin repo: %s as it is stale", n)
|
||||||
|
return gpp.FetchPlugin(
|
||||||
|
ctx,
|
||||||
|
registry,
|
||||||
|
plugin,
|
||||||
|
dest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := errgroup.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gpp *GitPluginProvider) FetchPlugin(ctx context.Context, registry string, plugin *schema.CharSchemaPlugin, dest string) error {
|
||||||
|
cloneUrl, err := plugin.Opts.GetCloneUrl(
|
||||||
|
ctx,
|
||||||
|
registry,
|
||||||
|
&schema.CloneUrlOpt{
|
||||||
|
Protocol: schema.GitProtocolSsh,
|
||||||
|
SshUser: "git",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(dest); !errors.Is(err, os.ErrNotExist) {
|
||||||
|
if err = os.RemoveAll(dest); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := exec.Command(
|
||||||
|
"git",
|
||||||
|
"clone",
|
||||||
|
"--depth=1",
|
||||||
|
cloneUrl,
|
||||||
|
dest,
|
||||||
|
).CombinedOutput()
|
||||||
|
if len(output) > 0 {
|
||||||
|
log.Print(string(output))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
29
pkg/register/plugin.go
Normal file
29
pkg/register/plugin.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package register
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type AboutCommand struct {
|
||||||
|
Name string `json:"name" yaml:"name"`
|
||||||
|
Args []string `json:"args" yaml:"args"`
|
||||||
|
Required []string `json:"required" yaml:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type About struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
About string `json:"about"`
|
||||||
|
Vars []string `json:"vars"`
|
||||||
|
Commands []*AboutCommand `json:"commands"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DoCommand struct {
|
||||||
|
CommandName string `json:"commandName"`
|
||||||
|
Args map[string]string `json:"args"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Plugin interface {
|
||||||
|
About(ctx context.Context) (*About, error)
|
||||||
|
Do(ctx context.Context, cmd *DoCommand) error
|
||||||
|
}
|
||||||
|
|
||||||
|
const PluginKey = "plugin"
|
20
pkg/register/plugin_api.go
Normal file
20
pkg/register/plugin_api.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package register
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/rpc"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginAPI struct {
|
||||||
|
path string
|
||||||
|
Impl Plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pa *PluginAPI) Server(*plugin.MuxBroker) (any, error) {
|
||||||
|
return &PluginServer{Impl: pa.Impl}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*PluginAPI) Client(b *plugin.MuxBroker, c *rpc.Client) (any, error) {
|
||||||
|
return &PluginClient{client: c}, nil
|
||||||
|
}
|
48
pkg/register/plugin_builder.go
Normal file
48
pkg/register/plugin_builder.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package register
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-hclog"
|
||||||
|
"github.com/hashicorp/go-plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginBuilder struct {
|
||||||
|
serveConfig *plugin.ServeConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPluginBuilder(p Plugin) *PluginBuilder {
|
||||||
|
logger := hclog.New(&hclog.LoggerOptions{
|
||||||
|
Level: hclog.Debug,
|
||||||
|
Output: os.Stderr,
|
||||||
|
JSONFormat: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
var pluginMap = map[string]plugin.Plugin{
|
||||||
|
PluginKey: &PluginAPI{
|
||||||
|
Impl: p,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
serveConfig := &plugin.ServeConfig{
|
||||||
|
HandshakeConfig: plugin.HandshakeConfig{
|
||||||
|
ProtocolVersion: 1,
|
||||||
|
MagicCookieKey: "BASIC_PLUGIN",
|
||||||
|
MagicCookieValue: "char",
|
||||||
|
},
|
||||||
|
Plugins: pluginMap,
|
||||||
|
Logger: logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &PluginBuilder{
|
||||||
|
serveConfig: serveConfig,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PluginBuilder) Serve(ctx context.Context) error {
|
||||||
|
plugin.Serve(
|
||||||
|
pr.serveConfig,
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
39
pkg/register/plugin_client.go
Normal file
39
pkg/register/plugin_client.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package register
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginClient struct {
|
||||||
|
client *rpc.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do implements Plugin
|
||||||
|
func (pc *PluginClient) Do(ctx context.Context, cmd *DoCommand) error {
|
||||||
|
err := pc.client.Call("Plugin.Do", cmd, new(string))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Plugin = &PluginClient{}
|
||||||
|
|
||||||
|
func (pc *PluginClient) About(ctx context.Context) (*About, error) {
|
||||||
|
var resp string
|
||||||
|
err := pc.client.Call("Plugin.About", new(any), &resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var about About
|
||||||
|
err = json.Unmarshal([]byte(resp), &about)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &about, nil
|
||||||
|
}
|
248
pkg/register/plugin_register.go
Normal file
248
pkg/register/plugin_register.go
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
package register
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-hclog"
|
||||||
|
"github.com/hashicorp/go-plugin"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginRegisterBuilder struct {
|
||||||
|
plugins map[string]PluginAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPluginRegisterBuilder() *PluginRegisterBuilder {
|
||||||
|
return &PluginRegisterBuilder{
|
||||||
|
plugins: make(map[string]PluginAPI),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PluginRegisterBuilder) Add(name, path string) *PluginRegisterBuilder {
|
||||||
|
pr.plugins[name] = PluginAPI{
|
||||||
|
path: path,
|
||||||
|
}
|
||||||
|
|
||||||
|
return pr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PluginRegisterBuilder) Build(ctx context.Context) (*PluginRegister, error) {
|
||||||
|
clients := make(map[string]*pluginClientWrapper, 0)
|
||||||
|
errgroup, _ := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
if err := os.MkdirAll(".char/plugins/", 0755); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, p := range pr.plugins {
|
||||||
|
name, p := name, p
|
||||||
|
|
||||||
|
errgroup.Go(func() error {
|
||||||
|
pluginPath := fmt.Sprintf(".char/plugins/%s/dist/plugin", name)
|
||||||
|
|
||||||
|
_, err := os.Stat(pluginPath)
|
||||||
|
if err != nil || os.Getenv("CHAR_DEV_MODE") == "true" {
|
||||||
|
log.Printf("building: %s", name)
|
||||||
|
cmd := exec.Command(
|
||||||
|
"sh",
|
||||||
|
"-c",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"(cd .char/plugins/%s; go build -o dist/plugin %s/main.go)",
|
||||||
|
name,
|
||||||
|
strings.TrimSuffix(
|
||||||
|
strings.TrimSuffix(
|
||||||
|
p.path,
|
||||||
|
"main.go",
|
||||||
|
),
|
||||||
|
"/",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if len(output) > 0 {
|
||||||
|
log.Println(string(output))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not build plugin: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client := plugin.NewClient(&plugin.ClientConfig{
|
||||||
|
HandshakeConfig: plugin.HandshakeConfig{
|
||||||
|
ProtocolVersion: 1,
|
||||||
|
MagicCookieKey: "BASIC_PLUGIN",
|
||||||
|
MagicCookieValue: "char",
|
||||||
|
},
|
||||||
|
Logger: hclog.New(&hclog.LoggerOptions{
|
||||||
|
Name: "char",
|
||||||
|
Output: os.Stdout,
|
||||||
|
Level: hclog.Debug,
|
||||||
|
}),
|
||||||
|
Cmd: exec.Command(
|
||||||
|
fmt.Sprintf(
|
||||||
|
".char/plugins/%s/dist/plugin",
|
||||||
|
name,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Plugins: map[string]plugin.Plugin{
|
||||||
|
PluginKey: &p,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
rpcClient, err := client.Client()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, err := rpcClient.Dispense("plugin")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginApi, ok := raw.(Plugin)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("could not cast as plugin")
|
||||||
|
}
|
||||||
|
|
||||||
|
clients[name] = &pluginClientWrapper{
|
||||||
|
plugin: pluginApi,
|
||||||
|
client: client,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
err := errgroup.Wait()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &PluginRegister{
|
||||||
|
clients: clients,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
type pluginClientWrapper struct {
|
||||||
|
plugin Plugin
|
||||||
|
client *plugin.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pcw *pluginClientWrapper) Close() {
|
||||||
|
pcw.client.Kill()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
type PluginRegister struct {
|
||||||
|
clients map[string]*pluginClientWrapper
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PluginRegister) Close() error {
|
||||||
|
errgroup, _ := errgroup.WithContext(context.Background())
|
||||||
|
|
||||||
|
for _, c := range pr.clients {
|
||||||
|
c := c
|
||||||
|
|
||||||
|
errgroup.Go(func() error {
|
||||||
|
c.Close()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := errgroup.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandAboutItem struct {
|
||||||
|
Name string
|
||||||
|
Args []string
|
||||||
|
Required []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandAboutItems []*CommandAboutItem
|
||||||
|
|
||||||
|
func FromAboutCommands(commands []*AboutCommand) CommandAboutItems {
|
||||||
|
cai := make(CommandAboutItems, 0)
|
||||||
|
for _, command := range commands {
|
||||||
|
cai = append(cai, &CommandAboutItem{
|
||||||
|
Name: command.Name,
|
||||||
|
Args: command.Args,
|
||||||
|
Required: command.Required,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return cai
|
||||||
|
}
|
||||||
|
|
||||||
|
type AboutItem struct {
|
||||||
|
Name string
|
||||||
|
Version string
|
||||||
|
About string
|
||||||
|
Vars []string
|
||||||
|
Commands CommandAboutItems
|
||||||
|
ClientName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PluginRegister) About(ctx context.Context) ([]AboutItem, error) {
|
||||||
|
list := make([]AboutItem, 0)
|
||||||
|
|
||||||
|
errgroup, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
for name, c := range pr.clients {
|
||||||
|
name, c := name, c
|
||||||
|
errgroup.Go(func() error {
|
||||||
|
about, err := c.plugin.About(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list = append(list, AboutItem{
|
||||||
|
Name: about.Name,
|
||||||
|
Version: about.Version,
|
||||||
|
About: about.About,
|
||||||
|
Vars: about.Vars,
|
||||||
|
Commands: FromAboutCommands(about.Commands),
|
||||||
|
ClientName: name,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := errgroup.Wait(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PluginRegister) Do(ctx context.Context, clientName string, commandName string, args map[string]string) error {
|
||||||
|
errgroup, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
client, ok := pr.clients[clientName]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("plugin was not found: %s", clientName)
|
||||||
|
}
|
||||||
|
|
||||||
|
errgroup.Go(func() error {
|
||||||
|
return client.plugin.Do(ctx, &DoCommand{
|
||||||
|
CommandName: commandName,
|
||||||
|
Args: args,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := errgroup.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
44
pkg/register/plugin_server.go
Normal file
44
pkg/register/plugin_server.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package register
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginServer struct {
|
||||||
|
Impl Plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *PluginServer) Do(args *DoCommand, resp *string) error {
|
||||||
|
//rawReq, ok := args.(string)
|
||||||
|
//if !ok {
|
||||||
|
// return errors.New("args is not a string")
|
||||||
|
//}
|
||||||
|
|
||||||
|
//var doReq DoRequest
|
||||||
|
//if err := json.Unmarshal([]byte(rawReq), &doReq); err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
if err := ps.Impl.Do(context.Background(), args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*resp = ""
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *PluginServer) About(args any, resp *string) error {
|
||||||
|
r, err := ps.Impl.About(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
respB, err := json.Marshal(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*resp = string(respB)
|
||||||
|
return nil
|
||||||
|
}
|
50
pkg/schema/schema.go
Normal file
50
pkg/schema/schema.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package schema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CharSchema struct {
|
||||||
|
Registry string `json:"registry" yaml:"registry"`
|
||||||
|
Plugins CharSchemaPlugins `json:"plugins" yaml:"plugins"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseFile(ctx context.Context, path string) (*CharSchema, error) {
|
||||||
|
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
|
||||||
|
return nil, fmt.Errorf("could not parse file, as it is not found or permitted: %s", path)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not read file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Parse(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Parse(content []byte) (*CharSchema, error) {
|
||||||
|
var schema CharSchema
|
||||||
|
if err := yaml.Unmarshal(content, &schema); err != nil {
|
||||||
|
return nil, fmt.Errorf("could not deserialize yaml into CharSchema: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &schema, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *CharSchema) GetPlugins(ctx context.Context) (CharSchemaPlugins, error) {
|
||||||
|
plugins := make(map[CharSchemaPluginName]*CharSchemaPlugin, len(cs.Plugins))
|
||||||
|
for n, plugin := range cs.Plugins {
|
||||||
|
po, err := n.Get()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
plugin.Opts = po
|
||||||
|
plugins[n] = plugin
|
||||||
|
}
|
||||||
|
return plugins, nil
|
||||||
|
}
|
104
pkg/schema/schema_plugin.go
Normal file
104
pkg/schema/schema_plugin.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package schema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CharSchemaPluginName string
|
||||||
|
|
||||||
|
func (cspn CharSchemaPluginName) Hash() string {
|
||||||
|
bytes := sha256.Sum256([]byte(cspn))
|
||||||
|
return hex.EncodeToString(bytes[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginOps struct {
|
||||||
|
Org string
|
||||||
|
RepositoryName string
|
||||||
|
Path string
|
||||||
|
Version string
|
||||||
|
}
|
||||||
|
|
||||||
|
type GitProtocol string
|
||||||
|
|
||||||
|
const (
|
||||||
|
GitProtocolHttps GitProtocol = "https"
|
||||||
|
GitProtocolSsh = "ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CloneUrlOpt struct {
|
||||||
|
Protocol GitProtocol
|
||||||
|
SshUser string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (po *PluginOps) GetCloneUrl(ctx context.Context, registry string, opt *CloneUrlOpt) (string, error) {
|
||||||
|
if opt == nil {
|
||||||
|
return "", errors.New("opt is required")
|
||||||
|
}
|
||||||
|
switch opt.Protocol {
|
||||||
|
case GitProtocolHttps:
|
||||||
|
return fmt.Sprintf("https://%s/%s/%s.git", registry, po.Org, po.RepositoryName), nil
|
||||||
|
case GitProtocolSsh:
|
||||||
|
return fmt.Sprintf("%s@%s:%s/%s.git", opt.SshUser, registry, po.Org, po.RepositoryName), nil
|
||||||
|
default:
|
||||||
|
return "", errors.New("protocol not allowed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var memo = map[string]*PluginOps{}
|
||||||
|
|
||||||
|
func (cspn CharSchemaPluginName) Get() (*PluginOps, error) {
|
||||||
|
if m, ok := memo[string(cspn)]; ok {
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
po := &PluginOps{}
|
||||||
|
reg := regexp.MustCompile(
|
||||||
|
`(?P<org>[\d\w\-_\.]+)\/(?P<repo>[\d\w\-_\.]+)(?P<path>#[\d\w\-_\.\/]+)?(?P<version>@[\d\w\-_\.\/]+)?(?P<path>#[\d\w\-_\.\/]+)?`,
|
||||||
|
)
|
||||||
|
matches := reg.FindStringSubmatch(string(cspn))
|
||||||
|
tags := reg.SubexpNames()
|
||||||
|
|
||||||
|
matchTags := make(map[string]string, len(matches))
|
||||||
|
for i, match := range matches {
|
||||||
|
tag := tags[i]
|
||||||
|
if existingTag, ok := matchTags[tag]; !ok || existingTag == "" {
|
||||||
|
matchTags[tag] = match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if org, ok := matchTags["org"]; ok {
|
||||||
|
po.Org = org
|
||||||
|
}
|
||||||
|
if repo, ok := matchTags["repo"]; ok {
|
||||||
|
po.RepositoryName = repo
|
||||||
|
}
|
||||||
|
if path, ok := matchTags["path"]; ok {
|
||||||
|
po.Path = strings.TrimLeft(path, "#")
|
||||||
|
}
|
||||||
|
if version, ok := matchTags["version"]; ok {
|
||||||
|
po.Version = strings.TrimLeft(version, "@")
|
||||||
|
}
|
||||||
|
|
||||||
|
if po.Org == "" || po.RepositoryName == "" {
|
||||||
|
return nil, errors.New("could not find org or repository name")
|
||||||
|
}
|
||||||
|
|
||||||
|
memo[string(cspn)] = po
|
||||||
|
|
||||||
|
return po, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CharSchemaPlugins map[CharSchemaPluginName]*CharSchemaPlugin
|
||||||
|
type CharSchemaPluginVarName string
|
||||||
|
type CharSchemaPluginVars map[CharSchemaPluginVarName]string
|
||||||
|
|
||||||
|
type CharSchemaPlugin struct {
|
||||||
|
Opts *PluginOps
|
||||||
|
Vars CharSchemaPluginVars `json:"vars"`
|
||||||
|
}
|
126
pkg/schema/schema_plugin_test.go
Normal file
126
pkg/schema/schema_plugin_test.go
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package schema_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSchemaNameCanParse(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tt := []struct {
|
||||||
|
name string
|
||||||
|
inputString schema.CharSchemaPluginName
|
||||||
|
expected schema.PluginOps
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "default string",
|
||||||
|
inputString: `kju123K_-ulh/someRepo-._123`,
|
||||||
|
expected: schema.PluginOps{
|
||||||
|
Org: "kju123K_-ulh",
|
||||||
|
RepositoryName: "someRepo-._123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default string with path",
|
||||||
|
inputString: `kju123K_-ulh/someRepo-._123#somepath/sometoherpath/somethridpath`,
|
||||||
|
expected: schema.PluginOps{
|
||||||
|
Org: "kju123K_-ulh",
|
||||||
|
RepositoryName: "someRepo-._123",
|
||||||
|
Path: "somepath/sometoherpath/somethridpath",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default string with version",
|
||||||
|
inputString: `kju123K_-ulh/someRepo-._123@12l3.jk1lj`,
|
||||||
|
expected: schema.PluginOps{
|
||||||
|
Org: "kju123K_-ulh",
|
||||||
|
RepositoryName: "someRepo-._123",
|
||||||
|
Version: "12l3.jk1lj",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default string with version and path",
|
||||||
|
inputString: `kju123K_-ulh/someRepo-._123@12l3.jk1lj#somepath/sometoherpath/somethridpath`,
|
||||||
|
expected: schema.PluginOps{
|
||||||
|
Org: "kju123K_-ulh",
|
||||||
|
RepositoryName: "someRepo-._123",
|
||||||
|
Version: "12l3.jk1lj",
|
||||||
|
Path: "somepath/sometoherpath/somethridpath",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default string with path and version",
|
||||||
|
inputString: `kju123K_-ulh/someRepo-._123#somepath/sometoherpath/somethridpath@12l3.jk1lj`,
|
||||||
|
expected: schema.PluginOps{
|
||||||
|
Org: "kju123K_-ulh",
|
||||||
|
RepositoryName: "someRepo-._123",
|
||||||
|
Version: "12l3.jk1lj",
|
||||||
|
Path: "somepath/sometoherpath/somethridpath",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tt {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
actual, _ := tc.inputString.Get()
|
||||||
|
require.Equal(t, tc.expected, *actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPluginOpt(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tt := []struct {
|
||||||
|
name string
|
||||||
|
pluginOpt schema.PluginOps
|
||||||
|
cloneUrlOpt schema.CloneUrlOpt
|
||||||
|
registry string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ssh values",
|
||||||
|
pluginOpt: schema.PluginOps{
|
||||||
|
Org: "kjuulh",
|
||||||
|
RepositoryName: "char",
|
||||||
|
Path: "",
|
||||||
|
Version: "",
|
||||||
|
},
|
||||||
|
cloneUrlOpt: schema.CloneUrlOpt{
|
||||||
|
Protocol: schema.GitProtocolSsh,
|
||||||
|
SshUser: "git",
|
||||||
|
},
|
||||||
|
registry: "git.front.kjuulh.io",
|
||||||
|
expected: "git@git.front.kjuulh.io:kjuulh/char.git",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "https values",
|
||||||
|
pluginOpt: schema.PluginOps{
|
||||||
|
Org: "kjuulh",
|
||||||
|
RepositoryName: "char",
|
||||||
|
Path: "",
|
||||||
|
Version: "",
|
||||||
|
},
|
||||||
|
cloneUrlOpt: schema.CloneUrlOpt{
|
||||||
|
Protocol: schema.GitProtocolHttps,
|
||||||
|
},
|
||||||
|
registry: "git.front.kjuulh.io",
|
||||||
|
expected: "https://git.front.kjuulh.io/kjuulh/char.git",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tt {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
url, err := tc.pluginOpt.GetCloneUrl(context.Background(), tc.registry, &tc.cloneUrlOpt)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tc.expected, url)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
93
pkg/schema/schema_test.go
Normal file
93
pkg/schema/schema_test.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package schema_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSchemaParse(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
tt := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expected *schema.CharSchema
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "with plugins",
|
||||||
|
input: `
|
||||||
|
registry: git.front.kjuulh.io
|
||||||
|
plugins:
|
||||||
|
"kjuulh/char#plugins/gocli": {}
|
||||||
|
"kjuulh/char#plugins/rust": {}
|
||||||
|
`,
|
||||||
|
expected: &schema.CharSchema{
|
||||||
|
Registry: "git.front.kjuulh.io",
|
||||||
|
Plugins: map[schema.CharSchemaPluginName]*schema.CharSchemaPlugin{
|
||||||
|
"kjuulh/char#plugins/gocli": {},
|
||||||
|
"kjuulh/char#plugins/rust": {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tt {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
s, err := schema.Parse([]byte(tc.input))
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tc.expected, s)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetPlugins(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
tt := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expected schema.CharSchemaPlugins
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "with plugins",
|
||||||
|
input: `
|
||||||
|
registry: git.front.kjuulh.io
|
||||||
|
plugins:
|
||||||
|
"kjuulh/char#plugins/gocli@v1.9.0": {}
|
||||||
|
"kjuulh/char#plugins/rust": {}
|
||||||
|
`,
|
||||||
|
expected: map[schema.CharSchemaPluginName]*schema.CharSchemaPlugin{
|
||||||
|
"kjuulh/char#plugins/gocli@v1.9.0": {
|
||||||
|
Opts: &schema.PluginOps{
|
||||||
|
Org: "kjuulh",
|
||||||
|
RepositoryName: "char",
|
||||||
|
Path: "plugins/gocli",
|
||||||
|
Version: "v1.9.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"kjuulh/char#plugins/rust": {
|
||||||
|
Opts: &schema.PluginOps{
|
||||||
|
Org: "kjuulh",
|
||||||
|
RepositoryName: "char",
|
||||||
|
Path: "plugins/rust",
|
||||||
|
Version: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tt {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
s, err := schema.Parse([]byte(tc.input))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
plugins, err := s.GetPlugins(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, tc.expected, plugins)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
47
plugins/gocli/main.go
Normal file
47
plugins/gocli/main.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/register"
|
||||||
|
"github.com/hashicorp/go-hclog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GoCliPlugin struct{}
|
||||||
|
|
||||||
|
// Do implements register.Plugin
|
||||||
|
func (*GoCliPlugin) Do(ctx context.Context, cmd *register.DoCommand) error {
|
||||||
|
hclog.L().Info("received command", "commandName", cmd.CommandName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GoCliPlugin) About(ctx context.Context) (*register.About, error) {
|
||||||
|
return ®ister.About{
|
||||||
|
Name: "gocli",
|
||||||
|
Version: "v0.0.1",
|
||||||
|
About: "golang cli provides a set of actions and presets supporting golang development",
|
||||||
|
Vars: []string{
|
||||||
|
"dev.mode",
|
||||||
|
},
|
||||||
|
Commands: []*register.AboutCommand{
|
||||||
|
{
|
||||||
|
Name: "local_up",
|
||||||
|
Args: []string{"fish"},
|
||||||
|
Required: []string{"fish"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ register.Plugin = &GoCliPlugin{}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := register.
|
||||||
|
NewPluginBuilder(
|
||||||
|
&GoCliPlugin{},
|
||||||
|
).
|
||||||
|
Serve(context.Background()); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
37
plugins/rust/main.go
Normal file
37
plugins/rust/main.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/register"
|
||||||
|
"github.com/hashicorp/go-hclog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GoCliPlugin struct{}
|
||||||
|
|
||||||
|
// Do implements register.Plugin
|
||||||
|
func (*GoCliPlugin) Do(ctx context.Context, cmd *register.DoCommand) error {
|
||||||
|
hclog.L().Info("received command", "commandName", cmd.CommandName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GoCliPlugin) About(ctx context.Context) (*register.About, error) {
|
||||||
|
return ®ister.About{
|
||||||
|
Name: "rust",
|
||||||
|
Version: "v0.0.1",
|
||||||
|
About: "rust cli provides a set of actions and presets supporting rust development",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ register.Plugin = &GoCliPlugin{}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := register.
|
||||||
|
NewPluginBuilder(
|
||||||
|
&GoCliPlugin{},
|
||||||
|
).
|
||||||
|
Serve(context.Background()); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
3
renovate.json
Normal file
3
renovate.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user