Browse Source

Merge pull request #2948 from liangshiw/liangshiwei/cli-custom-template-path

Allow CLI to generate templates with custom sources
pull/2953/head
Yunus Emre Kalkan 7 years ago
committed by GitHub
parent
commit
524760b6de
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      docs/en/CLI.md
  2. 7
      docs/zh-Hans/CLI.md
  3. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs
  4. 19
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
  5. 1
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs
  6. 42
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs
  7. 3
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs
  8. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs
  9. 7
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs
  10. 17
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs

1
docs/en/CLI.md

@ -55,6 +55,7 @@ abp new Acme.BookStore
* `--no-ui`: Specifies to not include the UI. This makes possible to create service-only modules (a.k.a. microservices - without UI).
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
* `--version` or `-v`: Specifies the ABP & template version. It can be a [release tag](https://github.com/abpframework/abp/releases) or a [branch name](https://github.com/abpframework/abp/branches). Uses the latest release if not specified. Most of the times, you will want to use the latest version.
* `--template-source` or `-ts`: Specifies a custom template source to use to build the project. Local and network sources can be used(Like `D\localTemplate` or `https://<your url>.zip`).
### add-package

7
docs/zh-Hans/CLI.md

@ -43,7 +43,7 @@ abp new Acme.BookStore
* `app` (default): [应用程序模板](Startup-Templates/Application.md). 其他选项:
* `--ui` 或者 `-u`: 指定ui框架.默认`mvc`框架.其他选项:
* `mvc`: ASP.NET Core MVC.此模板的其他选项:
* `--tiered`: 创建分层解决方案,Web和Http Api层在物理上是分开的.如果未指定会创建一个分层的解决方案,此解决方案没有那么复杂,适合大多数场景.
* `--tiered`: 创建分层解决方案,Web和Http Api层在物理上是分开的.如果未指定会创建一个分层的解决方案,此解决方案没有那么复杂,适合大多数场景.
* `angular`: Angular. 这个模板还有一些额外的选项:
* `--separate-identity-server`: 将Identity Server应用程序与API host应用程序分开. 如果未指定,则服务器端将只有一个端点.
* `none`: 无UI. 这个模板还有一些额外的选项:
@ -53,8 +53,9 @@ abp new Acme.BookStore
* `mongodb`: MongoDB.
* `module`: [Module template](Startup-Templates/Module.md). 其他选项:
* `--no-ui`: 不包含UI.仅创建服务模块(也称为微服务 - 没有UI).
* `--output-folder` 或者 `-o`: 指定输出文件夹,默认是当前目录.
* `--version` 或者 `-v`: 指定ABP和模板的版本.它可以是 [release tag](https://github.com/abpframework/abp/releases) 或者 [branch name](https://github.com/abpframework/abp/branches). 如果没有指定,则使用最新版本.大多数情况下,您会希望使用最新的版本.
* `--output-folder` 或者 `-o`: 指定输出文件夹,默认是当前目录.
* `--version` 或者 `-v`: 指定ABP和模板的版本.它可以是 [release tag](https://github.com/abpframework/abp/releases) 或者 [branch name](https://github.com/abpframework/abp/branches). 如果没有指定,则使用最新版本.大多数情况下,您会希望使用最新的版本.
* `--template-source` 或者 `-ts`: 指定自定义模板源用于生成项目,可以使用本地源和网络源(例如 `D\localTemplate` 或 `https://<your url>.zip`).
### add-package

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs

@ -55,7 +55,7 @@ namespace Volo.Abp.Cli.Commands
}
commandLineArgs.Options.Add(CliConsts.Command, commandLineArgs.Command);
await _sourceCodeDownloadService.DownloadAsync(
commandLineArgs.Target, outputFolder, version, gitHubLocalRepositoryPath, commandLineArgs.Options);
}

19
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs

@ -30,7 +30,7 @@ namespace Volo.Abp.Cli.Commands
public async Task ExecuteAsync(CommandLineArgs commandLineArgs)
{
var projectName = NamespaceHelper.NormalizeNamespace(commandLineArgs.Target);
if (projectName == null)
{
throw new CliUsageException(
@ -39,7 +39,7 @@ namespace Volo.Abp.Cli.Commands
GetUsageInfo()
);
}
Logger.LogInformation("Creating your project...");
Logger.LogInformation("Project name: " + projectName);
@ -79,6 +79,12 @@ namespace Volo.Abp.Cli.Commands
Logger.LogInformation("GitHub Local Repository Path: " + gitHubLocalRepositoryPath);
}
var templateSource = commandLineArgs.Options.GetOrNull(Options.TemplateSource.Short, Options.TemplateSource.Long);
if (templateSource != null)
{
Logger.LogInformation("Template Source: " + templateSource);
}
var outputFolder = commandLineArgs.Options.GetOrNull(Options.OutputFolder.Short, Options.OutputFolder.Long);
outputFolder = Path.Combine(outputFolder != null ? Path.GetFullPath(outputFolder) : Directory.GetCurrentDirectory(),
@ -102,6 +108,7 @@ namespace Volo.Abp.Cli.Commands
uiFramework,
mobileApp,
gitHubLocalRepositoryPath,
templateSource,
commandLineArgs.Options
)
);
@ -158,6 +165,7 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine("-d|--database-provider <database-provider> (if supported by the template)");
sb.AppendLine("-o|--output-folder <output-folder> (default: current folder)");
sb.AppendLine("-v|--version <version> (default: latest version)");
sb.AppendLine("-ts|--template-source <template-source> (your local or network abp template source)");
sb.AppendLine("--tiered (if supported by the template)");
sb.AppendLine("--no-ui (if supported by the template)");
sb.AppendLine("--separate-identity-server (if supported by the template)");
@ -173,6 +181,7 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine(" abp new Acme.BookStore -d mongodb -o d:\\my-project");
sb.AppendLine(" abp new Acme.BookStore -t module");
sb.AppendLine(" abp new Acme.BookStore -t module --no-ui");
sb.AppendLine(" abp new Acme.BookStore -ts \"D:\\localTemplate\\abp\"");
sb.AppendLine(" abp new Acme.BookStore --local-framework-ref --abp-path \"D:\\github\\abp\"");
sb.AppendLine("");
sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI");
@ -271,6 +280,12 @@ namespace Volo.Abp.Cli.Commands
public const string Short = "m";
public const string Long = "mobile";
}
public static class TemplateSource
{
public const string Short = "ts";
public const string Long = "template-source";
}
}
}
}

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

