@@ -150,7 +150,7 @@ impl TemplateNewCommandCore {
150150 variant : TemplateVariantInfo ,
151151 ) -> Result < ( ) > {
152152 let ( template_manager, suggested_plugins) =
153- env_templates_and_plugins ( target_environment) . await ?;
153+ env_templates_and_plugins ( target_environment, & variant ) . await ?;
154154
155155 let ( name, template_id) = self . resolve_name_template_syntax ( & template_manager, & variant) ?;
156156
@@ -284,11 +284,25 @@ impl TemplateNewCommandCore {
284284
285285async fn env_templates_and_plugins (
286286 target_environment : Option < & String > ,
287+ variant : & TemplateVariantInfo ,
287288) -> anyhow:: Result < ( TemplateManager , Vec < String > ) > {
288- Ok ( match target_environment {
289- Some ( env) => {
290- // - resolve the TE
291- let env_ref = parse_env ( env) ;
289+ let target_env_ref = match variant {
290+ TemplateVariantInfo :: NewApplication => target_environment. map ( |te| parse_env ( te) ) ,
291+ TemplateVariantInfo :: AddComponent { manifest_path } => {
292+ match infer_target_env_from_file ( manifest_path) {
293+ Ok ( t) => t,
294+ Err ( _) => {
295+ terminal:: warn!(
296+ "Couldn't determine target environment; using your installed templates.\n "
297+ ) ;
298+ None
299+ }
300+ }
301+ }
302+ } ;
303+
304+ Ok ( match target_env_ref {
305+ Some ( env_ref) => {
292306 let loaded_env =
293307 spin_environments:: load_environment_def ( & env_ref, & std:: env:: current_dir ( ) ?)
294308 . await ?;
@@ -313,11 +327,28 @@ async fn env_templates_and_plugins(
313327 . await ?;
314328 }
315329 if is_empty ( & template_manager) . await {
316- anyhow:: bail!(
317- "The {env} environment doesn't list any associated templates. Run `spin new` without `-E` to use generic templates."
318- ) ;
330+ match variant {
331+ TemplateVariantInfo :: NewApplication => {
332+ anyhow:: bail!(
333+ "The {env_ref} environment doesn't list any associated templates. Run `spin new` without `-E` to use generic templates."
334+ ) ;
335+ }
336+ TemplateVariantInfo :: AddComponent { .. } => {
337+ // `spin add` doesn't have an option for skipping a templateless env (the equivalent of `spin new` without `-E`).
338+ // Fall back to the installed templates.
339+ terminal:: warn!(
340+ "The application targets the {env_ref} environment, but that doesn't list any associated templates."
341+ ) ;
342+ eprintln ! (
343+ "Templates will instead be taken from the installed template set."
344+ ) ;
345+ eprintln ! ( ) ;
346+ ( TemplateManager :: try_default ( ) ?, vec ! [ ] )
347+ }
348+ }
349+ } else {
350+ ( template_manager, env_def. plugins ( ) . to_vec ( ) )
319351 }
320- ( template_manager, env_def. plugins ( ) . to_vec ( ) )
321352 }
322353 None => {
323354 let template_manager = TemplateManager :: try_default ( )
@@ -327,6 +358,25 @@ async fn env_templates_and_plugins(
327358 } )
328359}
329360
361+ fn infer_target_env_from_file (
362+ manifest_path : impl AsRef < Path > ,
363+ ) -> anyhow:: Result < Option < spin_manifest:: schema:: v2:: TargetEnvironmentRef > > {
364+ let manifest = spin_manifest:: manifest_from_file ( manifest_path) ?;
365+ match manifest. application . targets . len ( ) {
366+ 0 => Ok ( None ) ,
367+ 1 => Ok ( Some ( manifest. application . targets [ 0 ] . clone ( ) ) ) ,
368+ _ => {
369+ terminal:: warn!( "This application targets multiple environments." ) ;
370+ eprintln ! (
371+ "Spin doesn't currently support environment-specific templates for multiple environments."
372+ ) ;
373+ eprintln ! ( "Templates will instead be taken from the installed template set." ) ;
374+ eprintln ! ( ) ;
375+ Ok ( None )
376+ }
377+ }
378+ }
379+
330380#[ derive( Clone , Debug ) ]
331381pub struct ParameterValue {
332382 pub name : String ,
@@ -385,10 +435,16 @@ async fn prompt_template(
385435 . collect :: < Vec < _ > > ( ) ;
386436
387437 if templates. is_empty ( ) {
388- if tags. len ( ) == 1 {
389- bail ! ( "No templates matched '{}'" , tags[ 0 ] ) ;
390- } else {
391- bail ! ( "No templates matched all tags" ) ;
438+ match tags. len ( ) {
439+ 0 => {
440+ bail ! ( "No suitable templates found" ) ;
441+ } // can happen if `spin add` has env, env has templates, but no templates are add-able
442+ 1 => {
443+ bail ! ( "No templates matched '{}'" , tags[ 0 ] ) ;
444+ }
445+ _ => {
446+ bail ! ( "No templates matched all tags" ) ;
447+ }
392448 }
393449 }
394450
0 commit comments