diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliConsts.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliConsts.cs new file mode 100644 index 0000000000..341bf1880d --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliConsts.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Cli +{ + public static class CliConsts + { + public const string Command = "AbpCliCommand"; + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index 010f9d59d5..c2e6816b86 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -36,6 +36,8 @@ namespace Volo.Abp.Cli.Commands Logger.LogInformation("Creating a new project..."); Logger.LogInformation("Project name: " + commandLineArgs.Target); + commandLineArgs.Options.Add(CliConsts.Command, commandLineArgs.Command); + var result = await ProjectBuilder.BuildAsync( new ProjectBuildArgs( SolutionName.Parse(commandLineArgs.Target), diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs index a04111d5e4..f0b00b913b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs @@ -5,9 +5,13 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; using Volo.Abp.Cli.Args; +using Volo.Abp.Cli.ProjectBuilding.Analyticses; using Volo.Abp.Cli.ProjectModification; using Volo.Abp.DependencyInjection; +using Volo.Abp.Json; using Volo.Abp.Threading; namespace Volo.Abp.Cli.Commands @@ -18,11 +22,21 @@ namespace Volo.Abp.Cli.Commands private readonly VoloNugetPackagesVersionUpdater _nugetPackagesVersionUpdater; private readonly NpmPackagesUpdater _npmPackagesUpdater; - - public UpdateCommand(VoloNugetPackagesVersionUpdater nugetPackagesVersionUpdater, NpmPackagesUpdater npmPackagesUpdater) + private readonly ICliAnalyticsCollect _cliAnalyticsCollect; + private readonly CliOptions _options; + private readonly IJsonSerializer _jsonSerializer; + + public UpdateCommand(VoloNugetPackagesVersionUpdater nugetPackagesVersionUpdater, + NpmPackagesUpdater npmPackagesUpdater, + ICliAnalyticsCollect cliAnalyticsCollect, + IJsonSerializer jsonSerializer, + IOptions options) { _nugetPackagesVersionUpdater = nugetPackagesVersionUpdater; _npmPackagesUpdater = npmPackagesUpdater; + _cliAnalyticsCollect = cliAnalyticsCollect; + _jsonSerializer = jsonSerializer; + _options = options.Value; Logger = NullLogger.Instance; } @@ -31,6 +45,15 @@ namespace Volo.Abp.Cli.Commands { UpdateNugetPackages(commandLineArgs); UpdateNpmPackages(); + + var options = commandLineArgs.Options + .Select(x => x.Key).ToList(); + await _cliAnalyticsCollect.CollectAsync(new CliAnalyticsCollectInputDto + { + Tool = _options.ToolName, + Command = commandLineArgs.Command, + Options = _jsonSerializer.Serialize(options) + }); } private void UpdateNpmPackages() diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoTemplateStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoTemplateStore.cs index 918a0b7d35..f3c873b4d0 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoTemplateStore.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoTemplateStore.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using System; @@ -64,10 +64,7 @@ namespace Volo.Abp.Cli.ProjectBuilding new TemplateDownloadInputDto { Name = name, - Version = version, - DatabaseProvider = databaseProvider.ToString(), - ProjectName = projectName, - Tool = Options.ToolName + Version = version } ); @@ -127,12 +124,6 @@ namespace Volo.Abp.Cli.ProjectBuilding public string Name { get; set; } public string Version { get; set; } - - public string DatabaseProvider { get; set; } - - public string ProjectName { get; set; } - - public string Tool { get; set; } } public class GetLatestTemplateVersionDto diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/CliAnalyticsCollect.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/CliAnalyticsCollect.cs new file mode 100644 index 0000000000..6598c9fb31 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/CliAnalyticsCollect.cs @@ -0,0 +1,47 @@ +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Cli.Http; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http; +using Volo.Abp.Json; +using Volo.Abp.Threading; + +namespace Volo.Abp.Cli.ProjectBuilding.Analyticses +{ + public class CliAnalyticsCollect : ICliAnalyticsCollect, ITransientDependency + { + private readonly ICancellationTokenProvider _cancellationTokenProvider; + private readonly IJsonSerializer _jsonSerializer; + private readonly ILogger _logger; + + public CliAnalyticsCollect(ICancellationTokenProvider cancellationTokenProvider, + IJsonSerializer jsonSerializer) + { + _cancellationTokenProvider = cancellationTokenProvider; + _jsonSerializer = jsonSerializer; + _logger = NullLogger.Instance; + } + + public async Task CollectAsync(CliAnalyticsCollectInputDto input) + { + var postData = _jsonSerializer.Serialize(input); + using (var client = new CliHttpClient()) + { + var responseMessage = await client.PostAsync( + $"{CliUrls.WwwAbpIo}api/clianalytics/collect", + new StringContent(postData, Encoding.UTF8, MimeTypes.Application.Json), + _cancellationTokenProvider.Token + ); + + if (!responseMessage.IsSuccessStatusCode) + { + _logger.LogInformation("Remote server returns error! HTTP status code: " + + responseMessage.StatusCode); + } + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/CliAnalyticsCollectInputDto.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/CliAnalyticsCollectInputDto.cs new file mode 100644 index 0000000000..6017d87b24 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/CliAnalyticsCollectInputDto.cs @@ -0,0 +1,25 @@ +namespace Volo.Abp.Cli.ProjectBuilding.Analyticses +{ + public class CliAnalyticsCollectInputDto + { + public string Tool { get; set; } + + public string TemplateName { get; set; } + + public string TemplateVersion { get; set; } + + public string Command { get; set; } + + public string DatabaseProvider { get; set; } + + public string ProjectName { get; set; } + + public bool? IsTiered { get; set; } + + public string Options { get; set; } + + public string Language { get; set; } + + public string Ip { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/ICliAnalyticsCollect.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/ICliAnalyticsCollect.cs new file mode 100644 index 0000000000..c75f492526 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Analyticses/ICliAnalyticsCollect.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Cli.ProjectBuilding.Analyticses +{ + public interface ICliAnalyticsCollect + { + Task CollectAsync(CliAnalyticsCollectInputDto input); + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/DatabaseProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/DatabaseProvider.cs index 852c63057a..f7ca31e168 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/DatabaseProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/DatabaseProvider.cs @@ -6,4 +6,18 @@ EntityFrameworkCore = 1, MongoDb = 2 } + + public static class DatabaseProviderExtensions + { + public static string ToProviderName(this DatabaseProvider databaseProvider) + { + switch (databaseProvider) + { + case DatabaseProvider.EntityFrameworkCore: return "ef"; + case DatabaseProvider.MongoDb: return "mongodb"; + case DatabaseProvider.NotSpecified: return "NotSpecified"; + default: return "NotSpecified"; + } + } + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs index 574dd32a3d..49d7648e22 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs @@ -1,9 +1,13 @@ using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using Volo.Abp.Cli.ProjectBuilding.Analyticses; using Volo.Abp.Cli.ProjectBuilding.Building; using Volo.Abp.DependencyInjection; +using Volo.Abp.Json; namespace Volo.Abp.Cli.ProjectBuilding { @@ -13,11 +17,21 @@ namespace Volo.Abp.Cli.ProjectBuilding protected ITemplateStore TemplateStore { get; } protected ITemplateInfoProvider TemplateInfoProvider { get; } + protected ICliAnalyticsCollect CliAnalyticsCollect { get; } + protected CliOptions Options { get; } + protected IJsonSerializer JsonSerializer { get; } - public ProjectBuilder(ITemplateStore templateStore, ITemplateInfoProvider templateInfoProvider) + public ProjectBuilder(ITemplateStore templateStore, + ITemplateInfoProvider templateInfoProvider, + ICliAnalyticsCollect cliAnalyticsCollect, + IOptions options, + IJsonSerializer jsonSerializer) { TemplateStore = templateStore; TemplateInfoProvider = templateInfoProvider; + CliAnalyticsCollect = cliAnalyticsCollect; + Options = options.Value; + JsonSerializer = jsonSerializer; Logger = NullLogger.Instance; } @@ -55,6 +69,26 @@ namespace Volo.Abp.Cli.ProjectBuilding Logger.LogInformation("Check the documentation of this template: " + templateInfo.DocumentUrl); } + // Exclude unwanted or known options. + var options = args.ExtraProperties + .Where(x => x.Key != CliConsts.Command) + .Where(x => x.Key != "tiered") + .Where(x => x.Key != "database-provider" && x.Key != "d") + .Where(x => x.Key != "output-folder" && x.Key != "o") + .Select(x => x.Key).ToList(); + + await CliAnalyticsCollect.CollectAsync(new CliAnalyticsCollectInputDto + { + Tool = Options.ToolName, + Command = args.ExtraProperties.ContainsKey(CliConsts.Command) ? args.ExtraProperties[CliConsts.Command] : "", + DatabaseProvider = args.DatabaseProvider.ToProviderName(), + IsTiered = args.ExtraProperties.ContainsKey("tiered"), + Options = JsonSerializer.Serialize(options), + ProjectName = args.SolutionName.FullName, + TemplateName = args.TemplateName, + TemplateVersion = templateFile.Version + }); + return new ProjectBuildResult(context.Result.ZipContent, args.SolutionName.ProjectName); }