@ -40,6 +40,7 @@ namespace Volo.Abp.Cli.Commands.Services
UiFramework.NotSpecified,
null,
gitHubLocalRepositoryPath,
null,
options
)
);

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

@ -2,9 +2,7 @@ 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;
@ -46,7 +44,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
public async Task<TemplateFile> GetAsync(
string name,
string type,
string version = null)
string version = null,
string templateSource = null)
{
var latestVersion = await GetLatestSourceCodeVersionAsync(name, type);
@ -57,8 +56,14 @@ namespace Volo.Abp.Cli.ProjectBuilding
DirectoryHelper.CreateIfNotExists(CliPaths.TemplateCache);
if (!string.IsNullOrWhiteSpace(templateSource) && !IsNetworkSource(templateSource))
{
Logger.LogInformation("Using local " + type + ": " + name + ", version: " + version);
return new TemplateFile(File.ReadAllBytes(Path.Combine(templateSource, name + "-" + version + ".zip")), version, latestVersion);
}
var localCacheFile = Path.Combine(CliPaths.TemplateCache, name + "-" + version + ".zip");
if (Options.CacheTemplates && File.Exists(localCacheFile))
if (Options.CacheTemplates && File.Exists(localCacheFile) && templateSource.IsNullOrWhiteSpace())
{
Logger.LogInformation("Using cached " + type + ": " + name + ", version: " + version);
return new TemplateFile(File.ReadAllBytes(localCacheFile), version, latestVersion);
@ -71,11 +76,12 @@ namespace Volo.Abp.Cli.ProjectBuilding
{
Name = name,
Type = type,
TemplateSource = templateSource,
Version = version
}
);
if (Options.CacheTemplates)
if (Options.CacheTemplates && templateSource.IsNullOrWhiteSpace())
{
File.WriteAllBytes(localCacheFile, fileContent);
}
@ -114,11 +120,20 @@ namespace Volo.Abp.Cli.ProjectBuilding
using (var client = new CliHttpClient(TimeSpan.FromMinutes(10)))
{
var responseMessage = await client.PostAsync(
$"{CliUrls.WwwAbpIo}api/download/{input.Type}/",
new StringContent(postData, Encoding.UTF8, MimeTypes.Application.Json),
CancellationTokenProvider.Token
);
HttpResponseMessage responseMessage;
if (input.TemplateSource.IsNullOrWhiteSpace())
{
responseMessage = await client.PostAsync(
$"{CliUrls.WwwAbpIo}api/download/{input.Type}/",
new StringContent(postData, Encoding.UTF8, MimeTypes.Application.Json),
CancellationTokenProvider.Token
);
}
else
{
responseMessage = await client.GetAsync(input.TemplateSource, CancellationTokenProvider.Token);
}
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage);
@ -126,6 +141,11 @@ namespace Volo.Abp.Cli.ProjectBuilding
}
}
private bool IsNetworkSource(string source)
{
return source.ToLower().StartsWith("http");
}
public class SourceCodeDownloadInputDto
{
public string Name { get; set; }
@ -133,6 +153,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
public string Version { get; set; }
public string Type { get; set; }
public string TemplateSource { get; set; }
}
public class GetLatestSourceCodeVersionDto

