@ -1,4 +1,15 @@ |
|||
ui-angular: |
|||
- npm/ng-packs/* |
|||
- npm/ng-packs/**/* |
|||
- npm/ng-packs/**/**/* |
|||
- npm/ng-packs/**/**/**/* |
|||
- npm/ng-packs/**/**/**/**/* |
|||
- npm/ng-packs/**/**/**/**/**/* |
|||
- templates/app/angular/* |
|||
- templates/app/angular/**/* |
|||
- templates/app/angular/**/**/* |
|||
- templates/app/angular/**/**/**/* |
|||
- templates/module/angular/* |
|||
- templates/module/angular/**/* |
|||
- templates/module/angular/**/**/* |
|||
- templates/module/angular/**/**/**/* |
|||
|
|||
@ -1,17 +1,12 @@ |
|||
name: "Pull Request Labeler" |
|||
name: Pull request labeler |
|||
on: |
|||
pull_request: |
|||
paths: |
|||
- npm/ng-packs/**/* |
|||
- templates/app/angular/**/* |
|||
- templates/module/angular/**/* |
|||
branches: |
|||
- master |
|||
- dev |
|||
schedule: |
|||
- cron: '0 12 */1 * *' |
|||
jobs: |
|||
labeler: |
|||
runs-on: ubuntu-18.04 |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- uses: actions/labeler@v2 |
|||
with: |
|||
repo-token: "${{ secrets.GITHUB_TOKEN }}" |
|||
- uses: paulfantom/periodic-labeler@master |
|||
env: |
|||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
|||
GITHUB_REPOSITORY: ${{ github.repository }} |
|||
|
|||
@ -1,35 +0,0 @@ |
|||
## Entity Framework Core PostgreSQL integrace |
|||
|
|||
> Podívejte se na [Entity Framework Core integrační dokument](../Entity-Framework-Core.md) pro základy integrace EF Core. |
|||
|
|||
### Aktualizace projektu EntityFrameworkCore |
|||
|
|||
- V projektu `Acme.BookStore.EntityFrameworkCore` nahraďte balík `Volo.Abp.EntityFrameworkCore.SqlServer` za `Volo.Abp.EntityFrameworkCore.PostgreSql` |
|||
- Aktualizace pro použití PostgreSQL v `BookStoreEntityFrameworkCoreModule` |
|||
- Nahraďte `AbpEntityFrameworkCoreSqlServerModule` za `AbpEntityFrameworkCorePostgreSqlModule` |
|||
- Nahraďte `options.UseSqlServer()` za `options.UsePostgreSql()` |
|||
- V jiných projektech aktualizujte PostgreSQL connection string v nezbytných `appsettings.json` souborech |
|||
|
|||
#### Odstranění stávajících migrací |
|||
|
|||
Smažte všechny stavající migrační soubory (včetně `DbContextModelSnapshot`) |
|||
|
|||
 |
|||
|
|||
#### Znovu vygenerujte počáteční migraci & aktualizujte databázi |
|||
|
|||
Nastavte správný spouštěcí projekt (obvykle web projekt), |
|||
Otevřete **Package Manager Console** (Tools -> Nuget Package Manager -> Package Manager Console), zvolte `Acme.BookStore.EntityFrameworkCore.DbMigrations` jako **Default project** a proveďte následující příkaz: |
|||
|
|||
Proveďte příkaz `Add-Migration`: |
|||
```` |
|||
PM> Add-Migration Initial |
|||
```` |
|||
|
|||
Poté proveďte příkaz `Update-Database` k aktualizaci schématu databáze: |
|||
|
|||
```` |
|||
PM> Update-Database |
|||
```` |
|||
|
|||
 |
