Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
16 changes: 8 additions & 8 deletions src/Aspire.Cli/Backchannel/AppHostBackchannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ namespace Aspire.Cli.Backchannel;

internal sealed class AppHostBackchannel(ILogger<AppHostBackchannel> logger, CliRpcTarget target)
{
private readonly ActivitySource _activitySource = new(nameof(Aspire.Cli.Backchannel.AppHostBackchannel), "1.0.0");
private readonly ActivitySource _activitySource = new(nameof(AppHostBackchannel));
private readonly TaskCompletionSource<JsonRpc> _rpcTaskCompletionSource = new();
private Process? _process;

public async Task<long> PingAsync(long timestamp, CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity(nameof(PingAsync), ActivityKind.Client);
using var activity = _activitySource.StartActivity();

var rpc = await _rpcTaskCompletionSource.Task;

Expand All @@ -37,7 +37,7 @@ public async Task RequestStopAsync(CancellationToken cancellationToken)
// of the AppHost process. The AppHost process will then trigger the shutdown
// which will allow the CLI to await the pending run.

using var activity = _activitySource.StartActivity(nameof(RequestStopAsync), ActivityKind.Client);
using var activity = _activitySource.StartActivity();

var rpc = await _rpcTaskCompletionSource.Task;

Expand All @@ -51,7 +51,7 @@ await rpc.InvokeWithCancellationAsync(

public async Task<(string BaseUrlWithLoginToken, string? CodespacesUrlWithLoginToken)> GetDashboardUrlsAsync(CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity(nameof(GetDashboardUrlsAsync), ActivityKind.Client);
using var activity = _activitySource.StartActivity();

var rpc = await _rpcTaskCompletionSource.Task;

Expand All @@ -67,7 +67,7 @@ await rpc.InvokeWithCancellationAsync(

public async IAsyncEnumerable<(string Resource, string Type, string State, string[] Endpoints)> GetResourceStatesAsync([EnumeratorCancellation]CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity(nameof(GetResourceStatesAsync), ActivityKind.Client);
using var activity = _activitySource.StartActivity();

var rpc = await _rpcTaskCompletionSource.Task;

Expand All @@ -88,7 +88,7 @@ await rpc.InvokeWithCancellationAsync(

public async Task ConnectAsync(Process process, string socketPath, CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity(nameof(ConnectAsync), ActivityKind.Client);
using var activity = _activitySource.StartActivity();

_process = process;

Expand All @@ -111,7 +111,7 @@ public async Task ConnectAsync(Process process, string socketPath, CancellationT

public async Task<string[]> GetPublishersAsync(CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity(nameof(GetPublishersAsync), ActivityKind.Client);
using var activity = _activitySource.StartActivity();

var rpc = await _rpcTaskCompletionSource.Task.ConfigureAwait(false);

Expand All @@ -127,7 +127,7 @@ public async Task<string[]> GetPublishersAsync(CancellationToken cancellationTok

public async IAsyncEnumerable<(string Id, string StatusText, bool IsComplete, bool IsError)> GetPublishingActivitiesAsync([EnumeratorCancellation]CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity(nameof(GetPublishingActivitiesAsync), ActivityKind.Client);
using var activity = _activitySource.StartActivity();

var rpc = await _rpcTaskCompletionSource.Task;

Expand Down
6 changes: 3 additions & 3 deletions src/Aspire.Cli/Commands/AddCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Aspire.Cli.Commands;

internal sealed class AddCommand : BaseCommand
{
private readonly ActivitySource _activitySource = new ActivitySource("Aspire.Cli");
private readonly ActivitySource _activitySource = new ActivitySource(nameof(AddCommand));
private readonly DotNetCliRunner _runner;
private readonly INuGetPackageCache _nuGetPackageCache;

Expand Down Expand Up @@ -42,7 +42,7 @@ public AddCommand(DotNetCliRunner runner, INuGetPackageCache nuGetPackageCache)

protected override async Task<int> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity($"{nameof(ExecuteAsync)}", ActivityKind.Internal);
using var activity = _activitySource.StartActivity();

try
{
Expand All @@ -62,7 +62,7 @@ protected override async Task<int> ExecuteAsync(ParseResult parseResult, Cancell

var packages = await AnsiConsole.Status().StartAsync(
"Searching for Aspire packages...",
context => _nuGetPackageCache.GetPackagesAsync(effectiveAppHostProjectFile, prerelease, source, cancellationToken)
context => _nuGetPackageCache.GetPackagesAsync(effectiveAppHostProjectFile.Directory!, prerelease, source, cancellationToken)
);

var version = parseResult.GetValue<string?>("--version");
Expand Down
98 changes: 61 additions & 37 deletions src/Aspire.Cli/Commands/NewCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@
using System.CommandLine.Parsing;
using System.Diagnostics;
using Aspire.Cli.Utils;
using Semver;
using Spectre.Console;

namespace Aspire.Cli.Commands;

internal sealed class NewCommand : BaseCommand
{
private readonly ActivitySource _activitySource = new ActivitySource("Aspire.Cli");
private readonly ActivitySource _activitySource = new ActivitySource(nameof(NewCommand));
private readonly DotNetCliRunner _runner;
private readonly INuGetPackageCache _nuGetPackageCache;

public NewCommand(DotNetCliRunner runner) : base("new", "Create a new Aspire sample project.")
public NewCommand(DotNetCliRunner runner, INuGetPackageCache nuGetPackageCache) : base("new", "Create a new Aspire sample project.")
{
ArgumentNullException.ThrowIfNull(runner, nameof(runner));
ArgumentNullException.ThrowIfNull(nuGetPackageCache, nameof(nuGetPackageCache));
_runner = runner;
_nuGetPackageCache = nuGetPackageCache;

var templateArgument = new Argument<string>("template");
templateArgument.Validators.Add(ValidateProjectTemplate);
Expand All @@ -29,9 +33,6 @@ internal sealed class NewCommand : BaseCommand

var outputOption = new Option<string?>("--output", "-o");
Options.Add(outputOption);

var prereleaseOption = new Option<bool>("--prerelease");
Options.Add(prereleaseOption);

var sourceOption = new Option<string?>("--source", "-s");
Options.Add(sourceOption);
Expand Down Expand Up @@ -77,27 +78,65 @@ private static void ValidateProjectTemplate(ArgumentResult result)
}
}

protected override async Task<int> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
private static async Task<string> GetProjectNameAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity($"{nameof(ExecuteAsync)}", ActivityKind.Internal);
if (parseResult.GetValue<string>("--name") is not { } name)
{
var defaultName = new DirectoryInfo(Environment.CurrentDirectory).Name;
name = await PromptUtils.PromptForStringAsync("Enter the project name:",
defaultValue: defaultName,
cancellationToken: cancellationToken);
}

var templateVersion = parseResult.GetValue<string>("--version");
var prerelease = parseResult.GetValue<bool>("--prerelease");
return name;
}

if (templateVersion is not null && prerelease)
private static async Task<string> GetOutputPathAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
if (parseResult.GetValue<string>("--output") is not { } outputPath)
{
AnsiConsole.MarkupLine("[red bold]:thumbs_down: The --version and --prerelease options are mutually exclusive.[/]");
return ExitCodeConstants.FailedToCreateNewProject;
outputPath = await PromptUtils.PromptForStringAsync(
"Enter the output path:",
defaultValue: Path.Combine(Environment.CurrentDirectory, "src"),
cancellationToken: cancellationToken
);
}
else if (prerelease)

return Path.GetFullPath(outputPath);
}

private static async Task<string> GetProjectTemplatesVersionAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
if (parseResult.GetValue<string>("--version") is { } version)
{
templateVersion = "*-*";
return version;
}
else if (templateVersion is null)
else
{
templateVersion = VersionHelper.GetDefaultTemplateVersion();
version = await PromptUtils.PromptForStringAsync(
"Project templates version:",
defaultValue: VersionHelper.GetDefaultTemplateVersion(),
validator: (string value) => {
if (SemVersion.TryParse(value, out var parsedVersion))
{
return ValidationResult.Success();
}

return ValidationResult.Error("Invalid version format. Please enter a valid version.");
},
cancellationToken);

return version;
}
}

protected override async Task<int> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity();

var name = await GetProjectNameAsync(parseResult, cancellationToken);
var outputPath = await GetOutputPathAsync(parseResult, cancellationToken);
var version = await GetProjectTemplatesVersionAsync(parseResult, cancellationToken);
var source = parseResult.GetValue<string?>("--source");

var templateInstallResult = await AnsiConsole.Status()
Expand All @@ -106,7 +145,7 @@ protected override async Task<int> ExecuteAsync(ParseResult parseResult, Cancell
.StartAsync(
":ice: Getting latest templates...",
async context => {
return await _runner.InstallTemplateAsync("Aspire.ProjectTemplates", templateVersion!, source, true, cancellationToken);
return await _runner.InstallTemplateAsync("Aspire.ProjectTemplates", version, source, true, cancellationToken);
});

if (templateInstallResult.ExitCode != 0)
Expand All @@ -119,33 +158,18 @@ protected override async Task<int> ExecuteAsync(ParseResult parseResult, Cancell

var templateName = parseResult.GetValue<string>("template") ?? "aspire-starter";

if (parseResult.GetValue<string>("--output") is not { } outputPath)
{
outputPath = Environment.CurrentDirectory;
}
else
{
outputPath = Path.GetFullPath(outputPath);
}

if (parseResult.GetValue<string>("--name") is not { } name)
{
var outputPathDirectoryInfo = new DirectoryInfo(outputPath);
name = outputPathDirectoryInfo.Name;
}

int newProjectExitCode = await AnsiConsole.Status()
.Spinner(Spinner.Known.Dots3)
.SpinnerStyle(Style.Parse("purple"))
.StartAsync(
":rocket: Creating new Aspire project...",
async context => {
return await _runner.NewProjectAsync(
templateName,
name,
outputPath,
cancellationToken);
});
templateName,
name,
outputPath,
cancellationToken);
});

if (newProjectExitCode != 0)
{
Expand Down
4 changes: 2 additions & 2 deletions src/Aspire.Cli/Commands/PublishCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Aspire.Cli.Commands;

internal sealed class PublishCommand : BaseCommand
{
private readonly ActivitySource _activitySource = new ActivitySource("Aspire.Cli");
private readonly ActivitySource _activitySource = new ActivitySource(nameof(PublishCommand));
private readonly DotNetCliRunner _runner;

public PublishCommand(DotNetCliRunner runner) : base("publish", "Generates deployment artifacts for an Aspire app host project.")
Expand All @@ -34,7 +34,7 @@ internal sealed class PublishCommand : BaseCommand

protected override async Task<int> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity($"{nameof(ExecuteAsync)}", ActivityKind.Internal);
using var activity = _activitySource.StartActivity();

var passedAppHostProjectFile = parseResult.GetValue<FileInfo?>("--project");
var effectiveAppHostProjectFile = ProjectFileHelper.UseOrFindAppHostProjectFile(passedAppHostProjectFile);
Expand Down
4 changes: 2 additions & 2 deletions src/Aspire.Cli/Commands/RunCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Aspire.Cli.Commands;

internal sealed class RunCommand : BaseCommand
{
private readonly ActivitySource _activitySource = new ActivitySource("Aspire.Cli");
private readonly ActivitySource _activitySource = new ActivitySource(nameof(RunCommand));
private readonly DotNetCliRunner _runner;

public RunCommand(DotNetCliRunner runner) : base("run", "Run an Aspire app host in development mode.")
Expand All @@ -33,7 +33,7 @@ public RunCommand(DotNetCliRunner runner) : base("run", "Run an Aspire app host

protected override async Task<int> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
using var activity = _activitySource.StartActivity($"{nameof(ExecuteAsync)}", ActivityKind.Internal);
using var activity = _activitySource.StartActivity();

var passedAppHostProjectFile = parseResult.GetValue<FileInfo?>("--project");
var effectiveAppHostProjectFile = ProjectFileHelper.UseOrFindAppHostProjectFile(passedAppHostProjectFile);
Expand Down
Loading
Loading