3
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs

@ -8,7 +8,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
Task<TemplateFile> GetAsync(
string name,
string type,
[CanBeNull] string version = null
[CanBeNull] string version = null,
[CanBeNull] string templateSource = null
);
}
}

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

@ -83,6 +83,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
!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

7
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs

@ -24,17 +24,21 @@ namespace Volo.Abp.Cli.ProjectBuilding
[CanBeNull]
public string AbpGitHubLocalRepositoryPath { get; set; }
[CanBeNull]
public string TemplateSource { get; set; }
[NotNull]
public Dictionary<string, string> ExtraProperties { get; set; }
public ProjectBuildArgs(
[NotNull] SolutionName solutionName,
[NotNull] SolutionName solutionName,
[CanBeNull] string templateName = null,
[CanBeNull] string version = null,
DatabaseProvider databaseProvider = DatabaseProvider.NotSpecified,
UiFramework uiFramework = UiFramework.NotSpecified,
MobileApp? mobileApp = null,
[CanBeNull] string abpGitHubLocalRepositoryPath = null,
[CanBeNull] string templateSource = null,
Dictionary<string, string> extraProperties = null)
{
SolutionName = Check.NotNull(solutionName, nameof(solutionName));
@ -44,6 +48,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
UiFramework = uiFramework;
MobileApp = mobileApp;
AbpGitHubLocalRepositoryPath = abpGitHubLocalRepositoryPath;
TemplateSource = templateSource;
ExtraProperties = extraProperties ?? new Dictionary<string, string>();
}
}

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

@ -24,11 +24,11 @@ namespace Volo.Abp.Cli.ProjectBuilding
protected IJsonSerializer JsonSerializer { get; }
protected IApiKeyService ApiKeyService { get; }
public TemplateProjectBuilder(ISourceCodeStore sourceCodeStore,
public TemplateProjectBuilder(ISourceCodeStore sourceCodeStore,
ITemplateInfoProvider templateInfoProvider,
ICliAnalyticsCollect cliAnalyticsCollect,
ICliAnalyticsCollect cliAnalyticsCollect,
IOptions<AbpCliOptions> options,
IJsonSerializer jsonSerializer,
IJsonSerializer jsonSerializer,
IApiKeyService apiKeyService)
{
SourceCodeStore = sourceCodeStore;
@ -40,7 +40,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
Logger = NullLogger<TemplateProjectBuilder>.Instance;
}
public async Task<ProjectBuildResult> BuildAsync(ProjectBuildArgs args)
{
var templateInfo = GetTemplateInfo(args);
@ -50,9 +50,10 @@ namespace Volo.Abp.Cli.ProjectBuilding
var templateFile = await SourceCodeStore.GetAsync(
args.TemplateName,
SourceCodeTypes.Template,
args.Version
args.Version,
args.TemplateSource
);
var apiKeyResult = await ApiKeyService.GetApiKeyOrNullAsync();
if (apiKeyResult?.ApiKey != null)
{
@ -82,7 +83,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
var options = args.ExtraProperties
.Where(x => !x.Key.Equals(CliConsts.Command, StringComparison.InvariantCultureIgnoreCase))
.Where(x => !x.Key.Equals("tiered", StringComparison.InvariantCultureIgnoreCase))
.Where(x => !x.Key.Equals(NewCommand.Options.DatabaseProvider.Long, StringComparison.InvariantCultureIgnoreCase) &&
.Where(x => !x.Key.Equals(NewCommand.Options.DatabaseProvider.Long, StringComparison.InvariantCultureIgnoreCase) &&
!x.Key.Equals(NewCommand.Options.DatabaseProvider.Short, StringComparison.InvariantCultureIgnoreCase))
.Where(x => !x.Key.Equals(NewCommand.Options.OutputFolder.Long, StringComparison.InvariantCultureIgnoreCase) &&
!x.Key.Equals(NewCommand.Options.OutputFolder.Short, StringComparison.InvariantCultureIgnoreCase))
@ -92,6 +93,8 @@ namespace Volo.Abp.Cli.ProjectBuilding
!x.Key.Equals(NewCommand.Options.Mobile.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

Loading…
Cancel
Save