From 56a8f24cedb6cacf4489d4bbc854709f86383c45 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 24 Dec 2022 09:44:56 +1300 Subject: [PATCH 01/14] Update dependency versions. --- Cargo.toml | 2 +- crate/cfg/Cargo.toml | 4 ++-- crate/core/Cargo.toml | 2 +- crate/data_derive/Cargo.toml | 6 +++--- crate/diff/Cargo.toml | 2 +- crate/resources/Cargo.toml | 4 ++-- crate/rt/Cargo.toml | 4 ++-- crate/rt_model/Cargo.toml | 4 ++-- crate/rt_model_core/Cargo.toml | 4 ++-- crate/rt_model_native/Cargo.toml | 10 +++++----- crate/rt_model_web/Cargo.toml | 8 ++++---- crate/static_check_macros/Cargo.toml | 6 +++--- examples/app_cycle/Cargo.toml | 12 ++++++------ examples/download/Cargo.toml | 8 ++++---- item_specs/file_download/Cargo.toml | 10 +++++----- item_specs/sh_cmd/Cargo.toml | 8 ++++---- item_specs/sh_sync_cmd/Cargo.toml | 8 ++++---- item_specs/tar_x/Cargo.toml | 8 ++++---- workspace_tests/Cargo.toml | 10 +++++----- 19 files changed, 60 insertions(+), 60 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ad8e075a1..edf469d22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ members = [ ] [workspace.dependencies] -miette = { version = "5.4.1" } +miette = { version = "5.5.0" } derivative = "2.2.0" tar = "0.4.38" diff --git a/crate/cfg/Cargo.toml b/crate/cfg/Cargo.toml index e4929843c..fcbe1de00 100644 --- a/crate/cfg/Cargo.toml +++ b/crate/cfg/Cargo.toml @@ -16,8 +16,8 @@ doctest = false test = false [dependencies] -async-trait = "0.1.58" +async-trait = "0.1.60" peace_core = { path = "../core", version = "0.0.5" } peace_data = { path = "../data", version = "0.0.5" } peace_resources = { path = "../resources", version = "0.0.5" } -serde = { version = "1.0.147", features = ["derive"] } +serde = { version = "1.0.151", features = ["derive"] } diff --git a/crate/core/Cargo.toml b/crate/core/Cargo.toml index 4fa187bf6..9470c4888 100644 --- a/crate/core/Cargo.toml +++ b/crate/core/Cargo.toml @@ -17,4 +17,4 @@ test = false [dependencies] peace_static_check_macros = { path = "../static_check_macros", version = "0.0.5" } -serde = { version = "1.0.147", features = ["derive"] } +serde = { version = "1.0.151", features = ["derive"] } diff --git a/crate/data_derive/Cargo.toml b/crate/data_derive/Cargo.toml index 355f56e47..98367bc4b 100644 --- a/crate/data_derive/Cargo.toml +++ b/crate/data_derive/Cargo.toml @@ -17,6 +17,6 @@ doctest = false test = false [dependencies] -syn = "1.0.103" -quote = "1.0.21" -proc-macro2 = "1.0.47" +syn = "1.0.107" +quote = "1.0.23" +proc-macro2 = "1.0.49" diff --git a/crate/diff/Cargo.toml b/crate/diff/Cargo.toml index 8091ec2fe..a7ea35f77 100644 --- a/crate/diff/Cargo.toml +++ b/crate/diff/Cargo.toml @@ -16,4 +16,4 @@ doctest = false test = false [dependencies] -serde = { version = "1.0.147", features = ["derive"] } +serde = { version = "1.0.151", features = ["derive"] } diff --git a/crate/resources/Cargo.toml b/crate/resources/Cargo.toml index d92e96331..d0b8796b6 100644 --- a/crate/resources/Cargo.toml +++ b/crate/resources/Cargo.toml @@ -19,6 +19,6 @@ test = false peace_core = { version = "0.0.5", path = "../core" } peace_data = { version = "0.0.5", path = "../data" } resman = { version = "0.15.0", features = ["debug"] } -serde = { version = "1.0.147", features = ["derive"] } -tokio = { version = "1.22.0", features = ["sync"] } +serde = { version = "1.0.151", features = ["derive"] } +tokio = { version = "1.23.0", features = ["sync"] } type_reg = { version = "0.4.0", features = ["debug", "untagged", "ordered"] } diff --git a/crate/rt/Cargo.toml b/crate/rt/Cargo.toml index 5f2998671..cc886703f 100644 --- a/crate/rt/Cargo.toml +++ b/crate/rt/Cargo.toml @@ -22,10 +22,10 @@ peace_cfg = { path = "../cfg", version = "0.0.5" } peace_resources = { path = "../resources", version = "0.0.5" } peace_rt_model = { path = "../rt_model", version = "0.0.5" } peace_rt_model_core = { path = "../rt_model_core", version = "0.0.5" } -serde_yaml = "0.9.14" +serde_yaml = "0.9.16" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio = { version = "1.22.0", features = ["fs", "io-util"] } +tokio = { version = "1.23.0", features = ["fs", "io-util"] } tokio-util = { version = "0.7.4", features = ["io", "io-util"] } [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/crate/rt_model/Cargo.toml b/crate/rt_model/Cargo.toml index 5e0679bf5..d38a8e26c 100644 --- a/crate/rt_model/Cargo.toml +++ b/crate/rt_model/Cargo.toml @@ -24,8 +24,8 @@ peace_data = { path = "../data", version = "0.0.5" } peace_resources = { path = "../resources", version = "0.0.5" } peace_rt_model_core = { path = "../rt_model_core", version = "0.0.5" } peace_rt_model_hack = { path = "../rt_model_hack", version = "0.0.5", optional = true } -serde = "1.0.147" -serde_yaml = "0.9.14" +serde = "1.0.151" +serde_yaml = "0.9.16" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] peace_rt_model_native = { path = "../rt_model_native", version = "0.0.5" } diff --git a/crate/rt_model_core/Cargo.toml b/crate/rt_model_core/Cargo.toml index e9f3ed2c5..ca3141ddb 100644 --- a/crate/rt_model_core/Cargo.toml +++ b/crate/rt_model_core/Cargo.toml @@ -16,9 +16,9 @@ doctest = false test = false [dependencies] -async-trait = "0.1.58" +async-trait = "0.1.60" peace_resources = { path = "../resources", version = "0.0.5" } -serde_json = { version = "1.0.88", optional = true } +serde_json = { version = "1.0.91", optional = true } miette = { workspace = true, optional = true } [features] diff --git a/crate/rt_model_native/Cargo.toml b/crate/rt_model_native/Cargo.toml index 9731b5fed..640ff41f6 100644 --- a/crate/rt_model_native/Cargo.toml +++ b/crate/rt_model_native/Cargo.toml @@ -22,11 +22,11 @@ miette = { workspace = true, optional = true } peace_core = { path = "../core", version = "0.0.5" } peace_resources = { path = "../resources", version = "0.0.5" } peace_rt_model_core = { path = "../rt_model_core", version = "0.0.5" } -serde = "1.0.147" -serde_json = { version = "1.0.88", optional = true } -serde_yaml = "0.9.14" -thiserror = "1.0.37" -tokio = { version = "1.22.0", features = ["fs", "io-std"] } +serde = "1.0.151" +serde_json = { version = "1.0.91", optional = true } +serde_yaml = "0.9.16" +thiserror = "1.0.38" +tokio = { version = "1.23.0", features = ["fs", "io-std"] } tokio-util = { version = "0.7.4", features = ["io", "io-util"] } [features] diff --git a/crate/rt_model_web/Cargo.toml b/crate/rt_model_web/Cargo.toml index 15b959f24..bf6852b97 100644 --- a/crate/rt_model_web/Cargo.toml +++ b/crate/rt_model_web/Cargo.toml @@ -21,11 +21,11 @@ miette = { workspace = true, optional = true } peace_core = { path = "../core", version = "0.0.5" } peace_resources = { path = "../resources", version = "0.0.5" } peace_rt_model_core = { path = "../rt_model_core", version = "0.0.5" } -serde = "1.0.147" +serde = "1.0.151" serde-wasm-bindgen = "0.4.5" -serde_json = { version = "1.0.88", optional = true } -serde_yaml = "0.9.14" -thiserror = "1.0.37" +serde_json = { version = "1.0.91", optional = true } +serde_yaml = "0.9.16" +thiserror = "1.0.38" wasm-bindgen = "0.2.83" web-sys = { version = "0.3.60", features = ["Storage", "Window"] } diff --git a/crate/static_check_macros/Cargo.toml b/crate/static_check_macros/Cargo.toml index 8d743f1c3..466edbc14 100644 --- a/crate/static_check_macros/Cargo.toml +++ b/crate/static_check_macros/Cargo.toml @@ -17,6 +17,6 @@ doctest = true test = false [dependencies] -syn = "1.0.103" -quote = "1.0.21" -proc-macro2 = "1.0.47" +syn = "1.0.107" +quote = "1.0.23" +proc-macro2 = "1.0.49" diff --git a/examples/app_cycle/Cargo.toml b/examples/app_cycle/Cargo.toml index 958c0b964..cb8da4fa6 100644 --- a/examples/app_cycle/Cargo.toml +++ b/examples/app_cycle/Cargo.toml @@ -20,18 +20,18 @@ crate-type = ["cdylib", "rlib"] [dependencies] peace = { path = "../.." } peace_item_specs = { path = "../../item_specs", features = ["file_download", "tar_x"] } -semver = "1.0.14" -serde = { version = "1.0.147", features = ["derive"] } -thiserror = "1.0.37" +semver = "1.0.16" +serde = { version = "1.0.151", features = ["derive"] } +thiserror = "1.0.38" url = { version = "2.3.1", features = ["serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -clap = { version = "4.0.26", features = ["derive"] } -tokio = { version = "1.22.0", features = ["rt"] } +clap = { version = "4.0.32", features = ["derive"] } +tokio = { version = "1.23.0", features = ["rt"] } [target.'cfg(target_arch = "wasm32")'.dependencies] serde-wasm-bindgen = "0.4.5" -tokio = { version = "1.22.0" } +tokio = { version = "1.23.0" } wasm-bindgen = "0.2.83" wasm-bindgen-futures = "0.4.33" js-sys = "0.3.60" diff --git a/examples/download/Cargo.toml b/examples/download/Cargo.toml index 84a2c91b6..12da02a6a 100644 --- a/examples/download/Cargo.toml +++ b/examples/download/Cargo.toml @@ -20,17 +20,17 @@ crate-type = ["cdylib", "rlib"] [dependencies] peace = { path = "../.." } peace_item_specs = { path = "../../item_specs", features = ["file_download"] } -thiserror = "1.0.37" +thiserror = "1.0.38" url = { version = "2.3.1", features = ["serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -clap = { version = "4.0.26", features = ["derive"] } -tokio = { version = "1.22.0", features = ["net", "time", "rt"] } +clap = { version = "4.0.32", features = ["derive"] } +tokio = { version = "1.23.0", features = ["net", "time", "rt"] } [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.7" serde-wasm-bindgen = "0.4.5" -tokio = { version = "1.22.0" } +tokio = { version = "1.23.0" } wasm-bindgen = "0.2.83" wasm-bindgen-futures = "0.4.33" js-sys = "0.3.60" diff --git a/item_specs/file_download/Cargo.toml b/item_specs/file_download/Cargo.toml index 64ffa4e3b..3c0bf3ef3 100644 --- a/item_specs/file_download/Cargo.toml +++ b/item_specs/file_download/Cargo.toml @@ -16,20 +16,20 @@ doctest = false test = false [dependencies] -bytes = "1.2.1" +bytes = "1.3.0" futures = "0.3.25" miette = { workspace = true, optional = true } peace = { path = "../..", version = "0.0.5" } reqwest = { version = "0.11.13", features = ["stream"] } -serde = { version = "1.0.147", features = ["derive"] } -thiserror = "1.0.37" +serde = { version = "1.0.151", features = ["derive"] } +thiserror = "1.0.38" url = { version = "2.3.1", features = ["serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio = { version = "1.22.0", features = ["net", "time", "rt"] } +tokio = { version = "1.23.0", features = ["net", "time", "rt"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -tokio = { version = "1.22.0" } +tokio = { version = "1.23.0" } [features] default = [] diff --git a/item_specs/sh_cmd/Cargo.toml b/item_specs/sh_cmd/Cargo.toml index 0a07ca966..734cd0ac3 100644 --- a/item_specs/sh_cmd/Cargo.toml +++ b/item_specs/sh_cmd/Cargo.toml @@ -20,14 +20,14 @@ chrono = { version = "0.4.23", default-features = false, features = ["clock", "s derivative = { workspace = true } miette = { workspace = true, optional = true } peace = { path = "../..", version = "0.0.5" } -serde = { version = "1.0.147", features = ["derive"] } -thiserror = "1.0.37" +serde = { version = "1.0.151", features = ["derive"] } +thiserror = "1.0.38" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio = { version = "1.22.0", features = ["process"] } +tokio = { version = "1.23.0", features = ["process"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -tokio = { version = "1.22.0" } +tokio = { version = "1.23.0" } [features] default = [] diff --git a/item_specs/sh_sync_cmd/Cargo.toml b/item_specs/sh_sync_cmd/Cargo.toml index e009e71d8..96f63baf7 100644 --- a/item_specs/sh_sync_cmd/Cargo.toml +++ b/item_specs/sh_sync_cmd/Cargo.toml @@ -19,14 +19,14 @@ test = false chrono = { version = "0.4.23", default-features = false, features = ["clock", "serde"] } miette = { workspace = true, optional = true } peace = { path = "../..", version = "0.0.5" } -serde = { version = "1.0.147", features = ["derive"] } -thiserror = "1.0.37" +serde = { version = "1.0.151", features = ["derive"] } +thiserror = "1.0.38" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio = { version = "1.22.0", features = ["net", "time", "rt"] } +tokio = { version = "1.23.0", features = ["net", "time", "rt"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -tokio = { version = "1.22.0" } +tokio = { version = "1.23.0" } [features] default = [] diff --git a/item_specs/tar_x/Cargo.toml b/item_specs/tar_x/Cargo.toml index 7952c6d03..5852af515 100644 --- a/item_specs/tar_x/Cargo.toml +++ b/item_specs/tar_x/Cargo.toml @@ -19,7 +19,7 @@ test = false derivative = { workspace = true } miette = { workspace = true, optional = true } peace = { path = "../..", version = "0.0.5" } -serde = { version = "1.0.147", features = ["derive"] } +serde = { version = "1.0.151", features = ["derive"] } # We use this instead of tokio-tar, because: # # * We expect tar extraction to be a compute operation. @@ -30,14 +30,14 @@ serde = { version = "1.0.147", features = ["derive"] } # # [SyncIoBridge]: https://docs.rs/tokio-util/latest/tokio_util/io/struct.SyncIoBridge.html tar = { workspace = true } -thiserror = "1.0.37" +thiserror = "1.0.38" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] futures = "0.3.25" -tokio = { version = "1.22.0", features = ["fs"] } +tokio = { version = "1.23.0", features = ["fs"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -tokio = { version = "1.22.0" } +tokio = { version = "1.23.0" } [features] default = [] diff --git a/workspace_tests/Cargo.toml b/workspace_tests/Cargo.toml index 0fd8ec324..3056efede 100644 --- a/workspace_tests/Cargo.toml +++ b/workspace_tests/Cargo.toml @@ -17,16 +17,16 @@ doctest = false test = true [dev-dependencies] -diff-struct = "0.5.0" +diff-struct = "0.5.1" peace = { path = "..", version = "0.0.5" } peace_item_specs = { path = "../item_specs", version = "0.0.5" } pretty_assertions = "1.3.0" -serde = { version = "1.0.147", features = ["derive"] } -serde_yaml = "0.9.14" +serde = { version = "1.0.151", features = ["derive"] } +serde_yaml = "0.9.16" tar = { workspace = true } tempfile = "3.3.0" -thiserror = "1.0.37" -tokio = { version = "1.22.0", features = ["rt", "macros"] } +thiserror = "1.0.38" +tokio = { version = "1.23.0", features = ["rt", "macros"] } [features] default = ["item_specs"] From 2836fe73559174073e479cc31e06d06e3e5fae69 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 24 Dec 2022 15:24:59 +1300 Subject: [PATCH 02/14] Update `CmdContextBuilder` to take in multiple workspace, profile, and flow params. --- Cargo.toml | 1 + crate/resources/Cargo.toml | 2 +- crate/rt_model/src/cmd_context.rs | 2 +- crate/rt_model/src/cmd_context_builder.rs | 393 +++++++----------- crate/rt_model/src/lib.rs | 4 +- crate/rt_model_core/Cargo.toml | 4 +- crate/rt_model_core/src/cmd_context_params.rs | 35 ++ .../src/cmd_context_params/flow_params.rs | 86 ++++ .../src/cmd_context_params/profile_params.rs | 88 ++++ .../cmd_context_params/workspace_params.rs | 88 ++++ crate/rt_model_core/src/lib.rs | 2 + crate/rt_model_native/src/native_storage.rs | 44 +- .../src/workspace_initializer.rs | 100 +++-- crate/rt_model_web/src/web_storage.rs | 4 +- 14 files changed, 571 insertions(+), 282 deletions(-) create mode 100644 crate/rt_model_core/src/cmd_context_params.rs create mode 100644 crate/rt_model_core/src/cmd_context_params/flow_params.rs create mode 100644 crate/rt_model_core/src/cmd_context_params/profile_params.rs create mode 100644 crate/rt_model_core/src/cmd_context_params/workspace_params.rs diff --git a/Cargo.toml b/Cargo.toml index edf469d22..862ea0fd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ members = [ miette = { version = "5.5.0" } derivative = "2.2.0" tar = "0.4.38" +type_reg = { version = "0.4.0", features = ["debug", "untagged", "ordered"] } [features] default = ["error_reporting", "output_colorized"] diff --git a/crate/resources/Cargo.toml b/crate/resources/Cargo.toml index d0b8796b6..98a3d0a0a 100644 --- a/crate/resources/Cargo.toml +++ b/crate/resources/Cargo.toml @@ -21,4 +21,4 @@ peace_data = { version = "0.0.5", path = "../data" } resman = { version = "0.15.0", features = ["debug"] } serde = { version = "1.0.151", features = ["derive"] } tokio = { version = "1.23.0", features = ["sync"] } -type_reg = { version = "0.4.0", features = ["debug", "untagged", "ordered"] } +type_reg = { workspace = true } diff --git a/crate/rt_model/src/cmd_context.rs b/crate/rt_model/src/cmd_context.rs index 2a8e81385..bcb743517 100644 --- a/crate/rt_model/src/cmd_context.rs +++ b/crate/rt_model/src/cmd_context.rs @@ -77,7 +77,7 @@ pub struct CmdContext<'ctx, E, O, TS> { impl<'ctx, E, O> CmdContext<'ctx, E, O, SetUp> where - E: std::error::Error, + E: std::error::Error + From, { /// Returns a builder for the command context. /// diff --git a/crate/rt_model/src/cmd_context_builder.rs b/crate/rt_model/src/cmd_context_builder.rs index aa0c127ae..862566c9a 100644 --- a/crate/rt_model/src/cmd_context_builder.rs +++ b/crate/rt_model/src/cmd_context_builder.rs @@ -1,4 +1,4 @@ -use std::{fmt, future::IntoFuture, marker::PhantomData, pin::Pin}; +use std::{fmt::Debug, future::IntoFuture, hash::Hash, marker::PhantomData, pin::Pin}; use futures::{Future, StreamExt, TryStreamExt}; use peace_resources::{ @@ -6,11 +6,13 @@ use peace_resources::{ paths::StatesSavedFile, resources::ts::{Empty, SetUp}, states::StatesSaved, + type_reg::untagged::{BoxDt, TypeReg}, Resources, }; use serde::{de::DeserializeOwned, Serialize}; use crate::{ + cmd_context_params::{FlowParams, ProfileParams, WorkspaceParams}, CmdContext, Error, ItemSpecGraph, StatesDeserializer, StatesTypeRegs, Storage, Workspace, WorkspaceInitializer, }; @@ -35,32 +37,9 @@ use crate::{ /// /// * `E`: Consumer provided error type. /// * `O`: `OutputWrite` to return values / errors to. -/// * `WorkspaceInit`: Parameters to initialize the workspace. -/// -/// These are parameters common to the workspace. Examples: -/// -/// - Organization username. -/// - Repository URL for multiple environments. -/// -/// This may be `()` if there are no parameters common to the workspace. -/// -/// * `ProfileInit`: Parameters to initialize the profile. -/// -/// These are parameters specific to a profile, but common to flows within -/// that profile. Examples: -/// -/// - Environment specific credentials. -/// - URL to publish / download an artifact. -/// -/// This may be `()` if there are no profile specific parameters. -/// -/// * `FlowInit`: Parameters to initialize the flow. -/// -/// These are parameters specific to a flow. Examples: -/// -/// - Configuration to skip warnings for the particular flow. -/// -/// This may be `()` if there are no flow specific parameters. +/// * `WorkspaceParamsK`: `WorkspaceParams` map `K` type parameter. +/// * `ProfileParamsK`: `ProfileParams` map `K` type parameter. +/// * `FlowParamsK`: `FlowParams` map `K` type parameter. /// /// [`Profile`]: peace_cfg::Profile /// [`WorkspaceDir`]: peace::resources::paths::WorkspaceDir @@ -68,24 +47,41 @@ use crate::{ /// [`ProfileDir`]: peace::resources::paths::ProfileDir /// [`ProfileHistoryDir`]: peace::resources::paths::ProfileHistoryDir #[derive(Debug)] -pub struct CmdContextBuilder<'ctx, E, O, WorkspaceInit, ProfileInit, FlowInit> { +pub struct CmdContextBuilder<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> +where + WorkspaceParamsK: Debug + Eq + Hash, + ProfileParamsK: Debug + Eq + Hash, + FlowParamsK: Debug + Eq + Hash, +{ /// Workspace that the `peace` tool runs in. workspace: &'ctx Workspace, /// Graph of item specs. item_spec_graph: &'ctx ItemSpecGraph, /// `OutputWrite` to return values / errors to. output: &'ctx mut O, - /// Workspace initialization parameters. - workspace_init_params: Option, - /// Profile initialization parameters. - profile_init_params: Option, - /// Flow initialization parameters. - flow_init_params: Option, + /// Workspace parameters. + workspace_params: Option>, + /// Type registry for `WorkspaceParams` deserialization. + workspace_params_type_reg: TypeReg, + /// Profile parameters. + profile_params: Option>, + /// Type registry for `ProfileParams` deserialization. + profile_params_type_reg: TypeReg, + /// Flow parameters. + flow_params: Option>, + /// Type registry for `FlowParams` deserialization. + flow_params_type_reg: TypeReg, } -impl<'ctx, E, O> CmdContextBuilder<'ctx, E, O, (), (), ()> +impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> + CmdContextBuilder<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> where - E: std::error::Error, + E: std::error::Error + From, + WorkspaceParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + ProfileParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, { /// Returns a builder for the command context. /// @@ -105,193 +101,115 @@ where workspace, item_spec_graph, output, - workspace_init_params: None, - profile_init_params: None, - flow_init_params: None, + workspace_params: None, + workspace_params_type_reg: TypeReg::new(), + profile_params: None, + profile_params_type_reg: TypeReg::new(), + flow_params: None, + flow_params_type_reg: TypeReg::new(), } } -} -impl<'ctx, E, O, ProfileInit, FlowInit> CmdContextBuilder<'ctx, E, O, (), ProfileInit, FlowInit> -where - E: std::error::Error, - ProfileInit: Clone + fmt::Debug + Send + Sync + 'static, - FlowInit: Clone + fmt::Debug + Send + Sync + 'static, -{ - /// Sets the workspace initialization parameters. - /// - /// The init param is optional in case the init parameters should be loaded - /// from storage. - /// - /// Type state enforces that this can only be set once. + /// Sets the workspace parameters. /// /// # Parameters /// - /// * `workspace_init_next`: The parameters to initialize the workspace. - pub fn with_workspace_init( - self, - workspace_init_next: Option, - ) -> CmdContextBuilder<'ctx, E, O, WorkspaceInitNext, ProfileInit, FlowInit> + /// * `k`: Key to store the parameter with. + /// * `workspace_param`: The workspace parameter to register. + pub fn with_workspace_param( + mut self, + k: WorkspaceParamsK, + workspace_param: WorkspaceParam, + ) -> Self where - WorkspaceInitNext: Clone + fmt::Debug + Send + Sync + 'static, + WorkspaceParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, { - let CmdContextBuilder { - workspace, - item_spec_graph, - output, - workspace_init_params: _, - profile_init_params, - flow_init_params, - } = self; - - CmdContextBuilder { - workspace, - item_spec_graph, - output, - workspace_init_params: workspace_init_next, - profile_init_params, - flow_init_params, - } + self.workspace_params_type_reg + .register::(k.clone()); + self.workspace_params + .get_or_insert_with(WorkspaceParams::new) + .insert(k, workspace_param); + self } -} -impl<'ctx, E, O, WorkspaceInit, FlowInit> CmdContextBuilder<'ctx, E, O, WorkspaceInit, (), FlowInit> -where - E: std::error::Error, - WorkspaceInit: Clone + fmt::Debug + Send + Sync + 'static, - FlowInit: Clone + fmt::Debug + Send + Sync + 'static, -{ - /// Sets the profile initialization parameters. - /// - /// The init param is optional in case the init parameters should be loaded - /// from storage. - /// - /// Type state enforces that this can only be set once. + /// Sets the profile parameters. /// /// # Parameters /// - /// * `profile_init_next`: The parameters to initialize the profile. - pub fn with_profile_init( - self, - profile_init_next: Option, - ) -> CmdContextBuilder<'ctx, E, O, WorkspaceInit, ProfileInitNext, FlowInit> + /// * `k`: Key to store the parameter with. + /// * `profile_param`: The profile parameter to register. + pub fn with_profile_param( + mut self, + k: ProfileParamsK, + profile_param: ProfileParam, + ) -> Self where - ProfileInitNext: Clone + fmt::Debug + Send + Sync + 'static, + ProfileParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, { - let CmdContextBuilder { - workspace, - item_spec_graph, - output, - workspace_init_params, - profile_init_params: _, - flow_init_params, - } = self; - - CmdContextBuilder { - workspace, - item_spec_graph, - output, - workspace_init_params, - profile_init_params: profile_init_next, - flow_init_params, - } + self.profile_params_type_reg + .register::(k.clone()); + self.profile_params + .get_or_insert_with(ProfileParams::new) + .insert(k, profile_param); + self } -} -impl<'ctx, E, O, WorkspaceInit, ProfileInit> - CmdContextBuilder<'ctx, E, O, WorkspaceInit, ProfileInit, ()> -where - E: std::error::Error, - WorkspaceInit: Clone + fmt::Debug + Send + Sync + 'static, - ProfileInit: Clone + fmt::Debug + Send + Sync + 'static, -{ - /// Sets the flow initialization parameters. - /// - /// The init param is optional in case the init parameters should be loaded - /// from storage. - /// - /// Type state enforces that this can only be set once. + /// Sets the flow parameters. /// /// # Parameters /// - /// * `flow_init_next`: The parameters to initialize the flow. - pub fn with_flow_init( - self, - flow_init_next: Option, - ) -> CmdContextBuilder<'ctx, E, O, WorkspaceInit, ProfileInit, FlowInitNext> + /// * `k`: Key to store the parameter with. + /// * `flow_param`: The flow parameter to register. + pub fn with_flow_param(mut self, k: FlowParamsK, flow_param: FlowParam) -> Self where - FlowInitNext: Clone + fmt::Debug + Send + Sync + 'static, + FlowParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, { - let CmdContextBuilder { - workspace, - item_spec_graph, - output, - workspace_init_params, - profile_init_params, - flow_init_params: _, - } = self; - - CmdContextBuilder { - workspace, - item_spec_graph, - output, - workspace_init_params, - profile_init_params, - flow_init_params: flow_init_next, - } + self.flow_params_type_reg.register::(k.clone()); + self.flow_params + .get_or_insert_with(FlowParams::new) + .insert(k, flow_param); + self } -} -impl<'ctx, E, O, WorkspaceInit, ProfileInit, FlowInit> - CmdContextBuilder<'ctx, E, O, WorkspaceInit, ProfileInit, FlowInit> -where - E: std::error::Error + From, - WorkspaceInit: Clone + fmt::Debug + DeserializeOwned + Serialize + Send + Sync + 'static, - ProfileInit: Clone + fmt::Debug + DeserializeOwned + Serialize + Send + Sync + 'static, - FlowInit: Clone + fmt::Debug + DeserializeOwned + Serialize + Send + Sync + 'static, -{ /// Prepares a workspace to run commands in. /// /// # Parameters /// - /// * `workspace_init_params`: Initialization parameters for the workspace. - /// * `profile_init_params`: Initialization parameters for the profile. - /// * `flow_init_params`: Initialization parameters for the flow. - pub async fn build(self) -> Result, E> { - let CmdContextBuilder { - workspace, - item_spec_graph, - output, - mut workspace_init_params, - mut profile_init_params, - mut flow_init_params, - } = self; - - let dirs = workspace.dirs(); - let storage = workspace.storage(); + /// * `workspace_params`: Initialization parameters for the workspace. + /// * `profile_params`: Initialization parameters for the profile. + /// * `flow_params`: Initialization parameters for the flow. + pub async fn build(mut self) -> Result, E> { + let dirs = self.workspace.dirs(); + let storage = self.workspace.storage(); let workspace_init_file = WorkspaceInitFile::from(dirs.peace_dir()); let profile_init_file = ProfileInitFile::from(dirs.profile_dir()); let flow_init_file = FlowInitFile::from(dirs.flow_dir()); let states_saved_file = StatesSavedFile::from(dirs.flow_dir()); // Read existing init params from storage. - Self::init_params_deserialize( + self.init_params_deserialize( storage, - &mut workspace_init_params, &workspace_init_file, - &mut profile_init_params, &profile_init_file, - &mut flow_init_params, &flow_init_file, ) .await?; + let CmdContextBuilder { + workspace, + item_spec_graph, + output, + workspace_params, + workspace_params_type_reg: _, + profile_params, + profile_params_type_reg: _, + flow_params, + flow_params_type_reg: _, + } = self; + // Create directories and write init parameters to storage. #[cfg(target_arch = "wasm32")] - WorkspaceInitializer::::dirs_initialize( - storage, dirs, - ) - .await?; + WorkspaceInitializer::dirs_initialize(storage, dirs).await?; #[cfg(not(target_arch = "wasm32"))] { let workspace_dir = dirs.workspace_dir(); @@ -300,17 +218,16 @@ where error, })?; - WorkspaceInitializer::::dirs_initialize(dirs) - .await?; + WorkspaceInitializer::dirs_initialize(dirs).await?; } Self::init_params_serialize( storage, - workspace_init_params.as_ref(), + workspace_params.as_ref(), &workspace_init_file, - profile_init_params.as_ref(), + profile_params.as_ref(), &profile_init_file, - flow_init_params.as_ref(), + flow_params.as_ref(), &flow_init_file, ) .await?; @@ -323,9 +240,9 @@ where resources.insert(flow_init_file); Self::init_params_insert( &mut resources, - workspace_init_params, - profile_init_params, - flow_init_params, + workspace_params, + profile_params, + flow_params, ); // Read existing states from storage. @@ -382,42 +299,51 @@ where /// [#45]: https://github.com/azriel91/peace/issues/45 fn init_params_insert( resources: &mut Resources, - workspace_init_params: Option, - profile_init_params: Option, - flow_init_params: Option, + workspace_params: Option>, + profile_params: Option>, + flow_params: Option>, ) { - if let Some(workspace_init_params) = workspace_init_params { - resources.insert(workspace_init_params); + if let Some(workspace_params) = workspace_params { + resources.insert(workspace_params); } - if let Some(profile_init_params) = profile_init_params { - resources.insert(profile_init_params); + if let Some(profile_params) = profile_params { + resources.insert(profile_params); } - if let Some(flow_init_params) = flow_init_params { - resources.insert(flow_init_params); + if let Some(flow_params) = flow_params { + resources.insert(flow_params); } } async fn init_params_deserialize( + &mut self, storage: &Storage, - workspace_init_params: &mut Option, workspace_init_file: &WorkspaceInitFile, - profile_init_params: &mut Option, profile_init_file: &ProfileInitFile, - flow_init_params: &mut Option, flow_init_file: &FlowInitFile, ) -> Result<(), E> { - if workspace_init_params.is_none() { - *workspace_init_params = - WorkspaceInitializer::::workspace_init_params_deserialize(storage, workspace_init_file) - .await? + if self.workspace_params.is_none() { + self.workspace_params = WorkspaceInitializer::workspace_params_deserialize( + storage, + &self.workspace_params_type_reg, + workspace_init_file, + ) + .await? }; - if profile_init_params.is_none() { - *profile_init_params = - WorkspaceInitializer::::profile_init_params_deserialize(storage, profile_init_file).await?; + if self.profile_params.is_none() { + self.profile_params = WorkspaceInitializer::profile_params_deserialize( + storage, + &self.profile_params_type_reg, + profile_init_file, + ) + .await?; } - if flow_init_params.is_none() { - *flow_init_params = - WorkspaceInitializer::::flow_init_params_deserialize(storage, flow_init_file).await?; + if self.flow_params.is_none() { + self.flow_params = WorkspaceInitializer::flow_params_deserialize( + storage, + &self.flow_params_type_reg, + flow_init_file, + ) + .await?; } Ok(()) @@ -426,46 +352,45 @@ where /// Serializes init params to storage. async fn init_params_serialize( storage: &Storage, - workspace_init_params: Option<&WorkspaceInit>, + workspace_params: Option<&WorkspaceParams>, workspace_init_file: &WorkspaceInitFile, - profile_init_params: Option<&ProfileInit>, + profile_params: Option<&ProfileParams>, profile_init_file: &ProfileInitFile, - flow_init_params: Option<&FlowInit>, + flow_params: Option<&FlowParams>, flow_init_file: &FlowInitFile, ) -> Result<(), E> { - if let Some(workspace_init_params) = workspace_init_params { - WorkspaceInitializer::::workspace_init_params_serialize( + if let Some(workspace_params) = workspace_params { + WorkspaceInitializer::workspace_params_serialize( storage, - workspace_init_params, + workspace_params, workspace_init_file, ) .await?; } - if let Some(profile_init_params) = profile_init_params { - WorkspaceInitializer::::profile_init_params_serialize( + if let Some(profile_params) = profile_params { + WorkspaceInitializer::profile_params_serialize( storage, - profile_init_params, + profile_params, profile_init_file, ) .await?; } - if let Some(flow_init_params) = flow_init_params { - WorkspaceInitializer::::flow_init_params_serialize( - storage, - flow_init_params, - flow_init_file, - ) - .await?; + if let Some(flow_params) = flow_params { + WorkspaceInitializer::flow_params_serialize(storage, flow_params, flow_init_file) + .await?; } Ok(()) } } -impl<'ctx, E, O, WorkspaceInit, ProfileInit, FlowInit> - CmdContextBuilder<'ctx, E, O, WorkspaceInit, ProfileInit, FlowInit> +impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> + CmdContextBuilder<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> where E: std::error::Error, + WorkspaceParamsK: Debug + Eq + Hash, + ProfileParamsK: Debug + Eq + Hash, + FlowParamsK: Debug + Eq + Hash, { /// Registers each item spec's `State` and `StateLogical` for /// deserialization. @@ -504,13 +429,15 @@ where pub type CmdContextFuture<'ctx, E, O> = Pin, E>> + 'ctx>>; -impl<'ctx, E, O, WorkspaceInit, ProfileInit, FlowInit> IntoFuture - for CmdContextBuilder<'ctx, E, O, WorkspaceInit, ProfileInit, FlowInit> +impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> IntoFuture + for CmdContextBuilder<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> where E: std::error::Error + From, - WorkspaceInit: Clone + fmt::Debug + DeserializeOwned + Serialize + Send + Sync + 'static, - ProfileInit: Clone + fmt::Debug + DeserializeOwned + Serialize + Send + Sync + 'static, - FlowInit: Clone + fmt::Debug + DeserializeOwned + Serialize + Send + Sync + 'static, + WorkspaceParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + ProfileParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, { type IntoFuture = CmdContextFuture<'ctx, E, O>; type Output = ::Output; diff --git a/crate/rt_model/src/lib.rs b/crate/rt_model/src/lib.rs index dcb58b327..8f9d79eb9 100644 --- a/crate/rt_model/src/lib.rs +++ b/crate/rt_model/src/lib.rs @@ -5,7 +5,9 @@ // Re-exports pub use fn_graph::{self, FnRef, FnRefMut}; -pub use peace_rt_model_core::{OutputFormat, OutputFormatParseError, OutputWrite}; +pub use peace_rt_model_core::{ + cmd_context_params, OutputFormat, OutputFormatParseError, OutputWrite, +}; pub use crate::{ cmd_context::CmdContext, cmd_context_builder::CmdContextBuilder, diff --git a/crate/rt_model_core/Cargo.toml b/crate/rt_model_core/Cargo.toml index ca3141ddb..fc726b6c8 100644 --- a/crate/rt_model_core/Cargo.toml +++ b/crate/rt_model_core/Cargo.toml @@ -17,9 +17,11 @@ test = false [dependencies] async-trait = "0.1.60" +miette = { workspace = true, optional = true } peace_resources = { path = "../resources", version = "0.0.5" } +serde = "1.0.151" serde_json = { version = "1.0.91", optional = true } -miette = { workspace = true, optional = true } +type_reg = { workspace = true } [features] default = [] diff --git a/crate/rt_model_core/src/cmd_context_params.rs b/crate/rt_model_core/src/cmd_context_params.rs new file mode 100644 index 000000000..701e11b63 --- /dev/null +++ b/crate/rt_model_core/src/cmd_context_params.rs @@ -0,0 +1,35 @@ +//! Serializable data to initialize resources in a `CmdContext`. +//! +//! Each of these are `TypeMap` newtypes, and are: +//! +//! * automatically serialized when a `CmdContext` is created with params. +//! * automatically deserialized and inserted as resources when subsequent +//! `CmdContext`s are created. +//! +//! # Intended Use +//! +//! [`WorkspaceParams`] are information that is shared across all profiles and +//! flows in a workspace, such as: +//! +//! * User ID +//! * Customer ID +//! +//! [`ProfilesParams`] are information that are shared across flows in within a +//! profile, but specific to a profile -- `dev`, `prod` -- such as: +//! +//! * Profile name +//! * Server hostnames +//! +//! [`FlowParams`] are information that are applicable to a flow -- `deploy`, +//! `config_fetch`, `clean` -- such as: +//! +//! * Server count: applicable to `deploy` +//! * Force remove: applicable to `clean` + +pub use self::{ + flow_params::FlowParams, profile_params::ProfileParams, workspace_params::WorkspaceParams, +}; + +mod flow_params; +mod profile_params; +mod workspace_params; diff --git a/crate/rt_model_core/src/cmd_context_params/flow_params.rs b/crate/rt_model_core/src/cmd_context_params/flow_params.rs new file mode 100644 index 000000000..3a0b1122d --- /dev/null +++ b/crate/rt_model_core/src/cmd_context_params/flow_params.rs @@ -0,0 +1,86 @@ +use std::{ + hash::Hash, + marker::PhantomData, + ops::{Deref, DerefMut}, +}; + +use serde::Serialize; +use type_reg::untagged::{BoxDt, TypeMap}; + +/// Information that is applicable to a flow. `TypeMap` newtype. +/// +/// The information may not be of the same type across flows, as flows are +/// different in what they are doing. Example information include: +/// +/// * Server count: applicable to `deploy` +/// * Force remove: applicable to `clean` +/// +/// # Type Parameters +/// +/// * `K`: Type of key for the `FlowParams` map. +#[derive(Debug, Serialize)] +#[serde(transparent)] // Needed to serialize as a map instead of a list. +pub struct FlowParams(TypeMap, PhantomData) +where + K: Eq + Hash; + +impl FlowParams +where + K: Eq + Hash, +{ + /// Returns a new `FlowParams` map. + pub fn new() -> Self { + Self::default() + } + + /// Creates an empty `FlowParams` map with the specified capacity. + /// + /// The `FlowParams` will be able to hold at least capacity elements + /// without reallocating. If capacity is 0, the map will not allocate. + pub fn with_capacity(capacity: usize) -> Self { + Self(TypeMap::with_capacity_typed(capacity), PhantomData) + } + + /// Returns the inner map. + pub fn into_inner(self) -> TypeMap { + self.0 + } +} + +impl Default for FlowParams +where + K: Eq + Hash, +{ + fn default() -> Self { + Self(TypeMap::default(), PhantomData) + } +} + +impl Deref for FlowParams +where + K: Eq + Hash, +{ + type Target = TypeMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for FlowParams +where + K: Eq + Hash, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From> for FlowParams +where + K: Eq + Hash, +{ + fn from(type_map: TypeMap) -> Self { + Self(type_map, PhantomData) + } +} diff --git a/crate/rt_model_core/src/cmd_context_params/profile_params.rs b/crate/rt_model_core/src/cmd_context_params/profile_params.rs new file mode 100644 index 000000000..a34001f19 --- /dev/null +++ b/crate/rt_model_core/src/cmd_context_params/profile_params.rs @@ -0,0 +1,88 @@ +use std::{ + hash::Hash, + marker::PhantomData, + ops::{Deref, DerefMut}, +}; + +use serde::Serialize; +use type_reg::untagged::{BoxDt, TypeMap}; + +/// Information that is shared across flows within a profile. `TypeMap` +/// newtype. +/// +/// Shared information are the ones that will not change when using different +/// flows. For example, deploying a set of servers, or exporting configuration +/// from those servers will use the same values for the following: +/// +/// * Profile name +/// * Server hostnames +/// +/// # Type Parameters +/// +/// * `K`: Type of key for the `ProfileParams` map. +#[derive(Debug, Serialize)] +#[serde(transparent)] // Needed to serialize as a map instead of a list. +pub struct ProfileParams(TypeMap, PhantomData) +where + K: Eq + Hash; + +impl ProfileParams +where + K: Eq + Hash, +{ + /// Returns a new `ProfileParams` map. + pub fn new() -> Self { + Self::default() + } + + /// Creates an empty `ProfileParams` map with the specified capacity. + /// + /// The `ProfileParams` will be able to hold at least capacity elements + /// without reallocating. If capacity is 0, the map will not allocate. + pub fn with_capacity(capacity: usize) -> Self { + Self(TypeMap::with_capacity_typed(capacity), PhantomData) + } + + /// Returns the inner map. + pub fn into_inner(self) -> TypeMap { + self.0 + } +} + +impl Default for ProfileParams +where + K: Eq + Hash, +{ + fn default() -> Self { + Self(TypeMap::default(), PhantomData) + } +} + +impl Deref for ProfileParams +where + K: Eq + Hash, +{ + type Target = TypeMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for ProfileParams +where + K: Eq + Hash, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From> for ProfileParams +where + K: Eq + Hash, +{ + fn from(type_map: TypeMap) -> Self { + Self(type_map, PhantomData) + } +} diff --git a/crate/rt_model_core/src/cmd_context_params/workspace_params.rs b/crate/rt_model_core/src/cmd_context_params/workspace_params.rs new file mode 100644 index 000000000..ac9ded412 --- /dev/null +++ b/crate/rt_model_core/src/cmd_context_params/workspace_params.rs @@ -0,0 +1,88 @@ +use std::{ + hash::Hash, + marker::PhantomData, + ops::{Deref, DerefMut}, +}; + +use serde::Serialize; +use type_reg::untagged::{BoxDt, TypeMap}; + +/// Information that is shared across all profiles and flows in a workspace. +/// `TypeMap` newtype. +/// +/// Shared information are the ones that will not change when switching to +/// different profiles. For example, a user working on a project for a +/// particular customer may use the following information across profiles: +/// +/// * User ID +/// * Customer ID +/// +/// # Type Parameters +/// +/// * `K`: Type of key for the `WorkspaceParams` map. +#[derive(Debug, Serialize)] +#[serde(transparent)] // Needed to serialize as a map instead of a list. +pub struct WorkspaceParams(TypeMap, PhantomData) +where + K: Eq + Hash; + +impl WorkspaceParams +where + K: Eq + Hash, +{ + /// Returns a new `WorkspaceParams` map. + pub fn new() -> Self { + Self::default() + } + + /// Creates an empty `WorkspaceParams` map with the specified capacity. + /// + /// The `WorkspaceParams` will be able to hold at least capacity elements + /// without reallocating. If capacity is 0, the map will not allocate. + pub fn with_capacity(capacity: usize) -> Self { + Self(TypeMap::with_capacity_typed(capacity), PhantomData) + } + + /// Returns the inner map. + pub fn into_inner(self) -> TypeMap { + self.0 + } +} + +impl Default for WorkspaceParams +where + K: Eq + Hash, +{ + fn default() -> Self { + Self(TypeMap::default(), PhantomData) + } +} + +impl Deref for WorkspaceParams +where + K: Eq + Hash, +{ + type Target = TypeMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for WorkspaceParams +where + K: Eq + Hash, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From> for WorkspaceParams +where + K: Eq + Hash, +{ + fn from(type_map: TypeMap) -> Self { + Self(type_map, PhantomData) + } +} diff --git a/crate/rt_model_core/src/lib.rs b/crate/rt_model_core/src/lib.rs index e24abc996..f8c80cf10 100644 --- a/crate/rt_model_core/src/lib.rs +++ b/crate/rt_model_core/src/lib.rs @@ -12,6 +12,8 @@ pub use crate::{ output_write::OutputWrite, }; +pub mod cmd_context_params; + mod output_format; mod output_format_parse_error; mod output_write; diff --git a/crate/rt_model_native/src/native_storage.rs b/crate/rt_model_native/src/native_storage.rs index 991b95ce8..37cb65b6a 100644 --- a/crate/rt_model_native/src/native_storage.rs +++ b/crate/rt_model_native/src/native_storage.rs @@ -1,5 +1,6 @@ -use std::{io::Write, path::Path, sync::Mutex}; +use std::{fmt::Debug, hash::Hash, io::Write, path::Path, sync::Mutex}; +use peace_resources::type_reg::untagged::{DataTypeWrapper, TypeMap, TypeReg}; use serde::{de::DeserializeOwned, Serialize}; use tokio::{ fs::File, @@ -60,7 +61,7 @@ impl NativeStorage { f_map_err: F, ) -> Result, Error> where - T: Serialize + DeserializeOwned + Send + Sync, + T: DeserializeOwned + Send + Sync, F: FnOnce(serde_yaml::Error) -> Error + Send, { if file_path.exists() { @@ -76,6 +77,43 @@ impl NativeStorage { } } + /// Deserializes a typemap from the given path if the file exists. + /// + /// # Parameters + /// + /// * `thread_name`: Name of the thread to use to do the read operation. + /// * `type_reg`: Type registry with the stateful deserialization mappings. + /// * `file_path`: Path to the file to read the serialized item. + /// * `f_map_err`: Maps the deserialization error (if any) to an [`Error`]. + pub async fn serialized_typemap_read_opt( + &self, + thread_name: String, + type_reg: &TypeReg, + file_path: &Path, + f_map_err: F, + ) -> Result, Error> + where + T: From> + Send + Sync, + K: Debug + DeserializeOwned + Eq + Hash + Sync, + BoxDT: DataTypeWrapper + 'static, + F: FnOnce(serde_yaml::Error) -> Error + Send, + { + if file_path.exists() { + let t = self + .read_with_sync_api(thread_name, file_path, |file| { + let deserializer = serde_yaml::Deserializer::from_reader(file); + let type_map = type_reg.deserialize_map(deserializer).map_err(f_map_err)?; + + Ok(T::from(type_map)) + }) + .await?; + + Ok(Some(t)) + } else { + Ok(None) + } + } + /// Writes a serializable item to the given path. /// /// # Parameters @@ -92,7 +130,7 @@ impl NativeStorage { f_map_err: F, ) -> Result<(), Error> where - T: Serialize + DeserializeOwned + Send + Sync, + T: Serialize + Send + Sync, F: FnOnce(serde_yaml::Error) -> Error + Send, { self.write_with_sync_api(thread_name, file_path, |file| { diff --git a/crate/rt_model_native/src/workspace_initializer.rs b/crate/rt_model_native/src/workspace_initializer.rs index 5892b78ff..079754b92 100644 --- a/crate/rt_model_native/src/workspace_initializer.rs +++ b/crate/rt_model_native/src/workspace_initializer.rs @@ -1,8 +1,12 @@ -use std::{iter, marker::PhantomData, path::Path}; +use std::{fmt::Debug, hash::Hash, iter, path::Path}; use futures::{stream, StreamExt, TryStreamExt}; -use peace_resources::internal::{FlowInitFile, ProfileInitFile, WorkspaceDirs, WorkspaceInitFile}; +use peace_resources::{ + internal::{FlowInitFile, ProfileInitFile, WorkspaceDirs, WorkspaceInitFile}, + type_reg::untagged::TypeReg, +}; +use peace_rt_model_core::cmd_context_params::{FlowParams, ProfileParams, WorkspaceParams}; use serde::{de::DeserializeOwned, Serialize}; use crate::{Error, NativeStorage}; @@ -38,17 +42,9 @@ use crate::{Error, NativeStorage}; /// /// This may be `()` if there are no flow specific parameters. #[derive(Debug)] -pub struct WorkspaceInitializer( - PhantomData<(WorkspaceInit, ProfileInit, FlowInit)>, -); +pub struct WorkspaceInitializer; -impl - WorkspaceInitializer -where - WorkspaceInit: Serialize + DeserializeOwned + Send + Sync + 'static, - ProfileInit: Serialize + DeserializeOwned + Send + Sync + 'static, - FlowInit: Serialize + DeserializeOwned + Send + Sync + 'static, -{ +impl WorkspaceInitializer { /// Creates directories used by the peace framework. pub async fn dirs_initialize(dirs: &WorkspaceDirs) -> Result<(), Error> { let dirs = iter::once(AsRef::::as_ref(dirs.workspace_dir())) @@ -70,84 +66,108 @@ where .await } - pub async fn workspace_init_params_serialize( + pub async fn workspace_params_serialize( storage: &NativeStorage, - workspace_init_params: &WorkspaceInit, + workspace_params: &WorkspaceParams, workspace_init_file: &WorkspaceInitFile, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + K: Eq + Hash + Serialize + Send + Sync, + { storage .serialized_write( - "workspace_init_params_serialize".to_string(), + "workspace_params_serialize".to_string(), workspace_init_file, - workspace_init_params, + workspace_params, Error::WorkspaceInitParamsSerialize, ) .await } - pub async fn workspace_init_params_deserialize( + pub async fn workspace_params_deserialize( storage: &NativeStorage, + type_reg: &TypeReg, workspace_init_file: &WorkspaceInitFile, - ) -> Result, Error> { + ) -> Result>, Error> + where + K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, + { storage - .serialized_read_opt( - "workspace_init_params_deserialize".to_string(), + .serialized_typemap_read_opt( + "workspace_params_deserialize".to_string(), + type_reg, workspace_init_file, - Error::FlowInitParamsDeserialize, + Error::WorkspaceInitParamsDeserialize, ) .await } - pub async fn profile_init_params_serialize( + pub async fn profile_params_serialize( storage: &NativeStorage, - profile_init_params: &ProfileInit, + profile_params: &ProfileParams, profile_init_file: &ProfileInitFile, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + K: Eq + Hash + Serialize + Send + Sync, + { storage .serialized_write( - "profile_init_params_serialize".to_string(), + "profile_params_serialize".to_string(), profile_init_file, - profile_init_params, + profile_params, Error::ProfileInitParamsSerialize, ) .await } - pub async fn profile_init_params_deserialize( + pub async fn profile_params_deserialize( storage: &NativeStorage, + type_reg: &TypeReg, profile_init_file: &ProfileInitFile, - ) -> Result, Error> { + ) -> Result>, Error> + where + K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, + { storage - .serialized_read_opt( - "profile_init_params_deserialize".to_string(), + .serialized_typemap_read_opt( + "profile_params_deserialize".to_string(), + type_reg, profile_init_file, Error::ProfileInitParamsDeserialize, ) .await } - pub async fn flow_init_params_serialize( + pub async fn flow_params_serialize( storage: &NativeStorage, - flow_init_params: &FlowInit, + flow_params: &FlowParams, flow_init_file: &FlowInitFile, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + K: Eq + Hash + Serialize + Send + Sync, + { storage .serialized_write( - "flow_init_params_serialize".to_string(), + "flow_params_serialize".to_string(), flow_init_file, - flow_init_params, + flow_params, Error::FlowInitParamsSerialize, ) .await } - pub async fn flow_init_params_deserialize( + pub async fn flow_params_deserialize( storage: &NativeStorage, + type_reg: &TypeReg, flow_init_file: &FlowInitFile, - ) -> Result, Error> { + ) -> Result>, Error> + where + K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, + { storage - .serialized_read_opt( - "flow_init_params_deserialize".to_string(), + .serialized_typemap_read_opt( + "flow_params_deserialize".to_string(), + type_reg, flow_init_file, Error::FlowInitParamsDeserialize, ) diff --git a/crate/rt_model_web/src/web_storage.rs b/crate/rt_model_web/src/web_storage.rs index 8b933bf57..3c0217ba0 100644 --- a/crate/rt_model_web/src/web_storage.rs +++ b/crate/rt_model_web/src/web_storage.rs @@ -313,7 +313,7 @@ impl WebStorage { f_map_err: F, ) -> Result, Error> where - T: Serialize + DeserializeOwned + Send + Sync, + T: DeserializeOwned + Send + Sync, F: FnOnce(serde_yaml::Error) -> Error + Send, { self.get_item_opt(path)? @@ -335,7 +335,7 @@ impl WebStorage { f_map_err: F, ) -> Result<(), Error> where - T: Serialize + DeserializeOwned + Send + Sync, + T: Serialize + Send + Sync, F: FnOnce(serde_yaml::Error) -> Error + Send, { self.set_item(path, &serde_yaml::to_string(t).map_err(f_map_err)?)?; From a450c61de1c8d72eece13d361ca83dbfd658129f Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 24 Dec 2022 22:10:13 +1300 Subject: [PATCH 03/14] Statically determine workspace/profile/flow params key based on param registration. --- crate/rt_model/src/cmd_context.rs | 6 +- crate/rt_model/src/cmd_context_builder.rs | 464 ++++++++++++++---- examples/app_cycle/src/flows/app_init_flow.rs | 36 +- examples/download/src/lib.rs | 2 +- .../src/item_specs/tar_x_item_spec.rs | 92 +++- .../src/rt_model/cmd_context_builder.rs | 21 +- 6 files changed, 477 insertions(+), 144 deletions(-) diff --git a/crate/rt_model/src/cmd_context.rs b/crate/rt_model/src/cmd_context.rs index bcb743517..79cef77d3 100644 --- a/crate/rt_model/src/cmd_context.rs +++ b/crate/rt_model/src/cmd_context.rs @@ -2,7 +2,9 @@ use std::marker::PhantomData; use peace_resources::{resources::ts::SetUp, Resources}; -use crate::{CmdContextBuilder, ItemSpecGraph, StatesTypeRegs, Workspace}; +use crate::{ + cmd_context_builder::KeyUnknown, CmdContextBuilder, ItemSpecGraph, StatesTypeRegs, Workspace, +}; /// Information needed to execute a command. /// @@ -92,7 +94,7 @@ where workspace: &'ctx Workspace, item_spec_graph: &'ctx ItemSpecGraph, output: &'ctx mut O, - ) -> CmdContextBuilder<'ctx, E, O, (), (), ()> { + ) -> CmdContextBuilder<'ctx, E, O, KeyUnknown, KeyUnknown, KeyUnknown> { CmdContextBuilder::new(workspace, item_spec_graph, output) } } diff --git a/crate/rt_model/src/cmd_context_builder.rs b/crate/rt_model/src/cmd_context_builder.rs index 862566c9a..c3b7c33c0 100644 --- a/crate/rt_model/src/cmd_context_builder.rs +++ b/crate/rt_model/src/cmd_context_builder.rs @@ -9,7 +9,7 @@ use peace_resources::{ type_reg::untagged::{BoxDt, TypeReg}, Resources, }; -use serde::{de::DeserializeOwned, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::{ cmd_context_params::{FlowParams, ProfileParams, WorkspaceParams}, @@ -47,11 +47,17 @@ use crate::{ /// [`ProfileDir`]: peace::resources::paths::ProfileDir /// [`ProfileHistoryDir`]: peace::resources::paths::ProfileHistoryDir #[derive(Debug)] -pub struct CmdContextBuilder<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> -where - WorkspaceParamsK: Debug + Eq + Hash, - ProfileParamsK: Debug + Eq + Hash, - FlowParamsK: Debug + Eq + Hash, +pub struct CmdContextBuilder< + 'ctx, + E, + O, + WorkspaceParamsKMaybe = KeyUnknown, + ProfileParamsKMaybe = KeyUnknown, + FlowParamsKMaybe = KeyUnknown, +> where + WorkspaceParamsKMaybe: KeyMaybe, + ProfileParamsKMaybe: KeyMaybe, + FlowParamsKMaybe: KeyMaybe, { /// Workspace that the `peace` tool runs in. workspace: &'ctx Workspace, @@ -60,28 +66,43 @@ where /// `OutputWrite` to return values / errors to. output: &'ctx mut O, /// Workspace parameters. - workspace_params: Option>, + workspace_params: Option>, /// Type registry for `WorkspaceParams` deserialization. - workspace_params_type_reg: TypeReg, + workspace_params_type_reg: TypeReg, /// Profile parameters. - profile_params: Option>, + profile_params: Option>, /// Type registry for `ProfileParams` deserialization. - profile_params_type_reg: TypeReg, + profile_params_type_reg: TypeReg, /// Flow parameters. - flow_params: Option>, + flow_params: Option>, /// Type registry for `FlowParams` deserialization. - flow_params_type_reg: TypeReg, + flow_params_type_reg: TypeReg, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct KeyUnknown; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct KeyKnown(PhantomData); + +pub trait KeyMaybe { + type Key: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static; +} + +impl KeyMaybe for KeyUnknown { + type Key = (); } -impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> - CmdContextBuilder<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> +impl KeyMaybe for KeyKnown +where + K: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, +{ + type Key = K; +} + +impl<'ctx, E, O> CmdContextBuilder<'ctx, E, O, KeyUnknown, KeyUnknown, KeyUnknown> where E: std::error::Error + From, - WorkspaceParamsK: - Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, - ProfileParamsK: - Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, - FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, { /// Returns a builder for the command context. /// @@ -109,68 +130,16 @@ where flow_params_type_reg: TypeReg::new(), } } +} - /// Sets the workspace parameters. - /// - /// # Parameters - /// - /// * `k`: Key to store the parameter with. - /// * `workspace_param`: The workspace parameter to register. - pub fn with_workspace_param( - mut self, - k: WorkspaceParamsK, - workspace_param: WorkspaceParam, - ) -> Self - where - WorkspaceParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, - { - self.workspace_params_type_reg - .register::(k.clone()); - self.workspace_params - .get_or_insert_with(WorkspaceParams::new) - .insert(k, workspace_param); - self - } - - /// Sets the profile parameters. - /// - /// # Parameters - /// - /// * `k`: Key to store the parameter with. - /// * `profile_param`: The profile parameter to register. - pub fn with_profile_param( - mut self, - k: ProfileParamsK, - profile_param: ProfileParam, - ) -> Self - where - ProfileParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, - { - self.profile_params_type_reg - .register::(k.clone()); - self.profile_params - .get_or_insert_with(ProfileParams::new) - .insert(k, profile_param); - self - } - - /// Sets the flow parameters. - /// - /// # Parameters - /// - /// * `k`: Key to store the parameter with. - /// * `flow_param`: The flow parameter to register. - pub fn with_flow_param(mut self, k: FlowParamsK, flow_param: FlowParam) -> Self - where - FlowParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, - { - self.flow_params_type_reg.register::(k.clone()); - self.flow_params - .get_or_insert_with(FlowParams::new) - .insert(k, flow_param); - self - } - +impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsKMaybe> + CmdContextBuilder<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsKMaybe> +where + E: std::error::Error + From, + WorkspaceParamsKMaybe: KeyMaybe, + ProfileParamsKMaybe: KeyMaybe, + FlowParamsKMaybe: KeyMaybe, +{ /// Prepares a workspace to run commands in. /// /// # Parameters @@ -299,9 +268,9 @@ where /// [#45]: https://github.com/azriel91/peace/issues/45 fn init_params_insert( resources: &mut Resources, - workspace_params: Option>, - profile_params: Option>, - flow_params: Option>, + workspace_params: Option>, + profile_params: Option>, + flow_params: Option>, ) { if let Some(workspace_params) = workspace_params { resources.insert(workspace_params); @@ -352,11 +321,11 @@ where /// Serializes init params to storage. async fn init_params_serialize( storage: &Storage, - workspace_params: Option<&WorkspaceParams>, + workspace_params: Option<&WorkspaceParams>, workspace_init_file: &WorkspaceInitFile, - profile_params: Option<&ProfileParams>, + profile_params: Option<&ProfileParams>, profile_init_file: &ProfileInitFile, - flow_params: Option<&FlowParams>, + flow_params: Option<&FlowParams>, flow_init_file: &FlowInitFile, ) -> Result<(), E> { if let Some(workspace_params) = workspace_params { @@ -384,13 +353,13 @@ where } } -impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> - CmdContextBuilder<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> +impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsKMaybe> + CmdContextBuilder<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsKMaybe> where E: std::error::Error, - WorkspaceParamsK: Debug + Eq + Hash, - ProfileParamsK: Debug + Eq + Hash, - FlowParamsK: Debug + Eq + Hash, + WorkspaceParamsKMaybe: KeyMaybe, + ProfileParamsKMaybe: KeyMaybe, + FlowParamsKMaybe: KeyMaybe, { /// Registers each item spec's `State` and `StateLogical` for /// deserialization. @@ -429,20 +398,321 @@ where pub type CmdContextFuture<'ctx, E, O> = Pin, E>> + 'ctx>>; -impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> IntoFuture - for CmdContextBuilder<'ctx, E, O, WorkspaceParamsK, ProfileParamsK, FlowParamsK> +impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsKMaybe> IntoFuture + for CmdContextBuilder<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsKMaybe> +where + E: std::error::Error + From, + WorkspaceParamsKMaybe: KeyMaybe + 'ctx, + ProfileParamsKMaybe: KeyMaybe + 'ctx, + FlowParamsKMaybe: KeyMaybe + 'ctx, +{ + type IntoFuture = CmdContextFuture<'ctx, E, O>; + type Output = ::Output; + + fn into_future(self) -> Self::IntoFuture { + Box::pin(self.build()) + } +} + +// Crazy stuff for ergonomic API usage + +impl<'ctx, E, O, ProfileParamsKMaybe, FlowParamsKMaybe> + CmdContextBuilder<'ctx, E, O, KeyUnknown, ProfileParamsKMaybe, FlowParamsKMaybe> +where + E: std::error::Error + From, + ProfileParamsKMaybe: KeyMaybe, + FlowParamsKMaybe: KeyMaybe, +{ + /// Adds a workspace parameter. + /// + /// # Parameters + /// + /// * `k`: Key to store the parameter with. + /// * `workspace_param`: The workspace parameter to register. + pub fn with_workspace_param( + self, + k: WorkspaceParamsK, + workspace_param: WorkspaceParam, + ) -> CmdContextBuilder< + 'ctx, + E, + O, + KeyKnown, + ProfileParamsKMaybe, + FlowParamsKMaybe, + > + where + WorkspaceParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + WorkspaceParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, + { + let Self { + workspace, + item_spec_graph, + output, + workspace_params: _, + workspace_params_type_reg: _, + profile_params, + profile_params_type_reg, + flow_params, + flow_params_type_reg, + } = self; + + let mut workspace_params_type_reg = TypeReg::::new(); + workspace_params_type_reg.register::(k.clone()); + let mut workspace_params = WorkspaceParams::::new(); + workspace_params.insert(k, workspace_param); + + CmdContextBuilder { + workspace, + item_spec_graph, + output, + workspace_params: Some(workspace_params), + workspace_params_type_reg, + profile_params, + profile_params_type_reg, + flow_params, + flow_params_type_reg, + } + } +} + +impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> + CmdContextBuilder<'ctx, E, O, KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe> where E: std::error::Error + From, WorkspaceParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + ProfileParamsKMaybe: KeyMaybe, + FlowParamsKMaybe: KeyMaybe, +{ + /// Adds a workspace parameter. + /// + /// # Parameters + /// + /// * `k`: Key to store the parameter with. + /// * `workspace_param`: The workspace parameter to register. + pub fn with_workspace_param( + mut self, + k: WorkspaceParamsK, + workspace_param: WorkspaceParam, + ) -> CmdContextBuilder< + 'ctx, + E, + O, + KeyKnown, + ProfileParamsKMaybe, + FlowParamsKMaybe, + > + where + WorkspaceParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, + { + self.workspace_params_type_reg + .register::(k.clone()); + if let Some(workspace_params) = self.workspace_params.as_mut() { + workspace_params.insert(k, workspace_param); + } + + self + } +} + +impl<'ctx, E, O, WorkflowParamsKMaybe, FlowParamsKMaybe> + CmdContextBuilder<'ctx, E, O, WorkflowParamsKMaybe, KeyUnknown, FlowParamsKMaybe> +where + E: std::error::Error + From, + WorkflowParamsKMaybe: KeyMaybe, + FlowParamsKMaybe: KeyMaybe, +{ + /// Adds a profile parameter. + /// + /// # Parameters + /// + /// * `k`: Key to store the parameter with. + /// * `profile_param`: The profile parameter to register. + pub fn with_profile_param( + self, + k: ProfileParamsK, + profile_param: ProfileParam, + ) -> CmdContextBuilder< + 'ctx, + E, + O, + WorkflowParamsKMaybe, + KeyKnown, + FlowParamsKMaybe, + > + where + ProfileParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + ProfileParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, + { + let Self { + workspace, + item_spec_graph, + output, + workspace_params, + workspace_params_type_reg, + profile_params: _, + profile_params_type_reg: _, + flow_params, + flow_params_type_reg, + } = self; + + let mut profile_params_type_reg = TypeReg::::new(); + profile_params_type_reg.register::(k.clone()); + let mut profile_params = ProfileParams::::new(); + profile_params.insert(k, profile_param); + + CmdContextBuilder { + workspace, + item_spec_graph, + output, + workspace_params, + workspace_params_type_reg, + profile_params: Some(profile_params), + profile_params_type_reg, + flow_params, + flow_params_type_reg, + } + } +} + +impl<'ctx, E, O, WorkflowParamsKMaybe, ProfileParamsK, FlowParamsKMaybe> + CmdContextBuilder<'ctx, E, O, WorkflowParamsKMaybe, KeyKnown, FlowParamsKMaybe> +where + E: std::error::Error + From, + WorkflowParamsKMaybe: KeyMaybe, ProfileParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + FlowParamsKMaybe: KeyMaybe, +{ + /// Adds a profile parameter. + /// + /// # Parameters + /// + /// * `k`: Key to store the parameter with. + /// * `profile_param`: The profile parameter to register. + pub fn with_profile_param( + mut self, + k: ProfileParamsK, + profile_param: ProfileParam, + ) -> CmdContextBuilder< + 'ctx, + E, + O, + WorkflowParamsKMaybe, + KeyKnown, + FlowParamsKMaybe, + > + where + ProfileParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, + { + self.profile_params_type_reg + .register::(k.clone()); + if let Some(profile_params) = self.profile_params.as_mut() { + profile_params.insert(k, profile_param); + } + + self + } +} + +impl<'ctx, E, O, WorkflowParamsKMaybe, ProfileParamsKMaybe> + CmdContextBuilder<'ctx, E, O, WorkflowParamsKMaybe, ProfileParamsKMaybe, KeyUnknown> +where + E: std::error::Error + From, + WorkflowParamsKMaybe: KeyMaybe, + ProfileParamsKMaybe: KeyMaybe, +{ + /// Adds a flow parameter. + /// + /// # Parameters + /// + /// * `k`: Key to store the parameter with. + /// * `flow_param`: The flow parameter to register. + pub fn with_flow_param( + self, + k: FlowParamsK, + flow_param: FlowParam, + ) -> CmdContextBuilder< + 'ctx, + E, + O, + WorkflowParamsKMaybe, + ProfileParamsKMaybe, + KeyKnown, + > + where + FlowParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, + FlowParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, + { + let Self { + workspace, + item_spec_graph, + output, + workspace_params, + workspace_params_type_reg, + profile_params, + profile_params_type_reg, + flow_params: _, + flow_params_type_reg: _, + } = self; + + let mut flow_params_type_reg = TypeReg::::new(); + flow_params_type_reg.register::(k.clone()); + let mut flow_params = FlowParams::::new(); + flow_params.insert(k, flow_param); + + CmdContextBuilder { + workspace, + item_spec_graph, + output, + workspace_params, + workspace_params_type_reg, + profile_params, + profile_params_type_reg, + flow_params: Some(flow_params), + flow_params_type_reg, + } + } +} + +impl<'ctx, E, O, WorkflowParamsKMaybe, ProfileParamsKMaybe, FlowParamsK> + CmdContextBuilder<'ctx, E, O, WorkflowParamsKMaybe, ProfileParamsKMaybe, KeyKnown> +where + E: std::error::Error + From, + WorkflowParamsKMaybe: KeyMaybe, + ProfileParamsKMaybe: KeyMaybe, FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, { - type IntoFuture = CmdContextFuture<'ctx, E, O>; - type Output = ::Output; + /// Adds a flow parameter. + /// + /// # Parameters + /// + /// * `k`: Key to store the parameter with. + /// * `flow_param`: The flow parameter to register. + pub fn with_flow_param( + mut self, + k: FlowParamsK, + flow_param: FlowParam, + ) -> CmdContextBuilder< + 'ctx, + E, + O, + WorkflowParamsKMaybe, + ProfileParamsKMaybe, + KeyKnown, + > + where + FlowParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, + { + self.flow_params_type_reg.register::(k.clone()); + if let Some(flow_params) = self.flow_params.as_mut() { + flow_params.insert(k, flow_param); + } - fn into_future(self) -> Self::IntoFuture { - Box::pin(self.build()) + self } } diff --git a/examples/app_cycle/src/flows/app_init_flow.rs b/examples/app_cycle/src/flows/app_init_flow.rs index 0df77d730..0991f830d 100644 --- a/examples/app_cycle/src/flows/app_init_flow.rs +++ b/examples/app_cycle/src/flows/app_init_flow.rs @@ -7,7 +7,7 @@ use peace::{ }; use peace_item_specs::{ file_download::{FileDownloadItemSpec, FileDownloadParams}, - tar_x::TarXItemSpec, + tar_x::{TarXItemSpec, TarXParams}, }; use crate::model::{AppCycleError, WebAppFileId}; @@ -20,7 +20,7 @@ impl AppInitFlow { /// Sets up this workspace pub async fn run( output: &mut O, - app_cycle_file_download_params: FileDownloadParams, + web_app_file_download_params: FileDownloadParams, ) -> Result<(), AppCycleError> where O: OutputWrite, @@ -35,22 +35,38 @@ impl AppInitFlow { )?; let graph = Self::graph()?; + let web_app_tar_x_params = { + let tar_path = web_app_file_download_params.dest().to_path_buf(); + let dest = web_app_file_download_params.dest().join("web_app"); // TODO: get the name + + TarXParams::::new(tar_path, dest) + }; + let cmd_context = CmdContext::builder(&workspace, &graph, output) - .with_workspace_init::>(Some( - app_cycle_file_download_params, - )) + .with_workspace_param( + "web_app_file_download_params".to_string(), + Some(web_app_file_download_params), + ) + .with_workspace_param( + "web_app_tar_x_params".to_string(), + Some(web_app_tar_x_params), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, output) - .with_workspace_init::>(None) + .with_workspace_param( + "web_app_file_download_params".to_string(), + None::>, + ) + .with_workspace_param( + "web_app_tar_x_params".to_string(), + None::>, + ) .await?; EnsureCmd::exec(cmd_context).await?; - todo!( - "add `TarXParams` to command context somehow. \ - See " - ); + Ok(()) } fn graph() -> Result, AppCycleError> { diff --git a/examples/download/src/lib.rs b/examples/download/src/lib.rs index d269b087d..af30da232 100644 --- a/examples/download/src/lib.rs +++ b/examples/download/src/lib.rs @@ -94,7 +94,7 @@ where item_spec_graph, } = workspace_and_graph; CmdContext::builder(workspace, item_spec_graph, output) - .with_profile_init(file_download_params) + .with_profile_param("file_download_params".to_string(), file_download_params) .await } diff --git a/workspace_tests/src/item_specs/tar_x_item_spec.rs b/workspace_tests/src/item_specs/tar_x_item_spec.rs index 01f0a4f70..8cf255155 100644 --- a/workspace_tests/src/item_specs/tar_x_item_spec.rs +++ b/workspace_tests/src/item_specs/tar_x_item_spec.rs @@ -54,7 +54,10 @@ async fn state_current_returns_empty_file_metadatas_when_extraction_folder_not_e } = test_env(TAR_X2_TAR).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; let CmdContext { resources, .. } = StatesCurrentDiscoverCmd::exec(cmd_context).await?; @@ -87,7 +90,10 @@ async fn state_current_returns_file_metadatas_when_extraction_folder_contains_fi tar::Archive::new(Cursor::new(TAR_X2_TAR)).unpack(&dest)?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; let CmdContext { resources, .. } = StatesCurrentDiscoverCmd::exec(cmd_context).await?; @@ -121,7 +127,10 @@ async fn state_desired_returns_file_metadatas_from_tar() -> Result<(), Box::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; let CmdContext { resources, .. } = StatesDesiredDiscoverCmd::exec(cmd_context).await?; @@ -156,12 +165,15 @@ async fn state_diff_includes_added_when_file_in_tar_is_not_in_dest() let d_path = PathBuf::from("sub").join("d"); let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = DiffCmd::exec(cmd_context).await?; let state_diffs = resources.borrow::(); @@ -203,12 +215,15 @@ async fn state_diff_includes_added_when_file_in_tar_is_not_in_dest_and_dest_file tar::Archive::new(Cursor::new(TAR_X1_TAR)).unpack(&dest)?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = DiffCmd::exec(cmd_context).await?; let state_diffs = resources.borrow::(); @@ -252,12 +267,15 @@ async fn state_diff_includes_removed_when_file_in_dest_is_not_in_tar_and_tar_fil tar::Archive::new(Cursor::new(TAR_X2_TAR)).unpack(&dest)?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = DiffCmd::exec(cmd_context).await?; let state_diffs = resources.borrow::(); @@ -299,12 +317,15 @@ async fn state_diff_includes_removed_when_file_in_dest_is_not_in_tar_and_tar_fil tar::Archive::new(Cursor::new(TAR_X2_TAR)).unpack(&dest)?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = DiffCmd::exec(cmd_context).await?; let state_diffs = resources.borrow::(); @@ -351,12 +372,15 @@ async fn state_diff_includes_modified_when_dest_mtime_is_different() let d_path = PathBuf::from("sub").join("d"); let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = DiffCmd::exec(cmd_context).await?; let state_diffs = resources.borrow::(); @@ -397,12 +421,15 @@ async fn state_diff_returns_extraction_in_sync_when_tar_and_dest_in_sync() tar::Archive::new(Cursor::new(TAR_X2_TAR)).unpack(&dest)?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = DiffCmd::exec(cmd_context).await?; let state_diffs = resources.borrow::(); @@ -430,7 +457,10 @@ async fn ensure_check_returns_exec_not_required_when_tar_and_dest_in_sync() tar::Archive::new(Cursor::new(TAR_X2_TAR)).unpack(&dest)?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; let CmdContext { resources, .. } = StatesDiscoverCmd::exec(cmd_context).await?; let states_current = resources.borrow::(); @@ -439,7 +469,7 @@ async fn ensure_check_returns_exec_not_required_when_tar_and_dest_in_sync() .unwrap(); let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = DiffCmd::exec(cmd_context).await?; let states_desired = resources.borrow::(); @@ -475,12 +505,15 @@ async fn ensure_unpacks_tar_when_files_not_exists() -> Result<(), Box::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = EnsureCmd::exec(cmd_context).await?; @@ -524,13 +557,16 @@ async fn ensure_removes_other_files_and_is_idempotent() -> Result<(), Box::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; // Overwrite changed files and remove extra files let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = EnsureCmd::exec(cmd_context).await?; @@ -549,7 +585,7 @@ async fn ensure_removes_other_files_and_is_idempotent() -> Result<(), Box>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = EnsureCmd::exec(cmd_context).await?; @@ -582,7 +618,10 @@ async fn clean_check_returns_exec_not_required_when_dest_empty() } = test_env(TAR_X2_TAR).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init(Some(TarXParams::::new(tar_path, dest))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest)), + ) .await?; let CmdContext { resources, .. } = StatesDiscoverCmd::exec(cmd_context).await?; let states_current = resources.borrow::(); @@ -614,12 +653,15 @@ async fn clean_removes_files_in_dest_directory() -> Result<(), Box::new(tar_path, dest.clone()))) + .with_flow_param( + "param".to_string(), + Some(TarXParams::::new(tar_path, dest.clone())), + ) .await?; StatesDiscoverCmd::exec(cmd_context).await?; let cmd_context = CmdContext::builder(&workspace, &graph, &mut output) - .with_flow_init::>(None) + .with_flow_param("param".to_string(), None::>) .await?; let CmdContext { resources, .. } = CleanCmd::exec(cmd_context).await?; diff --git a/workspace_tests/src/rt_model/cmd_context_builder.rs b/workspace_tests/src/rt_model/cmd_context_builder.rs index 6041deb24..837e1cd13 100644 --- a/workspace_tests/src/rt_model/cmd_context_builder.rs +++ b/workspace_tests/src/rt_model/cmd_context_builder.rs @@ -51,7 +51,7 @@ async fn build_inserts_workspace_init_params_from_parameter() let (_tempdir, workspace, graph, mut output) = test_setup().await?; let CmdContext { resources, .. } = CmdContextBuilder::new(&workspace, &graph, &mut output) - .with_workspace_init(Some("workspace_init".to_string())) + .with_workspace_param("param".to_string(), Some("workspace_init".to_string())) .await?; let workspace_init_file = resources.borrow::(); let workspace_init = resources.borrow::(); @@ -70,12 +70,13 @@ async fn build_inserts_workspace_init_params_from_storage() -> Result<(), Box(None) + .with_workspace_param("param1".to_string(), Option::::None) + .with_workspace_param("param2".to_string(), Option::::None) .await?; let workspace_init_file = resources.borrow::(); let workspace_init = resources.borrow::(); @@ -95,7 +96,7 @@ async fn build_inserts_profile_init_params_from_parameter() -> Result<(), Box(); let profile_init = resources.borrow::(); @@ -114,12 +115,13 @@ async fn build_inserts_profile_init_params_from_storage() -> Result<(), Box(None) + .with_profile_param("param1".to_string(), None::) + .with_profile_param("param2".to_string(), None::) .await?; let profile_init_file = resources.borrow::(); let profile_init = resources.borrow::(); @@ -138,7 +140,7 @@ async fn build_inserts_flow_init_params_from_parameter() -> Result<(), Box(); let flow_init = resources.borrow::(); @@ -156,12 +158,13 @@ async fn build_inserts_flow_init_params_from_parameter() -> Result<(), Box Result<(), Box> { let (_tempdir, workspace, graph, mut output) = test_setup().await?; let _cmd_context = CmdContextBuilder::new(&workspace, &graph, &mut output) - .with_flow_init(Some("flow_init".to_string())) + .with_flow_param("param1".to_string(), Some("flow_init".to_string())) .await?; // Create another CmdContext, this time using no parameter. let CmdContext { resources, .. } = CmdContextBuilder::new(&workspace, &graph, &mut output) - .with_flow_init::(None) + .with_flow_param("param1".to_string(), None::) + .with_flow_param("param2".to_string(), None::) .await?; let flow_init_file = resources.borrow::(); let flow_init = resources.borrow::(); From e90a61ddfb921f15bf233880427da2d759ac5ca3 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Mon, 26 Dec 2022 16:30:05 +1300 Subject: [PATCH 04/14] Update dependency versions. --- Cargo.toml | 2 +- crate/data/Cargo.toml | 2 +- crate/resources/Cargo.toml | 2 +- crate/rt_model/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 862ea0fd8..3e28cc0de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ members = [ miette = { version = "5.5.0" } derivative = "2.2.0" tar = "0.4.38" -type_reg = { version = "0.4.0", features = ["debug", "untagged", "ordered"] } +type_reg = { version = "0.5.0", features = ["debug", "untagged", "ordered"] } [features] default = ["error_reporting", "output_colorized"] diff --git a/crate/data/Cargo.toml b/crate/data/Cargo.toml index 51104ebf3..2f1dfdfe0 100644 --- a/crate/data/Cargo.toml +++ b/crate/data/Cargo.toml @@ -16,5 +16,5 @@ doctest = false test = false [dependencies] -fn_graph = { version = "0.5.4", features = ["resman"] } +fn_graph = { version = "0.6.0", features = ["resman"] } peace_data_derive = { path = "../data_derive", version = "0.0.5" } diff --git a/crate/resources/Cargo.toml b/crate/resources/Cargo.toml index 98a3d0a0a..c84937019 100644 --- a/crate/resources/Cargo.toml +++ b/crate/resources/Cargo.toml @@ -18,7 +18,7 @@ test = false [dependencies] peace_core = { version = "0.0.5", path = "../core" } peace_data = { version = "0.0.5", path = "../data" } -resman = { version = "0.15.0", features = ["debug"] } +resman = { version = "0.16.0", features = ["debug"] } serde = { version = "1.0.151", features = ["derive"] } tokio = { version = "1.23.0", features = ["sync"] } type_reg = { workspace = true } diff --git a/crate/rt_model/Cargo.toml b/crate/rt_model/Cargo.toml index d38a8e26c..15cc1587a 100644 --- a/crate/rt_model/Cargo.toml +++ b/crate/rt_model/Cargo.toml @@ -16,7 +16,7 @@ doctest = false test = false [dependencies] -fn_graph = { version = "0.5.4", features = ["resman"] } +fn_graph = { version = "0.6.0", features = ["resman"] } futures = "0.3.25" miette = { workspace = true, optional = true } peace_cfg = { path = "../cfg", version = "0.0.5" } From cf1f60e7856b9df9883afcdcc2ff2c647eee0f0b Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Mon, 26 Dec 2022 16:29:33 +1300 Subject: [PATCH 05/14] Support multiple workspace, profile, and flow params. --- .github/workflows/ci.yml | 3 - crate/rt_model/src/cmd_context_builder.rs | 194 ++++++++++-------- crate/rt_model_core/Cargo.toml | 2 +- .../src/rt_model/cmd_context_builder.rs | 91 +++++++- 4 files changed, 196 insertions(+), 94 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b29a77943..54dc07bb2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,9 +78,6 @@ jobs: override: true components: clippy - - name: Install Clippy - run: rustup component add clippy - - # FIXME: Switch back when actions-rs/cargo#217 gets merged uses: r3-os/actions-rust-cargo@fb222fe18dc90e381546d012f9e3d6f353f0f627 with: diff --git a/crate/rt_model/src/cmd_context_builder.rs b/crate/rt_model/src/cmd_context_builder.rs index c3b7c33c0..12264d7b8 100644 --- a/crate/rt_model/src/cmd_context_builder.rs +++ b/crate/rt_model/src/cmd_context_builder.rs @@ -1,5 +1,6 @@ use std::{fmt::Debug, future::IntoFuture, hash::Hash, marker::PhantomData, pin::Pin}; +use fn_graph::resman::Resource; use futures::{Future, StreamExt, TryStreamExt}; use peace_resources::{ internal::{FlowInitFile, ProfileInitFile, WorkspaceInitFile}, @@ -164,18 +165,6 @@ where ) .await?; - let CmdContextBuilder { - workspace, - item_spec_graph, - output, - workspace_params, - workspace_params_type_reg: _, - profile_params, - profile_params_type_reg: _, - flow_params, - flow_params_type_reg: _, - } = self; - // Create directories and write init parameters to storage. #[cfg(target_arch = "wasm32")] WorkspaceInitializer::dirs_initialize(storage, dirs).await?; @@ -190,29 +179,33 @@ where WorkspaceInitializer::dirs_initialize(dirs).await?; } - Self::init_params_serialize( + self.init_params_serialize( storage, - workspace_params.as_ref(), &workspace_init_file, - profile_params.as_ref(), &profile_init_file, - flow_params.as_ref(), &flow_init_file, ) .await?; // Track items in memory. let mut resources = Resources::new(); + self.init_params_insert(&mut resources); + let CmdContextBuilder { + workspace, + item_spec_graph, + output, + workspace_params: _, + workspace_params_type_reg: _, + profile_params: _, + profile_params_type_reg: _, + flow_params: _, + flow_params_type_reg: _, + } = self; + Self::workspace_dirs_insert(&mut resources, workspace); resources.insert(workspace_init_file); resources.insert(profile_init_file); resources.insert(flow_init_file); - Self::init_params_insert( - &mut resources, - workspace_params, - profile_params, - flow_params, - ); // Read existing states from storage. let states_type_regs = Self::states_type_regs(item_spec_graph); @@ -258,28 +251,30 @@ where } /// Inserts init params into the `Resources` map. - /// - /// **TODO:** Multiple Init Params Support ([#45]) - /// - /// Implementors may wish to take in init parameters that are relevant to - /// different `ItemSpec`s, and so each init parameter needs to be able to be - /// mapped to multiple different data types. - /// - /// [#45]: https://github.com/azriel91/peace/issues/45 - fn init_params_insert( - resources: &mut Resources, - workspace_params: Option>, - profile_params: Option>, - flow_params: Option>, - ) { - if let Some(workspace_params) = workspace_params { - resources.insert(workspace_params); + fn init_params_insert(&mut self, resources: &mut Resources) { + // TODO: we need to insert the raw type, right now we're inserting the box + if let Some(workspace_params) = self.workspace_params.as_mut() { + workspace_params + .drain(..) + .for_each(|(_key, workspace_param)| { + let workspace_param = workspace_param.into_inner().upcast(); + let type_id = Resource::type_id(&*workspace_param); + resources.insert_raw(type_id, workspace_param); + }); } - if let Some(profile_params) = profile_params { - resources.insert(profile_params); + if let Some(profile_params) = self.profile_params.as_mut() { + profile_params.drain(..).for_each(|(_key, profile_param)| { + let profile_param = profile_param.into_inner().upcast(); + let type_id = Resource::type_id(&*profile_param); + resources.insert_raw(type_id, profile_param); + }); } - if let Some(flow_params) = flow_params { - resources.insert(flow_params); + if let Some(flow_params) = self.flow_params.as_mut() { + flow_params.drain(..).for_each(|(_key, flow_param)| { + let flow_param = flow_param.into_inner().upcast(); + let type_id = Resource::type_id(&*flow_param); + resources.insert_raw(type_id, flow_param); + }); } } @@ -290,45 +285,68 @@ where profile_init_file: &ProfileInitFile, flow_init_file: &FlowInitFile, ) -> Result<(), E> { - if self.workspace_params.is_none() { - self.workspace_params = WorkspaceInitializer::workspace_params_deserialize( - storage, - &self.workspace_params_type_reg, - workspace_init_file, - ) - .await? - }; - if self.profile_params.is_none() { - self.profile_params = WorkspaceInitializer::profile_params_deserialize( - storage, - &self.profile_params_type_reg, - profile_init_file, - ) - .await?; - } - if self.flow_params.is_none() { - self.flow_params = WorkspaceInitializer::flow_params_deserialize( - storage, - &self.flow_params_type_reg, - flow_init_file, - ) - .await?; + macro_rules! params_deserialize_and_merge { + ($params:ident, $params_type_reg:ident, $params_deserialize_fn:ident, $init_file:ident) => { + let params_deserialized = WorkspaceInitializer::$params_deserialize_fn( + storage, + &self.$params_type_reg, + $init_file, + ) + .await?; + match (self.$params.as_mut(), params_deserialized) { + (Some(params), Some(params_deserialized)) => { + // Merge `params` on top of `params_deserialized`. + // or, copy `params_deserialized` to `params` where + // there isn't a value. + + params_deserialized + .into_inner() + .into_inner() + .into_iter() + .for_each(|(key, param)| { + if !params.contains_key(&key) { + params.insert_raw(key, param); + } + }); + } + (None, Some(params_deserialized)) => self.$params = Some(params_deserialized), + (Some(_), None) => {} + (None, None) => {} + } + }; } + params_deserialize_and_merge!( + workspace_params, + workspace_params_type_reg, + workspace_params_deserialize, + workspace_init_file + ); + params_deserialize_and_merge!( + profile_params, + profile_params_type_reg, + profile_params_deserialize, + profile_init_file + ); + params_deserialize_and_merge!( + flow_params, + flow_params_type_reg, + flow_params_deserialize, + flow_init_file + ); + Ok(()) } /// Serializes init params to storage. async fn init_params_serialize( + &self, storage: &Storage, - workspace_params: Option<&WorkspaceParams>, workspace_init_file: &WorkspaceInitFile, - profile_params: Option<&ProfileParams>, profile_init_file: &ProfileInitFile, - flow_params: Option<&FlowParams>, flow_init_file: &FlowInitFile, ) -> Result<(), E> { - if let Some(workspace_params) = workspace_params { + if let Some(workspace_params) = self.workspace_params.as_ref() { WorkspaceInitializer::workspace_params_serialize( storage, workspace_params, @@ -336,7 +354,7 @@ where ) .await?; } - if let Some(profile_params) = profile_params { + if let Some(profile_params) = self.profile_params.as_ref() { WorkspaceInitializer::profile_params_serialize( storage, profile_params, @@ -344,7 +362,7 @@ where ) .await?; } - if let Some(flow_params) = flow_params { + if let Some(flow_params) = self.flow_params.as_ref() { WorkspaceInitializer::flow_params_serialize(storage, flow_params, flow_init_file) .await?; } @@ -432,7 +450,7 @@ where pub fn with_workspace_param( self, k: WorkspaceParamsK, - workspace_param: WorkspaceParam, + workspace_param: Option, ) -> CmdContextBuilder< 'ctx, E, @@ -461,7 +479,9 @@ where let mut workspace_params_type_reg = TypeReg::::new(); workspace_params_type_reg.register::(k.clone()); let mut workspace_params = WorkspaceParams::::new(); - workspace_params.insert(k, workspace_param); + if let Some(workspace_param) = workspace_param { + workspace_params.insert(k, workspace_param); + } CmdContextBuilder { workspace, @@ -495,7 +515,7 @@ where pub fn with_workspace_param( mut self, k: WorkspaceParamsK, - workspace_param: WorkspaceParam, + workspace_param: Option, ) -> CmdContextBuilder< 'ctx, E, @@ -509,7 +529,9 @@ where { self.workspace_params_type_reg .register::(k.clone()); - if let Some(workspace_params) = self.workspace_params.as_mut() { + if let (Some(workspace_params), Some(workspace_param)) = + (self.workspace_params.as_mut(), workspace_param) + { workspace_params.insert(k, workspace_param); } @@ -533,7 +555,7 @@ where pub fn with_profile_param( self, k: ProfileParamsK, - profile_param: ProfileParam, + profile_param: Option, ) -> CmdContextBuilder< 'ctx, E, @@ -562,7 +584,9 @@ where let mut profile_params_type_reg = TypeReg::::new(); profile_params_type_reg.register::(k.clone()); let mut profile_params = ProfileParams::::new(); - profile_params.insert(k, profile_param); + if let Some(profile_param) = profile_param { + profile_params.insert(k, profile_param); + } CmdContextBuilder { workspace, @@ -596,7 +620,7 @@ where pub fn with_profile_param( mut self, k: ProfileParamsK, - profile_param: ProfileParam, + profile_param: Option, ) -> CmdContextBuilder< 'ctx, E, @@ -610,7 +634,9 @@ where { self.profile_params_type_reg .register::(k.clone()); - if let Some(profile_params) = self.profile_params.as_mut() { + if let (Some(profile_params), Some(profile_param)) = + (self.profile_params.as_mut(), profile_param) + { profile_params.insert(k, profile_param); } @@ -634,7 +660,7 @@ where pub fn with_flow_param( self, k: FlowParamsK, - flow_param: FlowParam, + flow_param: Option, ) -> CmdContextBuilder< 'ctx, E, @@ -663,7 +689,9 @@ where let mut flow_params_type_reg = TypeReg::::new(); flow_params_type_reg.register::(k.clone()); let mut flow_params = FlowParams::::new(); - flow_params.insert(k, flow_param); + if let Some(flow_param) = flow_param { + flow_params.insert(k, flow_param); + } CmdContextBuilder { workspace, @@ -696,7 +724,7 @@ where pub fn with_flow_param( mut self, k: FlowParamsK, - flow_param: FlowParam, + flow_param: Option, ) -> CmdContextBuilder< 'ctx, E, @@ -709,7 +737,7 @@ where FlowParam: Clone + Debug + DeserializeOwned + Serialize + Send + Sync + 'static, { self.flow_params_type_reg.register::(k.clone()); - if let Some(flow_params) = self.flow_params.as_mut() { + if let (Some(flow_params), Some(flow_param)) = (self.flow_params.as_mut(), flow_param) { flow_params.insert(k, flow_param); } diff --git a/crate/rt_model_core/Cargo.toml b/crate/rt_model_core/Cargo.toml index fc726b6c8..4eb8492eb 100644 --- a/crate/rt_model_core/Cargo.toml +++ b/crate/rt_model_core/Cargo.toml @@ -21,7 +21,7 @@ miette = { workspace = true, optional = true } peace_resources = { path = "../resources", version = "0.0.5" } serde = "1.0.151" serde_json = { version = "1.0.91", optional = true } -type_reg = { workspace = true } +type_reg = { workspace = true, features = ["resman"] } [features] default = [] diff --git a/workspace_tests/src/rt_model/cmd_context_builder.rs b/workspace_tests/src/rt_model/cmd_context_builder.rs index 837e1cd13..853905682 100644 --- a/workspace_tests/src/rt_model/cmd_context_builder.rs +++ b/workspace_tests/src/rt_model/cmd_context_builder.rs @@ -8,6 +8,8 @@ use peace::{ WorkspaceSpec, }, }; +use pretty_assertions::assert_eq; +use serde::{Deserialize, Serialize}; use crate::{no_op_output::NoOpOutput, VecCopyError, VecCopyItemSpec}; @@ -58,7 +60,7 @@ async fn build_inserts_workspace_init_params_from_parameter() assert!(workspace_init_file.exists()); assert_eq!( - "workspace_init\n", + "param: workspace_init\n", tokio::fs::read_to_string(&*workspace_init_file).await? ); assert_eq!("workspace_init", workspace_init.as_str()); @@ -76,14 +78,14 @@ async fn build_inserts_workspace_init_params_from_storage() -> Result<(), Box::None) - .with_workspace_param("param2".to_string(), Option::::None) + .with_workspace_param("param2".to_string(), Option::::None) .await?; let workspace_init_file = resources.borrow::(); let workspace_init = resources.borrow::(); assert!(workspace_init_file.exists()); assert_eq!( - "workspace_init\n", + "param1: workspace_init\n", tokio::fs::read_to_string(&*workspace_init_file).await? ); assert_eq!("workspace_init", workspace_init.as_str()); @@ -103,7 +105,7 @@ async fn build_inserts_profile_init_params_from_parameter() -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box) .await?; // Create another CmdContext, this time using no parameter. @@ -171,13 +174,69 @@ async fn build_inserts_flow_init_params_from_storage() -> Result<(), Box Result<(), Box> { + let (_tempdir, workspace, graph, mut output) = test_setup().await?; + + let CmdContext { resources, .. } = CmdContextBuilder::new(&workspace, &graph, &mut output) + .with_flow_param(FlowKey::F1, Some("flow_1".to_string())) + .with_workspace_param(WorkspaceKey::W1, Some(true)) + .with_profile_param(ProfileKey::P1, Some(1u32)) + .with_workspace_param(WorkspaceKey::W2, Some(2u8)) + .with_flow_param(FlowKey::F2, Some(vec!["flow_2".to_string()])) + .with_profile_param(ProfileKey::P2, Some(2u64)) + .await?; + let workspace_init_file = resources.borrow::(); + let workspace_1 = resources.borrow::(); + let workspace_2 = resources.borrow::(); + let profile_init_file = resources.borrow::(); + let profile_1 = resources.borrow::(); + let profile_2 = resources.borrow::(); + let flow_init_file = resources.borrow::(); + let flow_1 = resources.borrow::(); + let flow_2 = resources.borrow::>(); + + assert!(workspace_init_file.exists()); + assert_eq!( + r#"W1: true +W2: 2 +"#, + tokio::fs::read_to_string(&*workspace_init_file).await? + ); + assert_eq!(true, *workspace_1); + assert_eq!(2u8, *workspace_2); + + assert!(profile_init_file.exists()); + assert_eq!( + r#"P1: 1 +P2: 2 +"#, + tokio::fs::read_to_string(&*profile_init_file).await? + ); + assert_eq!(1u32, *profile_1); + assert_eq!(2u64, *profile_2); + + assert!(flow_init_file.exists()); + assert_eq!( + r#"F1: flow_1 +F2: +- flow_2 +"#, + tokio::fs::read_to_string(&*flow_init_file).await? + ); + assert_eq!("flow_1", flow_1.as_str()); + assert_eq!(vec!["flow_2".to_string()], *flow_2); + + Ok(()) +} + // Test fixture async fn test_setup() -> Result< ( @@ -202,3 +261,21 @@ async fn test_setup() -> Result< Ok((tempdir, workspace, graph, NoOpOutput)) } + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +enum WorkspaceKey { + W1, + W2, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +enum ProfileKey { + P1, + P2, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +enum FlowKey { + F1, + F2, +} From 95706a0e238f17c82acaefbb2abf1a791d08b5c4 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Mon, 26 Dec 2022 16:46:43 +1300 Subject: [PATCH 06/14] Update `peace_rt_model_web` to support multiple params. --- crate/rt_model_web/src/web_storage.rs | 37 +++++++- .../rt_model_web/src/workspace_initializer.rs | 95 +++++++++++-------- 2 files changed, 94 insertions(+), 38 deletions(-) diff --git a/crate/rt_model_web/src/web_storage.rs b/crate/rt_model_web/src/web_storage.rs index 3c0217ba0..5fca8554f 100644 --- a/crate/rt_model_web/src/web_storage.rs +++ b/crate/rt_model_web/src/web_storage.rs @@ -1,5 +1,10 @@ -use std::path::{Path, PathBuf}; +use std::{ + fmt::Debug, + hash::Hash, + path::{Path, PathBuf}, +}; +use peace_resources::type_reg::untagged::{DataTypeWrapper, TypeMap, TypeReg}; use serde::{de::DeserializeOwned, Serialize}; use wasm_bindgen::prelude::*; @@ -321,6 +326,36 @@ impl WebStorage { .transpose() } + /// Deserializes a typemap from the given path if the file exists. + /// + /// # Parameters + /// + /// * `thread_name`: Name of the thread to use to do the read operation. + /// * `type_reg`: Type registry with the stateful deserialization mappings. + /// * `file_path`: Path to the file to read the serialized item. + /// * `f_map_err`: Maps the deserialization error (if any) to an [`Error`]. + pub async fn serialized_typemap_read_opt( + &self, + type_reg: &TypeReg, + path: &Path, + f_map_err: F, + ) -> Result, Error> + where + T: From> + Send + Sync, + K: Debug + DeserializeOwned + Eq + Hash + Sync, + BoxDT: DataTypeWrapper + 'static, + F: FnOnce(serde_yaml::Error) -> Error + Send, + { + self.get_item_opt(path)? + .map(|s| { + let deserializer = serde_yaml::Deserializer::from_str(&s); + let type_map = type_reg.deserialize_map(deserializer).map_err(f_map_err)?; + + Ok(T::from(type_map)) + }) + .transpose() + } + /// Writes a serializable item to the given path. /// /// # Parameters diff --git a/crate/rt_model_web/src/workspace_initializer.rs b/crate/rt_model_web/src/workspace_initializer.rs index 0684c5c72..698550fe4 100644 --- a/crate/rt_model_web/src/workspace_initializer.rs +++ b/crate/rt_model_web/src/workspace_initializer.rs @@ -1,6 +1,10 @@ -use std::{iter, marker::PhantomData, path::Path}; +use std::{fmt::Debug, hash::Hash, iter, path::Path}; -use peace_resources::internal::{FlowInitFile, ProfileInitFile, WorkspaceDirs, WorkspaceInitFile}; +use peace_resources::{ + internal::{FlowInitFile, ProfileInitFile, WorkspaceDirs, WorkspaceInitFile}, + type_reg::untagged::TypeReg, +}; +use peace_rt_model_core::cmd_context_params::{FlowParams, ProfileParams, WorkspaceParams}; use serde::{de::DeserializeOwned, Serialize}; use crate::{Error, WebStorage}; @@ -36,17 +40,9 @@ use crate::{Error, WebStorage}; /// /// This may be `()` if there are no flow specific parameters. #[derive(Debug)] -pub struct WorkspaceInitializer( - PhantomData<(WorkspaceInit, ProfileInit, FlowInit)>, -); +pub struct WorkspaceInitializer; -impl - WorkspaceInitializer -where - WorkspaceInit: Serialize + DeserializeOwned + Send + Sync + 'static, - ProfileInit: Serialize + DeserializeOwned + Send + Sync + 'static, - FlowInit: Serialize + DeserializeOwned + Send + Sync + 'static, -{ +impl WorkspaceInitializer { /// Creates directories used by the peace framework. /// /// For web storage, this sets empty values at directory paths to emulate @@ -65,72 +61,97 @@ where Ok(()) } - pub async fn workspace_init_params_serialize( + pub async fn workspace_params_serialize( storage: &WebStorage, - workspace_init_params: &WorkspaceInit, + workspace_params: &WorkspaceParams, workspace_init_file: &WorkspaceInitFile, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + K: Eq + Hash + Serialize + Send + Sync, + { storage .serialized_write( workspace_init_file, - workspace_init_params, + workspace_params, Error::WorkspaceInitParamsSerialize, ) .await } - pub async fn workspace_init_params_deserialize( + pub async fn workspace_params_deserialize( storage: &WebStorage, + type_reg: &TypeReg, workspace_init_file: &WorkspaceInitFile, - ) -> Result, Error> { + ) -> Result>, Error> + where + K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, + { storage - .serialized_read_opt(workspace_init_file, Error::WorkspaceInitParamsDeserialize) + .serialized_typemap_read_opt( + type_reg, + workspace_init_file, + Error::WorkspaceInitParamsDeserialize, + ) .await } - pub async fn profile_init_params_serialize( + pub async fn profile_params_serialize( storage: &WebStorage, - profile_init_params: &ProfileInit, + profile_params: &ProfileParams, profile_init_file: &ProfileInitFile, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + K: Eq + Hash + Serialize + Send + Sync, + { storage .serialized_write( profile_init_file, - profile_init_params, + profile_params, Error::ProfileInitParamsSerialize, ) .await } - pub async fn profile_init_params_deserialize( + pub async fn profile_params_deserialize( storage: &WebStorage, + type_reg: &TypeReg, profile_init_file: &ProfileInitFile, - ) -> Result, Error> { + ) -> Result>, Error> + where + K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, + { storage - .serialized_read_opt(profile_init_file, Error::ProfileInitParamsDeserialize) + .serialized_typemap_read_opt( + type_reg, + profile_init_file, + Error::ProfileInitParamsDeserialize, + ) .await } - pub async fn flow_init_params_serialize( + pub async fn flow_params_serialize( storage: &WebStorage, - flow_init_params: &FlowInit, + flow_params: &FlowParams, flow_init_file: &FlowInitFile, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + K: Eq + Hash + Serialize + Send + Sync, + { storage - .serialized_write( - flow_init_file, - flow_init_params, - Error::FlowInitParamsSerialize, - ) + .serialized_write(flow_init_file, flow_params, Error::FlowInitParamsSerialize) .await } - pub async fn flow_init_params_deserialize( + pub async fn flow_params_deserialize( storage: &WebStorage, + type_reg: &TypeReg, flow_init_file: &FlowInitFile, - ) -> Result, Error> { + ) -> Result>, Error> + where + K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, + { storage - .serialized_read_opt(flow_init_file, Error::FlowInitParamsDeserialize) + .serialized_typemap_read_opt(type_reg, flow_init_file, Error::FlowInitParamsDeserialize) .await } } From 27361a52c779bea4372950576614e9c7c3be3a43 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Mon, 26 Dec 2022 18:38:12 +1300 Subject: [PATCH 07/14] Rename `*InitFile` to `*ParamsFile`. --- crate/resources/src/internal.rs | 12 +-- ...{flow_init_file.rs => flow_params_file.rs} | 12 +-- ...le_init_file.rs => profile_params_file.rs} | 12 +-- ..._init_file.rs => workspace_params_file.rs} | 12 +-- crate/rt_model/src/cmd_context_builder.rs | 50 ++++++------ crate/rt_model_native/src/error.rs | 12 +-- .../src/workspace_initializer.rs | 38 ++++----- crate/rt_model_web/src/error.rs | 12 +-- .../rt_model_web/src/workspace_initializer.rs | 34 ++++---- workspace_tests/src/resources/internal.rs | 6 +- .../src/resources/internal/flow_init_file.rs | 79 ------------------- .../resources/internal/flow_params_file.rs | 79 +++++++++++++++++++ .../resources/internal/profile_init_file.rs | 78 ------------------ .../resources/internal/profile_params_file.rs | 78 ++++++++++++++++++ .../resources/internal/workspace_init_file.rs | 70 ---------------- .../internal/workspace_params_file.rs | 70 ++++++++++++++++ .../src/rt_model/cmd_context_builder.rs | 56 ++++++------- 17 files changed, 355 insertions(+), 355 deletions(-) rename crate/resources/src/internal/{flow_init_file.rs => flow_params_file.rs} (62%) rename crate/resources/src/internal/{profile_init_file.rs => profile_params_file.rs} (60%) rename crate/resources/src/internal/{workspace_init_file.rs => workspace_params_file.rs} (59%) delete mode 100644 workspace_tests/src/resources/internal/flow_init_file.rs create mode 100644 workspace_tests/src/resources/internal/flow_params_file.rs delete mode 100644 workspace_tests/src/resources/internal/profile_init_file.rs create mode 100644 workspace_tests/src/resources/internal/profile_params_file.rs delete mode 100644 workspace_tests/src/resources/internal/workspace_init_file.rs create mode 100644 workspace_tests/src/resources/internal/workspace_params_file.rs diff --git a/crate/resources/src/internal.rs b/crate/resources/src/internal.rs index ff47606f0..c23ba188d 100644 --- a/crate/resources/src/internal.rs +++ b/crate/resources/src/internal.rs @@ -4,15 +4,15 @@ //! framework). There may be breakage between releases. pub use self::{ - flow_init_file::FlowInitFile, op_check_statuses::OpCheckStatuses, - profile_init_file::ProfileInitFile, state_diffs_mut::StateDiffsMut, states_mut::StatesMut, - workspace_dirs::WorkspaceDirs, workspace_init_file::WorkspaceInitFile, + flow_params_file::FlowParamsFile, op_check_statuses::OpCheckStatuses, + profile_params_file::ProfileParamsFile, state_diffs_mut::StateDiffsMut, states_mut::StatesMut, + workspace_dirs::WorkspaceDirs, workspace_params_file::WorkspaceParamsFile, }; -mod flow_init_file; +mod flow_params_file; mod op_check_statuses; -mod profile_init_file; +mod profile_params_file; mod state_diffs_mut; mod states_mut; mod workspace_dirs; -mod workspace_init_file; +mod workspace_params_file; diff --git a/crate/resources/src/internal/flow_init_file.rs b/crate/resources/src/internal/flow_params_file.rs similarity index 62% rename from crate/resources/src/internal/flow_init_file.rs rename to crate/resources/src/internal/flow_params_file.rs index 2ed548d2c..3983417a3 100644 --- a/crate/resources/src/internal/flow_init_file.rs +++ b/crate/resources/src/internal/flow_params_file.rs @@ -6,20 +6,20 @@ use crate::paths::FlowDir; /// /// Typically `$workspace_dir/.peace/$profile/$flow_id/init.yaml`. /// -/// See `FlowInitFile::from<&FlowDir>` if you want to construct a -/// `FlowInitFile` with the conventional `$flow_dir/init.yaml` +/// See `FlowParamsFile::from<&FlowDir>` if you want to construct a +/// `FlowParamsFile` with the conventional `$flow_dir/init.yaml` /// path. #[derive(Clone, Debug, PartialEq, Eq)] -pub struct FlowInitFile(PathBuf); +pub struct FlowParamsFile(PathBuf); -crate::paths::pathbuf_newtype!(FlowInitFile); +crate::paths::pathbuf_newtype!(FlowParamsFile); -impl FlowInitFile { +impl FlowParamsFile { /// File name of the initialization parameters file. pub const NAME: &'static str = "init.yaml"; } -impl From<&FlowDir> for FlowInitFile { +impl From<&FlowDir> for FlowParamsFile { fn from(flow_dir: &FlowDir) -> Self { let path = flow_dir.join(Self::NAME); diff --git a/crate/resources/src/internal/profile_init_file.rs b/crate/resources/src/internal/profile_params_file.rs similarity index 60% rename from crate/resources/src/internal/profile_init_file.rs rename to crate/resources/src/internal/profile_params_file.rs index 23c1a4fb5..72ec0780b 100644 --- a/crate/resources/src/internal/profile_init_file.rs +++ b/crate/resources/src/internal/profile_params_file.rs @@ -6,20 +6,20 @@ use crate::paths::ProfileDir; /// /// Typically `$workspace_dir/.peace/$profile/init.yaml`. /// -/// See `ProfileInitFile::from<&ProfileDir>` if you want to construct a -/// `ProfileInitFile` with the conventional `$profile_dir/init.yaml` +/// See `ProfileParamsFile::from<&ProfileDir>` if you want to construct a +/// `ProfileParamsFile` with the conventional `$profile_dir/init.yaml` /// path. #[derive(Clone, Debug, PartialEq, Eq)] -pub struct ProfileInitFile(PathBuf); +pub struct ProfileParamsFile(PathBuf); -crate::paths::pathbuf_newtype!(ProfileInitFile); +crate::paths::pathbuf_newtype!(ProfileParamsFile); -impl ProfileInitFile { +impl ProfileParamsFile { /// File name of the initialization parameters file. pub const NAME: &'static str = "init.yaml"; } -impl From<&ProfileDir> for ProfileInitFile { +impl From<&ProfileDir> for ProfileParamsFile { fn from(flow_dir: &ProfileDir) -> Self { let path = flow_dir.join(Self::NAME); diff --git a/crate/resources/src/internal/workspace_init_file.rs b/crate/resources/src/internal/workspace_params_file.rs similarity index 59% rename from crate/resources/src/internal/workspace_init_file.rs rename to crate/resources/src/internal/workspace_params_file.rs index 88086de6e..ca1f60aa7 100644 --- a/crate/resources/src/internal/workspace_init_file.rs +++ b/crate/resources/src/internal/workspace_params_file.rs @@ -6,20 +6,20 @@ use crate::paths::PeaceDir; /// /// Typically `$workspace_dir/.peace/init.yaml`. /// -/// See `WorkspaceInitFile::from<&PeaceDir>` if you want to construct a -/// `WorkspaceInitFile` with the conventional `$peace_dir/init.yaml` +/// See `WorkspaceParamsFile::from<&PeaceDir>` if you want to construct a +/// `WorkspaceParamsFile` with the conventional `$peace_dir/init.yaml` /// path. #[derive(Clone, Debug, PartialEq, Eq)] -pub struct WorkspaceInitFile(PathBuf); +pub struct WorkspaceParamsFile(PathBuf); -crate::paths::pathbuf_newtype!(WorkspaceInitFile); +crate::paths::pathbuf_newtype!(WorkspaceParamsFile); -impl WorkspaceInitFile { +impl WorkspaceParamsFile { /// File name of the initialization parameters file. pub const NAME: &'static str = "init.yaml"; } -impl From<&PeaceDir> for WorkspaceInitFile { +impl From<&PeaceDir> for WorkspaceParamsFile { fn from(flow_dir: &PeaceDir) -> Self { let path = flow_dir.join(Self::NAME); diff --git a/crate/rt_model/src/cmd_context_builder.rs b/crate/rt_model/src/cmd_context_builder.rs index 12264d7b8..acb5955eb 100644 --- a/crate/rt_model/src/cmd_context_builder.rs +++ b/crate/rt_model/src/cmd_context_builder.rs @@ -3,7 +3,7 @@ use std::{fmt::Debug, future::IntoFuture, hash::Hash, marker::PhantomData, pin:: use fn_graph::resman::Resource; use futures::{Future, StreamExt, TryStreamExt}; use peace_resources::{ - internal::{FlowInitFile, ProfileInitFile, WorkspaceInitFile}, + internal::{FlowParamsFile, ProfileParamsFile, WorkspaceParamsFile}, paths::StatesSavedFile, resources::ts::{Empty, SetUp}, states::StatesSaved, @@ -151,17 +151,17 @@ where pub async fn build(mut self) -> Result, E> { let dirs = self.workspace.dirs(); let storage = self.workspace.storage(); - let workspace_init_file = WorkspaceInitFile::from(dirs.peace_dir()); - let profile_init_file = ProfileInitFile::from(dirs.profile_dir()); - let flow_init_file = FlowInitFile::from(dirs.flow_dir()); + let workspace_params_file = WorkspaceParamsFile::from(dirs.peace_dir()); + let profile_params_file = ProfileParamsFile::from(dirs.profile_dir()); + let flow_params_file = FlowParamsFile::from(dirs.flow_dir()); let states_saved_file = StatesSavedFile::from(dirs.flow_dir()); // Read existing init params from storage. self.init_params_deserialize( storage, - &workspace_init_file, - &profile_init_file, - &flow_init_file, + &workspace_params_file, + &profile_params_file, + &flow_params_file, ) .await?; @@ -181,9 +181,9 @@ where self.init_params_serialize( storage, - &workspace_init_file, - &profile_init_file, - &flow_init_file, + &workspace_params_file, + &profile_params_file, + &flow_params_file, ) .await?; @@ -203,9 +203,9 @@ where } = self; Self::workspace_dirs_insert(&mut resources, workspace); - resources.insert(workspace_init_file); - resources.insert(profile_init_file); - resources.insert(flow_init_file); + resources.insert(workspace_params_file); + resources.insert(profile_params_file); + resources.insert(flow_params_file); // Read existing states from storage. let states_type_regs = Self::states_type_regs(item_spec_graph); @@ -281,9 +281,9 @@ where async fn init_params_deserialize( &mut self, storage: &Storage, - workspace_init_file: &WorkspaceInitFile, - profile_init_file: &ProfileInitFile, - flow_init_file: &FlowInitFile, + workspace_params_file: &WorkspaceParamsFile, + profile_params_file: &ProfileParamsFile, + flow_params_file: &FlowParamsFile, ) -> Result<(), E> { macro_rules! params_deserialize_and_merge { ($params:ident, $params_type_reg:ident, $params_deserialize_fn:ident, $init_file:ident) => { @@ -320,19 +320,19 @@ where workspace_params, workspace_params_type_reg, workspace_params_deserialize, - workspace_init_file + workspace_params_file ); params_deserialize_and_merge!( profile_params, profile_params_type_reg, profile_params_deserialize, - profile_init_file + profile_params_file ); params_deserialize_and_merge!( flow_params, flow_params_type_reg, flow_params_deserialize, - flow_init_file + flow_params_file ); Ok(()) @@ -342,15 +342,15 @@ where async fn init_params_serialize( &self, storage: &Storage, - workspace_init_file: &WorkspaceInitFile, - profile_init_file: &ProfileInitFile, - flow_init_file: &FlowInitFile, + workspace_params_file: &WorkspaceParamsFile, + profile_params_file: &ProfileParamsFile, + flow_params_file: &FlowParamsFile, ) -> Result<(), E> { if let Some(workspace_params) = self.workspace_params.as_ref() { WorkspaceInitializer::workspace_params_serialize( storage, workspace_params, - workspace_init_file, + workspace_params_file, ) .await?; } @@ -358,12 +358,12 @@ where WorkspaceInitializer::profile_params_serialize( storage, profile_params, - profile_init_file, + profile_params_file, ) .await?; } if let Some(flow_params) = self.flow_params.as_ref() { - WorkspaceInitializer::flow_params_serialize(storage, flow_params, flow_init_file) + WorkspaceInitializer::flow_params_serialize(storage, flow_params, flow_params_file) .await?; } diff --git a/crate/rt_model_native/src/error.rs b/crate/rt_model_native/src/error.rs index a9cfed84f..2860b5238 100644 --- a/crate/rt_model_native/src/error.rs +++ b/crate/rt_model_native/src/error.rs @@ -120,7 +120,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::workspace_init_params_serialize)) )] - WorkspaceInitParamsSerialize(#[source] serde_yaml::Error), + WorkspaceParamsSerialize(#[source] serde_yaml::Error), /// Failed to deserialize workspace init params. #[error("Failed to serialize workspace init params.")] @@ -128,7 +128,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::workspace_init_params_deserialize)) )] - WorkspaceInitParamsDeserialize(#[source] serde_yaml::Error), + WorkspaceParamsDeserialize(#[source] serde_yaml::Error), /// Failed to serialize profile init params. #[error("Failed to serialize profile init params.")] @@ -136,7 +136,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::profile_init_params_serialize)) )] - ProfileInitParamsSerialize(#[source] serde_yaml::Error), + ProfileParamsSerialize(#[source] serde_yaml::Error), /// Failed to deserialize profile init params. #[error("Failed to serialize profile init params.")] @@ -144,7 +144,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::profile_init_params_deserialize)) )] - ProfileInitParamsDeserialize(#[source] serde_yaml::Error), + ProfileParamsDeserialize(#[source] serde_yaml::Error), /// Failed to serialize flow init params. #[error("Failed to serialize flow init params.")] @@ -152,7 +152,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::flow_init_params_serialize)) )] - FlowInitParamsSerialize(#[source] serde_yaml::Error), + FlowParamsSerialize(#[source] serde_yaml::Error), /// Failed to deserialize flow init params. #[error("Failed to serialize flow init params.")] @@ -160,7 +160,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::flow_init_params_deserialize)) )] - FlowInitParamsDeserialize(#[source] serde_yaml::Error), + FlowParamsDeserialize(#[source] serde_yaml::Error), /// Item does not exist in storage. #[error("Item does not exist in storage: `{}`.", path.display())] diff --git a/crate/rt_model_native/src/workspace_initializer.rs b/crate/rt_model_native/src/workspace_initializer.rs index 079754b92..31b062c50 100644 --- a/crate/rt_model_native/src/workspace_initializer.rs +++ b/crate/rt_model_native/src/workspace_initializer.rs @@ -3,7 +3,7 @@ use std::{fmt::Debug, hash::Hash, iter, path::Path}; use futures::{stream, StreamExt, TryStreamExt}; use peace_resources::{ - internal::{FlowInitFile, ProfileInitFile, WorkspaceDirs, WorkspaceInitFile}, + internal::{FlowParamsFile, ProfileParamsFile, WorkspaceDirs, WorkspaceParamsFile}, type_reg::untagged::TypeReg, }; use peace_rt_model_core::cmd_context_params::{FlowParams, ProfileParams, WorkspaceParams}; @@ -69,7 +69,7 @@ impl WorkspaceInitializer { pub async fn workspace_params_serialize( storage: &NativeStorage, workspace_params: &WorkspaceParams, - workspace_init_file: &WorkspaceInitFile, + workspace_params_file: &WorkspaceParamsFile, ) -> Result<(), Error> where K: Eq + Hash + Serialize + Send + Sync, @@ -77,9 +77,9 @@ impl WorkspaceInitializer { storage .serialized_write( "workspace_params_serialize".to_string(), - workspace_init_file, + workspace_params_file, workspace_params, - Error::WorkspaceInitParamsSerialize, + Error::WorkspaceParamsSerialize, ) .await } @@ -87,7 +87,7 @@ impl WorkspaceInitializer { pub async fn workspace_params_deserialize( storage: &NativeStorage, type_reg: &TypeReg, - workspace_init_file: &WorkspaceInitFile, + workspace_params_file: &WorkspaceParamsFile, ) -> Result>, Error> where K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, @@ -96,8 +96,8 @@ impl WorkspaceInitializer { .serialized_typemap_read_opt( "workspace_params_deserialize".to_string(), type_reg, - workspace_init_file, - Error::WorkspaceInitParamsDeserialize, + workspace_params_file, + Error::WorkspaceParamsDeserialize, ) .await } @@ -105,7 +105,7 @@ impl WorkspaceInitializer { pub async fn profile_params_serialize( storage: &NativeStorage, profile_params: &ProfileParams, - profile_init_file: &ProfileInitFile, + profile_params_file: &ProfileParamsFile, ) -> Result<(), Error> where K: Eq + Hash + Serialize + Send + Sync, @@ -113,9 +113,9 @@ impl WorkspaceInitializer { storage .serialized_write( "profile_params_serialize".to_string(), - profile_init_file, + profile_params_file, profile_params, - Error::ProfileInitParamsSerialize, + Error::ProfileParamsSerialize, ) .await } @@ -123,7 +123,7 @@ impl WorkspaceInitializer { pub async fn profile_params_deserialize( storage: &NativeStorage, type_reg: &TypeReg, - profile_init_file: &ProfileInitFile, + profile_params_file: &ProfileParamsFile, ) -> Result>, Error> where K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, @@ -132,8 +132,8 @@ impl WorkspaceInitializer { .serialized_typemap_read_opt( "profile_params_deserialize".to_string(), type_reg, - profile_init_file, - Error::ProfileInitParamsDeserialize, + profile_params_file, + Error::ProfileParamsDeserialize, ) .await } @@ -141,7 +141,7 @@ impl WorkspaceInitializer { pub async fn flow_params_serialize( storage: &NativeStorage, flow_params: &FlowParams, - flow_init_file: &FlowInitFile, + flow_params_file: &FlowParamsFile, ) -> Result<(), Error> where K: Eq + Hash + Serialize + Send + Sync, @@ -149,9 +149,9 @@ impl WorkspaceInitializer { storage .serialized_write( "flow_params_serialize".to_string(), - flow_init_file, + flow_params_file, flow_params, - Error::FlowInitParamsSerialize, + Error::FlowParamsSerialize, ) .await } @@ -159,7 +159,7 @@ impl WorkspaceInitializer { pub async fn flow_params_deserialize( storage: &NativeStorage, type_reg: &TypeReg, - flow_init_file: &FlowInitFile, + flow_params_file: &FlowParamsFile, ) -> Result>, Error> where K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, @@ -168,8 +168,8 @@ impl WorkspaceInitializer { .serialized_typemap_read_opt( "flow_params_deserialize".to_string(), type_reg, - flow_init_file, - Error::FlowInitParamsDeserialize, + flow_params_file, + Error::FlowParamsDeserialize, ) .await } diff --git a/crate/rt_model_web/src/error.rs b/crate/rt_model_web/src/error.rs index 299a57887..6cedbce83 100644 --- a/crate/rt_model_web/src/error.rs +++ b/crate/rt_model_web/src/error.rs @@ -118,7 +118,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::workspace_init_params_serialize)) )] - WorkspaceInitParamsSerialize(#[source] serde_yaml::Error), + WorkspaceParamsSerialize(#[source] serde_yaml::Error), /// Failed to deserialize workspace init params. #[error("Failed to serialize workspace init params.")] @@ -126,7 +126,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::workspace_init_params_deserialize)) )] - WorkspaceInitParamsDeserialize(#[source] serde_yaml::Error), + WorkspaceParamsDeserialize(#[source] serde_yaml::Error), /// Failed to serialize profile init params. #[error("Failed to serialize profile init params.")] @@ -134,7 +134,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::profile_init_params_serialize)) )] - ProfileInitParamsSerialize(#[source] serde_yaml::Error), + ProfileParamsSerialize(#[source] serde_yaml::Error), /// Failed to deserialize profile init params. #[error("Failed to serialize profile init params.")] @@ -142,7 +142,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::profile_init_params_deserialize)) )] - ProfileInitParamsDeserialize(#[source] serde_yaml::Error), + ProfileParamsDeserialize(#[source] serde_yaml::Error), /// Failed to serialize flow init params. #[error("Failed to serialize flow init params.")] @@ -150,7 +150,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::flow_init_params_serialize)) )] - FlowInitParamsSerialize(#[source] serde_yaml::Error), + FlowParamsSerialize(#[source] serde_yaml::Error), /// Failed to deserialize flow init params. #[error("Failed to serialize flow init params.")] @@ -158,7 +158,7 @@ pub enum Error { feature = "error_reporting", diagnostic(code(peace_rt_model::flow_init_params_deserialize)) )] - FlowInitParamsDeserialize(#[source] serde_yaml::Error), + FlowParamsDeserialize(#[source] serde_yaml::Error), /// Item does not exist in storage. #[error("Item does not exist in storage: `{}`.", path.display())] diff --git a/crate/rt_model_web/src/workspace_initializer.rs b/crate/rt_model_web/src/workspace_initializer.rs index 698550fe4..b966b7902 100644 --- a/crate/rt_model_web/src/workspace_initializer.rs +++ b/crate/rt_model_web/src/workspace_initializer.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, hash::Hash, iter, path::Path}; use peace_resources::{ - internal::{FlowInitFile, ProfileInitFile, WorkspaceDirs, WorkspaceInitFile}, + internal::{FlowParamsFile, ProfileParamsFile, WorkspaceDirs, WorkspaceParamsFile}, type_reg::untagged::TypeReg, }; use peace_rt_model_core::cmd_context_params::{FlowParams, ProfileParams, WorkspaceParams}; @@ -64,16 +64,16 @@ impl WorkspaceInitializer { pub async fn workspace_params_serialize( storage: &WebStorage, workspace_params: &WorkspaceParams, - workspace_init_file: &WorkspaceInitFile, + workspace_params_file: &WorkspaceParamsFile, ) -> Result<(), Error> where K: Eq + Hash + Serialize + Send + Sync, { storage .serialized_write( - workspace_init_file, + workspace_params_file, workspace_params, - Error::WorkspaceInitParamsSerialize, + Error::WorkspaceParamsSerialize, ) .await } @@ -81,7 +81,7 @@ impl WorkspaceInitializer { pub async fn workspace_params_deserialize( storage: &WebStorage, type_reg: &TypeReg, - workspace_init_file: &WorkspaceInitFile, + workspace_params_file: &WorkspaceParamsFile, ) -> Result>, Error> where K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, @@ -89,8 +89,8 @@ impl WorkspaceInitializer { storage .serialized_typemap_read_opt( type_reg, - workspace_init_file, - Error::WorkspaceInitParamsDeserialize, + workspace_params_file, + Error::WorkspaceParamsDeserialize, ) .await } @@ -98,16 +98,16 @@ impl WorkspaceInitializer { pub async fn profile_params_serialize( storage: &WebStorage, profile_params: &ProfileParams, - profile_init_file: &ProfileInitFile, + profile_params_file: &ProfileParamsFile, ) -> Result<(), Error> where K: Eq + Hash + Serialize + Send + Sync, { storage .serialized_write( - profile_init_file, + profile_params_file, profile_params, - Error::ProfileInitParamsSerialize, + Error::ProfileParamsSerialize, ) .await } @@ -115,7 +115,7 @@ impl WorkspaceInitializer { pub async fn profile_params_deserialize( storage: &WebStorage, type_reg: &TypeReg, - profile_init_file: &ProfileInitFile, + profile_params_file: &ProfileParamsFile, ) -> Result>, Error> where K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, @@ -123,8 +123,8 @@ impl WorkspaceInitializer { storage .serialized_typemap_read_opt( type_reg, - profile_init_file, - Error::ProfileInitParamsDeserialize, + profile_params_file, + Error::ProfileParamsDeserialize, ) .await } @@ -132,26 +132,26 @@ impl WorkspaceInitializer { pub async fn flow_params_serialize( storage: &WebStorage, flow_params: &FlowParams, - flow_init_file: &FlowInitFile, + flow_params_file: &FlowParamsFile, ) -> Result<(), Error> where K: Eq + Hash + Serialize + Send + Sync, { storage - .serialized_write(flow_init_file, flow_params, Error::FlowInitParamsSerialize) + .serialized_write(flow_params_file, flow_params, Error::FlowParamsSerialize) .await } pub async fn flow_params_deserialize( storage: &WebStorage, type_reg: &TypeReg, - flow_init_file: &FlowInitFile, + flow_params_file: &FlowParamsFile, ) -> Result>, Error> where K: Debug + Eq + Hash + DeserializeOwned + Send + Sync, { storage - .serialized_typemap_read_opt(type_reg, flow_init_file, Error::FlowInitParamsDeserialize) + .serialized_typemap_read_opt(type_reg, flow_params_file, Error::FlowParamsDeserialize) .await } } diff --git a/workspace_tests/src/resources/internal.rs b/workspace_tests/src/resources/internal.rs index 35f382103..9b08a8698 100644 --- a/workspace_tests/src/resources/internal.rs +++ b/workspace_tests/src/resources/internal.rs @@ -1,6 +1,6 @@ -mod flow_init_file; -mod profile_init_file; +mod flow_params_file; +mod profile_params_file; mod state_diffs_mut; mod states_mut; mod workspace_dirs; -mod workspace_init_file; +mod workspace_params_file; diff --git a/workspace_tests/src/resources/internal/flow_init_file.rs b/workspace_tests/src/resources/internal/flow_init_file.rs deleted file mode 100644 index 22a3ccff4..000000000 --- a/workspace_tests/src/resources/internal/flow_init_file.rs +++ /dev/null @@ -1,79 +0,0 @@ -use std::{ - ffi::OsStr, - path::{Path, PathBuf}, -}; - -use peace::{ - cfg::{flow_id, profile, FlowId, Profile}, - resources::{ - internal::FlowInitFile, - paths::{FlowDir, PeaceDir, ProfileDir}, - }, -}; - -#[test] -pub fn debug() { - let flow_init_file = FlowInitFile::from(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - r#"FlowInitFile("init.yaml")"#, - format!("{flow_init_file:?}") - ); -} - -#[test] -pub fn partial_eq() { - let flow_init_file_0 = FlowInitFile::from(Path::new("init.yaml").to_path_buf()); - let flow_init_file_1 = flow_init_file_0.clone(); - - assert_eq!(flow_init_file_0, flow_init_file_1); -} - -#[test] -pub fn from_path_buf() { - let flow_init_file = FlowInitFile::from(Path::new("init.yaml").to_path_buf()); - - assert_eq!(Path::new("init.yaml"), &*flow_init_file); -} - -#[test] -pub fn from_flow_dir_relative() { - let peace_dir = PeaceDir::from(Path::new(".").to_path_buf()); - let profile = profile!("test_profile"); - let profile_dir = ProfileDir::from((&peace_dir, &profile)); - let flow_dir = FlowDir::from((&profile_dir, &flow_id!("test_flow"))); - let flow_init_file = FlowInitFile::from(&flow_dir); - - let path = PathBuf::from_iter([".", "test_profile", "test_flow", "init.yaml"]); - assert_eq!(path, &*flow_init_file); -} - -#[test] -pub fn into_inner_returns_path_buf() { - let flow_init_file = FlowInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - Path::new("init.yaml").to_path_buf(), - flow_init_file.into_inner() - ); -} - -#[test] -pub fn as_ref_os_str() { - let flow_init_file = FlowInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - OsStr::new("init.yaml"), - >::as_ref(&flow_init_file) - ); -} - -#[test] -pub fn as_ref_path() { - let flow_init_file = FlowInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - Path::new("init.yaml"), - >::as_ref(&flow_init_file) - ); -} diff --git a/workspace_tests/src/resources/internal/flow_params_file.rs b/workspace_tests/src/resources/internal/flow_params_file.rs new file mode 100644 index 000000000..6c08f3fbb --- /dev/null +++ b/workspace_tests/src/resources/internal/flow_params_file.rs @@ -0,0 +1,79 @@ +use std::{ + ffi::OsStr, + path::{Path, PathBuf}, +}; + +use peace::{ + cfg::{flow_id, profile, FlowId, Profile}, + resources::{ + internal::FlowParamsFile, + paths::{FlowDir, PeaceDir, ProfileDir}, + }, +}; + +#[test] +pub fn debug() { + let flow_params_file = FlowParamsFile::from(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + r#"FlowParamsFile("init.yaml")"#, + format!("{flow_params_file:?}") + ); +} + +#[test] +pub fn partial_eq() { + let flow_params_file_0 = FlowParamsFile::from(Path::new("init.yaml").to_path_buf()); + let flow_params_file_1 = flow_params_file_0.clone(); + + assert_eq!(flow_params_file_0, flow_params_file_1); +} + +#[test] +pub fn from_path_buf() { + let flow_params_file = FlowParamsFile::from(Path::new("init.yaml").to_path_buf()); + + assert_eq!(Path::new("init.yaml"), &*flow_params_file); +} + +#[test] +pub fn from_flow_dir_relative() { + let peace_dir = PeaceDir::from(Path::new(".").to_path_buf()); + let profile = profile!("test_profile"); + let profile_dir = ProfileDir::from((&peace_dir, &profile)); + let flow_dir = FlowDir::from((&profile_dir, &flow_id!("test_flow"))); + let flow_params_file = FlowParamsFile::from(&flow_dir); + + let path = PathBuf::from_iter([".", "test_profile", "test_flow", "init.yaml"]); + assert_eq!(path, &*flow_params_file); +} + +#[test] +pub fn into_inner_returns_path_buf() { + let flow_params_file = FlowParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + Path::new("init.yaml").to_path_buf(), + flow_params_file.into_inner() + ); +} + +#[test] +pub fn as_ref_os_str() { + let flow_params_file = FlowParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + OsStr::new("init.yaml"), + >::as_ref(&flow_params_file) + ); +} + +#[test] +pub fn as_ref_path() { + let flow_params_file = FlowParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + Path::new("init.yaml"), + >::as_ref(&flow_params_file) + ); +} diff --git a/workspace_tests/src/resources/internal/profile_init_file.rs b/workspace_tests/src/resources/internal/profile_init_file.rs deleted file mode 100644 index 06613a3a7..000000000 --- a/workspace_tests/src/resources/internal/profile_init_file.rs +++ /dev/null @@ -1,78 +0,0 @@ -use std::{ - ffi::OsStr, - path::{Path, PathBuf}, -}; - -use peace::{ - cfg::{profile, Profile}, - resources::{ - internal::ProfileInitFile, - paths::{PeaceDir, ProfileDir}, - }, -}; - -#[test] -pub fn debug() { - let profile_init_file = ProfileInitFile::from(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - r#"ProfileInitFile("init.yaml")"#, - format!("{profile_init_file:?}") - ); -} - -#[test] -pub fn partial_eq() { - let profile_init_file_0 = ProfileInitFile::from(Path::new("init.yaml").to_path_buf()); - let profile_init_file_1 = profile_init_file_0.clone(); - - assert_eq!(profile_init_file_0, profile_init_file_1); -} - -#[test] -pub fn from_path_buf() { - let profile_init_file = ProfileInitFile::from(Path::new("init.yaml").to_path_buf()); - - assert_eq!(Path::new("init.yaml"), &*profile_init_file); -} - -#[test] -pub fn from_profile_dir_relative() { - let peace_dir = PeaceDir::from(Path::new(".").to_path_buf()); - let profile = profile!("test_profile"); - let profile_dir = ProfileDir::from((&peace_dir, &profile)); - let profile_init_file = ProfileInitFile::from(&profile_dir); - - let path = PathBuf::from_iter([".", "test_profile", "init.yaml"]); - assert_eq!(path, &*profile_init_file); -} - -#[test] -pub fn into_inner_returns_path_buf() { - let profile_init_file = ProfileInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - Path::new("init.yaml").to_path_buf(), - profile_init_file.into_inner() - ); -} - -#[test] -pub fn as_ref_os_str() { - let profile_init_file = ProfileInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - OsStr::new("init.yaml"), - >::as_ref(&profile_init_file) - ); -} - -#[test] -pub fn as_ref_path() { - let profile_init_file = ProfileInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - Path::new("init.yaml"), - >::as_ref(&profile_init_file) - ); -} diff --git a/workspace_tests/src/resources/internal/profile_params_file.rs b/workspace_tests/src/resources/internal/profile_params_file.rs new file mode 100644 index 000000000..3b370be0a --- /dev/null +++ b/workspace_tests/src/resources/internal/profile_params_file.rs @@ -0,0 +1,78 @@ +use std::{ + ffi::OsStr, + path::{Path, PathBuf}, +}; + +use peace::{ + cfg::{profile, Profile}, + resources::{ + internal::ProfileParamsFile, + paths::{PeaceDir, ProfileDir}, + }, +}; + +#[test] +pub fn debug() { + let profile_params_file = ProfileParamsFile::from(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + r#"ProfileParamsFile("init.yaml")"#, + format!("{profile_params_file:?}") + ); +} + +#[test] +pub fn partial_eq() { + let profile_params_file_0 = ProfileParamsFile::from(Path::new("init.yaml").to_path_buf()); + let profile_params_file_1 = profile_params_file_0.clone(); + + assert_eq!(profile_params_file_0, profile_params_file_1); +} + +#[test] +pub fn from_path_buf() { + let profile_params_file = ProfileParamsFile::from(Path::new("init.yaml").to_path_buf()); + + assert_eq!(Path::new("init.yaml"), &*profile_params_file); +} + +#[test] +pub fn from_profile_dir_relative() { + let peace_dir = PeaceDir::from(Path::new(".").to_path_buf()); + let profile = profile!("test_profile"); + let profile_dir = ProfileDir::from((&peace_dir, &profile)); + let profile_params_file = ProfileParamsFile::from(&profile_dir); + + let path = PathBuf::from_iter([".", "test_profile", "init.yaml"]); + assert_eq!(path, &*profile_params_file); +} + +#[test] +pub fn into_inner_returns_path_buf() { + let profile_params_file = ProfileParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + Path::new("init.yaml").to_path_buf(), + profile_params_file.into_inner() + ); +} + +#[test] +pub fn as_ref_os_str() { + let profile_params_file = ProfileParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + OsStr::new("init.yaml"), + >::as_ref(&profile_params_file) + ); +} + +#[test] +pub fn as_ref_path() { + let profile_params_file = ProfileParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + Path::new("init.yaml"), + >::as_ref(&profile_params_file) + ); +} diff --git a/workspace_tests/src/resources/internal/workspace_init_file.rs b/workspace_tests/src/resources/internal/workspace_init_file.rs deleted file mode 100644 index 5f8e56076..000000000 --- a/workspace_tests/src/resources/internal/workspace_init_file.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::{ - ffi::OsStr, - path::{Path, PathBuf}, -}; - -use peace::resources::{internal::WorkspaceInitFile, paths::PeaceDir}; - -#[test] -pub fn debug() { - let workspace_init_file = WorkspaceInitFile::from(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - r#"WorkspaceInitFile("init.yaml")"#, - format!("{workspace_init_file:?}") - ); -} - -#[test] -pub fn partial_eq() { - let workspace_init_file_0 = WorkspaceInitFile::from(Path::new("init.yaml").to_path_buf()); - let workspace_init_file_1 = workspace_init_file_0.clone(); - - assert_eq!(workspace_init_file_0, workspace_init_file_1); -} - -#[test] -pub fn from_path_buf() { - let workspace_init_file = WorkspaceInitFile::from(Path::new("init.yaml").to_path_buf()); - - assert_eq!(Path::new("init.yaml"), &*workspace_init_file); -} - -#[test] -pub fn from_peace_dir_relative() { - let peace_dir = PeaceDir::from(Path::new(".").to_path_buf()); - let workspace_init_file = WorkspaceInitFile::from(&peace_dir); - - let path = PathBuf::from_iter([".", "init.yaml"]); - assert_eq!(path, &*workspace_init_file); -} - -#[test] -pub fn into_inner_returns_path_buf() { - let workspace_init_file = WorkspaceInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - Path::new("init.yaml").to_path_buf(), - workspace_init_file.into_inner() - ); -} - -#[test] -pub fn as_ref_os_str() { - let workspace_init_file = WorkspaceInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - OsStr::new("init.yaml"), - >::as_ref(&workspace_init_file) - ); -} - -#[test] -pub fn as_ref_path() { - let workspace_init_file = WorkspaceInitFile::new(Path::new("init.yaml").to_path_buf()); - - assert_eq!( - Path::new("init.yaml"), - >::as_ref(&workspace_init_file) - ); -} diff --git a/workspace_tests/src/resources/internal/workspace_params_file.rs b/workspace_tests/src/resources/internal/workspace_params_file.rs new file mode 100644 index 000000000..ca5057c50 --- /dev/null +++ b/workspace_tests/src/resources/internal/workspace_params_file.rs @@ -0,0 +1,70 @@ +use std::{ + ffi::OsStr, + path::{Path, PathBuf}, +}; + +use peace::resources::{internal::WorkspaceParamsFile, paths::PeaceDir}; + +#[test] +pub fn debug() { + let workspace_params_file = WorkspaceParamsFile::from(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + r#"WorkspaceParamsFile("init.yaml")"#, + format!("{workspace_params_file:?}") + ); +} + +#[test] +pub fn partial_eq() { + let workspace_params_file_0 = WorkspaceParamsFile::from(Path::new("init.yaml").to_path_buf()); + let workspace_params_file_1 = workspace_params_file_0.clone(); + + assert_eq!(workspace_params_file_0, workspace_params_file_1); +} + +#[test] +pub fn from_path_buf() { + let workspace_params_file = WorkspaceParamsFile::from(Path::new("init.yaml").to_path_buf()); + + assert_eq!(Path::new("init.yaml"), &*workspace_params_file); +} + +#[test] +pub fn from_peace_dir_relative() { + let peace_dir = PeaceDir::from(Path::new(".").to_path_buf()); + let workspace_params_file = WorkspaceParamsFile::from(&peace_dir); + + let path = PathBuf::from_iter([".", "init.yaml"]); + assert_eq!(path, &*workspace_params_file); +} + +#[test] +pub fn into_inner_returns_path_buf() { + let workspace_params_file = WorkspaceParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + Path::new("init.yaml").to_path_buf(), + workspace_params_file.into_inner() + ); +} + +#[test] +pub fn as_ref_os_str() { + let workspace_params_file = WorkspaceParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + OsStr::new("init.yaml"), + >::as_ref(&workspace_params_file) + ); +} + +#[test] +pub fn as_ref_path() { + let workspace_params_file = WorkspaceParamsFile::new(Path::new("init.yaml").to_path_buf()); + + assert_eq!( + Path::new("init.yaml"), + >::as_ref(&workspace_params_file) + ); +} diff --git a/workspace_tests/src/rt_model/cmd_context_builder.rs b/workspace_tests/src/rt_model/cmd_context_builder.rs index 853905682..a87089ec8 100644 --- a/workspace_tests/src/rt_model/cmd_context_builder.rs +++ b/workspace_tests/src/rt_model/cmd_context_builder.rs @@ -2,7 +2,7 @@ use std::path::Path; use peace::{ cfg::{profile, FlowId, Profile}, - resources::internal::{FlowInitFile, ProfileInitFile, WorkspaceInitFile}, + resources::internal::{FlowParamsFile, ProfileParamsFile, WorkspaceParamsFile}, rt_model::{ CmdContext, CmdContextBuilder, ItemSpecGraph, ItemSpecGraphBuilder, Workspace, WorkspaceSpec, @@ -55,13 +55,13 @@ async fn build_inserts_workspace_init_params_from_parameter() let CmdContext { resources, .. } = CmdContextBuilder::new(&workspace, &graph, &mut output) .with_workspace_param("param".to_string(), Some("workspace_init".to_string())) .await?; - let workspace_init_file = resources.borrow::(); + let workspace_params_file = resources.borrow::(); let workspace_init = resources.borrow::(); - assert!(workspace_init_file.exists()); + assert!(workspace_params_file.exists()); assert_eq!( "param: workspace_init\n", - tokio::fs::read_to_string(&*workspace_init_file).await? + tokio::fs::read_to_string(&*workspace_params_file).await? ); assert_eq!("workspace_init", workspace_init.as_str()); Ok(()) @@ -80,13 +80,13 @@ async fn build_inserts_workspace_init_params_from_storage() -> Result<(), Box::None) .with_workspace_param("param2".to_string(), Option::::None) .await?; - let workspace_init_file = resources.borrow::(); + let workspace_params_file = resources.borrow::(); let workspace_init = resources.borrow::(); - assert!(workspace_init_file.exists()); + assert!(workspace_params_file.exists()); assert_eq!( "param1: workspace_init\n", - tokio::fs::read_to_string(&*workspace_init_file).await? + tokio::fs::read_to_string(&*workspace_params_file).await? ); assert_eq!("workspace_init", workspace_init.as_str()); Ok(()) @@ -100,13 +100,13 @@ async fn build_inserts_profile_init_params_from_parameter() -> Result<(), Box(); + let profile_params_file = resources.borrow::(); let profile_init = resources.borrow::(); - assert!(profile_init_file.exists()); + assert!(profile_params_file.exists()); assert_eq!( "param: profile_init\n", - tokio::fs::read_to_string(&*profile_init_file).await? + tokio::fs::read_to_string(&*profile_params_file).await? ); assert_eq!("profile_init", profile_init.as_str()); Ok(()) @@ -125,13 +125,13 @@ async fn build_inserts_profile_init_params_from_storage() -> Result<(), Box) .with_profile_param("param2".to_string(), None::) .await?; - let profile_init_file = resources.borrow::(); + let profile_params_file = resources.borrow::(); let profile_init = resources.borrow::(); - assert!(profile_init_file.exists()); + assert!(profile_params_file.exists()); assert_eq!( "param1: profile_init\n", - tokio::fs::read_to_string(&*profile_init_file).await? + tokio::fs::read_to_string(&*profile_params_file).await? ); assert_eq!("profile_init", profile_init.as_str()); Ok(()) @@ -144,13 +144,13 @@ async fn build_inserts_flow_init_params_from_parameter() -> Result<(), Box(); + let flow_params_file = resources.borrow::(); let flow_init = resources.borrow::(); - assert!(flow_init_file.exists()); + assert!(flow_params_file.exists()); assert_eq!( "param: flow_init\n", - tokio::fs::read_to_string(&*flow_init_file).await? + tokio::fs::read_to_string(&*flow_params_file).await? ); assert_eq!("flow_init", flow_init.as_str()); Ok(()) @@ -169,13 +169,13 @@ async fn build_inserts_flow_init_params_from_storage() -> Result<(), Box) .with_flow_param("param2".to_string(), None::) .await?; - let flow_init_file = resources.borrow::(); + let flow_params_file = resources.borrow::(); let flow_init = resources.borrow::(); - assert!(flow_init_file.exists()); + assert!(flow_params_file.exists()); assert_eq!( "param1: flow_init\n", - tokio::fs::read_to_string(&*flow_init_file).await? + tokio::fs::read_to_string(&*flow_params_file).await? ); assert_eq!("flow_init", flow_init.as_str()); Ok(()) @@ -193,43 +193,43 @@ async fn build_inserts_mix_params_from_parameters() -> Result<(), Box(); + let workspace_params_file = resources.borrow::(); let workspace_1 = resources.borrow::(); let workspace_2 = resources.borrow::(); - let profile_init_file = resources.borrow::(); + let profile_params_file = resources.borrow::(); let profile_1 = resources.borrow::(); let profile_2 = resources.borrow::(); - let flow_init_file = resources.borrow::(); + let flow_params_file = resources.borrow::(); let flow_1 = resources.borrow::(); let flow_2 = resources.borrow::>(); - assert!(workspace_init_file.exists()); + assert!(workspace_params_file.exists()); assert_eq!( r#"W1: true W2: 2 "#, - tokio::fs::read_to_string(&*workspace_init_file).await? + tokio::fs::read_to_string(&*workspace_params_file).await? ); assert_eq!(true, *workspace_1); assert_eq!(2u8, *workspace_2); - assert!(profile_init_file.exists()); + assert!(profile_params_file.exists()); assert_eq!( r#"P1: 1 P2: 2 "#, - tokio::fs::read_to_string(&*profile_init_file).await? + tokio::fs::read_to_string(&*profile_params_file).await? ); assert_eq!(1u32, *profile_1); assert_eq!(2u64, *profile_2); - assert!(flow_init_file.exists()); + assert!(flow_params_file.exists()); assert_eq!( r#"F1: flow_1 F2: - flow_2 "#, - tokio::fs::read_to_string(&*flow_init_file).await? + tokio::fs::read_to_string(&*flow_params_file).await? ); assert_eq!("flow_1", flow_1.as_str()); assert_eq!(vec!["flow_2".to_string()], *flow_2); From 52e61011692b70d0d31d63d34d1976c563d683bf Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Mon, 26 Dec 2022 18:47:21 +1300 Subject: [PATCH 08/14] Update `README.md`. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e9b57cf1..aacad9255 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,9 @@ See: * 🟢 Define items to manage with automation * 🟢 Define dependencies between items -* 🟢 Fetch current and desired states +* 🟢 Discover current and desired states * 🟢 Show diff: what would change +* 🟢 Store and recall parameters across commands * 🟢 Concurrent task execution via [`fn_graph`] * 🟢 Skip unnecessary work * 🟢 Idempotence: Multiple executions @@ -48,6 +49,7 @@ See: * 🟣 WASM support * ⚫ Understandable progress ([#42]) * ⚫ Informative +* ⚫ Tutorial for writing a software lifecycle management tool * ⚫ Built-in application execution methods -- CLI, web service * ⚫ `peace` binary for configuration based workflows * ⚫ Web based UI From 9a17b5168615c637c860ffed1be9ba6e2d56f976 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Mon, 26 Dec 2022 18:53:33 +1300 Subject: [PATCH 09/14] Add tests for `Resources`. --- workspace_tests/src/resources/resources.rs | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/workspace_tests/src/resources/resources.rs b/workspace_tests/src/resources/resources.rs index accb27acb..bd2449f1c 100644 --- a/workspace_tests/src/resources/resources.rs +++ b/workspace_tests/src/resources/resources.rs @@ -1,6 +1,8 @@ +use std::any::{Any, TypeId}; + use peace::resources::{ resources::ts::{ - Cleaned, CleanedDry, Ensured, EnsuredDry, SetUp, WithStatesCurrent, + Cleaned, CleanedDry, Empty, Ensured, EnsuredDry, SetUp, WithStatesCurrent, WithStatesCurrentAndDesired, WithStatesCurrentDiffs, WithStatesDesired, WithStatesSaved, WithStatesSavedAndDesired, WithStatesSavedDiffs, }, @@ -11,6 +13,27 @@ use peace::resources::{ Resources, }; +#[test] +fn debug() { + let mut resources = Resources::new(); + resources.insert(1u32); + + assert_eq!( + r#"Resources { inner: {u32: 1}, marker: PhantomData }"#, + format!("{resources:?}") + ); +} + +#[test] +fn defaults_to_resources_empty() { + let resources_default = Resources::default(); + + assert_eq!( + TypeId::of::>(), + resources_default.type_id() + ); +} + #[test] fn resources_set_up_from_resources_empty() { let resources_empty = Resources::new(); From 3f7f17d673a4787dad71a4827343927cdf52cf8a Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Mon, 26 Dec 2022 19:10:57 +1300 Subject: [PATCH 10/14] Add tests for `resources::ts` and `states::ts`. --- workspace_tests/src/resources/resources.rs | 2 + workspace_tests/src/resources/resources/ts.rs | 81 ++++++++++++++++ workspace_tests/src/resources/states.rs | 2 + workspace_tests/src/resources/states/ts.rs | 95 +++++++++++++++++++ 4 files changed, 180 insertions(+) create mode 100644 workspace_tests/src/resources/resources/ts.rs create mode 100644 workspace_tests/src/resources/states/ts.rs diff --git a/workspace_tests/src/resources/resources.rs b/workspace_tests/src/resources/resources.rs index bd2449f1c..3f8d68ef4 100644 --- a/workspace_tests/src/resources/resources.rs +++ b/workspace_tests/src/resources/resources.rs @@ -13,6 +13,8 @@ use peace::resources::{ Resources, }; +mod ts; + #[test] fn debug() { let mut resources = Resources::new(); diff --git a/workspace_tests/src/resources/resources/ts.rs b/workspace_tests/src/resources/resources/ts.rs new file mode 100644 index 000000000..222ac7240 --- /dev/null +++ b/workspace_tests/src/resources/resources/ts.rs @@ -0,0 +1,81 @@ +mod debug { + use peace::resources::resources::ts::{ + Cleaned, CleanedDry, Empty, Ensured, EnsuredDry, SetUp, WithStatesCurrent, + WithStatesCurrentAndDesired, WithStatesCurrentDiffs, WithStatesDesired, WithStatesSaved, + WithStatesSavedAndDesired, WithStatesSavedDiffs, + }; + + #[test] + fn cleaned() { + assert_eq!("Cleaned", format!("{Cleaned:?}")); + } + + #[test] + fn cleaned_dry() { + assert_eq!("CleanedDry", format!("{CleanedDry:?}")); + } + + #[test] + fn empty() { + assert_eq!("Empty", format!("{Empty:?}")); + } + + #[test] + fn ensured() { + assert_eq!("Ensured", format!("{Ensured:?}")); + } + + #[test] + fn ensured_dry() { + assert_eq!("EnsuredDry", format!("{EnsuredDry:?}")); + } + + #[test] + fn set_up() { + assert_eq!("SetUp", format!("{SetUp:?}")); + } + + #[test] + fn with_states_current() { + assert_eq!("WithStatesCurrent", format!("{WithStatesCurrent:?}")); + } + + #[test] + fn with_states_current_and_desired() { + assert_eq!( + "WithStatesCurrentAndDesired", + format!("{WithStatesCurrentAndDesired:?}") + ); + } + + #[test] + fn with_states_current_diffs() { + assert_eq!( + "WithStatesCurrentDiffs", + format!("{WithStatesCurrentDiffs:?}") + ); + } + + #[test] + fn with_states_desired() { + assert_eq!("WithStatesDesired", format!("{WithStatesDesired:?}")); + } + + #[test] + fn with_states_saved() { + assert_eq!("WithStatesSaved", format!("{WithStatesSaved:?}")); + } + + #[test] + fn with_states_saved_and_desired() { + assert_eq!( + "WithStatesSavedAndDesired", + format!("{WithStatesSavedAndDesired:?}") + ); + } + + #[test] + fn with_states_saved_diffs() { + assert_eq!("WithStatesSavedDiffs", format!("{WithStatesSavedDiffs:?}")); + } +} diff --git a/workspace_tests/src/resources/states.rs b/workspace_tests/src/resources/states.rs index 32c979f38..5bebe2c44 100644 --- a/workspace_tests/src/resources/states.rs +++ b/workspace_tests/src/resources/states.rs @@ -3,6 +3,8 @@ use peace::{ resources::{internal::StatesMut, states::StatesCurrent, type_reg::untagged::TypeMap}, }; +mod ts; + #[test] fn with_capacity_reserves_enough_capacity() { let states = StatesCurrent::with_capacity(100); diff --git a/workspace_tests/src/resources/states/ts.rs b/workspace_tests/src/resources/states/ts.rs new file mode 100644 index 000000000..36ab457f2 --- /dev/null +++ b/workspace_tests/src/resources/states/ts.rs @@ -0,0 +1,95 @@ +mod debug { + use peace::resources::states::ts::{ + Cleaned, CleanedDry, Current, Desired, Ensured, EnsuredDry, Saved, + }; + + #[test] + fn states_saved() { + assert_eq!("Saved", format!("{Saved:?}")) + } + + #[test] + fn states_current() { + assert_eq!("Current", format!("{Current:?}")) + } + + #[test] + fn states_desired() { + assert_eq!("Desired", format!("{Desired:?}")) + } + + #[test] + fn states_ensured() { + assert_eq!("Ensured", format!("{Ensured:?}")) + } + + #[test] + fn states_ensured_dry() { + assert_eq!("EnsuredDry", format!("{EnsuredDry:?}")) + } + + #[test] + fn states_cleaned() { + assert_eq!("Cleaned", format!("{Cleaned:?}")) + } + + #[test] + fn states_cleaned_dry() { + assert_eq!("CleanedDry", format!("{CleanedDry:?}")) + } +} + +mod serde { + use peace::resources::states::ts::{ + Cleaned, CleanedDry, Current, Desired, Ensured, EnsuredDry, Saved, + }; + + #[test] + fn saved() { + let s = serde_yaml::to_string(&Saved).unwrap(); + + assert!(serde_yaml::from_str::(&s).is_ok()); + } + + #[test] + fn current() { + let s = serde_yaml::to_string(&Current).unwrap(); + + assert!(serde_yaml::from_str::(&s).is_ok()); + } + + #[test] + fn desired() { + let s = serde_yaml::to_string(&Desired).unwrap(); + + assert!(serde_yaml::from_str::(&s).is_ok()); + } + + #[test] + fn ensured() { + let s = serde_yaml::to_string(&Ensured).unwrap(); + + assert!(serde_yaml::from_str::(&s).is_ok()); + } + + #[test] + fn ensured_dry() { + let s = serde_yaml::to_string(&EnsuredDry).unwrap(); + + assert!(serde_yaml::from_str::(&s).is_ok()); + } + + #[test] + fn cleaned() { + let s = serde_yaml::to_string(&Cleaned).unwrap(); + + assert!(serde_yaml::from_str::(&s).is_ok()); + } + + #[test] + fn cleaned_dry() { + let s = serde_yaml::to_string(&CleanedDry).unwrap(); + + assert!(serde_yaml::from_str::(&s).is_ok()); + } +} From 493f53548feba0f3866fa2eb69eaa00a5025e65e Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 27 Dec 2022 11:02:10 +1300 Subject: [PATCH 11/14] Add tests for `StatesDeserializer`. --- crate/rt_model/src/states_deserializer.rs | 151 ++++++++++-------- item_specs/Cargo.toml | 8 +- item_specs/file_download/Cargo.toml | 2 +- item_specs/sh_cmd/Cargo.toml | 2 +- item_specs/sh_sync_cmd/Cargo.toml | 2 +- item_specs/tar_x/Cargo.toml | 2 +- workspace_tests/Cargo.toml | 2 +- workspace_tests/b | 0 workspace_tests/src/rt_model.rs | 1 + .../src/rt_model/states_deserializer.rs | 111 +++++++++++++ 10 files changed, 204 insertions(+), 77 deletions(-) delete mode 100644 workspace_tests/b create mode 100644 workspace_tests/src/rt_model/states_deserializer.rs diff --git a/crate/rt_model/src/states_deserializer.rs b/crate/rt_model/src/states_deserializer.rs index 734cdb824..19d5d766a 100644 --- a/crate/rt_model/src/states_deserializer.rs +++ b/crate/rt_model/src/states_deserializer.rs @@ -12,14 +12,44 @@ use peace_resources::{ use crate::{Error, Storage}; -/// Reads [`StatesSaved`]s from storage. -#[derive(Debug)] +/// Reads [`StatesSaved`] and [`StatesDesired`] from storage. pub struct StatesDeserializer(PhantomData); impl StatesDeserializer where E: std::error::Error + From + Send, { + /// Returns the [`StatesSaved`] of all [`ItemSpec`]s if it exists on + /// disk. + /// + /// # Parameters: + /// + /// * `storage`: `Storage` to read from. + /// * `states`: States to serialize. + /// * `states_file_path`: Path to save the serialized states to. + /// + /// [`ItemSpec`]: peace_cfg::ItemSpec + pub async fn serialize( + storage: &Storage, + states: &States, + states_file_path: &Path, + ) -> Result<(), E> + where + TS: Send + Sync, + { + storage + .serialized_write( + #[cfg(not(target_arch = "wasm32"))] + "StatesDeserializer::serialize".to_string(), + states_file_path, + states, + Error::StatesSerialize, + ) + .await?; + + Ok(()) + } + /// Returns the [`StatesSaved`] of all [`ItemSpec`]s if it exists on /// disk. /// @@ -127,51 +157,37 @@ where states_file_path: &Path, ) -> Result>, E> where - TS: Send, + TS: Send + Sync, { - if !states_file_path.exists() { - return Ok(None); - } - - let states_current = storage - .read_with_sync_api(thread_name, states_file_path, |file| { - let deserializer = serde_yaml::Deserializer::from_reader(file); - let states_current = - States::from(states_type_reg.deserialize_map(deserializer).map_err( - |error| { - #[cfg(not(feature = "error_reporting"))] - { - Error::StatesDeserialize { error } - } - #[cfg(feature = "error_reporting")] - { - use miette::NamedSource; + let states_opt = storage + .serialized_typemap_read_opt(thread_name, states_type_reg, states_file_path, |error| { + #[cfg(not(feature = "error_reporting"))] + { + Error::StatesDeserialize { error } + } + #[cfg(feature = "error_reporting")] + { + use miette::NamedSource; - let file_contents = - std::fs::read_to_string(states_file_path).unwrap(); + let file_contents = std::fs::read_to_string(states_file_path).unwrap(); - let (error_span, error_message, context_span) = - Self::error_and_context(&file_contents, &error); - let states_file_source = NamedSource::new( - states_file_path.to_string_lossy(), - file_contents, - ); + let (error_span, error_message, context_span) = + Self::error_and_context(&file_contents, &error); + let states_file_source = + NamedSource::new(states_file_path.to_string_lossy(), file_contents); - Error::StatesDeserialize { - states_file_source, - error_span, - error_message, - context_span, - error, - } - } - }, - )?); - Ok(states_current) + Error::StatesDeserialize { + states_file_source, + error_span, + error_message, + context_span, + error, + } + } }) .await?; - Ok(Some(states_current)) + Ok(states_opt) } /// Returns the [`States`] of all [`ItemSpec`]s if it exists on disk. @@ -197,42 +213,35 @@ where states_type_reg: &TypeReg, states_file_path: &Path, ) -> Result>, E> { - let states_serialized = storage.get_item_opt(&states_file_path)?; - - if let Some(states_serialized) = states_serialized { - let deserializer = serde_yaml::Deserializer::from_str(&states_serialized); - let states = States::from(states_type_reg.deserialize_map(deserializer).map_err( - |error| { - #[cfg(not(feature = "error_reporting"))] - { - Error::StatesDeserialize { error } - } - #[cfg(feature = "error_reporting")] - { - use miette::NamedSource; + let states_opt = storage + .serialized_typemap_read_opt(states_type_reg, states_file_path, |error| { + #[cfg(not(feature = "error_reporting"))] + { + Error::StatesDeserialize { error } + } + #[cfg(feature = "error_reporting")] + { + use miette::NamedSource; - let file_contents = std::fs::read_to_string(&states_file_path).unwrap(); + let file_contents = std::fs::read_to_string(&states_file_path).unwrap(); - let (error_span, error_message, context_span) = - Self::error_and_context(&file_contents, &error); - let states_file_source = - NamedSource::new(states_file_path.to_string_lossy(), file_contents); + let (error_span, error_message, context_span) = + Self::error_and_context(&file_contents, &error); + let states_file_source = + NamedSource::new(states_file_path.to_string_lossy(), file_contents); - Error::StatesDeserialize { - states_file_source, - error_span, - error_message, - context_span, - error, - } + Error::StatesDeserialize { + states_file_source, + error_span, + error_message, + context_span, + error, } - }, - )?); + } + }) + .await?; - Ok(Some(states)) - } else { - Ok(None) - } + Ok(states_opt) } /// Returns the error location and message to pass to miette. diff --git a/item_specs/Cargo.toml b/item_specs/Cargo.toml index 85c74859e..292d1fef9 100644 --- a/item_specs/Cargo.toml +++ b/item_specs/Cargo.toml @@ -25,11 +25,17 @@ peace_item_spec_sh_sync_cmd = { path = "sh_sync_cmd", version = "0.0.5", optiona peace_item_spec_tar_x = { path = "tar_x", version = "0.0.5", optional = true } [dev-dependencies] -peace = { path = "..", version = "0.0.5" } +peace = { path = "..", version = "0.0.5", default-features = false } [features] default = [] + +# `peace` features +output_colorized = ["peace/output_colorized"] +output_json = ["peace/output_json"] + error_reporting = [ + "peace/error_reporting", "peace_item_spec_file_download?/error_reporting", "peace_item_spec_sh_cmd?/error_reporting", "peace_item_spec_sh_sync_cmd?/error_reporting", diff --git a/item_specs/file_download/Cargo.toml b/item_specs/file_download/Cargo.toml index 3c0bf3ef3..2b9c594bb 100644 --- a/item_specs/file_download/Cargo.toml +++ b/item_specs/file_download/Cargo.toml @@ -19,7 +19,7 @@ test = false bytes = "1.3.0" futures = "0.3.25" miette = { workspace = true, optional = true } -peace = { path = "../..", version = "0.0.5" } +peace = { path = "../..", version = "0.0.5", default-features = false } reqwest = { version = "0.11.13", features = ["stream"] } serde = { version = "1.0.151", features = ["derive"] } thiserror = "1.0.38" diff --git a/item_specs/sh_cmd/Cargo.toml b/item_specs/sh_cmd/Cargo.toml index 734cd0ac3..e2ac01452 100644 --- a/item_specs/sh_cmd/Cargo.toml +++ b/item_specs/sh_cmd/Cargo.toml @@ -19,7 +19,7 @@ test = false chrono = { version = "0.4.23", default-features = false, features = ["clock", "serde"] } derivative = { workspace = true } miette = { workspace = true, optional = true } -peace = { path = "../..", version = "0.0.5" } +peace = { path = "../..", version = "0.0.5", default-features = false } serde = { version = "1.0.151", features = ["derive"] } thiserror = "1.0.38" diff --git a/item_specs/sh_sync_cmd/Cargo.toml b/item_specs/sh_sync_cmd/Cargo.toml index 96f63baf7..6c603db14 100644 --- a/item_specs/sh_sync_cmd/Cargo.toml +++ b/item_specs/sh_sync_cmd/Cargo.toml @@ -18,7 +18,7 @@ test = false [dependencies] chrono = { version = "0.4.23", default-features = false, features = ["clock", "serde"] } miette = { workspace = true, optional = true } -peace = { path = "../..", version = "0.0.5" } +peace = { path = "../..", version = "0.0.5", default-features = false } serde = { version = "1.0.151", features = ["derive"] } thiserror = "1.0.38" diff --git a/item_specs/tar_x/Cargo.toml b/item_specs/tar_x/Cargo.toml index 5852af515..e885844a7 100644 --- a/item_specs/tar_x/Cargo.toml +++ b/item_specs/tar_x/Cargo.toml @@ -18,7 +18,7 @@ test = false [dependencies] derivative = { workspace = true } miette = { workspace = true, optional = true } -peace = { path = "../..", version = "0.0.5" } +peace = { path = "../..", version = "0.0.5", default-features = false } serde = { version = "1.0.151", features = ["derive"] } # We use this instead of tokio-tar, because: # diff --git a/workspace_tests/Cargo.toml b/workspace_tests/Cargo.toml index 3056efede..6d410e48b 100644 --- a/workspace_tests/Cargo.toml +++ b/workspace_tests/Cargo.toml @@ -18,7 +18,7 @@ test = true [dev-dependencies] diff-struct = "0.5.1" -peace = { path = "..", version = "0.0.5" } +peace = { path = "..", version = "0.0.5", default-features = false } peace_item_specs = { path = "../item_specs", version = "0.0.5" } pretty_assertions = "1.3.0" serde = { version = "1.0.151", features = ["derive"] } diff --git a/workspace_tests/b b/workspace_tests/b deleted file mode 100644 index e69de29bb..000000000 diff --git a/workspace_tests/src/rt_model.rs b/workspace_tests/src/rt_model.rs index 26dc9c8d4..85a0e06f6 100644 --- a/workspace_tests/src/rt_model.rs +++ b/workspace_tests/src/rt_model.rs @@ -5,4 +5,5 @@ mod item_spec_boxed; mod item_spec_wrapper; mod output_format; mod output_format_parse_error; +mod states_deserializer; mod workspace_dirs_builder; diff --git a/workspace_tests/src/rt_model/states_deserializer.rs b/workspace_tests/src/rt_model/states_deserializer.rs new file mode 100644 index 000000000..dd0984dbe --- /dev/null +++ b/workspace_tests/src/rt_model/states_deserializer.rs @@ -0,0 +1,111 @@ +use peace::{ + cfg::{item_spec_id, ItemSpecId}, + resources::{ + internal::StatesMut, paths::StatesSavedFile, states::StatesSaved, + type_reg::untagged::TypeReg, + }, + rt_model::{Error, StatesDeserializer, Storage}, +}; +use pretty_assertions::assert_eq; + +#[tokio::test] +async fn serialize() -> Result<(), Box> { + let tempdir = tempfile::tempdir()?; + let storage = Storage; + let states_saved_file = StatesSavedFile::new(tempdir.path().join("states_saved.yaml")); + + let states = { + let mut states = StatesMut::new(); + states.insert(item_spec_id!("a"), 123u32); + StatesSaved::from(states) + }; + StatesDeserializer::::serialize(&storage, &states, &states_saved_file).await?; + + let serialized = tokio::fs::read_to_string(states_saved_file).await?; + assert_eq!("a: 123\n", serialized); + + Ok(()) +} + +#[tokio::test] +async fn deserialize_saved() -> Result<(), Box> { + let tempdir = tempfile::tempdir()?; + let storage = Storage; + let item_spec_id = item_spec_id!("a"); + let mut states_type_reg = TypeReg::new_typed(); + states_type_reg.register::(item_spec_id.clone()); + let states_saved_file = StatesSavedFile::new(tempdir.path().join("states_saved.yaml")); + + let states = { + let mut states = StatesMut::new(); + states.insert(item_spec_id.clone(), 123u32); + StatesSaved::from(states) + }; + StatesDeserializer::::serialize(&storage, &states, &states_saved_file).await?; + + let states_deserialized = StatesDeserializer::::deserialize_saved( + &storage, + &states_type_reg, + &states_saved_file, + ) + .await?; + + assert_eq!( + Some(123), + states_deserialized.get::(&item_spec_id).copied() + ); + + Ok(()) +} + +#[tokio::test] +async fn deserialize_saved_error_maps_byte_indices() -> Result<(), Box> { + let tempdir = tempfile::tempdir()?; + let storage = Storage; + let item_spec_id = item_spec_id!("a"); + let mut states_type_reg = TypeReg::new_typed(); + states_type_reg.register::(item_spec_id.clone()); + let states_saved_file = StatesSavedFile::new(tempdir.path().join("states_saved.yaml")); + + let contents = "a: [123]\n"; + tokio::fs::write(&states_saved_file, contents).await?; + + let error = StatesDeserializer::::deserialize_saved( + &storage, + &states_type_reg, + &states_saved_file, + ) + .await + .unwrap_err(); + + #[cfg(feature = "error_reporting")] + { + use peace::miette::SourceOffset; + let error_span_expected = { + let line = 1; + let column = 4; + Some(SourceOffset::from_location(contents, line, column)) + }; + + if let Error::StatesDeserialize { + states_file_source: _, + error_span, + error_message, + context_span, + error: _, + } = error + { + assert_eq!(error_span_expected, error_span); + assert_eq!("a: invalid type: sequence, expected u32", error_message); + assert_eq!(None, context_span); + } else { + panic!("Expected error to be `Error::StatesDeserialize {{ .. }}`, but was {error:?}"); + } + } + #[cfg(not(feature = "error_reporting"))] + { + assert!(matches!(error, Error::StatesDeserialize { error: _ })); + } + + Ok(()) +} From 623858bc9c44f83b4217f3a92b31a86da252460f Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 27 Dec 2022 11:04:34 +1300 Subject: [PATCH 12/14] Update `StatesCurrentDiscoverCmd` and `StatesDesiredDiscoverCmd` to use `StatesDeserializer::serialize`. --- .../cmds/sub/states_current_discover_cmd.rs | 31 +++---------------- .../cmds/sub/states_desired_discover_cmd.rs | 30 ++---------------- crate/rt_model/src/states_deserializer.rs | 5 ++- 3 files changed, 10 insertions(+), 56 deletions(-) diff --git a/crate/rt/src/cmds/sub/states_current_discover_cmd.rs b/crate/rt/src/cmds/sub/states_current_discover_cmd.rs index 5e7dd770d..6484c2bb5 100644 --- a/crate/rt/src/cmds/sub/states_current_discover_cmd.rs +++ b/crate/rt/src/cmds/sub/states_current_discover_cmd.rs @@ -201,41 +201,18 @@ where Ok(states) } - #[cfg(not(target_arch = "wasm32"))] async fn serialize_internal( resources: &mut Resources, - states: &StatesCurrent, + states_current: &StatesCurrent, ) -> Result<(), E> { - let flow_dir = resources.borrow::(); - let storage = resources.borrow::(); - let states_saved_file = StatesSavedFile::from(&*flow_dir); - - storage - .write_with_sync_api( - "states_saved_file_write".to_string(), - &states_saved_file, - |file| serde_yaml::to_writer(file, states).map_err(Error::StatesSerialize), - ) - .await?; - drop(flow_dir); - drop(storage); - - resources.insert(states_saved_file); - - Ok(()) - } + use peace_rt_model::StatesDeserializer; - #[cfg(target_arch = "wasm32")] - async fn serialize_internal( - resources: &mut Resources, - states: &StatesCurrent, - ) -> Result<(), E> { let flow_dir = resources.borrow::(); let storage = resources.borrow::(); let states_saved_file = StatesSavedFile::from(&*flow_dir); - let states_serialized = serde_yaml::to_string(&*states).map_err(Error::StatesSerialize)?; - storage.set_item(&states_saved_file, &states_serialized)?; + StatesDeserializer::serialize(&storage, states_current, &states_saved_file).await?; + drop(flow_dir); drop(storage); diff --git a/crate/rt/src/cmds/sub/states_desired_discover_cmd.rs b/crate/rt/src/cmds/sub/states_desired_discover_cmd.rs index 7953656a0..8afd559b4 100644 --- a/crate/rt/src/cmds/sub/states_desired_discover_cmd.rs +++ b/crate/rt/src/cmds/sub/states_desired_discover_cmd.rs @@ -8,7 +8,7 @@ use peace_resources::{ states::{ts::Desired, StatesDesired}, Resources, }; -use peace_rt_model::{CmdContext, Error, ItemSpecGraph, Storage}; +use peace_rt_model::{CmdContext, Error, ItemSpecGraph, StatesDeserializer, Storage}; use crate::BUFFERED_FUTURES_MAX; @@ -83,7 +83,6 @@ where Ok(states_desired) } - #[cfg(not(target_arch = "wasm32"))] pub(crate) async fn serialize_internal( resources: &mut Resources, states_desired: &StatesDesired, @@ -92,33 +91,8 @@ where let storage = resources.borrow::(); let states_desired_file = StatesDesiredFile::from(&*flow_dir); - storage - .write_with_sync_api( - "states_desired_file_write".to_string(), - &states_desired_file, - |file| serde_yaml::to_writer(file, states_desired).map_err(Error::StatesSerialize), - ) - .await?; - drop(flow_dir); - drop(storage); - - resources.insert(states_desired_file); - - Ok(()) - } - - #[cfg(target_arch = "wasm32")] - pub(crate) async fn serialize_internal( - resources: &mut Resources, - states_desired: &StatesDesired, - ) -> Result<(), E> { - let flow_dir = resources.borrow::(); - let storage = resources.borrow::(); - let states_desired_file = StatesDesiredFile::from(&*flow_dir); + StatesDeserializer::serialize(&storage, states_desired, &states_desired_file).await?; - let states_serialized = - serde_yaml::to_string(states_desired).map_err(Error::StatesSerialize)?; - storage.set_item(&states_desired_file, &states_serialized)?; drop(flow_dir); drop(storage); diff --git a/crate/rt_model/src/states_deserializer.rs b/crate/rt_model/src/states_deserializer.rs index 19d5d766a..823581cc4 100644 --- a/crate/rt_model/src/states_deserializer.rs +++ b/crate/rt_model/src/states_deserializer.rs @@ -212,7 +212,10 @@ where storage: &Storage, states_type_reg: &TypeReg, states_file_path: &Path, - ) -> Result>, E> { + ) -> Result>, E> + where + TS: Send + Sync, + { let states_opt = storage .serialized_typemap_read_opt(states_type_reg, states_file_path, |error| { #[cfg(not(feature = "error_reporting"))] From 80eb15f50c9a1befcfc9d1d6a97625880eed816d Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 27 Dec 2022 11:52:16 +1300 Subject: [PATCH 13/14] Fix features to correctly not enable `"error_reporting"`. --- .cargo/config.toml | 4 ++-- Cargo.toml | 2 +- crate/rt_model_hack/Cargo.toml | 10 ++++++++-- examples/app_cycle/Cargo.toml | 2 +- examples/download/Cargo.toml | 2 +- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index dabbb54fd..64378b4fb 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,13 +3,13 @@ test_0 = ["nextest", "run", "--workspace", "--no-default-features"] test_1 = ["nextest", "run", "--workspace", "--features", "output_colorized"] test_2 = ["nextest", "run", "--workspace", "--features", "output_json"] -test_3 = ["nextest", "run", "--workspace", "--features", "output_colorized output_json"] +test_3 = ["nextest", "run", "--workspace", "--all-features"] # Coverage for different feature combinations coverage_clean = ["llvm-cov", "clean", "--workspace"] coverage_0 = ["llvm-cov", "--no-report", "--output-dir", "./target/coverage", "nextest", "--workspace", "--no-default-features"] coverage_1 = ["llvm-cov", "--no-report", "--output-dir", "./target/coverage", "nextest", "--workspace", "--features", "output_colorized"] coverage_2 = ["llvm-cov", "--no-report", "--output-dir", "./target/coverage", "nextest", "--workspace", "--features", "output_json"] -coverage_3 = ["llvm-cov", "--no-report", "--output-dir", "./target/coverage", "nextest", "--workspace", "--features", "output_colorized output_json"] +coverage_3 = ["llvm-cov", "--no-report", "--output-dir", "./target/coverage", "nextest", "--workspace", "--all-features"] coverage_merge = 'llvm-cov report --lcov --output-path ./target/coverage/lcov.info' coverage_open = 'llvm-cov report --open --output-dir ./target/coverage' diff --git a/Cargo.toml b/Cargo.toml index 3e28cc0de..59fdbedb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ tar = "0.4.38" type_reg = { version = "0.5.0", features = ["debug", "untagged", "ordered"] } [features] -default = ["error_reporting", "output_colorized"] +default = [] error_reporting = ["dep:miette", "miette?/fancy", "peace_rt/error_reporting", "peace_rt_model/error_reporting"] output_colorized = ["peace_rt_model/output_colorized"] output_json = ["peace_rt_model/output_json"] diff --git a/crate/rt_model_hack/Cargo.toml b/crate/rt_model_hack/Cargo.toml index 9ff66d585..b1f7f5768 100644 --- a/crate/rt_model_hack/Cargo.toml +++ b/crate/rt_model_hack/Cargo.toml @@ -33,7 +33,13 @@ test = false # [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -peace_rt_model_native = { path = "../rt_model_native", version = "0.0.5", features = ["error_reporting"] } +peace_rt_model_native = { path = "../rt_model_native", version = "0.0.5" } [target.'cfg(target_arch = "wasm32")'.dependencies] -peace_rt_model_web = { path = "../rt_model_web", version = "0.0.5", features = ["error_reporting"] } +peace_rt_model_web = { path = "../rt_model_web", version = "0.0.5" } + +[features] +error_reporting = [ + "peace_rt_model_native/error_reporting", + "peace_rt_model_web/error_reporting", +] diff --git a/examples/app_cycle/Cargo.toml b/examples/app_cycle/Cargo.toml index cb8da4fa6..0b3d57df2 100644 --- a/examples/app_cycle/Cargo.toml +++ b/examples/app_cycle/Cargo.toml @@ -18,7 +18,7 @@ test = false crate-type = ["cdylib", "rlib"] [dependencies] -peace = { path = "../.." } +peace = { path = "../..", default_features = false } peace_item_specs = { path = "../../item_specs", features = ["file_download", "tar_x"] } semver = "1.0.16" serde = { version = "1.0.151", features = ["derive"] } diff --git a/examples/download/Cargo.toml b/examples/download/Cargo.toml index 12da02a6a..14bc6a914 100644 --- a/examples/download/Cargo.toml +++ b/examples/download/Cargo.toml @@ -18,7 +18,7 @@ test = false crate-type = ["cdylib", "rlib"] [dependencies] -peace = { path = "../.." } +peace = { path = "../..", default_features = false } peace_item_specs = { path = "../../item_specs", features = ["file_download"] } thiserror = "1.0.38" url = { version = "2.3.1", features = ["serde"] } From c3a1f90a1922eb60b8b2e3ee5e6f915fd9a81208 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Tue, 27 Dec 2022 11:57:46 +1300 Subject: [PATCH 14/14] Update `CHANGELOG.md`. --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c42dc1622..f6166d6d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,13 @@ ## unreleased -* `FileDownload` item spec now supports base64 storage for WASM target. +* `FileDownload` item spec now supports base64 storage for WASM target. ([#62]) * Implement `TarXItemSpec` for native target. ([#62]) +* Support multiple workspace, profile, and flow parameters. ([#45], [#63]) [#62]: https://github.com/azriel91/peace/pull/62 +[#45]: https://github.com/azriel91/peace/issues/45 +[#63]: https://github.com/azriel91/peace/pull/63 ## 0.0.5 (2022-12-18)