Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions src/Aspire.Cli/Templating/CliTemplateFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,13 @@ private IEnumerable<ITemplate> GetTemplateDefinitions()
cmd => AddOptionIfMissing(cmd, _localhostTldOption),
ApplyEmptyAppHostTemplateAsync,
runtime: TemplateRuntime.Cli,
supportsLanguageCallback: static languageId =>
languageId.Equals(KnownLanguageId.CSharp, StringComparison.OrdinalIgnoreCase) ||
languageId.Equals(KnownLanguageId.TypeScript, StringComparison.OrdinalIgnoreCase) ||
languageId.Equals(KnownLanguageId.TypeScriptAlias, StringComparison.OrdinalIgnoreCase) ||
languageId.Equals(KnownLanguageId.Python, StringComparison.OrdinalIgnoreCase),
selectableAppHostLanguages: [KnownLanguageId.CSharp, KnownLanguageId.TypeScript, KnownLanguageId.Python],
supportsLanguageCallback: languageId =>
IsLanguageAvailable(languageId) &&
(languageId.Equals(KnownLanguageId.CSharp, StringComparison.OrdinalIgnoreCase) ||
languageId.Equals(KnownLanguageId.TypeScript, StringComparison.OrdinalIgnoreCase) ||
languageId.Equals(KnownLanguageId.TypeScriptAlias, StringComparison.OrdinalIgnoreCase) ||
languageId.Equals(KnownLanguageId.Python, StringComparison.OrdinalIgnoreCase)),
selectableAppHostLanguages: FilterAvailableLanguages([KnownLanguageId.CSharp, KnownLanguageId.TypeScript, KnownLanguageId.Python]),
isEmpty: true),

new CallbackTemplate(
Expand Down Expand Up @@ -184,6 +185,16 @@ private bool IsTemplateAvailable(ITemplate template)
return _languageDiscovery.GetLanguageById(new LanguageId(template.LanguageId)) is not null;
}

private bool IsLanguageAvailable(string languageId)
{
return _languageDiscovery.GetLanguageById(new LanguageId(languageId)) is not null;
}

private string[] FilterAvailableLanguages(string[] languageIds)
{
return languageIds.Where(IsLanguageAvailable).ToArray();
}

private static string ApplyTokens(string content, string projectName, string projectNameLower, string aspireVersion, AppHostProfilePorts ports, string hostName = "localhost")
{
return content
Expand Down
60 changes: 60 additions & 0 deletions tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,66 @@ public void NewCommandWithPolyglotDisabled_ExposesTemplateSubcommands()
Assert.DoesNotContain(command.Options, option => option.Aliases.Contains("--language", StringComparer.OrdinalIgnoreCase));
}

[Fact]
public void EmptyAppHostTemplate_DoesNotOfferPythonLanguage_WhenPolyglotPythonDisabled()
{
using var workspace = TemporaryWorkspace.Create(outputHelper);
var services = CreateServiceCollection(workspace);
using var provider = services.BuildServiceProvider();

var templateProvider = provider.GetRequiredService<ITemplateProvider>();
var emptyTemplate = templateProvider.GetTemplates()
.Single(t => t.Name == KnownTemplateId.CSharpEmptyAppHost);

Assert.Contains(KnownLanguageId.CSharp, emptyTemplate.SelectableAppHostLanguages);
Assert.Contains(KnownLanguageId.TypeScript, emptyTemplate.SelectableAppHostLanguages);
Assert.DoesNotContain(KnownLanguageId.Python, emptyTemplate.SelectableAppHostLanguages);

Assert.True(emptyTemplate.SupportsLanguage(KnownLanguageId.CSharp));
Assert.True(emptyTemplate.SupportsLanguage(KnownLanguageId.TypeScript));
Assert.False(emptyTemplate.SupportsLanguage(KnownLanguageId.Python));
}

[Fact]
public void EmptyAppHostTemplate_OffersPythonLanguage_WhenPolyglotPythonEnabled()
{
using var workspace = TemporaryWorkspace.Create(outputHelper);
var services = CreateServiceCollection(workspace, options =>
{
options.FeatureFlagsFactory = _ =>
{
var features = new TestFeatures();
features.SetFeature(KnownFeatures.ExperimentalPolyglotPython, true);
return features;
};
});
using var provider = services.BuildServiceProvider();

var templateProvider = provider.GetRequiredService<ITemplateProvider>();
var emptyTemplate = templateProvider.GetTemplates()
.Single(t => t.Name == KnownTemplateId.CSharpEmptyAppHost);

Assert.Contains(KnownLanguageId.CSharp, emptyTemplate.SelectableAppHostLanguages);
Assert.Contains(KnownLanguageId.TypeScript, emptyTemplate.SelectableAppHostLanguages);
Assert.Contains(KnownLanguageId.Python, emptyTemplate.SelectableAppHostLanguages);

Assert.True(emptyTemplate.SupportsLanguage(KnownLanguageId.Python));
}

[Fact]
public async Task NewCommandWithExplicitPythonOnEmptyTemplate_FailsWhenPolyglotPythonDisabled()
{
using var workspace = TemporaryWorkspace.Create(outputHelper);
var services = CreateServiceCollection(workspace);
using var provider = services.BuildServiceProvider();

var command = provider.GetRequiredService<NewCommand>();
var result = command.Parse($"new {KnownTemplateId.CSharpEmptyAppHost} --name TestApp --output . --language python");

var exitCode = await result.InvokeAsync().DefaultTimeout();
Assert.NotEqual(ExitCodeConstants.Success, exitCode);
}
Comment on lines +121 to +133

[Fact]
public async Task NewCommandInteractiveFlowSmokeTest()
{
Expand Down
Loading