Skip to content

Commit 8e99755

Browse files
authored
Merge pull request #2527 from itowlson/validate-on-build
Try to load manifest during `spin build`
2 parents 9f1d9db + f54cf1f commit 8e99755

File tree

2 files changed

+51
-9
lines changed

2 files changed

+51
-9
lines changed

crates/build/src/lib.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,31 @@ use crate::manifest::component_build_configs;
1717

1818
/// If present, run the build command of each component.
1919
pub async fn build(manifest_file: &Path, component_ids: &[String]) -> Result<()> {
20-
let components = component_build_configs(manifest_file)
21-
.await
22-
.with_context(|| {
23-
format!(
24-
"Cannot read manifest file from {}",
25-
quoted_path(manifest_file)
26-
)
27-
})?;
20+
let (components, manifest_err) =
21+
component_build_configs(manifest_file)
22+
.await
23+
.with_context(|| {
24+
format!(
25+
"Cannot read manifest file from {}",
26+
quoted_path(manifest_file)
27+
)
28+
})?;
2829
let app_dir = parent_dir(manifest_file)?;
2930

31+
let build_result = build_components(component_ids, components, app_dir);
32+
33+
if let Some(e) = manifest_err {
34+
terminal::warn!("The manifest has errors not related to the Wasm component build. Error details:\n{e:#}");
35+
}
36+
37+
build_result
38+
}
39+
40+
fn build_components(
41+
component_ids: &[String],
42+
components: Vec<ComponentBuildInfo>,
43+
app_dir: PathBuf,
44+
) -> Result<(), anyhow::Error> {
3045
let components_to_build = if component_ids.is_empty() {
3146
components
3247
} else {

crates/build/src/manifest.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,36 @@ use std::{collections::BTreeMap, path::Path};
55
use spin_manifest::{schema::v2, ManifestVersion};
66

77
/// Returns a map of component IDs to [`v2::ComponentBuildConfig`]s for the
8-
/// given (v1 or v2) manifest path.
8+
/// given (v1 or v2) manifest path. If the manifest cannot be loaded, the
9+
/// function attempts fallback: if fallback succeeds, result is Ok but the load error
10+
/// is also returned via the second part of the return value tuple.
911
pub async fn component_build_configs(
1012
manifest_file: impl AsRef<Path>,
13+
) -> Result<(Vec<ComponentBuildInfo>, Option<spin_manifest::Error>)> {
14+
let manifest = spin_manifest::manifest_from_file(&manifest_file);
15+
match manifest {
16+
Ok(manifest) => Ok((build_configs_from_manifest(manifest), None)),
17+
Err(e) => fallback_load_build_configs(&manifest_file)
18+
.await
19+
.map(|bc| (bc, Some(e))),
20+
}
21+
}
22+
23+
fn build_configs_from_manifest(
24+
manifest: spin_manifest::schema::v2::AppManifest,
25+
) -> Vec<ComponentBuildInfo> {
26+
manifest
27+
.components
28+
.into_iter()
29+
.map(|(id, c)| ComponentBuildInfo {
30+
id: id.to_string(),
31+
build: c.build,
32+
})
33+
.collect()
34+
}
35+
36+
async fn fallback_load_build_configs(
37+
manifest_file: impl AsRef<Path>,
1138
) -> Result<Vec<ComponentBuildInfo>> {
1239
let manifest_text = tokio::fs::read_to_string(manifest_file).await?;
1340
Ok(match ManifestVersion::detect(&manifest_text)? {

0 commit comments

Comments
 (0)