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