From 92486177a8ac70a951f45252e06ccadb6f7e3181 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 20 Sep 2019 15:55:18 +0300 Subject: [PATCH 01/10] source code download --- .../Volo/Abp/Cli/AbpCliCoreModule.cs | 1 + .../Volo/Abp/Cli/Commands/GetSourceCommand.cs | 157 ++++++++++++++++++ .../Volo/Abp/Cli/Commands/NewCommand.cs | 8 +- ...mplateStore.cs => AbpIoSourceCodeStore.cs} | 40 +++-- .../ProjectBuilding/Building/ModuleInfo.cs | 11 ++ .../ModuleProjectBuildPipelineBuilder.cs | 18 ++ .../Building/ProjectBuildContext.cs | 9 +- .../Steps/NugetReferenceReplaceStep.cs | 2 +- ...=> TemplateProjectBuildPipelineBuilder.cs} | 2 +- .../ProjectBuilding/IModuleInfoProvider.cs | 13 ++ ...{ITemplateStore.cs => ISourceCodeStore.cs} | 3 +- .../Cli/ProjectBuilding/ModuleInfoProvider.cs | 58 +++++++ .../ProjectBuilding/ModuleProjectBuilder.cs | 110 ++++++++++++ .../Cli/ProjectBuilding/SourceCodeTypes.cs | 13 ++ ...ctBuilder.cs => TemplateProjectBuilder.cs} | 20 ++- 15 files changed, 428 insertions(+), 37 deletions(-) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs rename framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/{AbpIoTemplateStore.cs => AbpIoSourceCodeStore.cs} (71%) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleInfo.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs rename framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/{ProjectBuildPipelineBuilder.cs => TemplateProjectBuildPipelineBuilder.cs} (94%) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs rename framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/{ITemplateStore.cs => ISourceCodeStore.cs} (78%) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs rename framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/{ProjectBuilder.cs => TemplateProjectBuilder.cs} (90%) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs index 11e2e23a98..b51ef5fb2d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs @@ -27,6 +27,7 @@ namespace Volo.Abp.Cli { options.Commands["help"] = typeof(HelpCommand); options.Commands["new"] = typeof(NewCommand); + options.Commands["get-source"] = typeof(GetSourceCommand); options.Commands["update"] = typeof(UpdateCommand); options.Commands["add-package"] = typeof(AddPackageCommand); options.Commands["add-module"] = typeof(AddModuleCommand); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs new file mode 100644 index 0000000000..54711fbc31 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs @@ -0,0 +1,157 @@ +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using ICSharpCode.SharpZipLib.Core; +using ICSharpCode.SharpZipLib.Zip; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Cli.Args; +using Volo.Abp.Cli.ProjectBuilding; +using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Cli.Commands +{ + public class GetSourceCommand : IConsoleCommand, ITransientDependency + { + public ModuleProjectBuilder ModuleProjectBuilder { get; } + + public ILogger Logger { get; set; } + + public GetSourceCommand(ModuleProjectBuilder moduleProjectBuilder) + { + ModuleProjectBuilder = moduleProjectBuilder; + Logger = NullLogger.Instance; + } + + public async Task ExecuteAsync(CommandLineArgs commandLineArgs) + { + if (commandLineArgs.Target == null) + { + throw new CliUsageException( + "Module name is missing!" + + Environment.NewLine + Environment.NewLine + + GetUsageInfo() + ); + } + + Logger.LogInformation("Downloading source code of " + commandLineArgs.Target); + + var version = commandLineArgs.Options.GetOrNull(Options.Version.Short, Options.Version.Long); + if (version != null) + { + Logger.LogInformation("Version: " + version); + } + + var outputFolder = commandLineArgs.Options.GetOrNull(Options.OutputFolder.Short, Options.OutputFolder.Long); + if (outputFolder != null) + { + if (!Directory.Exists(outputFolder)) + { + Directory.CreateDirectory(outputFolder); + } + + outputFolder = Path.GetFullPath(outputFolder); + } + else + { + outputFolder = Directory.GetCurrentDirectory(); + } + + Logger.LogInformation("Output folder: " + outputFolder); + + commandLineArgs.Options.Add(CliConsts.Command, commandLineArgs.Command); + + var result = await ModuleProjectBuilder.BuildAsync( + new ProjectBuildArgs( + SolutionName.Parse(commandLineArgs.Target), + commandLineArgs.Target, + version, + DatabaseProvider.NotSpecified, + UiFramework.NotSpecified, + commandLineArgs.Options + ) + ); + + using (var templateFileStream = new MemoryStream(result.ZipContent)) + { + using (var zipInputStream = new ZipInputStream(templateFileStream)) + { + var zipEntry = zipInputStream.GetNextEntry(); + while (zipEntry != null) + { + var fullZipToPath = Path.Combine(outputFolder, zipEntry.Name); + var directoryName = Path.GetDirectoryName(fullZipToPath); + + if (!string.IsNullOrEmpty(directoryName)) + { + Directory.CreateDirectory(directoryName); + } + + var fileName = Path.GetFileName(fullZipToPath); + if (fileName.Length == 0) + { + zipEntry = zipInputStream.GetNextEntry(); + continue; + } + + var buffer = new byte[4096]; // 4K is optimum + using (var streamWriter = File.Create(fullZipToPath)) + { + StreamUtils.Copy(zipInputStream, streamWriter, buffer); + } + + zipEntry = zipInputStream.GetNextEntry(); + } + } + } + + Logger.LogInformation($"'{commandLineArgs.Target}' has been successfully downloaded to '{outputFolder}'"); + } + + public string GetUsageInfo() + { + var sb = new StringBuilder(); + + sb.AppendLine(""); + sb.AppendLine("Usage:"); + sb.AppendLine(""); + sb.AppendLine(" abp get-source [options]"); + sb.AppendLine(""); + sb.AppendLine("Options:"); + sb.AppendLine(""); + sb.AppendLine("-o|--output-folder (default: current folder)"); + sb.AppendLine("-v|--version (default: latest version)"); + sb.AppendLine(""); + sb.AppendLine("Examples:"); + sb.AppendLine(""); + sb.AppendLine(" abp get-source Volo.Blogging"); + sb.AppendLine(" abp get-source Volo.Blogging -o d:\\my-project"); + sb.AppendLine(""); + sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI"); + + return sb.ToString(); + } + + public string GetShortDescription() + { + return "Downloads the source code of the specified module."; + } + + public static class Options + { + public static class OutputFolder + { + public const string Short = "o"; + public const string Long = "output-folder"; + } + + public static class Version + { + public const string Short = "v"; + public const string Long = "version"; + } + } + } +} 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 6921f8e4d8..d8d9395554 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 @@ -17,11 +17,11 @@ namespace Volo.Abp.Cli.Commands { public ILogger Logger { get; set; } - protected ProjectBuilder ProjectBuilder { get; } + protected TemplateProjectBuilder TemplateProjectBuilder { get; } - public NewCommand(ProjectBuilder projectBuilder) + public NewCommand(TemplateProjectBuilder templateProjectBuilder) { - ProjectBuilder = projectBuilder; + TemplateProjectBuilder = templateProjectBuilder; Logger = NullLogger.Instance; } @@ -83,7 +83,7 @@ namespace Volo.Abp.Cli.Commands commandLineArgs.Options.Add(CliConsts.Command, commandLineArgs.Command); - var result = await ProjectBuilder.BuildAsync( + var result = await TemplateProjectBuilder.BuildAsync( new ProjectBuildArgs( SolutionName.Parse(commandLineArgs.Target), template, 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/AbpIoSourceCodeStore.cs similarity index 71% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoTemplateStore.cs rename to framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs index 21f868e73f..6fde8db9e3 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/AbpIoSourceCodeStore.cs @@ -15,9 +15,9 @@ using Volo.Abp.Threading; namespace Volo.Abp.Cli.ProjectBuilding { - public class AbpIoTemplateStore : ITemplateStore, ITransientDependency + public class AbpIoSourceCodeStore : ISourceCodeStore, ITransientDependency { - public ILogger Logger { get; set; } + public ILogger Logger { get; set; } protected CliOptions Options { get; } @@ -25,7 +25,7 @@ namespace Volo.Abp.Cli.ProjectBuilding protected ICancellationTokenProvider CancellationTokenProvider { get; } - public AbpIoTemplateStore( + public AbpIoSourceCodeStore( IOptions options, IJsonSerializer jsonSerializer, ICancellationTokenProvider cancellationTokenProvider) @@ -34,14 +34,15 @@ namespace Volo.Abp.Cli.ProjectBuilding CancellationTokenProvider = cancellationTokenProvider; Options = options.Value; - Logger = NullLogger.Instance; + Logger = NullLogger.Instance; } public async Task GetAsync( string name, + string type, string version = null) { - var latestVersion = await GetLatestTemplateVersionAsync(name); + var latestVersion = await GetLatestSourceCodeVersionAsync(name, type); if (version == null) { version = latestVersion; @@ -52,16 +53,17 @@ namespace Volo.Abp.Cli.ProjectBuilding var localCacheFile = Path.Combine(CliPaths.TemplateCache, name + "-" + version + ".zip"); if (Options.CacheTemplates && File.Exists(localCacheFile)) { - Logger.LogInformation("Using cached template: " + name + ", version: " + version); + Logger.LogInformation("Using cached " + type + ": " + name + ", version: " + version); return new TemplateFile(File.ReadAllBytes(localCacheFile), version, latestVersion); } - Logger.LogInformation("Downloading template: " + name + ", version: " + version); + Logger.LogInformation("Downloading " + type + ": " + name + ", version: " + version); - var fileContent = await DownloadTemplateFileContentAsync( - new TemplateDownloadInputDto + var fileContent = await DownloadSourceCodeContentAsync( + new SourceCodeDownloadInputDto { Name = name, + Type = type, Version = version } ); @@ -74,14 +76,14 @@ namespace Volo.Abp.Cli.ProjectBuilding return new TemplateFile(fileContent, version, latestVersion); } - private async Task GetLatestTemplateVersionAsync(string name) + private async Task GetLatestSourceCodeVersionAsync(string name, string type) { - var postData = JsonSerializer.Serialize(new GetLatestTemplateVersionDto { Name = name }); + var postData = JsonSerializer.Serialize(new GetLatestSourceCodeVersionDto { Name = name }); using (var client = new CliHttpClient()) { var responseMessage = await client.PostAsync( - $"{CliUrls.WwwAbpIo}api/download/template/get-version/", + $"{CliUrls.WwwAbpIo}api/download/{type}/get-version/", new StringContent(postData, Encoding.UTF8, MimeTypes.Application.Json), CancellationTokenProvider.Token ); @@ -92,18 +94,18 @@ namespace Volo.Abp.Cli.ProjectBuilding } var result = await responseMessage.Content.ReadAsStringAsync(); - return JsonSerializer.Deserialize(result).Version; + return JsonSerializer.Deserialize(result).Version; } } - private async Task DownloadTemplateFileContentAsync(TemplateDownloadInputDto input) + private async Task DownloadSourceCodeContentAsync(SourceCodeDownloadInputDto input) { var postData = JsonSerializer.Serialize(input); using (var client = new CliHttpClient(TimeSpan.FromMinutes(10))) { var responseMessage = await client.PostAsync( - $"{CliUrls.WwwAbpIo}api/download/template/", + $"{CliUrls.WwwAbpIo}api/download/{input.Type}/", new StringContent(postData, Encoding.UTF8, MimeTypes.Application.Json), CancellationTokenProvider.Token ); @@ -117,19 +119,21 @@ namespace Volo.Abp.Cli.ProjectBuilding } } - public class TemplateDownloadInputDto + public class SourceCodeDownloadInputDto { public string Name { get; set; } public string Version { get; set; } + + public string Type { get; set; } } - public class GetLatestTemplateVersionDto + public class GetLatestSourceCodeVersionDto { public string Name { get; set; } } - public class GetLatestTemplateVersionResultDto + public class GetLatestSourceCodeVersionResultDto { public string Version { get; set; } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleInfo.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleInfo.cs new file mode 100644 index 0000000000..dfeabf6aed --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleInfo.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.Cli.ProjectBuilding.Building +{ + public class ModuleInfo + { + public string Name { get; set; } + + public string Namespace { get; set; } + + public string DocumentUrl { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs new file mode 100644 index 0000000000..3a5fcee77b --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs @@ -0,0 +1,18 @@ +using Volo.Abp.Cli.ProjectBuilding.Building.Steps; + +namespace Volo.Abp.Cli.ProjectBuilding.Building +{ + public static class ModuleProjectBuildPipelineBuilder + { + public static ProjectBuildPipeline Build(ProjectBuildContext context) + { + var pipeline = new ProjectBuildPipeline(context); + + pipeline.Steps.Add(new FileEntryListReadStep()); + pipeline.Steps.Add(new NugetReferenceReplaceStep()); + pipeline.Steps.Add(new CreateProjectResultZipStep()); + + return pipeline; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs index 1ea040022f..8b5522165f 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs @@ -11,19 +11,22 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building [NotNull] public ProjectBuildArgs BuildArgs { get; } - [NotNull] public TemplateInfo Template { get; } + public ModuleInfo Module { get; } + public FileEntryList Files { get; set; } public ProjectResult Result { get; set; } public ProjectBuildContext( - [NotNull] TemplateInfo template, + TemplateInfo template, + ModuleInfo module, [NotNull] TemplateFile templateFile, [NotNull] ProjectBuildArgs buildArgs) { - Template = Check.NotNull(template, nameof(template)); + Template = template; + Module = module; TemplateFile = Check.NotNull(templateFile, nameof(templateFile)); BuildArgs = Check.NotNull(buildArgs, nameof(buildArgs)); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs index cb790ba91f..7d08ed7ff6 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps new NugetReferenceReplacer( context.Files, - "MyCompanyName.MyProjectName", + context.Module?.Namespace ?? "MyCompanyName.MyProjectName", nugetPackageVersion ).Run(); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs similarity index 94% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildPipelineBuilder.cs rename to framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs index 49cb44d13a..7ff1f5a38a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateProjectBuildPipelineBuilder.cs @@ -3,7 +3,7 @@ using Volo.Abp.Cli.ProjectBuilding.Templates.App; namespace Volo.Abp.Cli.ProjectBuilding.Building { - public static class ProjectBuildPipelineBuilder + public static class TemplateProjectBuildPipelineBuilder { public static ProjectBuildPipeline Build(ProjectBuildContext context) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs new file mode 100644 index 0000000000..7e490a78d2 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Cli.ProjectBuilding.Building; + +namespace Volo.Abp.Cli.ProjectBuilding +{ + public interface IModuleInfoProvider + { + Task GetAsync(string name); + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ITemplateStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs similarity index 78% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ITemplateStore.cs rename to framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs index 728d4d4a51..4d1ed7aa0c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ITemplateStore.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs @@ -3,10 +3,11 @@ using JetBrains.Annotations; namespace Volo.Abp.Cli.ProjectBuilding { - public interface ITemplateStore + public interface ISourceCodeStore { Task GetAsync( string name, + string type, [CanBeNull] string version = null ); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs new file mode 100644 index 0000000000..b13cf262c9 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Json; +using Volo.Abp.Cli.Http; +using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http; +using Volo.Abp.Threading; + +namespace Volo.Abp.Cli.ProjectBuilding +{ + public class ModuleInfoProvider: IModuleInfoProvider, ITransientDependency + { + public IJsonSerializer JsonSerializer { get; } + public ICancellationTokenProvider CancellationTokenProvider { get; } + + public ModuleInfoProvider(IJsonSerializer jsonSerializer, ICancellationTokenProvider cancellationTokenProvider) + { + JsonSerializer = jsonSerializer; + CancellationTokenProvider = cancellationTokenProvider; + } + + public async Task GetAsync(string name) + { + var moduleList = await GetModuleListAsync(); + + var module = moduleList.FirstOrDefault(m => m.Name == name); + + if (module == null) + { + throw new Exception("Module not found!"); + } + + return module; + } + + private async Task> GetModuleListAsync() + { + using (var client = new CliHttpClient()) + { + var responseMessage = await client.GetAsync( + $"{CliUrls.WwwAbpIo}api/download/modules/", + CancellationTokenProvider.Token + ); + + if (!responseMessage.IsSuccessStatusCode) + { + throw new Exception("Remote server returns error! HTTP status code: " + responseMessage.StatusCode); + } + + var result = await responseMessage.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize>(result); + } + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs new file mode 100644 index 0000000000..c527375a70 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs @@ -0,0 +1,110 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Cli.Commands; +using Volo.Abp.Cli.Licensing; +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 +{ + public class ModuleProjectBuilder : IProjectBuilder, ITransientDependency + { + public ILogger Logger { get; set; } + + protected ISourceCodeStore SourceCodeStore { get; } + protected IModuleInfoProvider ModuleInfoProvider { get; } + protected ICliAnalyticsCollect CliAnalyticsCollect { get; } + protected CliOptions Options { get; } + protected IJsonSerializer JsonSerializer { get; } + protected IApiKeyService ApiKeyService { get; } + + public ModuleProjectBuilder(ISourceCodeStore sourceCodeStore, + IModuleInfoProvider moduleInfoProvider, + ICliAnalyticsCollect cliAnalyticsCollect, + IOptions options, + IJsonSerializer jsonSerializer, + IApiKeyService apiKeyService) + { + SourceCodeStore = sourceCodeStore; + ModuleInfoProvider = moduleInfoProvider; + CliAnalyticsCollect = cliAnalyticsCollect; + Options = options.Value; + JsonSerializer = jsonSerializer; + ApiKeyService = apiKeyService; + + Logger = NullLogger.Instance; + } + + public async Task BuildAsync(ProjectBuildArgs args) + { + var moduleInfo = await GetModuleInfoAsync(args); + + var templateFile = await SourceCodeStore.GetAsync( + args.TemplateName, + SourceCodeTypes.Module, + args.Version + ); + + var apiKeyResult = await ApiKeyService.GetApiKeyOrNullAsync(); + if (apiKeyResult?.ApiKey != null) + { + args.ExtraProperties["api-key"] = apiKeyResult.ApiKey; + } + + if (apiKeyResult?.LicenseCode != null) + { + args.ExtraProperties["license-code"] = apiKeyResult.LicenseCode; + } + + var context = new ProjectBuildContext( + null, + moduleInfo, + templateFile, + args + ); + + ModuleProjectBuildPipelineBuilder.Build(context).Execute(); + + if (!moduleInfo.DocumentUrl.IsNullOrEmpty()) + { + Logger.LogInformation("Check out the documents at " + moduleInfo.DocumentUrl); + } + + // Exclude unwanted or known options. + var options = args.ExtraProperties + .Where(x => !x.Key.Equals(CliConsts.Command, StringComparison.InvariantCultureIgnoreCase)) + .Where(x => !x.Key.Equals(NewCommand.Options.OutputFolder.Long, StringComparison.InvariantCultureIgnoreCase) && + !x.Key.Equals(NewCommand.Options.OutputFolder.Short, StringComparison.InvariantCultureIgnoreCase)) + .Where(x => !x.Key.Equals(NewCommand.Options.Version.Long, StringComparison.InvariantCultureIgnoreCase) && + !x.Key.Equals(NewCommand.Options.Version.Short, StringComparison.InvariantCultureIgnoreCase)) + .Select(x => x.Key).ToList(); + + await CliAnalyticsCollect.CollectAsync(new CliAnalyticsCollectInputDto + { + Tool = Options.ToolName, + Command = args.ExtraProperties.ContainsKey(CliConsts.Command) ? args.ExtraProperties[CliConsts.Command] : "", + DatabaseProvider = null, + IsTiered = false, + UiFramework = null, + Options = JsonSerializer.Serialize(options), + ProjectName = null, + TemplateName = args.TemplateName, + TemplateVersion = templateFile.Version + }); + + return new ProjectBuildResult(context.Result.ZipContent, args.TemplateName); + } + + private async Task GetModuleInfoAsync(ProjectBuildArgs args) + { + return await ModuleInfoProvider.GetAsync(args.TemplateName); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs new file mode 100644 index 0000000000..9b2d21cc8d --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Volo.Abp.Cli.ProjectBuilding +{ + public static class SourceCodeTypes + { + public const string Template = "template"; + + public const string Module = "module"; + } +} 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/TemplateProjectBuilder.cs similarity index 90% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs rename to framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs index 6c9b6fa145..1031b965e0 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/TemplateProjectBuilder.cs @@ -14,32 +14,32 @@ using Volo.Abp.Json; namespace Volo.Abp.Cli.ProjectBuilding { - public class ProjectBuilder : IProjectBuilder, ITransientDependency + public class TemplateProjectBuilder : IProjectBuilder, ITransientDependency { - public ILogger Logger { get; set; } + public ILogger Logger { get; set; } - protected ITemplateStore TemplateStore { get; } + protected ISourceCodeStore SourceCodeStore { get; } protected ITemplateInfoProvider TemplateInfoProvider { get; } protected ICliAnalyticsCollect CliAnalyticsCollect { get; } protected CliOptions Options { get; } protected IJsonSerializer JsonSerializer { get; } protected IApiKeyService ApiKeyService { get; } - public ProjectBuilder(ITemplateStore templateStore, + public TemplateProjectBuilder(ISourceCodeStore sourceCodeStore, ITemplateInfoProvider templateInfoProvider, ICliAnalyticsCollect cliAnalyticsCollect, IOptions options, IJsonSerializer jsonSerializer, IApiKeyService apiKeyService) { - TemplateStore = templateStore; + SourceCodeStore = sourceCodeStore; TemplateInfoProvider = templateInfoProvider; CliAnalyticsCollect = cliAnalyticsCollect; Options = options.Value; JsonSerializer = jsonSerializer; ApiKeyService = apiKeyService; - Logger = NullLogger.Instance; + Logger = NullLogger.Instance; } public async Task BuildAsync(ProjectBuildArgs args) @@ -48,11 +48,12 @@ namespace Volo.Abp.Cli.ProjectBuilding NormalizeArgs(args, templateInfo); - var templateFile = await TemplateStore.GetAsync( + var templateFile = await SourceCodeStore.GetAsync( args.TemplateName, + SourceCodeTypes.Template, args.Version ); - + var apiKeyResult = await ApiKeyService.GetApiKeyOrNullAsync(); if (apiKeyResult?.ApiKey != null) { @@ -66,11 +67,12 @@ namespace Volo.Abp.Cli.ProjectBuilding var context = new ProjectBuildContext( templateInfo, + null, templateFile, args ); - ProjectBuildPipelineBuilder.Build(context).Execute(); + TemplateProjectBuildPipelineBuilder.Build(context).Execute(); if (!templateInfo.DocumentUrl.IsNullOrEmpty()) { From 4e63a7b8311a53b4ad14b31f59f9112e7bf0889b Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 30 Sep 2019 09:23:33 +0300 Subject: [PATCH 02/10] removed unused using statements --- .../Volo/Abp/Cli/Commands/UpdateCommand.cs | 3 --- .../Volo/Abp/Cli/Licensing/IApiKeyService.cs | 3 +-- .../Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs | 5 +---- .../Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs | 1 - .../Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs | 1 - .../Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs | 6 +----- .../Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs | 1 - .../ProjectBuilding/Templates/Module/ModuleTemplateBase.cs | 4 +--- .../Abp/Cli/ProjectModification/EfCoreMigrationAdder.cs | 1 - .../Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs | 1 - .../Abp/Cli/ProjectModification/PackageJsonFileFinder.cs | 1 - 11 files changed, 4 insertions(+), 23 deletions(-) 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 aa1c1501b5..742d327c1c 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 @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -7,13 +6,11 @@ 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 { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/IApiKeyService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/IApiKeyService.cs index 0fb8058c61..23ff81555a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/IApiKeyService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/IApiKeyService.cs @@ -1,5 +1,4 @@ -using System.Net; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace Volo.Abp.Cli.Licensing { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs index 7e490a78d2..bb8d0d72cb 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IModuleInfoProvider.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; using Volo.Abp.Cli.ProjectBuilding.Building; namespace Volo.Abp.Cli.ProjectBuilding diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs index b13cf262c9..e82d4478b7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs @@ -6,7 +6,6 @@ using Volo.Abp.Json; using Volo.Abp.Cli.Http; using Volo.Abp.Cli.ProjectBuilding.Building; using Volo.Abp.DependencyInjection; -using Volo.Abp.Http; using Volo.Abp.Threading; namespace Volo.Abp.Cli.ProjectBuilding diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs index c527375a70..d7d31c81af 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs @@ -2,7 +2,6 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.Cli.Commands; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs index 9b2d21cc8d..5f7ad58ef7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Volo.Abp.Cli.ProjectBuilding +namespace Volo.Abp.Cli.ProjectBuilding { public static class SourceCodeTypes { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs index 1031b965e0..e1248b32f0 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs @@ -2,7 +2,6 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.Cli.Commands; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs index 2d308d9219..904ac77d87 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; using JetBrains.Annotations; using Volo.Abp.Cli.ProjectBuilding.Building; using Volo.Abp.Cli.ProjectBuilding.Building.Steps; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationAdder.cs index cc4d3f74a9..1c8727852b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/EfCoreMigrationAdder.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.IO; using Volo.Abp.Cli.Utils; using Volo.Abp.DependencyInjection; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs index fd6f5be5d1..419b52f7fe 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Threading; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageJsonFileFinder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageJsonFileFinder.cs index b3138e1f87..65aaf44a59 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageJsonFileFinder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackageJsonFileFinder.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Cli.ProjectModification From 5eb24b0f75d153c56cf70eab85d1b6ac65d1d9db Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 30 Sep 2019 09:24:50 +0300 Subject: [PATCH 03/10] Update ModuleTemplateBase.cs --- .../Templates/Module/ModuleTemplateBase.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs index 904ac77d87..09b75ac0e2 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Module/ModuleTemplateBase.cs @@ -25,22 +25,24 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Module private void DeleteUnrelatedProjects(ProjectBuildContext context, List steps) { - if (context.BuildArgs.ExtraProperties.ContainsKey("no-ui")) + if (!context.BuildArgs.ExtraProperties.ContainsKey("no-ui")) { - steps.Add(new RemoveProjectFromSolutionStep( - "MyCompanyName.MyProjectName.Web" - )); - - steps.Add(new RemoveProjectFromSolutionStep( - "MyCompanyName.MyProjectName.Web.Host", - projectFolderPath: "/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host" - )); - - steps.Add(new RemoveProjectFromSolutionStep( - "MyCompanyName.MyProjectName.Web.Unified", - projectFolderPath: "/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified" - )); + return; } + + steps.Add(new RemoveProjectFromSolutionStep( + "MyCompanyName.MyProjectName.Web" + )); + + steps.Add(new RemoveProjectFromSolutionStep( + "MyCompanyName.MyProjectName.Web.Host", + projectFolderPath: "/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host" + )); + + steps.Add(new RemoveProjectFromSolutionStep( + "MyCompanyName.MyProjectName.Web.Unified", + projectFolderPath: "/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified" + )); } private void RandomizeSslPorts(ProjectBuildContext context, List steps) From 8c10e70f417f7d1d56ae35511ca986e869856bb7 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 10 Oct 2019 09:49:23 +0300 Subject: [PATCH 04/10] removed NugetReferenceReplaceStep --- .../ModuleProjectBuildPipelineBuilder.cs | 2 +- .../Steps/NugetReferenceReplaceStep.cs | 138 ------------------ 2 files changed, 1 insertion(+), 139 deletions(-) delete mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs index 3a5fcee77b..fc2a5b0dbc 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building var pipeline = new ProjectBuildPipeline(context); pipeline.Steps.Add(new FileEntryListReadStep()); - pipeline.Steps.Add(new NugetReferenceReplaceStep()); + pipeline.Steps.Add(new ProjectReferenceReplaceStep()); pipeline.Steps.Add(new CreateProjectResultZipStep()); return pipeline; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs deleted file mode 100644 index 7d08ed7ff6..0000000000 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text.RegularExpressions; -using System.Xml; -using Volo.Abp.Cli.ProjectBuilding.Files; - -namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps -{ - public class NugetReferenceReplaceStep : ProjectBuildPipelineStep - { - public override void Execute(ProjectBuildContext context) - { - var nugetPackageVersion = context.TemplateFile.Version; - if (IsBranchName(nugetPackageVersion)) - { - nugetPackageVersion = context.TemplateFile.LatestVersion; - } - - new NugetReferenceReplacer( - context.Files, - context.Module?.Namespace ?? "MyCompanyName.MyProjectName", - nugetPackageVersion - ).Run(); - } - - private bool IsBranchName(string versionOrBranchName) - { - Check.NotNullOrWhiteSpace(versionOrBranchName, nameof(versionOrBranchName)); - - if (char.IsDigit(versionOrBranchName[0])) - { - return false; - } - - if (versionOrBranchName[0].IsIn('v','V') && - versionOrBranchName.Length > 1 && - char.IsDigit(versionOrBranchName[1])) - { - return false; - } - - return true; - } - - private class NugetReferenceReplacer - { - private readonly List _entries; - private readonly string _companyAndProjectNamePlaceHolder; - private readonly string _nugetPackageVersion; - - public NugetReferenceReplacer( - List entries, - string companyAndProjectNamePlaceHolder, - string nugetPackageVersion) - { - _entries = entries; - _companyAndProjectNamePlaceHolder = companyAndProjectNamePlaceHolder; - _nugetPackageVersion = nugetPackageVersion; - } - - public void Run() - { - foreach (var fileEntry in _entries) - { - if (fileEntry.Name.EndsWith(".csproj")) - { - fileEntry.SetContent(ProcessFileContent(fileEntry.Content)); - } - } - } - - private string ProcessFileContent(string content) - { - Check.NotNull(content, nameof(content)); - - var doc = new XmlDocument() { PreserveWhitespace = true }; - - doc.Load(GenerateStreamFromString(content)); - - return ProcessReferenceNodes(doc, content); - } - - private string ProcessReferenceNodes(XmlDocument doc, string content) - { - Check.NotNull(content, nameof(content)); - - var nodes = doc.SelectNodes("/Project/ItemGroup/ProjectReference[@Include]"); - - foreach (XmlNode oldNode in nodes) - { - var oldNodeIncludeValue = oldNode.Attributes["Include"].Value; - - // ReSharper disable once PossibleNullReferenceException : Can not be null because nodes are selected with include attribute filter in previous method - if (oldNodeIncludeValue.Contains($"{_companyAndProjectNamePlaceHolder}")) - { - continue; - } - - var newNode = doc.CreateElement("PackageReference"); - - var includeAttr = doc.CreateAttribute("Include"); - includeAttr.Value = ConvertToNugetReference(oldNodeIncludeValue); - newNode.Attributes.Append(includeAttr); - - var versionAttr = doc.CreateAttribute("Version"); - versionAttr.Value = _nugetPackageVersion; - newNode.Attributes.Append(versionAttr); - - oldNode.ParentNode.ReplaceChild(newNode, oldNode); - } - - return doc.OuterXml; - } - - private string ConvertToNugetReference(string oldValue) - { - var newValue = Regex.Match(oldValue, @"\\((?!.+?\\).+?)\.csproj", RegexOptions.CultureInvariant | RegexOptions.Compiled); - if (newValue.Success && newValue.Groups.Count == 2) - { - return newValue.Groups[1].Value; - } - - return oldValue; - } - - private static Stream GenerateStreamFromString(string s) - { - var stream = new MemoryStream(); - var writer = new StreamWriter(stream); - writer.Write(s); - writer.Flush(); - stream.Position = 0; - return stream; - } - } - } -} From 55119d8b5040fe6ee0eb85bca3694e4d4e12840e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 10 Oct 2019 09:49:45 +0300 Subject: [PATCH 05/10] GitHubLocalRepositoryPath option added to source-code download --- .../Volo/Abp/Cli/Commands/GetSourceCommand.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs index 54711fbc31..97dfe23944 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs @@ -61,6 +61,12 @@ namespace Volo.Abp.Cli.Commands Logger.LogInformation("Output folder: " + outputFolder); + var gitHubLocalRepositoryPath = commandLineArgs.Options.GetOrNull(Options.GitHubLocalRepositoryPath.Long); + if (gitHubLocalRepositoryPath != null) + { + Logger.LogInformation("GitHub Local Repository Path: " + gitHubLocalRepositoryPath); + } + commandLineArgs.Options.Add(CliConsts.Command, commandLineArgs.Command); var result = await ModuleProjectBuilder.BuildAsync( @@ -70,6 +76,7 @@ namespace Volo.Abp.Cli.Commands version, DatabaseProvider.NotSpecified, UiFramework.NotSpecified, + gitHubLocalRepositoryPath, commandLineArgs.Options ) ); @@ -147,6 +154,11 @@ namespace Volo.Abp.Cli.Commands public const string Long = "output-folder"; } + public static class GitHubLocalRepositoryPath + { + public const string Long = "abp-path"; + } + public static class Version { public const string Short = "v"; From 42808add45937a344bbd2ef0b7b0a1a2999bbb14 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 10 Oct 2019 10:17:45 +0300 Subject: [PATCH 06/10] Update ModuleProjectBuilder.cs --- .../Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs index d7d31c81af..57332bd5e2 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs @@ -90,7 +90,7 @@ namespace Volo.Abp.Cli.ProjectBuilding Tool = Options.ToolName, Command = args.ExtraProperties.ContainsKey(CliConsts.Command) ? args.ExtraProperties[CliConsts.Command] : "", DatabaseProvider = null, - IsTiered = false, + IsTiered = null, UiFramework = null, Options = JsonSerializer.Serialize(options), ProjectName = null, From a54735811b9875acf155e0122ffad2178774f694 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 11 Oct 2019 09:28:20 +0300 Subject: [PATCH 07/10] fixed a bug --- .../Steps/ProjectReferenceReplaceStep.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs index b040c5320d..44c4f9c0aa 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs @@ -22,7 +22,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps new ProjectReferenceReplacer.LocalProjectPathReferenceReplacer( context.Files, - "MyCompanyName.MyProjectName", + context.Module.Namespace, localAbpRepoPath ).Run(); } @@ -65,14 +65,14 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps private abstract class ProjectReferenceReplacer { private readonly List _entries; - private readonly string _companyAndProjectNamePlaceHolder; + private readonly string _projectName; protected ProjectReferenceReplacer( List entries, - string companyAndProjectNamePlaceHolder) + string projectName) { _entries = entries; - _companyAndProjectNamePlaceHolder = companyAndProjectNamePlaceHolder; + _projectName = projectName; } public void Run() @@ -108,7 +108,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps var oldNodeIncludeValue = oldNode.Attributes["Include"].Value; // ReSharper disable once PossibleNullReferenceException : Can not be null because nodes are selected with include attribute filter in previous method - if (oldNodeIncludeValue.Contains($"{_companyAndProjectNamePlaceHolder}")) + if (oldNodeIncludeValue.Contains($"{_projectName}")) { continue; } @@ -140,8 +140,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { private readonly string _nugetPackageVersion; - public NugetReferenceReplacer(List entries, string companyAndProjectNamePlaceHolder, string nugetPackageVersion) - : base(entries, companyAndProjectNamePlaceHolder) + public NugetReferenceReplacer(List entries, string projectName, string nugetPackageVersion) + : base(entries, projectName) { _nugetPackageVersion = nugetPackageVersion; } @@ -177,8 +177,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps { private readonly string _gitHubLocalRepositoryPath; - public LocalProjectPathReferenceReplacer(List entries, string companyAndProjectNamePlaceHolder, string gitHubLocalRepositoryPath) - : base(entries, companyAndProjectNamePlaceHolder) + public LocalProjectPathReferenceReplacer(List entries, string projectName, string gitHubLocalRepositoryPath) + : base(entries, projectName) { _gitHubLocalRepositoryPath = gitHubLocalRepositoryPath; } From 88025ddac72b1fbb9a3608be327242448d35c975 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 11 Oct 2019 10:02:56 +0300 Subject: [PATCH 08/10] added ReplaceCommonPropsStep --- .../ModuleProjectBuildPipelineBuilder.cs | 1 + .../Steps/ProjectReferenceReplaceStep.cs | 6 +- .../Building/Steps/ReplaceCommonPropsStep.cs | 96 +++++++++++++++++++ 3 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ReplaceCommonPropsStep.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs index fc2a5b0dbc..5eba01b388 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ModuleProjectBuildPipelineBuilder.cs @@ -10,6 +10,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building pipeline.Steps.Add(new FileEntryListReadStep()); pipeline.Steps.Add(new ProjectReferenceReplaceStep()); + pipeline.Steps.Add(new ReplaceCommonPropsStep()); pipeline.Steps.Add(new CreateProjectResultZipStep()); return pipeline; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs index 44c4f9c0aa..29f5afb19c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs @@ -22,7 +22,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps new ProjectReferenceReplacer.LocalProjectPathReferenceReplacer( context.Files, - context.Module.Namespace, + context.Module?.Namespace ?? "MyCompanyName.MyProjectName", localAbpRepoPath ).Run(); } @@ -37,7 +37,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps new ProjectReferenceReplacer.NugetReferenceReplacer( context.Files, - "MyCompanyName.MyProjectName", + context.Module?.Namespace ?? "MyCompanyName.MyProjectName", nugetPackageVersion ).Run(); } @@ -108,7 +108,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps var oldNodeIncludeValue = oldNode.Attributes["Include"].Value; // ReSharper disable once PossibleNullReferenceException : Can not be null because nodes are selected with include attribute filter in previous method - if (oldNodeIncludeValue.Contains($"{_projectName}")) + if (oldNodeIncludeValue.Contains(_projectName)) { continue; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ReplaceCommonPropsStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ReplaceCommonPropsStep.cs new file mode 100644 index 0000000000..07b2081738 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ReplaceCommonPropsStep.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; +using System.Xml; +using Volo.Abp.Cli.ProjectBuilding.Files; + +namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps +{ + public class ReplaceCommonPropsStep : ProjectBuildPipelineStep + { + public override void Execute(ProjectBuildContext context) + { + new CommonPropsReplacer(context.Files).Run(); + } + + private class CommonPropsReplacer + { + private readonly List _entries; + + public CommonPropsReplacer( + List entries) + { + _entries = entries; + } + + public void Run() + { + foreach (var fileEntry in _entries) + { + if (fileEntry.Name.EndsWith(".csproj")) + { + fileEntry.SetContent(ProcessFileContent(fileEntry.Content)); + } + } + } + + private string ProcessFileContent(string content) + { + Check.NotNull(content, nameof(content)); + + var doc = new XmlDocument() { PreserveWhitespace = true }; + + doc.Load(GenerateStreamFromString(content)); + + return ProcessReferenceNodes(doc, content); + } + + private string ProcessReferenceNodes(XmlDocument doc, string content) + { + Check.NotNull(content, nameof(content)); + + var importNodes = doc.SelectNodes("/Project/Import[@Project]"); + + if (importNodes == null) + { + return doc.OuterXml; + } + + foreach (XmlNode node in importNodes) + { + if (!(node.Attributes?["Project"]?.Value?.EndsWith("\\common.props") ?? false)) + { + continue; + } + + node.ParentNode?.RemoveChild(node); + } + + var propertyGroupNodes = doc.SelectNodes("/Project/PropertyGroup"); + + if (propertyGroupNodes == null || propertyGroupNodes.Count < 1) + { + return doc.OuterXml; + } + + var firstPropertyGroupNode = propertyGroupNodes.Item(0); + var langNode = doc.CreateElement("LangVersion"); + langNode.InnerText = "latest"; + firstPropertyGroupNode?.PrependChild(langNode); + + return doc.OuterXml; + } + + private static Stream GenerateStreamFromString(string s) + { + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); + writer.Write(s); + writer.Flush(); + stream.Position = 0; + return stream; + } + } + } +} From 403513b633916d9ac09fbd5d32de98b360de80ae Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 11 Oct 2019 11:28:00 +0300 Subject: [PATCH 09/10] bugfix in audit log repos --- .../EntityFrameworkCore/EfCoreAuditLogRepository.cs | 4 ++-- .../Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs index 4564a6d7ae..094f946777 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs @@ -110,8 +110,8 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore .IncludeDetails(includeDetails) .WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime) .WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime) - .WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null) - .WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null) + .WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "") + .WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "") .WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod) .WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url)) .WhereIf(userName != null, auditLog => auditLog.UserName == userName) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs index 1f090f81f2..a0e3c31961 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs @@ -109,8 +109,8 @@ namespace Volo.Abp.AuditLogging.MongoDB return GetMongoQueryable() .WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime) .WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime) - .WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null) - .WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null) + .WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "") + .WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "") .WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod) .WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url)) .WhereIf(userName != null, auditLog => auditLog.UserName == userName) From f053870733afdee384c097542bb389b7b624ab6d Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 11 Oct 2019 16:09:46 +0300 Subject: [PATCH 10/10] add RemoteServiceExceptionHandler --- .../Abp/Cli/Licensing/AbpIoApiKeyService.cs | 12 ++- .../Volo/Abp/Cli/NuGet/NuGetService.cs | 13 ++- .../ProjectBuilding/AbpIoSourceCodeStore.cs | 33 ++++--- .../Analyticses/CliAnalyticsCollect.cs | 19 +++- .../IRemoteServiceExceptionHandler.cs | 12 +++ .../Cli/ProjectBuilding/ModuleInfoProvider.cs | 15 +-- .../RemoteServiceExceptionHandler.cs | 92 +++++++++++++++++++ .../ProjectNugetPackageAdder.cs | 8 +- .../SolutionModuleAdder.cs | 8 +- 9 files changed, 176 insertions(+), 36 deletions(-) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IRemoteServiceExceptionHandler.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/RemoteServiceExceptionHandler.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/AbpIoApiKeyService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/AbpIoApiKeyService.cs index 22cd692ec3..c8f221b73c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/AbpIoApiKeyService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Licensing/AbpIoApiKeyService.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Volo.Abp.Cli.Http; +using Volo.Abp.Cli.ProjectBuilding; using Volo.Abp.DependencyInjection; using Volo.Abp.Json; @@ -8,13 +9,16 @@ namespace Volo.Abp.Cli.Licensing { public class AbpIoApiKeyService : IApiKeyService, ITransientDependency { - public AbpIoApiKeyService(IJsonSerializer jsonSerializer) + protected IJsonSerializer JsonSerializer { get; } + + protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } + + public AbpIoApiKeyService(IJsonSerializer jsonSerializer, IRemoteServiceExceptionHandler remoteServiceExceptionHandler) { JsonSerializer = jsonSerializer; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; } - protected IJsonSerializer JsonSerializer { get; } - public async Task GetApiKeyOrNullAsync() { using (var client = new CliHttpClient()) @@ -28,6 +32,8 @@ namespace Volo.Abp.Cli.Licensing throw new Exception($"ERROR: Remote server returns '{response.StatusCode}'"); } + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response); + var responseContent = await response.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize(responseContent); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs index b0dd6328db..700303006b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/NuGet/NuGetService.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.Cli.Http; +using Volo.Abp.Cli.ProjectBuilding; using Volo.Abp.DependencyInjection; using Volo.Abp.Json; using Volo.Abp.Threading; @@ -17,11 +18,15 @@ namespace Volo.Abp.Cli.NuGet protected ICancellationTokenProvider CancellationTokenProvider { get; } + protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } + public NuGetService( IJsonSerializer jsonSerializer, + IRemoteServiceExceptionHandler remoteServiceExceptionHandler, ICancellationTokenProvider cancellationTokenProvider) { JsonSerializer = jsonSerializer; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; CancellationTokenProvider = cancellationTokenProvider; } @@ -35,10 +40,7 @@ namespace Volo.Abp.Cli.NuGet var responseMessage = await client.GetAsync(url, CancellationTokenProvider.Token); - if (!responseMessage.IsSuccessStatusCode) - { - throw new Exception("Remote server returns error! HTTP status code: " + responseMessage.StatusCode); - } + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage); var result = await responseMessage.Content.ReadAsStringAsync(); @@ -49,7 +51,8 @@ namespace Volo.Abp.Cli.NuGet versions = versions.Where(x => !x.IsPrerelease); } - return versions.Any() ? versions.Max() : null; + var semanticVersions = versions.ToList(); + return semanticVersions.Any() ? semanticVersions.Max() : null; } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs index 6fde8db9e3..ac51be6fac 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs @@ -2,7 +2,9 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; @@ -23,14 +25,18 @@ namespace Volo.Abp.Cli.ProjectBuilding protected IJsonSerializer JsonSerializer { get; } + protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } + protected ICancellationTokenProvider CancellationTokenProvider { get; } public AbpIoSourceCodeStore( IOptions options, IJsonSerializer jsonSerializer, + IRemoteServiceExceptionHandler remoteServiceExceptionHandler, ICancellationTokenProvider cancellationTokenProvider) { JsonSerializer = jsonSerializer; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; CancellationTokenProvider = cancellationTokenProvider; Options = options.Value; @@ -42,6 +48,7 @@ namespace Volo.Abp.Cli.ProjectBuilding string type, string version = null) { + var latestVersion = await GetLatestSourceCodeVersionAsync(name, type); if (version == null) { @@ -74,26 +81,29 @@ namespace Volo.Abp.Cli.ProjectBuilding } return new TemplateFile(fileContent, version, latestVersion); + } private async Task GetLatestSourceCodeVersionAsync(string name, string type) { - var postData = JsonSerializer.Serialize(new GetLatestSourceCodeVersionDto { Name = name }); - using (var client = new CliHttpClient()) { - var responseMessage = await client.PostAsync( + var response = await client.PostAsync( $"{CliUrls.WwwAbpIo}api/download/{type}/get-version/", - new StringContent(postData, Encoding.UTF8, MimeTypes.Application.Json), + new StringContent( + JsonSerializer.Serialize( + new GetLatestSourceCodeVersionDto { Name = name } + ), + Encoding.UTF8, + MimeTypes.Application.Json + ), CancellationTokenProvider.Token ); - if (!responseMessage.IsSuccessStatusCode) - { - throw new Exception("Remote server returns error! HTTP status code: " + responseMessage.StatusCode); - } + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response); + + var result = await response.Content.ReadAsStringAsync(); - var result = await responseMessage.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize(result).Version; } } @@ -110,10 +120,7 @@ namespace Volo.Abp.Cli.ProjectBuilding CancellationTokenProvider.Token ); - if (!responseMessage.IsSuccessStatusCode) - { - throw new Exception("Remote server returns error! HTTP status code: " + responseMessage.StatusCode); - } + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage); return await responseMessage.Content.ReadAsByteArrayAsync(); } 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 index 6598c9fb31..fdfbb8b5d3 100644 --- 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 @@ -16,12 +16,16 @@ namespace Volo.Abp.Cli.ProjectBuilding.Analyticses private readonly ICancellationTokenProvider _cancellationTokenProvider; private readonly IJsonSerializer _jsonSerializer; private readonly ILogger _logger; + private readonly IRemoteServiceExceptionHandler _remoteServiceExceptionHandler; - public CliAnalyticsCollect(ICancellationTokenProvider cancellationTokenProvider, - IJsonSerializer jsonSerializer) + public CliAnalyticsCollect( + ICancellationTokenProvider cancellationTokenProvider, + IJsonSerializer jsonSerializer, + IRemoteServiceExceptionHandler remoteServiceExceptionHandler) { _cancellationTokenProvider = cancellationTokenProvider; _jsonSerializer = jsonSerializer; + _remoteServiceExceptionHandler = remoteServiceExceptionHandler; _logger = NullLogger.Instance; } @@ -38,8 +42,15 @@ namespace Volo.Abp.Cli.ProjectBuilding.Analyticses if (!responseMessage.IsSuccessStatusCode) { - _logger.LogInformation("Remote server returns error! HTTP status code: " + - responseMessage.StatusCode); + var exceptionMessage = "Remote server returns '" + (int)responseMessage.StatusCode + "-" + responseMessage.ReasonPhrase + "'. "; + var remoteServiceErrorMessage = await _remoteServiceExceptionHandler.GetAbpRemoteServiceErrorAsync(responseMessage); + + if (remoteServiceErrorMessage != null) + { + exceptionMessage += remoteServiceErrorMessage; + } + + _logger.LogInformation(exceptionMessage); } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IRemoteServiceExceptionHandler.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IRemoteServiceExceptionHandler.cs new file mode 100644 index 0000000000..b3459f53ed --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/IRemoteServiceExceptionHandler.cs @@ -0,0 +1,12 @@ +using System.Net.Http; +using System.Threading.Tasks; + +namespace Volo.Abp.Cli.ProjectBuilding +{ + public interface IRemoteServiceExceptionHandler + { + Task EnsureSuccessfulHttpResponseAsync(HttpResponseMessage responseMessage); + + Task GetAbpRemoteServiceErrorAsync(HttpResponseMessage responseMessage); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs index e82d4478b7..10b3a07172 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleInfoProvider.cs @@ -10,15 +10,20 @@ using Volo.Abp.Threading; namespace Volo.Abp.Cli.ProjectBuilding { - public class ModuleInfoProvider: IModuleInfoProvider, ITransientDependency + public class ModuleInfoProvider : IModuleInfoProvider, ITransientDependency { public IJsonSerializer JsonSerializer { get; } public ICancellationTokenProvider CancellationTokenProvider { get; } + public IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } - public ModuleInfoProvider(IJsonSerializer jsonSerializer, ICancellationTokenProvider cancellationTokenProvider) + public ModuleInfoProvider( + IJsonSerializer jsonSerializer, + ICancellationTokenProvider cancellationTokenProvider, + IRemoteServiceExceptionHandler remoteServiceExceptionHandler) { JsonSerializer = jsonSerializer; CancellationTokenProvider = cancellationTokenProvider; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; } public async Task GetAsync(string name) @@ -44,11 +49,7 @@ namespace Volo.Abp.Cli.ProjectBuilding CancellationTokenProvider.Token ); - if (!responseMessage.IsSuccessStatusCode) - { - throw new Exception("Remote server returns error! HTTP status code: " + responseMessage.StatusCode); - } - + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage); var result = await responseMessage.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize>(result); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/RemoteServiceExceptionHandler.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/RemoteServiceExceptionHandler.cs new file mode 100644 index 0000000000..fe41577583 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/RemoteServiceExceptionHandler.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http; +using Volo.Abp.Json; + +namespace Volo.Abp.Cli.ProjectBuilding +{ + public class RemoteServiceExceptionHandler : IRemoteServiceExceptionHandler, ITransientDependency + { + private readonly IJsonSerializer _jsonSerializer; + + public RemoteServiceExceptionHandler(IJsonSerializer jsonSerializer) + { + _jsonSerializer = jsonSerializer; + } + + public async Task EnsureSuccessfulHttpResponseAsync(HttpResponseMessage responseMessage) + { + if (responseMessage == null) + { + return; + } + + if (responseMessage.IsSuccessStatusCode) + { + return; + } + + var exceptionMessage = "Remote server returns '" + (int)responseMessage.StatusCode + "-" + responseMessage.ReasonPhrase + "'. "; + + var remoteServiceErrorMessage = await GetAbpRemoteServiceErrorAsync(responseMessage); + if (remoteServiceErrorMessage != null) + { + exceptionMessage += remoteServiceErrorMessage; + } + + throw new Exception(exceptionMessage); + } + + public async Task GetAbpRemoteServiceErrorAsync(HttpResponseMessage responseMessage) + { + var errorResult = _jsonSerializer.Deserialize + ( + await responseMessage.Content.ReadAsStringAsync() + ); + + if (errorResult?.Error == null) + { + return null; + } + + var sbError = new StringBuilder(); + if (!string.IsNullOrWhiteSpace(errorResult.Error.Code)) + { + sbError.Append("Code: " + errorResult.Error.Code); + } + + if (!string.IsNullOrWhiteSpace(errorResult.Error.Message)) + { + if (sbError.Length > 0) + { + sbError.Append(" - "); + } + + sbError.Append("Message: " + errorResult.Error.Message); + } + + if (errorResult.Error.ValidationErrors != null && errorResult.Error.ValidationErrors.Any()) + { + if (sbError.Length > 0) + { + sbError.Append(" - "); + } + + sbError.AppendLine("Validation Errors: "); + for (var i = 0; i < errorResult.Error.ValidationErrors.Length; i++) + { + var validationError = errorResult.Error.ValidationErrors[i]; + sbError.AppendLine("Validation error #" + i + ": " + validationError.Message + " - Members: " + validationError.Members.JoinAsString(", ") + "."); + } + } + + return sbError.ToString(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs index 2b2941a30d..1bacd7cd61 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Cli.Http; +using Volo.Abp.Cli.ProjectBuilding; using Volo.Abp.Cli.Utils; using Volo.Abp.DependencyInjection; using Volo.Abp.IO; @@ -22,17 +23,20 @@ namespace Volo.Abp.Cli.ProjectModification protected ProjectNpmPackageAdder NpmPackageAdder { get; } protected DerivedClassFinder ModuleClassFinder { get; } protected ModuleClassDependcyAdder ModuleClassDependcyAdder { get; } + protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } public ProjectNugetPackageAdder( IJsonSerializer jsonSerializer, ProjectNpmPackageAdder npmPackageAdder, DerivedClassFinder moduleClassFinder, - ModuleClassDependcyAdder moduleClassDependcyAdder) + ModuleClassDependcyAdder moduleClassDependcyAdder, + IRemoteServiceExceptionHandler remoteServiceExceptionHandler) { JsonSerializer = jsonSerializer; NpmPackageAdder = npmPackageAdder; ModuleClassFinder = moduleClassFinder; ModuleClassDependcyAdder = moduleClassDependcyAdder; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; Logger = NullLogger.Instance; } @@ -84,7 +88,7 @@ namespace Volo.Abp.Cli.ProjectModification throw new CliUsageException($"'{moduleName}' nuget package could not be found!"); } - throw new Exception($"ERROR: Remote server returns '{response.StatusCode}'"); + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response); } var responseContent = await response.Content.ReadAsStringAsync(); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs index 22e063a8ae..5950872419 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Net; using System.Threading.Tasks; using Volo.Abp.Cli.Http; +using Volo.Abp.Cli.ProjectBuilding; using Volo.Abp.DependencyInjection; using Volo.Abp.Json; @@ -24,6 +25,7 @@ namespace Volo.Abp.Cli.ProjectModification protected DerivedClassFinder DerivedClassFinder { get; } protected ProjectNpmPackageAdder ProjectNpmPackageAdder { get; } protected NpmGlobalPackagesChecker NpmGlobalPackagesChecker { get; } + protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } public SolutionModuleAdder( IJsonSerializer jsonSerializer, @@ -32,7 +34,8 @@ namespace Volo.Abp.Cli.ProjectModification EfCoreMigrationAdder efCoreMigrationAdder, DerivedClassFinder derivedClassFinder, ProjectNpmPackageAdder projectNpmPackageAdder, - NpmGlobalPackagesChecker npmGlobalPackagesChecker) + NpmGlobalPackagesChecker npmGlobalPackagesChecker, + IRemoteServiceExceptionHandler remoteServiceExceptionHandler) { JsonSerializer = jsonSerializer; ProjectNugetPackageAdder = projectNugetPackageAdder; @@ -41,6 +44,7 @@ namespace Volo.Abp.Cli.ProjectModification DerivedClassFinder = derivedClassFinder; ProjectNpmPackageAdder = projectNpmPackageAdder; NpmGlobalPackagesChecker = npmGlobalPackagesChecker; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; Logger = NullLogger.Instance; } @@ -142,7 +146,7 @@ namespace Volo.Abp.Cli.ProjectModification throw new CliUsageException($"ERROR: '{moduleName}' module could not be found!"); } - throw new Exception($"ERROR: Remote server returns '{response.StatusCode}'"); + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response); } var responseContent = await response.Content.ReadAsStringAsync();