diff --git a/src/config/imp.rs b/src/config/imp.rs index c646a8c..a4208dc 100644 --- a/src/config/imp.rs +++ b/src/config/imp.rs @@ -5,7 +5,7 @@ //! Configuration for a package. use crate::package::{Package, PackageOutput, PackageSource}; -use crate::target::Target; +use crate::target::TargetMap; use serde_derive::Deserialize; use std::collections::BTreeMap; use std::path::Path; @@ -110,7 +110,7 @@ pub struct Config { impl Config { /// Returns target packages to be assembled on the builder machine. - pub fn packages_to_build(&self, target: &Target) -> PackageMap<'_> { + pub fn packages_to_build(&self, target: &TargetMap) -> PackageMap<'_> { PackageMap( self.packages .iter() @@ -120,7 +120,7 @@ impl Config { } /// Returns target packages which should execute on the deployment machine. - pub fn packages_to_deploy(&self, target: &Target) -> PackageMap<'_> { + pub fn packages_to_deploy(&self, target: &TargetMap) -> PackageMap<'_> { let all_packages = self.packages_to_build(target).0; PackageMap( all_packages @@ -189,7 +189,7 @@ mod test { ]), }; - let mut order = cfg.packages_to_build(&Target::default()).build_order(); + let mut order = cfg.packages_to_build(&TargetMap::default()).build_order(); // "pkg-a" comes first, because "pkg-b" depends on it. assert_eq!(order.next(), Some(vec![(&pkg_a_name, &pkg_a)])); assert_eq!(order.next(), Some(vec![(&pkg_b_name, &pkg_b)])); @@ -230,7 +230,7 @@ mod test { ]), }; - let mut order = cfg.packages_to_build(&Target::default()).build_order(); + let mut order = cfg.packages_to_build(&TargetMap::default()).build_order(); order.next(); } @@ -255,7 +255,7 @@ mod test { packages: BTreeMap::from([(pkg_a_name.clone(), pkg_a.clone())]), }; - let mut order = cfg.packages_to_build(&Target::default()).build_order(); + let mut order = cfg.packages_to_build(&TargetMap::default()).build_order(); order.next(); } } diff --git a/src/package.rs b/src/package.rs index ee75b1a..d62e6a2 100644 --- a/src/package.rs +++ b/src/package.rs @@ -13,7 +13,7 @@ use crate::cache::{Cache, CacheError}; use crate::config::{PackageName, ServiceName}; use crate::input::{BuildInput, BuildInputs, MappedPath, TargetDirectory, TargetPackage}; use crate::progress::{NoProgress, Progress}; -use crate::target::Target; +use crate::target::TargetMap; use crate::timer::BuildTimer; use anyhow::{anyhow, bail, Context, Result}; @@ -183,7 +183,7 @@ pub struct Package { /// Identifies the targets for which the package should be included. /// /// If ommitted, the package is assumed to be included for all targets. - pub only_for_targets: Option>, + pub only_for_targets: Option, /// A human-readable string with suggestions for setup if packaging fails. #[serde(default)] @@ -204,7 +204,7 @@ async fn new_zone_archive_builder( /// Configuration that can modify how a package is built. pub struct BuildConfig<'a> { /// Describes the [Target] to build the package for. - pub target: &'a Target, + pub target: &'a TargetMap, /// Describes how progress will be communicated back to the caller. pub progress: &'a dyn Progress, @@ -213,7 +213,7 @@ pub struct BuildConfig<'a> { pub cache_disabled: bool, } -static DEFAULT_TARGET: Target = Target(BTreeMap::new()); +static DEFAULT_TARGET: TargetMap = TargetMap(BTreeMap::new()); static DEFAULT_PROGRESS: NoProgress = NoProgress::new(); impl Default for BuildConfig<'_> { @@ -266,7 +266,7 @@ impl Package { #[deprecated = "Use 'Package::create', which now takes a 'BuildConfig', and implements 'Default'"] pub async fn create_for_target( &self, - target: &Target, + target: &TargetMap, name: &PackageName, output_directory: &Utf8Path, ) -> Result { @@ -362,7 +362,7 @@ impl Package { pub async fn create_with_progress_for_target( &self, progress: &impl Progress, - target: &Target, + target: &TargetMap, name: &PackageName, output_directory: &Utf8Path, ) -> Result { @@ -444,7 +444,7 @@ impl Package { fn get_paths_inputs( &self, - target: &Target, + target: &TargetMap, paths: &Vec, ) -> Result { let mut inputs = BuildInputs::new(); @@ -532,7 +532,7 @@ impl Package { fn get_all_inputs( &self, package_name: &PackageName, - target: &Target, + target: &TargetMap, output_directory: &Utf8Path, zoned: bool, version: Option<&semver::Version>, @@ -870,7 +870,7 @@ pub struct InterpolatedString(String); impl InterpolatedString { // Interpret the string for the specified target. // Substitutes key/value pairs as necessary. - pub fn interpolate(&self, target: &Target) -> Result { + pub fn interpolate(&self, target: &TargetMap) -> Result { let mut input = self.0.as_str(); let mut output = String::new(); @@ -912,7 +912,7 @@ pub struct InterpolatedMappedPath { } impl InterpolatedMappedPath { - fn interpolate(&self, target: &Target) -> Result { + fn interpolate(&self, target: &TargetMap) -> Result { Ok(MappedPath { from: Utf8PathBuf::from(self.from.interpolate(target)?), to: Utf8PathBuf::from(self.to.interpolate(target)?), @@ -926,7 +926,7 @@ mod test { #[test] fn interpolate_noop() { - let target = Target(BTreeMap::new()); + let target = TargetMap(BTreeMap::new()); let is = InterpolatedString(String::from("nothing to change")); let s = is.interpolate(&target).unwrap(); @@ -935,7 +935,7 @@ mod test { #[test] fn interpolate_single() { - let mut target = Target(BTreeMap::new()); + let mut target = TargetMap(BTreeMap::new()); target.0.insert("key1".to_string(), "value1".to_string()); let is = InterpolatedString(String::from("{{key1}}")); @@ -945,7 +945,7 @@ mod test { #[test] fn interpolate_single_with_prefix() { - let mut target = Target(BTreeMap::new()); + let mut target = TargetMap(BTreeMap::new()); target.0.insert("key1".to_string(), "value1".to_string()); let is = InterpolatedString(String::from("prefix-{{key1}}")); @@ -955,7 +955,7 @@ mod test { #[test] fn interpolate_single_with_suffix() { - let mut target = Target(BTreeMap::new()); + let mut target = TargetMap(BTreeMap::new()); target.0.insert("key1".to_string(), "value1".to_string()); let is = InterpolatedString(String::from("{{key1}}-suffix")); @@ -965,7 +965,7 @@ mod test { #[test] fn interpolate_multiple() { - let mut target = Target(BTreeMap::new()); + let mut target = TargetMap(BTreeMap::new()); target.0.insert("key1".to_string(), "value1".to_string()); target.0.insert("key2".to_string(), "value2".to_string()); let is = InterpolatedString(String::from("{{key1}}-{{key2}}")); @@ -976,7 +976,7 @@ mod test { #[test] fn interpolate_missing_key() { - let mut target = Target(BTreeMap::new()); + let mut target = TargetMap(BTreeMap::new()); target.0.insert("key1".to_string(), "value1".to_string()); let is = InterpolatedString(String::from("{{key3}}")); @@ -991,7 +991,7 @@ mod test { #[test] fn interpolate_missing_closing() { - let mut target = Target(BTreeMap::new()); + let mut target = TargetMap(BTreeMap::new()); target.0.insert("key1".to_string(), "value1".to_string()); let is = InterpolatedString(String::from("{{key1")); @@ -1011,7 +1011,7 @@ mod test { // as part of they key -- INCLUDING other "{{" characters. #[test] fn interpolate_key_as_literal() { - let mut target = Target(BTreeMap::new()); + let mut target = TargetMap(BTreeMap::new()); target.0.insert("oh{{no".to_string(), "value".to_string()); let is = InterpolatedString(String::from("{{oh{{no}}")); diff --git a/src/target.rs b/src/target.rs index d803525..4b19c32 100644 --- a/src/target.rs +++ b/src/target.rs @@ -3,14 +3,19 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use crate::package::Package; +use serde::Deserialize; use std::collections::BTreeMap; -/// A target describes what platform and configuration we're trying -/// to deploy on. -#[derive(Clone, Debug, Default)] -pub struct Target(pub BTreeMap); +/// Describes what platform and configuration we're trying to deploy on. +/// +/// For flexibility, this is an arbitrary key-value map without any attached +/// semantics to particular keys. Those semantics are provided by the consumers +/// of this tooling within omicron. +#[derive(Clone, Debug, Default, PartialEq, Deserialize)] +#[serde(transparent)] +pub struct TargetMap(pub BTreeMap); -impl Target { +impl TargetMap { // Returns true if this target should include the package. pub(crate) fn includes_package(&self, pkg: &Package) -> bool { let valid_targets = if let Some(targets) = &pkg.only_for_targets { @@ -24,7 +29,7 @@ impl Target { // For each of the targets permitted by the package, check if // the current target matches. - for (k, v) in valid_targets { + for (k, v) in &valid_targets.0 { let target_value = if let Some(target_value) = self.0.get(k) { target_value } else { @@ -39,7 +44,7 @@ impl Target { } } -impl std::fmt::Display for Target { +impl std::fmt::Display for TargetMap { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { for (key, value) in &self.0 { write!(f, "{}={} ", key, value)?; @@ -54,7 +59,7 @@ pub enum TargetParseError { MissingEquals(String), } -impl std::str::FromStr for Target { +impl std::str::FromStr for TargetMap { type Err = TargetParseError; fn from_str(s: &str) -> Result { @@ -66,6 +71,6 @@ impl std::str::FromStr for Target { .map(|(k, v)| (k.to_string(), v.to_string())) }) .collect::, _>>()?; - Ok(Target(kvs)) + Ok(TargetMap(kvs)) } } diff --git a/tests/mod.rs b/tests/mod.rs index 13d7541..6453a57 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -15,7 +15,7 @@ mod test { use omicron_zone_package::config::{self, PackageName, ServiceName}; use omicron_zone_package::package::BuildConfig; use omicron_zone_package::progress::NoProgress; - use omicron_zone_package::target::Target; + use omicron_zone_package::target::TargetMap; const MY_PACKAGE: PackageName = PackageName::new_const("my-package"); @@ -224,7 +224,7 @@ mod test { let out = camino_tempfile::tempdir().unwrap(); // Ask for the order of packages to-be-built - let packages = cfg.packages_to_build(&Target::default()); + let packages = cfg.packages_to_build(&TargetMap::default()); let mut build_order = packages.build_order(); // Build the dependencies first.