Rust/cargo-azsphere/src/config/mod.rs (140 lines of code) (raw):
use cargo_toml::Error as CargoTomlError;
use cargo_toml::Manifest;
use std::path::{Path, PathBuf};
use toml::value::Value;
use crate::error::{ConfigError, Error};
use metadata::{CompoundMetadataConfig, ExtraMetaData, MetadataConfig, TomlValueHelper};
mod metadata;
#[derive(Debug, Clone)]
pub enum ExtraMetadataSource {
File(PathBuf, Option<String>),
Text(String),
}
#[derive(Debug)]
pub struct Config {
manifest: Manifest,
_manifest_path: PathBuf,
extra_metadata: Vec<ExtraMetaData>,
}
/// Required fields, retrieved from the app's Cargo.toml
#[derive(Debug)]
pub struct PackageConfig {
/// Cargo.Toml package.name
pub name: String,
/// app manifest filename
pub app_manifest: String,
/// ARV version to target
pub arv: String,
/// subdir under the HardwareDefinitions directory tree to use (usually, mt3620_rdb)
pub target_hardware: Option<String>,
/// base of JSON filename to use for the target (usually, sample_appliance)
pub target_definition: Option<String>,
/// extra files to include in the app package
pub extra_files: Option<Vec<Value>>,
}
/// Parse the app's Cargo.toml, with optional overrides
impl Config {
pub fn new(path: &Path, extra_metadata: &[ExtraMetadataSource]) -> Result<Self, Error> {
let manifest_path = path.to_path_buf();
let extra_metadata = extra_metadata
.iter()
.map(|v| ExtraMetaData::new(v))
.collect::<Result<Vec<_>, _>>()?;
Manifest::from_path(&path)
.map(|manifest| Config {
manifest,
_manifest_path: manifest_path,
extra_metadata,
})
.map_err(|err| match err {
CargoTomlError::Io(e) => Error::FileIo(PathBuf::from(path), e),
_ => Error::CargoToml(err),
})
}
fn get_value_from_config(package_root: &String, variable_name: &str) -> Option<String> {
let config_file = PathBuf::from(package_root).join(".cargo/config");
let str = std::fs::read_to_string(&config_file).expect("Error in reading the file");
let toml = str.parse::<Value>();
if let Ok(toml) = toml {
let env = toml["env"].as_table();
if let Some(env) = env {
let value = env[variable_name].as_str();
if let Some(value) = value {
let value = value.to_string();
return Some(value.replace("\"", ""));
}
}
}
return None;
}
fn get_arv_from_config(package_root: &String, verbose: bool) -> String {
let arv = Self::get_value_from_config(&package_root, "AZURE_SPHERE_ARV");
match arv {
Some(arv) => arv,
_ => {
let default_arv = "14".to_string();
if verbose {
println!("WARNING: Using default ARV {}", default_arv);
}
default_arv
}
}
}
pub fn package_config(
&self,
package_root: String,
verbose: bool,
) -> Result<PackageConfig, Error> {
let mut metadata_config = Vec::new();
let metadata = MetadataConfig::new_from_manifest(&self.manifest)?;
if let Some(metadata_file) = metadata {
metadata_config.push(metadata_file);
} else if verbose {
println!("No [package.metadata.azsphere] found. Using defaults.")
}
for v in &self.extra_metadata {
metadata_config.push(MetadataConfig::new_from_extra_metadata(v));
}
let metadata = CompoundMetadataConfig::new(metadata_config.as_slice());
let pkg = self
.manifest
.package
.as_ref()
.ok_or(ConfigError::Missing("package".to_string()))?;
let name = metadata
.get_str("name")?
.unwrap_or_else(|| pkg.name.as_str());
let app_manifest = metadata
.get_str("app_manifest")?
.unwrap_or_else(|| "app_manifest.json");
let arv = metadata.get_str("arv")?;
let arv = if arv.is_none() {
Self::get_arv_from_config(&package_root, verbose)
} else {
arv.unwrap().to_string()
};
let extra_files = metadata.get_array("extra_files")?;
let extra_files = if let Some(files) = extra_files {
Some(files.to_vec())
} else {
None
};
let target_definition = metadata.get_str("target_definition")?;
let target_definition = if target_definition.is_none() {
Self::get_value_from_config(&package_root, "AZURE_SPHERE_TARGET_DEFINITION")
} else {
Some(target_definition.unwrap().to_string())
};
let target_definition = if let Some(t) = target_definition {
Some(t)
} else {
None
};
let target_hardware = metadata.get_str("target_hardware")?;
let target_hardware = if target_hardware.is_none() {
Self::get_value_from_config(&package_root, "AZURE_SPHERE_TARGET_HARDWARE")
} else {
Some(target_hardware.unwrap().to_string())
};
Ok(PackageConfig {
name: name.to_string(),
app_manifest: app_manifest.to_string(),
arv,
target_definition,
target_hardware,
extra_files,
})
}
}