diff --git a/Cargo.lock b/Cargo.lock index 11b16b9ff6..81a731a7c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4116,6 +4116,7 @@ dependencies = [ "spk-storage", "tempfile", "tokio", + "tracing", ] [[package]] @@ -4257,6 +4258,7 @@ dependencies = [ "async-trait", "clap 4.5.0", "miette", + "serde_yaml 0.9.27", "spfs", "spk-build", "spk-cli-common", diff --git a/crates/spk-cli/cmd-build/Cargo.toml b/crates/spk-cli/cmd-build/Cargo.toml index 6b9d926972..e54493437b 100644 --- a/crates/spk-cli/cmd-build/Cargo.toml +++ b/crates/spk-cli/cmd-build/Cargo.toml @@ -27,10 +27,11 @@ spfs = { workspace = true } spk-cli-common = { workspace = true } spk-cmd-make-binary = { workspace = true } spk-cmd-make-source = { workspace = true } +spk-schema = { workspace = true } +tracing = { workspace = true } [dev-dependencies] rstest = { workspace = true } -spk-schema = { workspace = true } spk-storage = { workspace = true } tempfile = { workspace = true } tokio = { workspace = true } diff --git a/crates/spk-cli/cmd-build/src/cmd_build.rs b/crates/spk-cli/cmd-build/src/cmd_build.rs index 2d6718f326..c4c23f9f83 100644 --- a/crates/spk-cli/cmd-build/src/cmd_build.rs +++ b/crates/spk-cli/cmd-build/src/cmd_build.rs @@ -2,10 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 // https://github.com/spkenv/spk +use std::collections::BTreeMap; + use clap::Args; use miette::Result; use spk_cli_common::{flags, CommandArgs, Run}; use spk_cmd_make_binary::cmd_make_binary::PackageSpecifier; +use spk_schema::Lint::Key; #[cfg(test)] #[path = "./cmd_build_test/mod.rs"] @@ -83,6 +86,8 @@ impl Run for Build { } let mut builds_for_summary = spk_cli_common::BuildResult::default(); + let mut generated_lints = BTreeMap::new(); + for packages in runs { let mut make_source = spk_cmd_make_source::cmd_make_source::MakeSource { options: self.options.clone(), @@ -90,10 +95,13 @@ impl Run for Build { packages: packages.clone(), runtime: self.runtime.clone(), created_src: spk_cli_common::BuildResult::default(), + lints: BTreeMap::new(), }; let idents = make_source.make_source().await?; builds_for_summary.extend(make_source.created_src); + generated_lints.extend(std::mem::take(&mut make_source.lints)); + let mut make_binary = spk_cmd_make_binary::cmd_make_binary::MakeBinary { verbose: self.verbose, runtime: self.runtime.clone(), @@ -129,6 +137,17 @@ impl Run for Build { println!(" {artifact}"); } + if !generated_lints.is_empty() { + println!("Lints:"); + for (pkg, lints) in generated_lints.iter() { + for lint in lints.iter() { + match lint { + Key(k) => tracing::warn!("{} {}", pkg, k.generate_message()), + } + } + } + } + Ok(BuildResult { exit_status: 0, created_builds: builds_for_summary, diff --git a/crates/spk-cli/cmd-make-source/Cargo.toml b/crates/spk-cli/cmd-make-source/Cargo.toml index 702ce38687..037ef78887 100644 --- a/crates/spk-cli/cmd-make-source/Cargo.toml +++ b/crates/spk-cli/cmd-make-source/Cargo.toml @@ -24,6 +24,7 @@ migration-to-components = [ miette = { workspace = true, features = ["fancy"] } async-trait = { workspace = true } clap = { workspace = true } +serde_yaml = { workspace = true } spfs = { workspace = true } spk-build = { workspace = true } spk-cli-common = { workspace = true } diff --git a/crates/spk-cli/cmd-make-source/src/cmd_make_source.rs b/crates/spk-cli/cmd-make-source/src/cmd_make_source.rs index 6b7629cc61..54bd0779ad 100644 --- a/crates/spk-cli/cmd-make-source/src/cmd_make_source.rs +++ b/crates/spk-cli/cmd-make-source/src/cmd_make_source.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // https://github.com/spkenv/spk +use std::collections::BTreeMap; use std::path::PathBuf; use std::sync::Arc; @@ -11,7 +12,17 @@ use spk_build::SourcePackageBuilder; use spk_cli_common::{flags, BuildArtifact, BuildResult, CommandArgs, Run}; use spk_schema::foundation::format::FormatIdent; use spk_schema::ident::LocatedBuildIdent; -use spk_schema::{Package, Recipe, SpecTemplate, Template, TemplateExt}; +use spk_schema::v0::Spec; +use spk_schema::{ + AnyIdent, + Lint, + LintedItem, + Package, + Recipe, + SpecTemplate, + Template, + TemplateExt, +}; use spk_storage as storage; /// Build a source package from a spec file. @@ -34,6 +45,10 @@ pub struct MakeSource { /// Populated with the created src to generate a summary from the caller. #[clap(skip)] pub created_src: BuildResult, + + /// Used to gather lints to output at the end of a build. + #[clap(skip)] + pub lints: BTreeMap>, } #[async_trait::async_trait] @@ -81,6 +96,7 @@ impl MakeSource { template } }; + let root = template .file_path() .parent() @@ -100,6 +116,20 @@ impl MakeSource { })?; let ident = recipe.ident(); + let lints: std::result::Result>, serde_yaml::Error> = + serde_yaml::from_str(&template.render_to_string(&options)?); + + match lints { + Ok(linted_item) => match linted_item.lints.is_empty() { + true => (), + false => { + self.lints + .insert(ident.format_ident(), linted_item.lints.clone()); + } + }, + Err(e) => tracing::error!("Failed to retrieve lints: {e}"), + } + tracing::info!("saving package recipe for {}", ident.format_ident()); local.force_publish_recipe(&recipe).await?;