Browse Source

Merge pull request #8261 from abpframework/cli-add-package-angular

Cli: add-package with source code for Angular
pull/8283/head
Alper Ebicoglu 6 years ago
committed by GitHub
parent
commit
b69110275d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 88
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs
  2. 60
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs
  3. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs
  4. 18
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NpmPackageProjectBuildPipelineBuilder.cs
  5. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NugetPackageProjectBuildPipelineBuilder.cs
  6. 14
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs
  7. 10
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs
  8. 1
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs
  9. 62
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs
  10. 110
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageProjectBuilder.cs
  11. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageInfoProvider.cs
  12. 13
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageProjectBuilder.cs
  13. 4
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs
  14. 1
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs
  15. 32
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs
  16. 118
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs
  17. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs
  18. 12
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs

88
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs

@ -18,9 +18,12 @@ namespace Volo.Abp.Cli.Commands
protected ProjectNugetPackageAdder ProjectNugetPackageAdder { get; } protected ProjectNugetPackageAdder ProjectNugetPackageAdder { get; }
public AddPackageCommand(ProjectNugetPackageAdder projectNugetPackageAdder) public ProjectNpmPackageAdder ProjectNpmPackageAdder { get; }
public AddPackageCommand(ProjectNugetPackageAdder projectNugetPackageAdder, ProjectNpmPackageAdder projectNpmPackageAdder)
{ {
ProjectNugetPackageAdder = projectNugetPackageAdder; ProjectNugetPackageAdder = projectNugetPackageAdder;
ProjectNpmPackageAdder = projectNpmPackageAdder;
Logger = NullLogger<AddPackageCommand>.Instance; Logger = NullLogger<AddPackageCommand>.Instance;
} }
@ -35,19 +38,42 @@ namespace Volo.Abp.Cli.Commands
); );
} }
var isAngularPackage = false;
var isNugetPackage = true;
if (commandLineArgs.Target.StartsWith("@"))
{
isAngularPackage = true;
isNugetPackage = false;
}
var version = commandLineArgs.Options.GetOrNull(Options.Version.Short, Options.Version.Long); var version = commandLineArgs.Options.GetOrNull(Options.Version.Short, Options.Version.Long);
var withSourceCode =commandLineArgs.Options.ContainsKey(Options.SourceCode.Long); var withSourceCode =commandLineArgs.Options.ContainsKey(Options.SourceCode.Long);
var addSourceCodeToSolutionFile = withSourceCode && commandLineArgs.Options.ContainsKey("add-to-solution-file");
if (isNugetPackage)
await ProjectNugetPackageAdder.AddAsync( {
GetSolutionFile(commandLineArgs), var addSourceCodeToSolutionFile = withSourceCode && commandLineArgs.Options.ContainsKey("add-to-solution-file");
GetProjectFile(commandLineArgs),
commandLineArgs.Target, await ProjectNugetPackageAdder.AddAsync(
version, GetSolutionFile(commandLineArgs),
true, GetProjectFile(commandLineArgs),
withSourceCode, commandLineArgs.Target,
addSourceCodeToSolutionFile version,
); true,
withSourceCode,
addSourceCodeToSolutionFile
);
}
else if (isAngularPackage)
{
await ProjectNpmPackageAdder.AddAngularPackageAsync(
GetAngularDirectory(commandLineArgs),
commandLineArgs.Target,
version,
withSourceCode
);
}
} }
public string GetUsageInfo() public string GetUsageInfo()
@ -56,7 +82,7 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("'add-package' command is used to add an ABP package to a project."); sb.AppendLine("'add-package' command is used to add an ABP package to a project.");
sb.AppendLine("It should be used in a folder containing a .csproj file."); sb.AppendLine("It should be used in a folder containing a .csproj file, .sln file or angular.json.");
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("Usage:"); sb.AppendLine("Usage:");
sb.AppendLine(""); sb.AppendLine("");
@ -64,13 +90,18 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("Options:"); sb.AppendLine("Options:");
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine(" -p|--project <project-file> Specify the project file explicitly."); sb.AppendLine(" -p|--project <project-file> Specifies the project file explicitly. (Only available for NuGet packages)");
sb.AppendLine(" -v|--version <version> Specify the version of the package. Default is your project's ABP version or latest ABP version."); sb.AppendLine(" -s|--solution <solution-file> Specifies the solution file explicitly. (Only available for NuGet packages)");
sb.AppendLine(" --with-source-code Downloads the source code of the NPM/NuGet package and make other projects depends on it.");
sb.AppendLine(" --add-to-solution-file Adds the downloaded project to the .sln file, when source code is downloaded. (Only available for NuGet packages)");
sb.AppendLine(" -ad|--angular-directory <angular-project-directory> Specifies the Angular project directory explicitly. (Only available for Angular packages)");
sb.AppendLine(" -v|--version <version> Specifies the version of the package. Default is your project's ABP version or latest ABP version.");
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("Examples:"); sb.AppendLine("Examples:");
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine(" abp add-package Volo.Abp.FluentValidation Adds the package to the current project."); sb.AppendLine(" abp add-package Volo.Abp.FluentValidation Adds the NuGet package to the current project.");
sb.AppendLine(" abp add-package Volo.Abp.FluentValidation -p Acme.BookStore.Application Adds the package to the given project."); sb.AppendLine(" abp add-package Volo.Abp.FluentValidation -p Acme.BookStore.Application Adds the NuGet package to the given project.");
sb.AppendLine(" abp add-package @abp/ng.theme.basic Adds the NPM package to the given corresponding project.");
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI"); sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI");
@ -116,6 +147,23 @@ namespace Volo.Abp.Cli.Commands
return Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln").FirstOrDefault(); return Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln").FirstOrDefault();
} }
protected virtual string GetAngularDirectory(CommandLineArgs commandLineArgs)
{
var providedAngularDirectory = PathHelper.NormalizePath(
commandLineArgs.Options.GetOrNull(
Options.AngularDirectory.Short,
Options.AngularDirectory.Long
)
);
if (!providedAngularDirectory.IsNullOrWhiteSpace())
{
return providedAngularDirectory;
}
return Directory.GetCurrentDirectory();
}
public static class Options public static class Options
{ {
public static class Project public static class Project
@ -130,6 +178,12 @@ namespace Volo.Abp.Cli.Commands
public const string Long = "solution"; public const string Long = "solution";
} }
public static class AngularDirectory
{
public const string Short = "ad";
public const string Long = "angular-directory";
}
public static class Version public static class Version
{ {
public const string Short = "v"; public const string Short = "v";

60
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs

@ -17,13 +17,17 @@ namespace Volo.Abp.Cli.Commands.Services
public class SourceCodeDownloadService : ITransientDependency public class SourceCodeDownloadService : ITransientDependency
{ {
public ModuleProjectBuilder ModuleProjectBuilder { get; } public ModuleProjectBuilder ModuleProjectBuilder { get; }
public PackageProjectBuilder PackageProjectBuilder { get; } public NugetPackageProjectBuilder NugetPackageProjectBuilder { get; }
public NpmPackageProjectBuilder NpmPackageProjectBuilder { get; }
public ILogger<SourceCodeDownloadService> Logger { get; set; } public ILogger<SourceCodeDownloadService> Logger { get; set; }
public SourceCodeDownloadService(ModuleProjectBuilder moduleProjectBuilder, PackageProjectBuilder packageProjectBuilder) public SourceCodeDownloadService(ModuleProjectBuilder moduleProjectBuilder,
NugetPackageProjectBuilder nugetPackageProjectBuilder,
NpmPackageProjectBuilder npmPackageProjectBuilder)
{ {
ModuleProjectBuilder = moduleProjectBuilder; ModuleProjectBuilder = moduleProjectBuilder;
PackageProjectBuilder = packageProjectBuilder; NugetPackageProjectBuilder = nugetPackageProjectBuilder;
NpmPackageProjectBuilder = npmPackageProjectBuilder;
Logger = NullLogger<SourceCodeDownloadService>.Instance; Logger = NullLogger<SourceCodeDownloadService>.Instance;
} }
@ -92,13 +96,13 @@ namespace Volo.Abp.Cli.Commands.Services
Logger.LogInformation($"'{moduleName}' has been successfully downloaded to '{outputFolder}'"); Logger.LogInformation($"'{moduleName}' has been successfully downloaded to '{outputFolder}'");
} }
public async Task DownloadPackageAsync(string packageName, string outputFolder, string version) public async Task DownloadNugetPackageAsync(string packageName, string outputFolder, string version)
{ {
Logger.LogInformation("Downloading source code of " + packageName); Logger.LogInformation("Downloading source code of " + packageName);
Logger.LogInformation("Version: " + version); Logger.LogInformation("Version: " + version);
Logger.LogInformation("Output folder: " + outputFolder); Logger.LogInformation("Output folder: " + outputFolder);
var result = await PackageProjectBuilder.BuildAsync( var result = await NugetPackageProjectBuilder.BuildAsync(
new ProjectBuildArgs( new ProjectBuildArgs(
SolutionName.Parse(packageName), SolutionName.Parse(packageName),
packageName, packageName,
@ -113,12 +117,56 @@ namespace Volo.Abp.Cli.Commands.Services
var zipEntry = zipInputStream.GetNextEntry(); var zipEntry = zipInputStream.GetNextEntry();
while (zipEntry != null) while (zipEntry != null)
{ {
if (IsAngularTestFile(zipEntry.Name)) 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(); zipEntry = zipInputStream.GetNextEntry();
continue; 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($"'{packageName}' has been successfully downloaded to '{outputFolder}'");
}
public async Task DownloadNpmPackageAsync(string packageName, string outputFolder, string version)
{
Logger.LogInformation("Downloading source code of " + packageName);
Logger.LogInformation("Version: " + version);
Logger.LogInformation("Output folder: " + outputFolder);
var result = await NpmPackageProjectBuilder.BuildAsync(
new ProjectBuildArgs(
SolutionName.Parse(packageName),
packageName,
version
)
);
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 fullZipToPath = Path.Combine(outputFolder, zipEntry.Name);
var directoryName = Path.GetDirectoryName(fullZipToPath); var directoryName = Path.GetDirectoryName(fullZipToPath);

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs

@ -91,7 +91,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
return new TemplateFile(File.ReadAllBytes(Path.Combine(templateSource, name + "-" + version + ".zip")), version, latestVersion, nugetVersion); return new TemplateFile(File.ReadAllBytes(Path.Combine(templateSource, name + "-" + version + ".zip")), version, latestVersion, nugetVersion);
} }
var localCacheFile = Path.Combine(CliPaths.TemplateCache, name + "-" + version + ".zip"); var localCacheFile = Path.Combine(CliPaths.TemplateCache, name.Replace("/",".") + "-" + version + ".zip");
#if DEBUG #if DEBUG
if (File.Exists(localCacheFile)) if (File.Exists(localCacheFile))

18
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NpmPackageProjectBuildPipelineBuilder.cs

@ -0,0 +1,18 @@
using Volo.Abp.Cli.ProjectBuilding.Building.Steps;
using Volo.Abp.Cli.ProjectBuilding.Templates;
namespace Volo.Abp.Cli.ProjectBuilding.Building
{
public static class NpmPackageProjectBuildPipelineBuilder
{
public static ProjectBuildPipeline Build(ProjectBuildContext context)
{
var pipeline = new ProjectBuildPipeline(context);
pipeline.Steps.Add(new FileEntryListReadStep());
pipeline.Steps.Add(new CreateProjectResultZipStep());
return pipeline;
}
}
}

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/PackageProjectBuildPipelineBuilder.cs → framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NugetPackageProjectBuildPipelineBuilder.cs

@ -3,7 +3,7 @@ using Volo.Abp.Cli.ProjectBuilding.Templates;
namespace Volo.Abp.Cli.ProjectBuilding.Building namespace Volo.Abp.Cli.ProjectBuilding.Building
{ {
public static class PackageProjectBuildPipelineBuilder public static class NugetPackageProjectBuildPipelineBuilder
{ {
public static ProjectBuildPipeline Build(ProjectBuildContext context) public static ProjectBuildPipeline Build(ProjectBuildContext context)
{ {

14
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs

@ -17,24 +17,28 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building
public ModuleInfo Module { get; } public ModuleInfo Module { get; }
public NugetPackageInfo Package { get; } public NugetPackageInfo NugetPackage { get; }
public NpmPackageInfo NpmPackage { get; }
public FileEntryList Files { get; set; } public FileEntryList Files { get; set; }
public ProjectResult Result { get; set; } public ProjectResult Result { get; set; }
public List<string> Symbols { get; } //TODO: Fill the symbols, like "UI-Angular", "CMS-KIT"! public List<string> Symbols { get; } //TODO: Fill the symbols, like "UI-Angular", "CMS-KIT"!
public ProjectBuildContext( public ProjectBuildContext(
TemplateInfo template, TemplateInfo template,
ModuleInfo module, ModuleInfo module,
NugetPackageInfo package, NugetPackageInfo nugetPackage,
NpmPackageInfo npmPackage,
[NotNull] TemplateFile templateFile, [NotNull] TemplateFile templateFile,
[NotNull] ProjectBuildArgs buildArgs) [NotNull] ProjectBuildArgs buildArgs)
{ {
Template = template; Template = template;
Module = module; Module = module;
Package = package; NugetPackage = nugetPackage;
NpmPackage = npmPackage;
TemplateFile = Check.NotNull(templateFile, nameof(templateFile)); TemplateFile = Check.NotNull(templateFile, nameof(templateFile));
BuildArgs = Check.NotNull(buildArgs, nameof(buildArgs)); BuildArgs = Check.NotNull(buildArgs, nameof(buildArgs));
Symbols = new List<string>(); Symbols = new List<string>();

10
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs

@ -0,0 +1,10 @@
using System.Threading.Tasks;
using Volo.Abp.Cli.ProjectModification;
namespace Volo.Abp.Cli.ProjectBuilding
{
public interface INpmPackageInfoProvider
{
Task<NpmPackageInfo> GetAsync(string name);
}
}

1
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs

@ -68,6 +68,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
null, null,
moduleInfo, moduleInfo,
null, null,
null,
templateFile, templateFile,
args args
); );

62
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs

@ -0,0 +1,62 @@
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.ProjectModification;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.Cli.ProjectBuilding
{
public class NpmPackageInfoProvider : INpmPackageInfoProvider, ITransientDependency
{
public IJsonSerializer JsonSerializer { get; }
public ICancellationTokenProvider CancellationTokenProvider { get; }
public IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; }
private readonly CliHttpClientFactory _cliHttpClientFactory;
public NpmPackageInfoProvider(
IJsonSerializer jsonSerializer,
ICancellationTokenProvider cancellationTokenProvider,
IRemoteServiceExceptionHandler remoteServiceExceptionHandler,
CliHttpClientFactory cliHttpClientFactory)
{
JsonSerializer = jsonSerializer;
CancellationTokenProvider = cancellationTokenProvider;
RemoteServiceExceptionHandler = remoteServiceExceptionHandler;
_cliHttpClientFactory = cliHttpClientFactory;
}
public async Task<NpmPackageInfo> GetAsync(string name)
{
var packageList = await GetPackageListInternalAsync();
var package = packageList.FirstOrDefault(m => m.Name == name);
if (package == null)
{
throw new Exception("Package is not found or downloadable!");
}
return package;
}
private async Task<List<NpmPackageInfo>> GetPackageListInternalAsync()
{
var client = _cliHttpClientFactory.CreateClient();
using (var responseMessage = await client.GetAsync(
$"{CliUrls.WwwAbpIo}api/download/npmPackages/",
CancellationTokenProvider.Token
))
{
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage);
var result = await responseMessage.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<List<NpmPackageInfo>>(result);
}
}
}
}

110
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageProjectBuilder.cs

@ -0,0 +1,110 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
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.Cli.ProjectModification;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
namespace Volo.Abp.Cli.ProjectBuilding
{
public class NpmPackageProjectBuilder : IProjectBuilder, ITransientDependency
{
public ILogger<NpmPackageProjectBuilder> Logger { get; set; }
protected ISourceCodeStore SourceCodeStore { get; }
protected INpmPackageInfoProvider NpmPackageInfoProvider { get; }
protected ICliAnalyticsCollect CliAnalyticsCollect { get; }
protected AbpCliOptions Options { get; }
protected IJsonSerializer JsonSerializer { get; }
protected IApiKeyService ApiKeyService { get; }
public NpmPackageProjectBuilder(ISourceCodeStore sourceCodeStore,
INpmPackageInfoProvider npmPackageInfoProvider,
ICliAnalyticsCollect cliAnalyticsCollect,
IOptions<AbpCliOptions> options,
IJsonSerializer jsonSerializer,
IApiKeyService apiKeyService)
{
SourceCodeStore = sourceCodeStore;
NpmPackageInfoProvider = npmPackageInfoProvider;
CliAnalyticsCollect = cliAnalyticsCollect;
Options = options.Value;
JsonSerializer = jsonSerializer;
ApiKeyService = apiKeyService;
Logger = NullLogger<NpmPackageProjectBuilder>.Instance;
}
public async Task<ProjectBuildResult> BuildAsync(ProjectBuildArgs args)
{
var packageInfo = await GetPackageInfoAsync(args);
var templateFile = await SourceCodeStore.GetAsync(
args.TemplateName,
SourceCodeTypes.NpmPackage,
args.Version,
null,
args.ExtraProperties.ContainsKey(GetSourceCommand.Options.Preview.Long)
);
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,
null,
null,
packageInfo,
templateFile,
args
);
NpmPackageProjectBuildPipelineBuilder.Build(context).Execute();
// 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))
.Where(x => !x.Key.Equals(NewCommand.Options.TemplateSource.Short, StringComparison.InvariantCultureIgnoreCase) &&
!x.Key.Equals(NewCommand.Options.TemplateSource.Long, 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 = null,
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<NpmPackageInfo> GetPackageInfoAsync(ProjectBuildArgs args)
{
return await NpmPackageInfoProvider.GetAsync(args.TemplateName);
}
}
}

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageInfoProvider.cs

@ -49,7 +49,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
var client = _cliHttpClientFactory.CreateClient(); var client = _cliHttpClientFactory.CreateClient();
using (var responseMessage = await client.GetAsync( using (var responseMessage = await client.GetAsync(
$"{CliUrls.WwwAbpIo}api/download/packages/", $"{CliUrls.WwwAbpIo}api/download/nugetPackages/",
CancellationTokenProvider.Token CancellationTokenProvider.Token
)) ))
{ {

13
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/PackageProjectBuilder.cs → framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageProjectBuilder.cs

@ -14,9 +14,9 @@ using Volo.Abp.Json;
namespace Volo.Abp.Cli.ProjectBuilding namespace Volo.Abp.Cli.ProjectBuilding
{ {
public class PackageProjectBuilder : IProjectBuilder, ITransientDependency public class NugetPackageProjectBuilder : IProjectBuilder, ITransientDependency
{ {
public ILogger<PackageProjectBuilder> Logger { get; set; } public ILogger<NugetPackageProjectBuilder> Logger { get; set; }
protected ISourceCodeStore SourceCodeStore { get; } protected ISourceCodeStore SourceCodeStore { get; }
protected INugetPackageInfoProvider NugetPackageInfoProvider { get; } protected INugetPackageInfoProvider NugetPackageInfoProvider { get; }
protected ICliAnalyticsCollect CliAnalyticsCollect { get; } protected ICliAnalyticsCollect CliAnalyticsCollect { get; }
@ -24,7 +24,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
protected IJsonSerializer JsonSerializer { get; } protected IJsonSerializer JsonSerializer { get; }
protected IApiKeyService ApiKeyService { get; } protected IApiKeyService ApiKeyService { get; }
public PackageProjectBuilder(ISourceCodeStore sourceCodeStore, public NugetPackageProjectBuilder(ISourceCodeStore sourceCodeStore,
INugetPackageInfoProvider nugetPackageInfoProvider, INugetPackageInfoProvider nugetPackageInfoProvider,
ICliAnalyticsCollect cliAnalyticsCollect, ICliAnalyticsCollect cliAnalyticsCollect,
IOptions<AbpCliOptions> options, IOptions<AbpCliOptions> options,
@ -38,7 +38,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
JsonSerializer = jsonSerializer; JsonSerializer = jsonSerializer;
ApiKeyService = apiKeyService; ApiKeyService = apiKeyService;
Logger = NullLogger<PackageProjectBuilder>.Instance; Logger = NullLogger<NugetPackageProjectBuilder>.Instance;
} }
public async Task<ProjectBuildResult> BuildAsync(ProjectBuildArgs args) public async Task<ProjectBuildResult> BuildAsync(ProjectBuildArgs args)
@ -47,7 +47,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
var templateFile = await SourceCodeStore.GetAsync( var templateFile = await SourceCodeStore.GetAsync(
args.TemplateName, args.TemplateName,
SourceCodeTypes.Package, SourceCodeTypes.NugetPackage,
args.Version, args.Version,
null, null,
args.ExtraProperties.ContainsKey(GetSourceCommand.Options.Preview.Long) args.ExtraProperties.ContainsKey(GetSourceCommand.Options.Preview.Long)
@ -68,11 +68,12 @@ namespace Volo.Abp.Cli.ProjectBuilding
null, null,
null, null,
packageInfo, packageInfo,
null,
templateFile, templateFile,
args args
); );
PackageProjectBuildPipelineBuilder.Build(context).Execute(); NugetPackageProjectBuildPipelineBuilder.Build(context).Execute();
// Exclude unwanted or known options. // Exclude unwanted or known options.
var options = args.ExtraProperties var options = args.ExtraProperties

4
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs

@ -6,6 +6,8 @@
public const string Module = "module"; public const string Module = "module";
public const string Package = "package"; public const string NugetPackage = "nugetPackage";
public const string NpmPackage = "npmPackage";
} }
} }

1
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs

@ -106,6 +106,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
templateInfo, templateInfo,
null, null,
null, null,
null,
templateFile, templateFile,
args args
); );

32
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularModuleSourceCodeAdder.cs → framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs

@ -11,16 +11,16 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.ProjectModification namespace Volo.Abp.Cli.ProjectModification
{ {
public class AngularModuleSourceCodeAdder : ITransientDependency public class AngularSourceCodeAdder : ITransientDependency
{ {
public ILogger<SolutionModuleAdder> Logger { get; set; } public ILogger<SolutionModuleAdder> Logger { get; set; }
public AngularModuleSourceCodeAdder() public AngularSourceCodeAdder()
{ {
Logger = NullLogger<SolutionModuleAdder>.Instance; Logger = NullLogger<SolutionModuleAdder>.Instance;
} }
public async Task AddAsync(string solutionFilePath, string angularPath) public async Task AddFromModuleAsync(string solutionFilePath, string angularPath)
{ {
try try
{ {
@ -36,7 +36,7 @@ namespace Volo.Abp.Cli.ProjectModification
await AddPathsToTsConfigAsync(angularPath, angularProjectsPath, projects); await AddPathsToTsConfigAsync(angularPath, angularProjectsPath, projects);
await CreateTsConfigProdJsonAsync(angularPath); await CreateTsConfigProdJsonAsync(angularPath);
await AddScriptsToPackageJsonAsync(angularPath); await AddScriptsToPackageJsonAsync(angularPath);
await AddProjectToAngularJsonAsync(angularPath, projects); await AddProjectsToAngularJsonAsync(angularPath, projects);
} }
catch (Exception e) catch (Exception e)
{ {
@ -44,7 +44,29 @@ namespace Volo.Abp.Cli.ProjectModification
} }
} }
private async Task AddProjectToAngularJsonAsync(string angularPath, List<string> projects) public async Task AddAsync(string angularPath, NpmPackageInfo package)
{
try
{
var angularProjectsPath = Path.Combine(angularPath, "projects");
var projects = new List<string>
{
package.Name.RemovePreFix("@").Replace("/","-")
};
await AddPathsToTsConfigAsync(angularPath, angularProjectsPath, projects);
await CreateTsConfigProdJsonAsync(angularPath);
await AddScriptsToPackageJsonAsync(angularPath);
await AddProjectsToAngularJsonAsync(angularPath, projects);
}
catch (Exception e)
{
Logger.LogError("Unable to add angular source code: " + e.Message + Environment.NewLine + e.StackTrace);
}
}
private async Task AddProjectsToAngularJsonAsync(string angularPath, List<string> projects)
{ {
var angularJsonFilePath = Path.Combine(angularPath, "angular.json"); var angularJsonFilePath = Path.Combine(angularPath, "angular.json");
var fileContent = File.ReadAllText(angularJsonFilePath); var fileContent = File.ReadAllText(angularJsonFilePath);

118
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs

@ -1,23 +1,107 @@
using System.IO; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands;
using Volo.Abp.Cli.Commands.Services;
using Volo.Abp.Cli.Http;
using Volo.Abp.Cli.ProjectBuilding;
using Volo.Abp.Cli.Utils; using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.IO; using Volo.Abp.IO;
using Volo.Abp.Json;
namespace Volo.Abp.Cli.ProjectModification namespace Volo.Abp.Cli.ProjectModification
{ {
public class ProjectNpmPackageAdder : ITransientDependency public class ProjectNpmPackageAdder : ITransientDependency
{ {
public IJsonSerializer JsonSerializer { get; }
public SourceCodeDownloadService SourceCodeDownloadService { get; }
public AngularSourceCodeAdder AngularSourceCodeAdder { get; }
public IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; }
private readonly CliHttpClientFactory _cliHttpClientFactory;
public ILogger<ProjectNpmPackageAdder> Logger { get; set; } public ILogger<ProjectNpmPackageAdder> Logger { get; set; }
public ProjectNpmPackageAdder() public ProjectNpmPackageAdder(CliHttpClientFactory cliHttpClientFactory,
IJsonSerializer jsonSerializer,
SourceCodeDownloadService sourceCodeDownloadService,
AngularSourceCodeAdder angularSourceCodeAdder,
IRemoteServiceExceptionHandler remoteServiceExceptionHandler)
{ {
JsonSerializer = jsonSerializer;
SourceCodeDownloadService = sourceCodeDownloadService;
AngularSourceCodeAdder = angularSourceCodeAdder;
RemoteServiceExceptionHandler = remoteServiceExceptionHandler;
_cliHttpClientFactory = cliHttpClientFactory;
Logger = NullLogger<ProjectNpmPackageAdder>.Instance; Logger = NullLogger<ProjectNpmPackageAdder>.Instance;
} }
public Task AddAsync(string directory, NpmPackageInfo npmPackage, bool skipGulpCommand = false) public async Task AddAngularPackageAsync(string directory, string npmPackageName, string version = null, bool withSourceCode = false)
{
await AddAngularPackageAsync(
directory,
await FindNpmPackageInfoAsync(npmPackageName),
version,
withSourceCode
);
}
public async Task AddAngularPackageAsync(string directory, NpmPackageInfo npmPackage, string version = null, bool withSourceCode = false)
{
var packageJsonFilePath = Path.Combine(directory, "package.json");
if (!File.Exists(packageJsonFilePath))
{
Logger.LogError($"package.json not found!");
return;
}
Logger.LogInformation($"Installing '{npmPackage.Name}' package to the project '{packageJsonFilePath}'...");
if (!File.ReadAllText(packageJsonFilePath).Contains($"\"{npmPackage.Name}\""))
{
var versionPostfix = version != null ? $"@{version}" : string.Empty;
using (DirectoryHelper.ChangeCurrentDirectory(directory))
{
Logger.LogInformation("yarn add " + npmPackage.Name + versionPostfix);
CmdHelper.RunCmd("yarn add " + npmPackage.Name + versionPostfix);
}
}
else
{
Logger.LogInformation($"'{npmPackage.Name}' is already installed.");
}
if (withSourceCode)
{
await DownloadAngularSourceCode(directory, npmPackage, version);
await AngularSourceCodeAdder.AddAsync(directory, npmPackage);
}
}
protected virtual async Task DownloadAngularSourceCode(string angularDirectory, NpmPackageInfo package, string version = null)
{
var targetFolder = Path.Combine(angularDirectory, "projects", package.Name.RemovePreFix("@").Replace("/","-"));
if (Directory.Exists(targetFolder))
{
Directory.Delete(targetFolder, true);
}
await SourceCodeDownloadService.DownloadNpmPackageAsync(
package.Name,
targetFolder,
version
);
}
public Task AddMvcPackageAsync(string directory, NpmPackageInfo npmPackage, string version = null, bool skipGulpCommand = false)
{ {
var packageJsonFilePath = Path.Combine(directory, "package.json"); var packageJsonFilePath = Path.Combine(directory, "package.json");
if (!File.Exists(packageJsonFilePath) || if (!File.Exists(packageJsonFilePath) ||
@ -29,11 +113,12 @@ namespace Volo.Abp.Cli.ProjectModification
Logger.LogInformation($"Installing '{npmPackage.Name}' package to the project '{packageJsonFilePath}'..."); Logger.LogInformation($"Installing '{npmPackage.Name}' package to the project '{packageJsonFilePath}'...");
var versionPostfix = version != null ? $"@{version}" : string.Empty;
using (DirectoryHelper.ChangeCurrentDirectory(directory)) using (DirectoryHelper.ChangeCurrentDirectory(directory))
{ {
Logger.LogInformation("yarn add " + npmPackage.Name); Logger.LogInformation("yarn add " + npmPackage.Name + versionPostfix);
CmdHelper.RunCmd("yarn add " + npmPackage.Name); CmdHelper.RunCmd("yarn add " + npmPackage.Name + versionPostfix);
if (skipGulpCommand) if (skipGulpCommand)
{ {
@ -46,5 +131,28 @@ namespace Volo.Abp.Cli.ProjectModification
return Task.CompletedTask; return Task.CompletedTask;
} }
private async Task<NpmPackageInfo> FindNpmPackageInfoAsync(string packageName)
{
var url = $"{CliUrls.WwwAbpIo}api/app/npmPackage/byName/?name=" + packageName;
var client = _cliHttpClientFactory.CreateClient();
using (var response = await client.GetAsync(url, _cliHttpClientFactory.GetCancellationToken()))
{
if (!response.IsSuccessStatusCode)
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
throw new CliUsageException($"'{packageName}' npm package could not be found!");
}
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response);
}
var responseContent = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<NpmPackageInfo>(responseContent);
}
}
} }
} }

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs

@ -194,7 +194,7 @@ namespace Volo.Abp.Cli.ProjectModification
protected virtual async Task DownloadSourceCode(string targetFolder, NugetPackageInfo package, string version = null) protected virtual async Task DownloadSourceCode(string targetFolder, NugetPackageInfo package, string version = null)
{ {
await SourceCodeDownloadService.DownloadPackageAsync( await SourceCodeDownloadService.DownloadNugetPackageAsync(
package.Name, package.Name,
targetFolder, targetFolder,
version version

12
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs

@ -27,7 +27,7 @@ namespace Volo.Abp.Cli.ProjectModification
public SourceCodeDownloadService SourceCodeDownloadService { get; } public SourceCodeDownloadService SourceCodeDownloadService { get; }
public SolutionFileModifier SolutionFileModifier { get; } public SolutionFileModifier SolutionFileModifier { get; }
public NugetPackageToLocalReferenceConverter NugetPackageToLocalReferenceConverter { get; } public NugetPackageToLocalReferenceConverter NugetPackageToLocalReferenceConverter { get; }
public AngularModuleSourceCodeAdder AngularModuleSourceCodeAdder { get; } public AngularSourceCodeAdder AngularSourceCodeAdder { get; }
public NewCommand NewCommand { get; } public NewCommand NewCommand { get; }
public BundleCommand BundleCommand { get; } public BundleCommand BundleCommand { get; }
@ -55,7 +55,7 @@ namespace Volo.Abp.Cli.ProjectModification
SourceCodeDownloadService sourceCodeDownloadService, SourceCodeDownloadService sourceCodeDownloadService,
SolutionFileModifier solutionFileModifier, SolutionFileModifier solutionFileModifier,
NugetPackageToLocalReferenceConverter nugetPackageToLocalReferenceConverter, NugetPackageToLocalReferenceConverter nugetPackageToLocalReferenceConverter,
AngularModuleSourceCodeAdder angularModuleSourceCodeAdder, AngularSourceCodeAdder angularSourceCodeAdder,
NewCommand newCommand, NewCommand newCommand,
BundleCommand bundleCommand, BundleCommand bundleCommand,
CliHttpClientFactory cliHttpClientFactory) CliHttpClientFactory cliHttpClientFactory)
@ -71,7 +71,7 @@ namespace Volo.Abp.Cli.ProjectModification
SourceCodeDownloadService = sourceCodeDownloadService; SourceCodeDownloadService = sourceCodeDownloadService;
SolutionFileModifier = solutionFileModifier; SolutionFileModifier = solutionFileModifier;
NugetPackageToLocalReferenceConverter = nugetPackageToLocalReferenceConverter; NugetPackageToLocalReferenceConverter = nugetPackageToLocalReferenceConverter;
AngularModuleSourceCodeAdder = angularModuleSourceCodeAdder; AngularSourceCodeAdder = angularSourceCodeAdder;
NewCommand = newCommand; NewCommand = newCommand;
BundleCommand = bundleCommand; BundleCommand = bundleCommand;
_cliHttpClientFactory = cliHttpClientFactory; _cliHttpClientFactory = cliHttpClientFactory;
@ -327,7 +327,7 @@ namespace Volo.Abp.Cli.ProjectModification
{ {
foreach (var npmPackage in angularPackages) foreach (var npmPackage in angularPackages)
{ {
await ProjectNpmPackageAdder.AddAsync(angularPath, npmPackage, true); await ProjectNpmPackageAdder.AddAngularPackageAsync(angularPath, npmPackage);
} }
} }
} }
@ -347,7 +347,7 @@ namespace Volo.Abp.Cli.ProjectModification
MoveAngularFolderInNewTemplate(modulesFolderInSolution, moduleName); MoveAngularFolderInNewTemplate(modulesFolderInSolution, moduleName);
} }
await AngularModuleSourceCodeAdder.AddAsync(solutionFilePath, angularPath); await AngularSourceCodeAdder.AddFromModuleAsync(solutionFilePath, angularPath);
} }
private static void DeleteAngularDirectoriesInModulesFolder(string modulesFolderInSolution) private static void DeleteAngularDirectoriesInModulesFolder(string modulesFolderInSolution)
@ -490,7 +490,7 @@ namespace Volo.Abp.Cli.ProjectModification
{ {
foreach (var npmPackage in mvcNpmPackages) foreach (var npmPackage in mvcNpmPackages)
{ {
await ProjectNpmPackageAdder.AddAsync(Path.GetDirectoryName(targetProject), npmPackage); await ProjectNpmPackageAdder.AddMvcPackageAsync(Path.GetDirectoryName(targetProject), npmPackage, null, true);
} }
} }
} }

Loading…
Cancel
Save