Skip to content

Commit

Permalink
Merge pull request #2527 from itowlson/validate-on-build
Browse files Browse the repository at this point in the history
Try to load manifest during `spin build`
  • Loading branch information
itowlson authored May 23, 2024
2 parents 9f1d9db + f54cf1f commit 8e99755
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 9 deletions.
31 changes: 23 additions & 8 deletions crates/build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,31 @@ use crate::manifest::component_build_configs;

/// If present, run the build command of each component.
pub async fn build(manifest_file: &Path, component_ids: &[String]) -> Result<()> {
let components = component_build_configs(manifest_file)
.await
.with_context(|| {
format!(
"Cannot read manifest file from {}",
quoted_path(manifest_file)
)
})?;
let (components, manifest_err) =
component_build_configs(manifest_file)
.await
.with_context(|| {
format!(
"Cannot read manifest file from {}",
quoted_path(manifest_file)
)
})?;
let app_dir = parent_dir(manifest_file)?;

let build_result = build_components(component_ids, components, app_dir);

if let Some(e) = manifest_err {
terminal::warn!("The manifest has errors not related to the Wasm component build. Error details:\n{e:#}");
}

build_result
}

fn build_components(
component_ids: &[String],
components: Vec<ComponentBuildInfo>,
app_dir: PathBuf,
) -> Result<(), anyhow::Error> {
let components_to_build = if component_ids.is_empty() {
components
} else {
Expand Down
29 changes: 28 additions & 1 deletion crates/build/src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,36 @@ use std::{collections::BTreeMap, path::Path};
use spin_manifest::{schema::v2, ManifestVersion};

/// Returns a map of component IDs to [`v2::ComponentBuildConfig`]s for the
/// given (v1 or v2) manifest path.
/// given (v1 or v2) manifest path. If the manifest cannot be loaded, the
/// function attempts fallback: if fallback succeeds, result is Ok but the load error
/// is also returned via the second part of the return value tuple.
pub async fn component_build_configs(
manifest_file: impl AsRef<Path>,
) -> Result<(Vec<ComponentBuildInfo>, Option<spin_manifest::Error>)> {
let manifest = spin_manifest::manifest_from_file(&manifest_file);
match manifest {
Ok(manifest) => Ok((build_configs_from_manifest(manifest), None)),
Err(e) => fallback_load_build_configs(&manifest_file)
.await
.map(|bc| (bc, Some(e))),
}
}

fn build_configs_from_manifest(
manifest: spin_manifest::schema::v2::AppManifest,
) -> Vec<ComponentBuildInfo> {
manifest
.components
.into_iter()
.map(|(id, c)| ComponentBuildInfo {
id: id.to_string(),
build: c.build,
})
.collect()
}

async fn fallback_load_build_configs(
manifest_file: impl AsRef<Path>,
) -> Result<Vec<ComponentBuildInfo>> {
let manifest_text = tokio::fs::read_to_string(manifest_file).await?;
Ok(match ManifestVersion::detect(&manifest_text)? {
Expand Down

0 comments on commit 8e99755

Please sign in to comment.