add base cmd
This commit is contained in:
parent
332ef8e00d
commit
936c6b4741
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/target
|
|
45
.vscode/launch.json
vendored
Normal file
45
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'char'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=char",
|
||||||
|
"--package=char"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "char",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'char'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=char",
|
||||||
|
"--package=char"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "char",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
139
Cargo.lock
generated
139
Cargo.lock
generated
@ -17,6 +17,12 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.67"
|
version = "0.3.67"
|
||||||
@ -57,13 +63,10 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"eyre",
|
"eyre",
|
||||||
"tracing-subscriber",
|
"serde",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "char_core"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.1.1"
|
version = "4.1.1"
|
||||||
@ -150,6 +153,12 @@ version = "0.27.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793"
|
checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
@ -165,6 +174,16 @@ version = "0.3.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-lifetimes"
|
name = "io-lifetimes"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -205,15 +224,6 @@ version = "0.1.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.4.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -229,16 +239,6 @@ dependencies = [
|
|||||||
"adler",
|
"adler",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[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]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.30.2"
|
version = "0.30.2"
|
||||||
@ -260,12 +260,6 @@ version = "6.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "overload"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owo-colors"
|
name = "owo-colors"
|
||||||
version = "3.5.0"
|
version = "3.5.0"
|
||||||
@ -278,6 +272,24 @@ version = "0.2.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
|
||||||
|
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]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.21"
|
version = "0.1.21"
|
||||||
@ -298,6 +310,26 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.152"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.152"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@ -307,18 +339,23 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smallvec"
|
|
||||||
version = "1.10.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
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]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -337,6 +374,16 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.37"
|
version = "0.1.37"
|
||||||
@ -368,31 +415,23 @@ dependencies = [
|
|||||||
"tracing-subscriber",
|
"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]]
|
[[package]]
|
||||||
name = "tracing-subscriber"
|
name = "tracing-subscriber"
|
||||||
version = "0.3.16"
|
version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
|
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-ansi-term",
|
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
|
||||||
"thread_local",
|
"thread_local",
|
||||||
"tracing-core",
|
"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]]
|
[[package]]
|
||||||
name = "valuable"
|
name = "valuable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
16
Cargo.toml
16
Cargo.toml
@ -6,16 +6,8 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
eyre.workspace = true
|
clap = "4.1.1"
|
||||||
clap = { workspace = true }
|
color-eyre = "0.6.2"
|
||||||
tracing-subscriber = { workspace = true }
|
|
||||||
|
|
||||||
color-eyre = "*"
|
|
||||||
|
|
||||||
[workspace]
|
|
||||||
members = ["crates/char_core"]
|
|
||||||
|
|
||||||
[workspace.dependencies]
|
|
||||||
eyre = "0.6.8"
|
eyre = "0.6.8"
|
||||||
clap = "*"
|
serde = { version = "1.0.152", features = ["derive"] }
|
||||||
tracing-subscriber = "*"
|
toml = { version = "0.5.11", features = ["preserve_order"] }
|
||||||
|
2
crates/char_core/.gitignore
vendored
2
crates/char_core/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
/target
|
|
||||||
/Cargo.lock
|
|
@ -1,14 +0,0 @@
|
|||||||
pub fn add(left: usize, right: usize) -> usize {
|
|
||||||
left + right
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,208 +0,0 @@
|
|||||||
# Pipelines design docs
|
|
||||||
|
|
||||||
The goal of this experiment is to play with various code sharing features. The
|
|
||||||
pipelines in this experiment is supposed to model normal code sharing behavior
|
|
||||||
of libraries, with overriding capabilities of the downstream repository
|
|
||||||
|
|
||||||
The goal is to split the body of the work in three parts.
|
|
||||||
|
|
||||||
- libraries,
|
|
||||||
- compendiums
|
|
||||||
- articles
|
|
||||||
|
|
||||||
The terminology is as such:
|
|
||||||
|
|
||||||
## Libraries
|
|
||||||
|
|
||||||
Libraries provide raw functions, and is a general abstraction on an underlying
|
|
||||||
process, such as running a container, executing a shell script etc. Libraries
|
|
||||||
might define an API descripting how to interact with it. It is up to the
|
|
||||||
compendium, and article to use these in a sane manner.
|
|
||||||
|
|
||||||
Such that:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub fn execute_shell(&self, input: &ShellOpts) -> Result<ShellOutput> {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
These work similar to raw primitive functions, but should serve as an
|
|
||||||
opinionated flyweight. These may be extremely specific, such as building a go
|
|
||||||
binary, creating a github release etc. The details are left to the caller.
|
|
||||||
|
|
||||||
A version scheme of the library should follow semver, as that is the best model
|
|
||||||
at the moment for versioning. Libraries should be pulled using the native
|
|
||||||
package manager, or include as a submodule.
|
|
||||||
|
|
||||||
## Compendiums
|
|
||||||
|
|
||||||
A compendium is an opinionated collection of libraries, which consists of files,
|
|
||||||
configurations etc. A compendium is to be used by either other compendiums, or
|
|
||||||
articles. They are not to be used by libraries, this is to provide a natural
|
|
||||||
hierachy. The end result should be a directed acyclic graph.
|
|
||||||
|
|
||||||
A compendium should provide an API for either other compendiums, or articles.
|
|
||||||
These apis, need to remain flexible, and be open to mutations. As such all
|
|
||||||
primitive features, files, configurations need to be exposed as raw data or data
|
|
||||||
structures if suitable.
|
|
||||||
|
|
||||||
This is done using pipelines, or middleware for the specific parts. A data
|
|
||||||
object will pass from above, containing the data to implement the required
|
|
||||||
interfaces of the Compendium, these must be fulfilled for the construction of
|
|
||||||
the Compendium, else the compilation should fail.
|
|
||||||
|
|
||||||
The caller will have the ability to replace the specifics of the Compendium, by
|
|
||||||
replacing certain pipelines, or mutating the data. In case of mutations, the
|
|
||||||
data is only modified for that pipeline and below, if a fork occurs above, then
|
|
||||||
the divergent paths won't be affected.
|
|
||||||
|
|
||||||
Compendiums are driven by pipelines applied to them either from other
|
|
||||||
compendiums or articles. An article or compendium will only have access to their
|
|
||||||
direct dependent compendiums pipelines. An article will naturally expose
|
|
||||||
pipelines to be called by the user.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub struct GoApplication;
|
|
||||||
|
|
||||||
impl Compendium for GoApplication {
|
|
||||||
type Input = GoApplicationOpts;
|
|
||||||
|
|
||||||
pub fn get_pipelines(&mut self) -> Result<Pipelines> {
|
|
||||||
let pipelines = self.pipelines
|
|
||||||
.clone()
|
|
||||||
.add(self.get_application_pipelines())?
|
|
||||||
.add(self.get_go_releaser_pipelines())?;
|
|
||||||
|
|
||||||
Ok(pipelines)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Articles
|
|
||||||
|
|
||||||
An article is a specific implementation of a compendium, it is the end of the
|
|
||||||
chain, and is meant to be directly executed by the user, using a client
|
|
||||||
application.
|
|
||||||
|
|
||||||
It by default is supposed to be a golden path, I.e. it passes the defaults of
|
|
||||||
the Compendium, but on a case-by-case basis has the ability to modify its
|
|
||||||
pipelines to its needs. This may be changing certain default configurations,
|
|
||||||
mutate a dockerfile, add additional steps to a pipeline etc, and remove others.
|
|
||||||
|
|
||||||
We reason that once you stray from the golden path, you should be in control,
|
|
||||||
this may be done by forking the compendium's features.
|
|
||||||
|
|
||||||
It provides pipelines as actions, and implements a strict protocol for
|
|
||||||
communication.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub struct MyGoService;
|
|
||||||
|
|
||||||
impl Article for MyGoService {
|
|
||||||
|
|
||||||
fn get_pipelines(&mut self) -> Result<Pipelines> {
|
|
||||||
let mut go_pipelines = GoApplication::new().get_pipelines()?;
|
|
||||||
let api_pipeline = self.get_api_pipeline()?;
|
|
||||||
let build_pipeline = self.get_docker_pipeline(go_pipelines.extract::<BuildPipeline>()?)?;;
|
|
||||||
|
|
||||||
let pipelines = PipelineBuilder::new()
|
|
||||||
.append(go_pipelines)
|
|
||||||
.append(api_pipeline)
|
|
||||||
.append(build_pipeline)
|
|
||||||
.build()?
|
|
||||||
|
|
||||||
Ok(pipelines)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
A host app can now call these:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
char ls
|
|
||||||
```
|
|
||||||
|
|
||||||
ls simply displays the information on what pipeline are available
|
|
||||||
|
|
||||||
```bash
|
|
||||||
char run build
|
|
||||||
```
|
|
||||||
|
|
||||||
run build will execute the pipeline build. It will validate input available from
|
|
||||||
char.toml, push these keys/values through to the pipeline, which will go through
|
|
||||||
all the steps.
|
|
||||||
|
|
||||||
- build
|
|
||||||
- MyGoService
|
|
||||||
- DockerBuildPipeline
|
|
||||||
- (BuildPipeline)
|
|
||||||
- DockerLibrary
|
|
||||||
- `fn docker_build(dockerfile_contents: string)`
|
|
||||||
- Native dependencies
|
|
||||||
- "write dockerfile /tmp/abc/dockerfile"
|
|
||||||
- "shell -> docker build -f /tmp/abc/dockerfile some-library-path"
|
|
||||||
|
|
||||||
## Common scenarios
|
|
||||||
|
|
||||||
### Replacing parts of a build script (dockerfile)
|
|
||||||
|
|
||||||
A compendium may embed/provide a dockerfile or any other resource, these are
|
|
||||||
provided through consistent interfaces.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub struct GoDockerBuildPipeline;
|
|
||||||
|
|
||||||
impl GoDockerBuildPipeline {
|
|
||||||
fn get_resources(&self) -> Result<(
|
|
||||||
libraries::docker::DockerContents,
|
|
||||||
libraries::docker::DockerBuildTags)> {
|
|
||||||
return (self.contents, self.build_tags)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mutate_resources(
|
|
||||||
&mut self,
|
|
||||||
contents: libraries::docker::DockerContents,
|
|
||||||
build_tags: libraries::docker::DockerBuildTags,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.contents = contents;
|
|
||||||
self.build_tags = build_tags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BuildPipeline for GoDockerBuildPipeline {
|
|
||||||
fn execute(&mut self, config: Configuration) -> Result<()> {
|
|
||||||
let (docker_contents, base_tags) = self.get_resources()
|
|
||||||
libraries::docker::build(docker_contents, base_tags, config)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In the article you can now replace the resources to fit your needs, that or
|
|
||||||
building your own pipeline.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub struct MyGoService;
|
|
||||||
|
|
||||||
impl Article for MyGoService {
|
|
||||||
|
|
||||||
fn get_pipelines(&mut self) -> Result<Pipelines> {
|
|
||||||
let go_app = GoApplication::new();
|
|
||||||
let go_pipelines = go_app.get_pipelines();
|
|
||||||
|
|
||||||
let mut go_build_pipeline = go_pipelines.get_pipeline::<GoDockerBuildPipeline>()?;
|
|
||||||
let go_resources = go_build_pipeline.get_resources()?;
|
|
||||||
let go_resources = self.mutate_go_resources(&go_resources)?;
|
|
||||||
go_build_pipeline.mutate_resources(go_resources)?;
|
|
||||||
go_pipelines.replace::<GoDockerBuildPipeline>(go_build_pipeline)?;
|
|
||||||
|
|
||||||
let pipelines = PipelineBuilder::new()
|
|
||||||
.append(.get_pipelines())
|
|
||||||
.build()?
|
|
||||||
|
|
||||||
Ok(pipelines)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
55
examples/service/char.toml
Normal file
55
examples/service/char.toml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
[char]
|
||||||
|
plan = "plans/base/"
|
||||||
|
dependencies = ["plans/extension"]
|
||||||
|
|
||||||
|
[char.overrides]
|
||||||
|
org = "overrides/org"
|
||||||
|
|
||||||
|
[application]
|
||||||
|
name = "service"
|
||||||
|
|
||||||
|
[config]
|
||||||
|
# provides both local and k8s by default can also be set using:
|
||||||
|
# config.k8s.rabbitmq = true
|
||||||
|
# config.docker-compose.rabbitmq = true
|
||||||
|
rabbitmq = true
|
||||||
|
postgres = true
|
||||||
|
|
||||||
|
[config.org]
|
||||||
|
squad = "kjuulh"
|
||||||
|
domain = "tooling"
|
||||||
|
|
||||||
|
[config.pipeline]
|
||||||
|
path = "char/ci/" # most of these are default, showing them here as a showcase
|
||||||
|
|
||||||
|
[config.actions]
|
||||||
|
path = "char/actions"
|
||||||
|
|
||||||
|
[config.releaser]
|
||||||
|
type = "rust-releaser"
|
||||||
|
|
||||||
|
[config.cargo]
|
||||||
|
crates = ["crates/service_core", "crates/service_util"]
|
||||||
|
|
||||||
|
[config.rust_bin]
|
||||||
|
name = "service"
|
||||||
|
logging = { pretty = true }
|
||||||
|
|
||||||
|
[config.environments.local]
|
||||||
|
type = "docker-compose" # technically default
|
||||||
|
|
||||||
|
[config.environments.local.env]
|
||||||
|
"env" = "local"
|
||||||
|
"db.hostname" = "postgres"
|
||||||
|
"db.secret" = "postgres"
|
||||||
|
|
||||||
|
[config.k8s]
|
||||||
|
monitoring = true
|
||||||
|
|
||||||
|
[config.environments.dev]
|
||||||
|
type = "k8s"
|
||||||
|
|
||||||
|
[config.environments.local.dev]
|
||||||
|
"env" = "local"
|
||||||
|
"db.hostname" = "service-db"
|
||||||
|
"db.secret" = { type = "secret" }
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "char_core"
|
name = "actions"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
3
examples/service/char/actions/src/main.rs
Normal file
3
examples/service/char/actions/src/main.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
7
examples/service/char/overrides/org/Cargo.lock
generated
Normal file
7
examples/service/char/overrides/org/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "org"
|
||||||
|
version = "0.1.0"
|
8
examples/service/char/overrides/org/Cargo.toml
Normal file
8
examples/service/char/overrides/org/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "org"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
0
examples/service/char/overrides/org/char.toml
Normal file
0
examples/service/char/overrides/org/char.toml
Normal file
3
examples/service/char/overrides/org/src/main.rs
Normal file
3
examples/service/char/overrides/org/src/main.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc_fingerprint":13769919407148446586,"outputs":{"10376369925670944939":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/kah/.rustup/toolchains/stable-aarch64-apple-darwin\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"vh\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"15697416045686424142":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.66.0 (69f9c33d7 2022-12-12)\nbinary: rustc\ncommit-hash: 69f9c33d71c871fc16ac445211281c6e7a340943\ncommit-date: 2022-12-12\nhost: aarch64-apple-darwin\nrelease: 1.66.0\nLLVM version: 15.0.2\n","stderr":""}},"successes":{}}
|
3
examples/service/char/overrides/org/target/CACHEDIR.TAG
Normal file
3
examples/service/char/overrides/org/target/CACHEDIR.TAG
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Signature: 8a477f597d28d172789f06886806bc55
|
||||||
|
# This file is a cache directory tag created by cargo.
|
||||||
|
# For information about cache directory tags see https://bford.info/cachedir/
|
@ -0,0 +1 @@
|
|||||||
|
baa57697ce65b314
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[]","target":10808372008975436347,"profile":11736316127369858332,"path":1684066648322511884,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/org-2413d5d1cd4f3ae1/dep-bin-org"}}],"rustflags":[],"metadata":7797948686568424061,"config":2202906307356721367,"compile_kind":0}
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
BIN
examples/service/char/overrides/org/target/debug/deps/org-2413d5d1cd4f3ae1
Executable file
BIN
examples/service/char/overrides/org/target/debug/deps/org-2413d5d1cd4f3ae1
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,5 @@
|
|||||||
|
/Users/kah/git/git.front.kjuulh.io/kjuulh/char/examples/service/char/overrides/org/target/debug/deps/org-2413d5d1cd4f3ae1: src/main.rs
|
||||||
|
|
||||||
|
/Users/kah/git/git.front.kjuulh.io/kjuulh/char/examples/service/char/overrides/org/target/debug/deps/org-2413d5d1cd4f3ae1.d: src/main.rs
|
||||||
|
|
||||||
|
src/main.rs:
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
examples/service/char/overrides/org/target/debug/org
Executable file
BIN
examples/service/char/overrides/org/target/debug/org
Executable file
Binary file not shown.
1
examples/service/char/overrides/org/target/debug/org.d
Normal file
1
examples/service/char/overrides/org/target/debug/org.d
Normal file
@ -0,0 +1 @@
|
|||||||
|
/Users/kah/git/git.front.kjuulh.io/kjuulh/char/examples/service/char/overrides/org/target/debug/org: /Users/kah/git/git.front.kjuulh.io/kjuulh/char/examples/service/char/overrides/org/src/main.rs
|
5
examples/service/plans/base/char.toml
Normal file
5
examples/service/plans/base/char.toml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[char]
|
||||||
|
|
||||||
|
[plan]
|
||||||
|
|
||||||
|
name = "base"
|
44
src/cli.rs
Normal file
44
src/cli.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
use std::{ops::DerefMut, path::PathBuf};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
deps,
|
||||||
|
resolvers::{install, Resolver},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Cli {
|
||||||
|
deps: deps::Deps,
|
||||||
|
install: Box<dyn Resolver + Send + Sync>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cli {
|
||||||
|
pub fn new(deps: deps::Deps) -> eyre::Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
deps: deps.clone(),
|
||||||
|
install: install::Install::new(deps),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn matches(self, args: &[&str]) -> eyre::Result<()> {
|
||||||
|
let mut cli = clap::Command::new("char")
|
||||||
|
.arg(clap::Arg::new("path").long("path").short('p'))
|
||||||
|
.subcommand(self.install.cmd()?);
|
||||||
|
|
||||||
|
let matches = cli.clone().get_matches_from(args);
|
||||||
|
|
||||||
|
let path = matches.get_one::<String>("path");
|
||||||
|
if let Some(p) = path {
|
||||||
|
let validated_path = PathBuf::from(p);
|
||||||
|
if !validated_path.exists() {
|
||||||
|
eyre::bail!("no char.toml exists at --path")
|
||||||
|
}
|
||||||
|
self.deps.parser.set_path(validated_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
match matches.subcommand() {
|
||||||
|
Some(("install", args)) => self.install.matches(args)?,
|
||||||
|
_ => cli.print_help()?,
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
34
src/deps.rs
Normal file
34
src/deps.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use std::{
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::parser::Parser;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Deps {
|
||||||
|
inner: Arc<InnerDeps>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct InnerDeps {
|
||||||
|
pub parser: Parser,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Deps {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Arc::new(InnerDeps {
|
||||||
|
parser: Parser::default(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Deps {
|
||||||
|
type Target = Arc<InnerDeps>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
180
src/main.rs
180
src/main.rs
@ -1,9 +1,18 @@
|
|||||||
|
pub mod cli;
|
||||||
|
mod deps;
|
||||||
|
mod models;
|
||||||
|
mod parser;
|
||||||
|
mod resolvers;
|
||||||
|
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
color_eyre::install()?;
|
color_eyre::install()?;
|
||||||
|
|
||||||
let args = std::env::args();
|
let args = std::env::args();
|
||||||
|
|
||||||
Char::new().execute_from(
|
let deps = deps::Deps::default();
|
||||||
|
|
||||||
|
let c = cli::Cli::new(deps)?;
|
||||||
|
c.matches(
|
||||||
args.collect::<Vec<String>>()
|
args.collect::<Vec<String>>()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.as_str())
|
.map(|s| s.as_str())
|
||||||
@ -11,174 +20,11 @@ fn main() -> eyre::Result<()> {
|
|||||||
.as_slice(),
|
.as_slice(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
let p = std::path::PathBuf::from("examples/service/char.toml");
|
||||||
}
|
|
||||||
|
|
||||||
mod library {
|
let char = std::fs::read_to_string(p)?.parse::<models::Char>()?;
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
pub struct Shell {
|
dbg!(char);
|
||||||
path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Shell {
|
|
||||||
pub fn new(path: Option<PathBuf>) -> eyre::Result<Self> {
|
|
||||||
Ok(Self {
|
|
||||||
path: path.unwrap_or(std::env::current_dir()?),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
pub fn execute_shell(&self, args: &[&str]) -> eyre::Result<String> {
|
|
||||||
let output = std::process::Command::new(
|
|
||||||
args.get(0)
|
|
||||||
.ok_or(eyre::anyhow!("no first arg in shell command"))?,
|
|
||||||
)
|
|
||||||
.args(args.get(1..).unwrap_or(&[]))
|
|
||||||
.current_dir(&self.path)
|
|
||||||
.output()?;
|
|
||||||
|
|
||||||
Ok(String::from_utf8(output.stdout)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_static_str(s: String) -> &'static str {
|
|
||||||
Box::leak(s.into_boxed_str())
|
|
||||||
}
|
|
||||||
|
|
||||||
trait Pipeline {
|
|
||||||
fn name(&self) -> String;
|
|
||||||
fn cmd(&self) -> clap::Command {
|
|
||||||
let name = self.name();
|
|
||||||
|
|
||||||
clap::Command::new(into_static_str(name))
|
|
||||||
}
|
|
||||||
fn execute(&self, args: &clap::ArgMatches) -> eyre::Result<()>;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BuildPipeline {}
|
|
||||||
|
|
||||||
impl Pipeline for BuildPipeline {
|
|
||||||
fn name(&self) -> String {
|
|
||||||
"build_pipeline".into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cmd(&self) -> clap::Command {
|
|
||||||
let name = self.name();
|
|
||||||
|
|
||||||
clap::Command::new(into_static_str(name)).arg(clap::Arg::new("some").long("some"))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute(&self, args: &clap::ArgMatches) -> eyre::Result<()> {
|
|
||||||
let some = args
|
|
||||||
.get_one::<String>("some")
|
|
||||||
.ok_or(eyre::anyhow!("some is missing"))?;
|
|
||||||
|
|
||||||
let output = library::Shell::new(None)?.execute_shell(&["echo", some])?;
|
|
||||||
|
|
||||||
println!("{output}");
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type DynPipeline = Box<dyn Pipeline + Send + Sync>;
|
|
||||||
struct Pipelines {
|
|
||||||
pipelines: Vec<DynPipeline>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pipelines {
|
|
||||||
fn list(&self) -> eyre::Result<Vec<String>> {
|
|
||||||
let cmds = self.pipelines.iter().map(|p| p.name()).collect();
|
|
||||||
|
|
||||||
Ok(cmds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct Char {
|
|
||||||
pipelines: Pipelines,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Char {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let build_pipeline = BuildPipeline {};
|
|
||||||
Self {
|
|
||||||
pipelines: Pipelines {
|
|
||||||
pipelines: vec![Box::new(build_pipeline)],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute_from(self, args: &[&str]) -> eyre::Result<()> {
|
|
||||||
let matches = self.main_cmd().get_matches_from(args);
|
|
||||||
|
|
||||||
match matches.subcommand() {
|
|
||||||
Some(("list", _)) => self.execute_list()?,
|
|
||||||
Some(("run", sub)) => self.execute_run(sub)?,
|
|
||||||
_ => eyre::bail!("no command matches, please [char --help] to see available commands"),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main_cmd(&self) -> clap::Command {
|
|
||||||
clap::Command::new("char")
|
|
||||||
.subcommand(self.list_cmd())
|
|
||||||
.subcommand(self.run_cmd())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn list_cmd(&self) -> clap::Command {
|
|
||||||
clap::Command::new("list")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_cmd(&self) -> clap::Command {
|
|
||||||
clap::Command::new("run").subcommands(self.pipelines.pipelines.iter().map(|p| p.cmd()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute_list(&self) -> eyre::Result<()> {
|
|
||||||
println!("list");
|
|
||||||
self.pipelines
|
|
||||||
.pipelines
|
|
||||||
.iter()
|
|
||||||
.for_each(|p| println!(" - {}", p.name()));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute_run(&self, sub: &clap::ArgMatches) -> eyre::Result<()> {
|
|
||||||
if let Some((name, subm)) = sub.subcommand() {
|
|
||||||
let pipelines: Vec<&DynPipeline> = self
|
|
||||||
.pipelines
|
|
||||||
.pipelines
|
|
||||||
.iter()
|
|
||||||
.filter(|p| p.name() == name)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if let Some(pipeline) = pipelines.get(0) {
|
|
||||||
println!("{}", pipeline.name());
|
|
||||||
|
|
||||||
pipeline.execute(subm)?;
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eyre::bail!("no command matches, please [char list] to see available commands");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::Char;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn execute_list() {
|
|
||||||
Char::new().execute_from(&["char", "list"]).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn execute_run() {
|
|
||||||
Char::new()
|
|
||||||
.execute_from(&["char", "run", "build_pipeline", "--some", "arg"])
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
48
src/models.rs
Normal file
48
src/models.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
type Overrides = BTreeMap<String, String>;
|
||||||
|
type Dependencies = Vec<String>;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
pub struct Conf {
|
||||||
|
plan: String,
|
||||||
|
dependencies: Option<Dependencies>,
|
||||||
|
overrides: Option<Overrides>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
pub struct Application {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
pub struct Plan {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Char {
|
||||||
|
Application {
|
||||||
|
char: Option<Conf>,
|
||||||
|
application: Application,
|
||||||
|
config: BTreeMap<String, toml::Value>,
|
||||||
|
},
|
||||||
|
Plan {
|
||||||
|
char: Option<Conf>,
|
||||||
|
plan: Plan,
|
||||||
|
config: BTreeMap<String, toml::Value>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for Char {
|
||||||
|
type Err = eyre::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let t: Char = toml::from_str(s)?;
|
||||||
|
|
||||||
|
Ok(t)
|
||||||
|
}
|
||||||
|
}
|
46
src/parser.rs
Normal file
46
src/parser.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use std::{
|
||||||
|
path::PathBuf,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
|
use eyre::Context;
|
||||||
|
|
||||||
|
use crate::models::{self, Char};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Parser {
|
||||||
|
path: Arc<RwLock<Option<PathBuf>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parser {
|
||||||
|
pub fn new(path: PathBuf) -> Self {
|
||||||
|
Self {
|
||||||
|
path: Arc::new(RwLock::new(Some(path))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_path(&self, path: PathBuf) {
|
||||||
|
let writer = self.path.write().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(&self) -> eyre::Result<models::Char> {
|
||||||
|
let read_path = self.path.read().unwrap();
|
||||||
|
let path = match read_path.clone() {
|
||||||
|
Some(p) => p,
|
||||||
|
None => todo!(), // find using git later on
|
||||||
|
};
|
||||||
|
|
||||||
|
let contents =
|
||||||
|
std::fs::read_to_string(&path).context("char.toml doesn't exist at that path")?;
|
||||||
|
|
||||||
|
contents.parse::<Char>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Parser {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
path: Arc::new(RwLock::new(None)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
src/resolvers/install.rs
Normal file
30
src/resolvers/install.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use crate::deps;
|
||||||
|
|
||||||
|
use super::{DynResolver, Resolver};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Install {
|
||||||
|
deps: deps::Deps,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Install {
|
||||||
|
pub fn new(deps: deps::Deps) -> DynResolver {
|
||||||
|
Box::new(Self { deps })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Resolver for Install {
|
||||||
|
fn cmd(&self) -> eyre::Result<clap::Command> {
|
||||||
|
let install = clap::Command::new("install");
|
||||||
|
|
||||||
|
Ok(install)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matches(&self, args: &clap::ArgMatches) -> eyre::Result<()> {
|
||||||
|
let char = self.deps.parser.parse()?;
|
||||||
|
|
||||||
|
dbg!(char);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
8
src/resolvers/mod.rs
Normal file
8
src/resolvers/mod.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
pub(crate) mod install;
|
||||||
|
|
||||||
|
pub trait Resolver {
|
||||||
|
fn cmd(&self) -> eyre::Result<clap::Command>;
|
||||||
|
fn matches(&self, args: &clap::ArgMatches) -> eyre::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type DynResolver = Box<dyn Resolver + Send + Sync>;
|
1
target/.rustc_info.json
Normal file
1
target/.rustc_info.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"rustc_fingerprint":13769919407148446586,"outputs":{"10376369925670944939":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/kah/.rustup/toolchains/stable-aarch64-apple-darwin\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"vh\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.66.0 (69f9c33d7 2022-12-12)\nbinary: rustc\ncommit-hash: 69f9c33d71c871fc16ac445211281c6e7a340943\ncommit-date: 2022-12-12\nhost: aarch64-apple-darwin\nrelease: 1.66.0\nLLVM version: 15.0.2\n","stderr":""},"15697416045686424142":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n","stderr":""}},"successes":{}}
|
3
target/CACHEDIR.TAG
Normal file
3
target/CACHEDIR.TAG
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Signature: 8a477f597d28d172789f06886806bc55
|
||||||
|
# This file is a cache directory tag created by cargo.
|
||||||
|
# For information about cache directory tags see https://bford.info/cachedir/
|
0
target/debug/.cargo-lock
Normal file
0
target/debug/.cargo-lock
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
01a66840cac14170
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[]","target":5058954644684423156,"profile":8344124108420085910,"path":1622647420939292329,"deps":[[6052011622176946403,"gimli",false,10209649094175699238]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/addr2line-0a74bc86d7231145/dep-lib-addr2line"}}],"rustflags":[],"metadata":12740932805375460336,"config":2202906307356721367,"compile_kind":0}
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
7deeb1487b2b4669
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[]","target":5058954644684423156,"profile":8987646332441898785,"path":1622647420939292329,"deps":[[6052011622176946403,"gimli",false,13849317035548400969]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/addr2line-4daea2d689f01763/dep-lib-addr2line"}}],"rustflags":[],"metadata":12740932805375460336,"config":2202906307356721367,"compile_kind":0}
|
BIN
target/debug/.fingerprint/adler-36db4dde439c9ca2/dep-lib-adler
Normal file
BIN
target/debug/.fingerprint/adler-36db4dde439c9ca2/dep-lib-adler
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
ffee3b5e61c2dd43
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[]","target":17946092562950227216,"profile":8987646332441898785,"path":7211852901486469175,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/adler-36db4dde439c9ca2/dep-lib-adler"}}],"rustflags":[],"metadata":10673633425720882208,"config":2202906307356721367,"compile_kind":0}
|
BIN
target/debug/.fingerprint/adler-3badcf05765e7cb8/dep-lib-adler
Normal file
BIN
target/debug/.fingerprint/adler-3badcf05765e7cb8/dep-lib-adler
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
8de2bfe646315aa4
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[]","target":17946092562950227216,"profile":8344124108420085910,"path":7211852901486469175,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/adler-3badcf05765e7cb8/dep-lib-adler"}}],"rustflags":[],"metadata":10673633425720882208,"config":2202906307356721367,"compile_kind":0}
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
9cc60849ec37a3a4
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[]","target":10236397793970852656,"profile":8344124108420085910,"path":6198841384383516255,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/autocfg-a180fc05a18cb66c/dep-lib-autocfg"}}],"rustflags":[],"metadata":13102859075309379048,"config":2202906307356721367,"compile_kind":0}
|
@ -0,0 +1 @@
|
|||||||
|
3ec467c4b5628a06
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"","target":0,"profile":0,"path":0,"deps":[[1894761282145504461,"build_script_build",false,16888667174750270372]],"local":[{"Precalculated":"0.3.67"}],"rustflags":[],"metadata":0,"config":0,"compile_kind":0}
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
ba1c95867cfe94f8
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[\"default\", \"gimli-symbolize\", \"std\"]","target":18222607620431226260,"profile":8987646332441898785,"path":18005795319063570362,"deps":[[1894761282145504461,"build_script_build",false,471297643837375550],[2452538001284770427,"cfg_if",false,1801842567802704597],[10042388369396437804,"libc",false,16838104131994591615],[11143999024690331725,"rustc_demangle",false,4592352165580730829],[14961818183230099209,"object",false,358952644854955862],[15301050416053251221,"addr2line",false,7585798430852771453],[15577722655483729366,"miniz_oxide",false,8480172166096170905]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/backtrace-4a67468d29243687/dep-lib-backtrace"}}],"rustflags":[],"metadata":7223263141473362705,"config":2202906307356721367,"compile_kind":0}
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
50f76e8255cadf68
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[\"default\", \"gimli-symbolize\", \"std\"]","target":18222607620431226260,"profile":8344124108420085910,"path":18005795319063570362,"deps":[[1894761282145504461,"build_script_build",false,471297643837375550],[2452538001284770427,"cfg_if",false,6036890147053457869],[10042388369396437804,"libc",false,8783508030180488951],[11143999024690331725,"rustc_demangle",false,9411200536309298346],[14961818183230099209,"object",false,17195232253756424914],[15301050416053251221,"addr2line",false,8088959480142276097],[15577722655483729366,"miniz_oxide",false,3111252082654846445]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/backtrace-8cc2a3694ae991a3/dep-lib-backtrace"}}],"rustflags":[],"metadata":7223263141473362705,"config":2202906307356721367,"compile_kind":0}
|
@ -0,0 +1 @@
|
|||||||
|
a433cac0509960ea
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[\"default\", \"gimli-symbolize\", \"std\"]","target":13294766831966498538,"profile":8344124108420085910,"path":6314454965963632675,"deps":[[8260795008238812391,"cc",false,13722322572734014901]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/backtrace-94bb9ac43afb8248/dep-build-script-build-script-build"}}],"rustflags":[],"metadata":7223263141473362705,"config":2202906307356721367,"compile_kind":0}
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
fee82aa93b12f393
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[\"default\", \"gimli-symbolize\", \"std\"]","target":18222607620431226260,"profile":8987646332441898785,"path":18005795319063570362,"deps":[[1894761282145504461,"build_script_build",false,471297643837375550],[2452538001284770427,"cfg_if",false,1801842567802704597],[10042388369396437804,"libc",false,4030868332334094095],[11143999024690331725,"rustc_demangle",false,4592352165580730829],[14961818183230099209,"object",false,358952644854955862],[15301050416053251221,"addr2line",false,7585798430852771453],[15577722655483729366,"miniz_oxide",false,8480172166096170905]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/backtrace-98161a90c1c9cb06/dep-lib-backtrace"}}],"rustflags":[],"metadata":7223263141473362705,"config":2202906307356721367,"compile_kind":0}
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
This file has an mtime of when this was started.
|
@ -0,0 +1 @@
|
|||||||
|
efc16aa2d51972c8
|
@ -0,0 +1 @@
|
|||||||
|
{"rustc":15520539443732555526,"features":"[\"default\", \"gimli-symbolize\", \"std\"]","target":18222607620431226260,"profile":8344124108420085910,"path":18005795319063570362,"deps":[[1894761282145504461,"build_script_build",false,471297643837375550],[2452538001284770427,"cfg_if",false,6036890147053457869],[10042388369396437804,"libc",false,6240630739280180992],[11143999024690331725,"rustc_demangle",false,9411200536309298346],[14961818183230099209,"object",false,17195232253756424914],[15301050416053251221,"addr2line",false,8088959480142276097],[15577722655483729366,"miniz_oxide",false,3111252082654846445]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/backtrace-a43b754519a04894/dep-lib-backtrace"}}],"rustflags":[],"metadata":7223263141473362705,"config":2202906307356721367,"compile_kind":0}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user