|||
@ -0,0 +1,74 @@ |
|||
## Entity Framework Core PostgreSQL integrace |
|||
|
|||
> Podívejte se na [Entity Framework Core integrační dokument](../Entity-Framework-Core.md) pro základy integrace EF Core. |
|||
|
|||
### Aktualizace projektu EntityFrameworkCore |
|||
|
|||
- V projektu `Acme.BookStore.EntityFrameworkCore` nahraďte balík `Volo.Abp.EntityFrameworkCore.SqlServer` za `Volo.Abp.EntityFrameworkCore.PostgreSql` |
|||
- Aktualizace pro použití PostgreSQL v `BookStoreEntityFrameworkCoreModule` |
|||
- Nahraďte `AbpEntityFrameworkCoreSqlServerModule` za `AbpEntityFrameworkCorePostgreSqlModule` |
|||
- Nahraďte `options.UseSqlServer()` za `options.UsePostgreSql()` |
|||
- V jiných projektech aktualizujte PostgreSQL connection string v nezbytných `appsettings.json` souborech |
|||
- Více informací v [PostgreSQL connection strings](https://www.connectionstrings.com/postgresql/), v tomto dokumentu věnujte pozornost sekci `Npgsql` |
|||
|
|||
### Aktualizace projektu EntityFrameworkCore.DbMigrations |
|||
- Aktualizace pro použití PostgreSQL v `XXXMigrationsDbContextFactory` |
|||
- Nahraďte `new DbContextOptionsBuilder<XXXMigrationsDbContext>().UseSqlServer()` za `new DbContextOptionsBuilder<XXXMigrationsDbContext>().UseNpgsql()` |
|||
|
|||
|
|||
### Odstranění stávajících migrací |
|||
|
|||
Smažte všechny stavající migrační soubory (včetně `DbContextModelSnapshot`) |
|||
|
|||
 |
|||
|
|||
### Znovu vygenerujte počáteční migraci |
|||
|
|||
Nastavte správný spouštěcí projekt (obvykle web projekt) |
|||
|
|||
 |
|||
|
|||
Otevřete **Package Manager Console** (Tools -> Nuget Package Manager -> Package Manager Console), zvolte `.EntityFrameworkCore.DbMigrations` jako **Default project** a proveďte následující příkaz: |
|||
|
|||
Proveďte příkaz `Add-Migration`: |
|||
```` |
|||
PM> Add-Migration Initial |
|||
```` |
|||
|
|||
### Aktualizace databáze |
|||
|
|||
K vytvoření databáze máte dvě možnosti. |
|||
|
|||
#### Použití DbMigrator aplikace |
|||
|
|||
Řešení obsahuje konzolovou aplikaci (v tomto příkladu nazvanou `Acme.BookStore.DbMigrator`), která může vytvářet databáze, aplikovat migrace a vkládat seed data. Je užitečná jak pro vývojové, tak pro produkční prostředí. |
|||
|
|||
> Projekt `.DbMigrator` má vlastní `appsettings.json`. Takže pokud jste změnili connection string uvedený výše, musíte změnit také tento. |
|||
|
|||
Klikněte pravým na projekt `.DbMigrator` a vyberte **Set as StartUp Project**: |
|||
|
|||
 |
|||
|
|||
Zmáčkněte F5 (nebo Ctrl+F5) ke spuštění aplikace. Výstup bude vypadat následovně: |
|||
|
|||
 |
|||
|
|||
#### Použití EF Core Update-Database příkazu |
|||
|
|||
Ef Core má `Update-Database` příkaz, který v případě potřeby vytvoří databázi a aplikuje čekající migrace. |
|||
|
|||
Nastavte správný spouštěcí projekt (obvykle web projekt) |
|||
|
|||
 |
|||
|
|||
Otevřete **Package Manager Console** (Tools -> Nuget Package Manager -> Package Manager Console), vyberte projekt `.EntityFrameworkCore.DbMigrations` jako **Default Project** and spusťte následující příkaz: |
|||
|
|||
```` |
|||
PM> Update-Database |
|||
```` |
|||
|
|||
Dojde k vytvoření nové databáze na základě nakonfigurovaného connection stringu. |
|||
|
|||
 |
|||
|
|||
> Použití nástroje `.DbMigrator` je doporučený způsob, jelikož zároveň vloží seed data nutné k správnému běhu webové aplikace. |
|||
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
@ -1,9 +1,10 @@ |
|||
using Volo.Abp.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.BackgroundJobs.RabbitMQ |
|||
{ |
|||
public interface IJobQueueManager : IRunnable |
|||
{ |
|||
IJobQueue<TArgs> Get<TArgs>(); |
|||
Task<IJobQueue<TArgs>> GetAsync<TArgs>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using Castle.DynamicProxy; |
|||
using Volo.Abp.DynamicProxy; |
|||
|
|||
namespace Volo.Abp.Castle.DynamicProxy |
|||
{ |
|||
public class AbpAsyncDeterminationInterceptor<TInterceptor> : AsyncDeterminationInterceptor |
|||
where TInterceptor : IAbpInterceptor |
|||
{ |
|||
public AbpAsyncDeterminationInterceptor(TInterceptor abpInterceptor) |
|||
: base(new CastleAsyncAbpInterceptorAdapter<TInterceptor>(abpInterceptor)) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,89 +0,0 @@ |
|||
using System.Reflection; |
|||
using System.Threading.Tasks; |
|||
using Castle.DynamicProxy; |
|||
using Volo.Abp.DynamicProxy; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.Castle.DynamicProxy |
|||
{ |
|||
public class CastleAbpInterceptorAdapter<TInterceptor> : IInterceptor |
|||
where TInterceptor : IAbpInterceptor |
|||
{ |
|||
private static readonly MethodInfo MethodExecuteWithoutReturnValueAsync = |
|||
typeof(CastleAbpInterceptorAdapter<TInterceptor>) |
|||
.GetMethod( |
|||
nameof(ExecuteWithoutReturnValueAsync), |
|||
BindingFlags.NonPublic | BindingFlags.Instance |
|||
); |
|||
|
|||
private static readonly MethodInfo MethodExecuteWithReturnValueAsync = |
|||
typeof(CastleAbpInterceptorAdapter<TInterceptor>) |
|||
.GetMethod( |
|||
nameof(ExecuteWithReturnValueAsync), |
|||
BindingFlags.NonPublic | BindingFlags.Instance |
|||
); |
|||
|
|||
private readonly TInterceptor _abpInterceptor; |
|||
|
|||
public CastleAbpInterceptorAdapter(TInterceptor abpInterceptor) |
|||
{ |
|||
_abpInterceptor = abpInterceptor; |
|||
} |
|||
|
|||
public void Intercept(IInvocation invocation) |
|||
{ |
|||
var proceedInfo = invocation.CaptureProceedInfo(); |
|||
|
|||
var method = invocation.MethodInvocationTarget ?? invocation.Method; |
|||
|
|||
if (method.IsAsync()) |
|||
{ |
|||
InterceptAsyncMethod(invocation, proceedInfo); |
|||
} |
|||
else |
|||
{ |
|||
InterceptSyncMethod(invocation, proceedInfo); |
|||
} |
|||
} |
|||
|
|||
private void InterceptSyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|||
{ |
|||
_abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation, proceedInfo)); |
|||
} |
|||
|
|||
private void InterceptAsyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|||
{ |
|||
if (invocation.Method.ReturnType == typeof(Task)) |
|||
{ |
|||
invocation.ReturnValue = MethodExecuteWithoutReturnValueAsync |
|||
.Invoke(this, new object[] { invocation, proceedInfo }); |
|||
} |
|||
else |
|||
{ |
|||
invocation.ReturnValue = MethodExecuteWithReturnValueAsync |
|||
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) |
|||
.Invoke(this, new object[] {invocation, proceedInfo}); |
|||
} |
|||
} |
|||
|
|||
private async Task ExecuteWithoutReturnValueAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|||
{ |
|||
await Task.Yield(); |
|||
|
|||
await _abpInterceptor.InterceptAsync( |
|||
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo) |
|||
); |
|||
} |
|||
|
|||
private async Task<T> ExecuteWithReturnValueAsync<T>(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|||
{ |
|||
await Task.Yield(); |
|||
|
|||
await _abpInterceptor.InterceptAsync( |
|||
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo) |
|||
); |
|||
|
|||
return await (Task<T>)invocation.ReturnValue; |
|||
} |
|||
} |
|||
} |
|||
@ -1,77 +1,26 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
using System.Threading.Tasks; |
|||
using Castle.DynamicProxy; |
|||
using Volo.Abp.DynamicProxy; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.Castle.DynamicProxy |
|||
{ |
|||
public class CastleAbpMethodInvocationAdapter : IAbpMethodInvocation |
|||
public class CastleAbpMethodInvocationAdapter : CastleAbpMethodInvocationAdapterBase, IAbpMethodInvocation |
|||
{ |
|||
public object[] Arguments => Invocation.Arguments; |
|||
|
|||
public IReadOnlyDictionary<string, object> ArgumentsDictionary => _lazyArgumentsDictionary.Value; |
|||
private readonly Lazy<IReadOnlyDictionary<string, object>> _lazyArgumentsDictionary; |
|||
|
|||
public Type[] GenericArguments => Invocation.GenericArguments; |
|||
|
|||
public object TargetObject => Invocation.InvocationTarget ?? Invocation.MethodInvocationTarget; |
|||
|
|||
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method; |
|||
|
|||
public object ReturnValue |
|||
{ |
|||
get => _actualReturnValue ?? Invocation.ReturnValue; |
|||
set => Invocation.ReturnValue = value; |
|||
} |
|||
|
|||
private object _actualReturnValue; |
|||
|
|||
protected IInvocation Invocation { get; } |
|||
protected IInvocationProceedInfo ProceedInfo { get; } |
|||
protected Func<IInvocation, IInvocationProceedInfo, Task> Proceed { get; } |
|||
|
|||
public CastleAbpMethodInvocationAdapter(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|||
public CastleAbpMethodInvocationAdapter(IInvocation invocation, IInvocationProceedInfo proceedInfo, |
|||
Func<IInvocation, IInvocationProceedInfo, Task> proceed) |
|||
: base(invocation) |
|||
{ |
|||
Invocation = invocation; |
|||
ProceedInfo = proceedInfo; |
|||
|
|||
_lazyArgumentsDictionary = new Lazy<IReadOnlyDictionary<string, object>>(GetArgumentsDictionary); |
|||
Proceed = proceed; |
|||
} |
|||
|
|||
public void Proceed() |
|||
public override async Task ProceedAsync() |
|||
{ |
|||
ProceedInfo.Invoke(); |
|||
|
|||
if (Invocation.Method.IsAsync()) |
|||
{ |
|||
AsyncHelper.RunSync(() => (Task)Invocation.ReturnValue); |
|||
} |
|||
} |
|||
|
|||
public Task ProceedAsync() |
|||
{ |
|||
ProceedInfo.Invoke(); |
|||
|
|||
_actualReturnValue = Invocation.ReturnValue; |
|||
|
|||
return Invocation.Method.IsAsync() |
|||
? (Task)_actualReturnValue |
|||
: Task.FromResult(_actualReturnValue); |
|||
} |
|||
|
|||
private IReadOnlyDictionary<string, object> GetArgumentsDictionary() |
|||
{ |
|||
var dict = new Dictionary<string, object>(); |
|||
|
|||
var methodParameters = Method.GetParameters(); |
|||
for (int i = 0; i < methodParameters.Length; i++) |
|||
{ |
|||
dict[methodParameters[i].Name] = Invocation.Arguments[i]; |
|||
} |
|||
|
|||
return dict; |
|||
await Proceed(Invocation, ProceedInfo); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
using System.Threading.Tasks; |
|||
using Castle.DynamicProxy; |
|||
using Volo.Abp.DynamicProxy; |
|||
|
|||
namespace Volo.Abp.Castle.DynamicProxy |
|||
{ |
|||
public abstract class CastleAbpMethodInvocationAdapterBase : IAbpMethodInvocation |
|||
{ |
|||
public object[] Arguments => Invocation.Arguments; |
|||
|
|||
public IReadOnlyDictionary<string, object> ArgumentsDictionary => _lazyArgumentsDictionary.Value; |
|||
private readonly Lazy<IReadOnlyDictionary<string, object>> _lazyArgumentsDictionary; |
|||
|
|||
public Type[] GenericArguments => Invocation.GenericArguments; |
|||
|
|||
public object TargetObject => Invocation.InvocationTarget ?? Invocation.MethodInvocationTarget; |
|||
|
|||
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method; |
|||
|
|||
public object ReturnValue { get; set; } |
|||
|
|||
protected IInvocation Invocation { get; } |
|||
|
|||
protected CastleAbpMethodInvocationAdapterBase(IInvocation invocation) |
|||
{ |
|||
Invocation = invocation; |
|||
_lazyArgumentsDictionary = new Lazy<IReadOnlyDictionary<string, object>>(GetArgumentsDictionary); |
|||
} |
|||
|
|||
public abstract Task ProceedAsync(); |
|||
|
|||
private IReadOnlyDictionary<string, object> GetArgumentsDictionary() |
|||
{ |
|||
var dict = new Dictionary<string, object>(); |
|||
|
|||
var methodParameters = Method.GetParameters(); |
|||
for (int i = 0; i < methodParameters.Length; i++) |
|||
{ |
|||
dict[methodParameters[i].Name] = Invocation.Arguments[i]; |
|||
} |
|||
|
|||
return dict; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Castle.DynamicProxy; |
|||
using Volo.Abp.DynamicProxy; |
|||
|
|||
namespace Volo.Abp.Castle.DynamicProxy |
|||
{ |
|||
public class CastleAbpMethodInvocationAdapterWithReturnValue<TResult> : CastleAbpMethodInvocationAdapterBase, IAbpMethodInvocation |
|||
{ |
|||
protected IInvocationProceedInfo ProceedInfo { get; } |
|||
protected Func<IInvocation, IInvocationProceedInfo, Task<TResult>> Proceed { get; } |
|||
|
|||
public CastleAbpMethodInvocationAdapterWithReturnValue(IInvocation invocation, |
|||
IInvocationProceedInfo proceedInfo, |
|||
Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed) |
|||
: base(invocation) |
|||
{ |
|||
ProceedInfo = proceedInfo; |
|||
Proceed = proceed; |
|||
} |
|||
|
|||
public override async Task ProceedAsync() |
|||
{ |
|||
ReturnValue = await Proceed(Invocation, ProceedInfo); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Castle.DynamicProxy; |
|||
using Volo.Abp.DynamicProxy; |
|||
|
|||
namespace Volo.Abp.Castle.DynamicProxy |
|||
{ |
|||
public class CastleAsyncAbpInterceptorAdapter<TInterceptor> : AsyncInterceptorBase |
|||
where TInterceptor : IAbpInterceptor |
|||
{ |
|||
private readonly TInterceptor _abpInterceptor; |
|||
|
|||
public CastleAsyncAbpInterceptorAdapter(TInterceptor abpInterceptor) |
|||
{ |
|||
_abpInterceptor = abpInterceptor; |
|||
} |
|||
|
|||
protected override async Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task> proceed) |
|||
{ |
|||
await _abpInterceptor.InterceptAsync( |
|||
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo, proceed) |
|||
); |
|||
} |
|||
|
|||
protected override async Task<TResult> InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed) |
|||
{ |
|||
var adapter = new CastleAbpMethodInvocationAdapterWithReturnValue<TResult>(invocation, proceedInfo, proceed); |
|||
|
|||
await _abpInterceptor.InterceptAsync( |
|||
adapter |
|||
); |
|||
|
|||
return (TResult)adapter.ReturnValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,156 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using Volo.Abp.Cli.Args; |
|||
using Volo.Abp.Cli.Licensing; |
|||
using Volo.Abp.Cli.Utils; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Cli.Commands |
|||
{ |
|||
public class SuiteCommand : IConsoleCommand, ITransientDependency |
|||
{ |
|||
private const string SuitePackageName = "Volo.Abp.Suite"; |
|||
public ILogger<SuiteCommand> Logger { get; set; } |
|||
private readonly IApiKeyService _apiKeyService; |
|||
|
|||
public SuiteCommand(IApiKeyService apiKeyService) |
|||
{ |
|||
_apiKeyService = apiKeyService; |
|||
Logger = NullLogger<SuiteCommand>.Instance; |
|||
} |
|||
|
|||
public async Task ExecuteAsync(CommandLineArgs commandLineArgs) |
|||
{ |
|||
var operationType = NamespaceHelper.NormalizeNamespace(commandLineArgs.Target); |
|||
|
|||
switch (operationType) |
|||
{ |
|||
case "": |
|||
case null: |
|||
RunSuite(); |
|||
break; |
|||
|
|||
case "install": |
|||
Logger.LogInformation("Installing ABP Suite..."); |
|||
await InstallSuiteAsync(); |
|||
break; |
|||
|
|||
case "update": |
|||
Logger.LogInformation("Updating ABP Suite..."); |
|||
await UpdateSuiteAsync(); |
|||
break; |
|||
|
|||
case "remove": |
|||
Logger.LogInformation("Removing ABP Suite..."); |
|||
RemoveSuite(); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
private async Task InstallSuiteAsync() |
|||
{ |
|||
var nugetIndexUrl = await GetNuGetIndexUrlAsync(); |
|||
|
|||
if (nugetIndexUrl == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var result = CmdHelper.RunCmd("dotnet tool install " + SuitePackageName + " --add-source " + nugetIndexUrl + " -g"); |
|||
|
|||
if (result == 0) |
|||
{ |
|||
Logger.LogInformation("ABP Suite has been successfully installed."); |
|||
Logger.LogInformation("You can run it with the CLI command \"abp suite\""); |
|||
} |
|||
} |
|||
|
|||
private async Task UpdateSuiteAsync() |
|||
{ |
|||
var nugetIndexUrl = await GetNuGetIndexUrlAsync(); |
|||
|
|||
if (nugetIndexUrl == null) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
CmdHelper.RunCmd("dotnet tool update " + SuitePackageName + " --add-source " + nugetIndexUrl + " -g"); |
|||
} |
|||
|
|||
private static void RemoveSuite() |
|||
{ |
|||
CmdHelper.RunCmd("dotnet tool uninstall " + SuitePackageName + " -g"); |
|||
} |
|||
|
|||
private void RunSuite() |
|||
{ |
|||
try |
|||
{ |
|||
if (!GlobalToolHelper.IsGlobalToolInstalled("abp-suite")) |
|||
{ |
|||
Logger.LogWarning("ABP Suite is not installed! To install it you can run the command: \"abp suite install\""); |
|||
return; |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Logger.LogWarning("Couldn't check ABP Suite installed status: " + ex.Message); |
|||
} |
|||
|
|||
CmdHelper.RunCmd("abp-suite"); |
|||
} |
|||
|
|||
private async Task<string> GetNuGetIndexUrlAsync() |
|||
{ |
|||
var apiKeyResult = await _apiKeyService.GetApiKeyOrNullAsync(); |
|||
|
|||
if (apiKeyResult == null || string.IsNullOrEmpty(apiKeyResult.ApiKey)) |
|||
{ |
|||
Logger.LogError("Couldn't retrieve your NuGet API key!"); |
|||
Logger.LogWarning(File.Exists(CliPaths.AccessToken) |
|||
? "Make sure you have an active session and license on commercial.abp.io. To re-sign in you can use the CLI command \"abp login <username>\"." |
|||
: "You are not signed in to commercial.abp.io. Use the CLI command \"abp login <username>\" to sign in."); |
|||
|
|||
return null; |
|||
} |
|||
|
|||
return CliUrls.GetNuGetServiceIndexUrl(apiKeyResult.ApiKey); |
|||
} |
|||
|
|||
public string GetUsageInfo() |
|||
{ |
|||
var sb = new StringBuilder(); |
|||
|
|||
sb.AppendLine(""); |
|||
sb.AppendLine("Usage:"); |
|||
sb.AppendLine(""); |
|||
sb.AppendLine(" abp suite [options]"); |
|||
sb.AppendLine(""); |
|||
sb.AppendLine("Options:"); |
|||
sb.AppendLine(""); |
|||
sb.AppendLine("<no argument> (run ABP Suite)"); |
|||
sb.AppendLine("install (install ABP Suite as a dotnet global tool)"); |
|||
sb.AppendLine("update (update ABP Suite to the latest)"); |
|||
sb.AppendLine("remove (uninstall ABP Suite)"); |
|||
sb.AppendLine(""); |
|||
sb.AppendLine("Examples:"); |
|||
sb.AppendLine(""); |
|||
sb.AppendLine(" abp suite"); |
|||
sb.AppendLine(" abp suite install"); |
|||
sb.AppendLine(" abp suite update"); |
|||
sb.AppendLine(" abp suite remove"); |
|||
sb.AppendLine(""); |
|||
|
|||
return sb.ToString(); |
|||
} |
|||
|
|||
public string GetShortDescription() |
|||
{ |
|||
return "Install, update, remove or start ABP Suite. See https://commercial.abp.io/tools/suite."; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System; |
|||
using System.IO; |
|||
|
|||
namespace Volo.Abp.Cli.Utils |
|||
{ |
|||
public class GlobalToolHelper |
|||
{ |
|||
/// <summary>
|
|||
/// Checks whether the tool is installed or not.
|
|||
/// </summary>
|
|||
/// <param name="toolCommandName">Eg: For AbpSuite tool it's "abp-suite", for ABP CLI tool it's "abp"</param>
|
|||
public static bool IsGlobalToolInstalled(string toolCommandName) |
|||
{ |
|||
string suitePath; |
|||
|
|||
if (PlatformHelper.GetPlatform() == RuntimePlatform.LinuxOrMacOs) |
|||
{ |
|||
suitePath = Environment |
|||
.ExpandEnvironmentVariables( |
|||
Path.Combine("%HOME%", ".dotnet", "tools", toolCommandName) |
|||
); |
|||
} |
|||
else |
|||
{ |
|||
suitePath = Environment |
|||
.ExpandEnvironmentVariables( |
|||
Path.Combine(@"%USERPROFILE%", ".dotnet", "tools", toolCommandName + ".exe") |
|||
); |
|||
} |
|||
|
|||
return File.Exists(suitePath); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
namespace Volo.Abp.Cli.Utils |
|||
{ |
|||
public class PlatformHelper |
|||
{ |
|||
public static OSPlatform GetOperatingSystem() |
|||
{ |
|||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) |
|||
{ |
|||
//MAC
|
|||
return OSPlatform.OSX; |
|||
} |
|||
|
|||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) |
|||
{ |
|||
return OSPlatform.Linux; |
|||
} |
|||
|
|||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
|||
{ |
|||
return OSPlatform.Windows; |
|||
} |
|||
|
|||
throw new Exception("Cannot determine operating system!"); |
|||
} |
|||
|
|||
public static RuntimePlatform GetPlatform() |
|||
{ |
|||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || |
|||
RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) |
|||
{ |
|||
return RuntimePlatform.LinuxOrMacOs; |
|||
} |
|||
|
|||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
|||
{ |
|||
return RuntimePlatform.Windows; |
|||
} |
|||
|
|||
throw new Exception("Cannot determine runtime platform!"); |
|||
} |
|||
} |
|||
|
|||
public enum RuntimePlatform |
|||
{ |
|||
Windows = 1, |
|||
LinuxOrMacOs = 2 |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"profiles": { |
|||
"Volo.Abp.Cli": { |
|||
"commandName": "Project" |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +1,30 @@ |
|||
using Volo.Abp.Auditing; |
|||
using Volo.Abp.Application.Localization.Resources.AbpDdd; |
|||
using Volo.Abp.Auditing; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Volo.Abp.Application |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAuditingModule) |
|||
typeof(AbpAuditingModule), |
|||
typeof(AbpLocalizationModule) |
|||
)] |
|||
public class AbpDddApplicationContractsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpDddApplicationContractsModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<AbpDddResource>("en") |
|||
.AddVirtualJson("/Volo/Abp/Application/Localization/Resources/AbpDdd"); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.Application.Localization.Resources.AbpDdd |
|||
{ |
|||
[LocalizationResourceName("AbpDdd")] |
|||
public class AbpDddResource |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"MaxResultCountExceededExceptionMessage": "{0} can not be more than {1}! Increase {2}.{3} on the server side to allow more results." |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"MaxResultCountExceededExceptionMessage": "{0} en fazla {1} olabilir, daha büyük olamaz! Daha fazla sonuca izin vermek için {2}.{3}'ü sunucu tarafında artırın." |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"MaxResultCountExceededExceptionMessage": "{0}不能超过 {1}! 在服务器端增加{2}.{3}以获得更多结果." |
|||
} |
|||
} |
|||