diff --git a/build/version.props b/build/version.props index 8e0c968..8013612 100644 --- a/build/version.props +++ b/build/version.props @@ -1,8 +1,8 @@ 2 - 3 - 6 + 4 + 0-preview.1 $(VersionMajor).$(VersionMinor).$(VersionPatch) diff --git a/src/SmartCode.App/BuildTasks/ProcessBuildTask.cs b/src/SmartCode.App/BuildTasks/ProcessBuildTask.cs index 8929ab0..1544dcf 100644 --- a/src/SmartCode.App/BuildTasks/ProcessBuildTask.cs +++ b/src/SmartCode.App/BuildTasks/ProcessBuildTask.cs @@ -37,7 +37,7 @@ public Task Build(BuildContext context) var startInfo = new ProcessStartInfo(fileName) { UseShellExecute = false, - RedirectStandardInput = true, + RedirectStandardInput = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = DEFAULT_CREATE_NO_WINDOW @@ -103,7 +103,7 @@ public Task Build(BuildContext context) } _logger.LogDebug($"--------Process.FileName:{startInfo.FileName},Args:{startInfo.Arguments},Taken:{process.TotalProcessorTime.TotalMilliseconds} End--------"); } - return Task.CompletedTask; + return Task.CompletedTask; } private void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e) diff --git a/src/SmartCode.App/Outputs/FileOutput.cs b/src/SmartCode.App/Outputs/FileOutput.cs index 1efd8a3..602a4f0 100644 --- a/src/SmartCode.App/Outputs/FileOutput.cs +++ b/src/SmartCode.App/Outputs/FileOutput.cs @@ -7,6 +7,7 @@ using HandlebarsDotNet; using SmartCode.Configuration; using SmartCode.Utilities; +using System.Text.RegularExpressions; namespace SmartCode.App.Outputs { @@ -69,23 +70,26 @@ public async Task Output(BuildContext context, Output output = null) { case Configuration.CreateMode.None: case Configuration.CreateMode.Incre: - { - _logger.LogWarning( - $"------ Mode:{output.Mode},Build:{context.BuildKey},FilePath:{filePath} Exists ignore output End! ------"); - return; - } + { + _logger.LogWarning( + $"------ Mode:{output.Mode},Build:{context.BuildKey},FilePath:{filePath} Exists ignore output End! ------"); + return; + } case Configuration.CreateMode.Full: - { - File.Delete(filePath); - _logger.LogWarning($"------ Mode:{output.Mode},FilePath:{filePath} Exists Deleted ! ------"); - break; - } + { + File.Delete(filePath); + _logger.LogWarning($"------ Mode:{output.Mode},FilePath:{filePath} Exists Deleted ! ------"); + break; + } } } - using (StreamWriter streamWriter = new StreamWriter(filePath)) + //采购VS默认的UTF-8 WITH BOM 编码 + using (StreamWriter streamWriter = new StreamWriter(filePath, false, new UTF8Encoding(true))) { - await streamWriter.WriteAsync(context.Result.Trim()); + //强制行尾为 \r\n + var result = Regex.Replace(context.Result.Trim(), @"[\r\n]+", "\r\n", RegexOptions.Multiline); + await streamWriter.WriteAsync(result); } _logger.LogInformation($"------ Mode:{output.Mode},Build:{context.BuildKey} -> {filePath} End! ------"); diff --git a/src/SmartCode.App/PluginManager.cs b/src/SmartCode.App/PluginManager.cs index c0128a6..498911f 100644 --- a/src/SmartCode.App/PluginManager.cs +++ b/src/SmartCode.App/PluginManager.cs @@ -56,19 +56,23 @@ private IEnumerable ResolvePlugins() where TPlugin : IPlugin var plugins = _serviceProvider.GetServices(); foreach (var plugin in plugins) { - if (!plugin.Initialized) + lock (this) { - var pluginType = plugin.GetType(); - var names = pluginType.AssemblyQualifiedName.Split(','); - var typeName = names[0].Trim(); - var assName = names[1].Trim(); - var pluginConfig = _smartCodeOptions - .Plugins - .FirstOrDefault(m => m.ImplAssemblyName == assName && m.ImplTypeName == typeName); - plugin.Initialize(pluginConfig.Parameters); + if (!plugin.Initialized) + { + var pluginType = plugin.GetType(); + var names = pluginType.AssemblyQualifiedName.Split(','); + var typeName = names[0].Trim(); + var assName = names[1].Trim(); + var pluginConfig = _smartCodeOptions + .Plugins + .FirstOrDefault(m => m.ImplAssemblyName == assName && m.ImplTypeName == typeName); + plugin.Initialize(pluginConfig.Parameters); + } } } return plugins; + } } } diff --git a/src/SmartCode.CLI/Program.cs b/src/SmartCode.CLI/Program.cs index fa00641..e54f256 100644 --- a/src/SmartCode.CLI/Program.cs +++ b/src/SmartCode.CLI/Program.cs @@ -12,9 +12,11 @@ namespace SmartCode.CLI { class Program { - static async Task Main(string[] args) + static async Task Main(string[] args) { - await CommandLineApplication.ExecuteAsync(args); + ThreadPool.SetMinThreads(1000, 1000); + ThreadPool.SetMaxThreads(1000, 1000); + await CommandLineApplication.ExecuteAsync(args); } } } diff --git a/src/SmartCode.Db/SmartCode.Db.csproj b/src/SmartCode.Db/SmartCode.Db.csproj index 6c40434..22f33f7 100644 --- a/src/SmartCode.Db/SmartCode.Db.csproj +++ b/src/SmartCode.Db/SmartCode.Db.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/SmartCode.Generator/BuildTasks/TableBuildTask.cs b/src/SmartCode.Generator/BuildTasks/TableBuildTask.cs index 92ff6ed..42dc537 100644 --- a/src/SmartCode.Generator/BuildTasks/TableBuildTask.cs +++ b/src/SmartCode.Generator/BuildTasks/TableBuildTask.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace SmartCode.Generator.BuildTasks diff --git a/src/SmartCode.Generator/GeneratorProjectBuilder.cs b/src/SmartCode.Generator/GeneratorProjectBuilder.cs index 7944eb3..d43ac21 100644 --- a/src/SmartCode.Generator/GeneratorProjectBuilder.cs +++ b/src/SmartCode.Generator/GeneratorProjectBuilder.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using SmartCode.Configuration; @@ -20,28 +24,118 @@ Project project _logger = logger; } + CountdownEvent countdown = new CountdownEvent(1); + public async Task Build() { - BuildContext buildContext = null; var dataSource = _pluginManager.Resolve(_project.DataSource.Name); await dataSource.InitData(); + + if (_project.AllowParallel) + { + await this.ParallelBuild(dataSource); + } + else + { + await this.SerialBuild(dataSource); + } + } + + public async Task SerialBuild(IDataSource dataSource) + { foreach (var buildKV in _project.BuildTasks) { _logger.LogInformation($"-------- BuildTask:{buildKV.Key} Start! ---------"); - var output = buildKV.Value.Output; - buildContext = new BuildContext + var context = new BuildContext { PluginManager = _pluginManager, Project = _project, DataSource = dataSource, BuildKey = buildKV.Key, Build = buildKV.Value, - Output = output?.Copy() + Output = buildKV.Value.Output?.Copy(), }; - await _pluginManager.Resolve(buildKV.Value.Type).Build(buildContext); + + //ִ���������� + await _pluginManager.Resolve(context.Build.Type).Build(context); + _logger.LogInformation($"-------- BuildTask:{buildKV.Key} End! ---------"); } } + + private Task ParallelBuild(IDataSource dataSource) + { + + IList allContexts = _project.BuildTasks.Select(d => new BuildContext + { + PluginManager = _pluginManager, + Project = _project, + DataSource = dataSource, + BuildKey = d.Key, + Build = d.Value, + Output = d.Value.Output?.Copy(), + }).ToArray(); + foreach (var context in allContexts) + { + if (context.Build.DependOn != null && context.Build.DependOn.Count() > 0) + { + context.DependOn = allContexts.Where(d => context.Build.DependOn.Contains(d.BuildKey)).ToArray(); + } + } + countdown.Reset(); + countdown.AddCount(allContexts.Count); + foreach (var context in allContexts) + { + context.CountDown.Reset(); + if (context.DependOn != null && context.DependOn.Count > 0) + { + context.CountDown.AddCount(context.DependOn.Count); + } + + ThreadPool.QueueUserWorkItem((obj) => _ = this.BuildTask(obj), (context, allContexts)); + } + + foreach (var context in allContexts) + { + context.CountDown.Signal(); + } + + countdown.Signal(); + countdown.Wait(); + + return Task.CompletedTask; + } + + private async Task BuildTask(object obj) + { + var p = ((BuildContext context, IList allContexts))obj; + + if (p.context.DependOn != null && p.context.DependOn.Count > 0) + { + _logger.LogInformation($"-------- BuildTask:{p.context.BuildKey} Wait [{string.Join(",", p.context.DependOn?.Select(d => d.BuildKey)?.ToArray())}]---------"); + } + //�ȴ��������� + p.context.CountDown.Wait(); + + _logger.LogInformation($"-------- BuildTask:{p.context.BuildKey} Start! ---------"); + //ִ���������� + await _pluginManager.Resolve(p.context.Build.Type).Build(p.context); + + foreach (var c in p.allContexts) + { + if (c.DependOn == null || c.DependOn.Count == 0) + { + continue; + } + if (c.DependOn.Contains(p.context)) + { + c.CountDown.Signal(); + } + } + + countdown.Signal(); + _logger.LogInformation($"-------- BuildTask:{p.context.BuildKey} End! ---------"); + } } } \ No newline at end of file diff --git a/src/SmartCode/BuildContext.cs b/src/SmartCode/BuildContext.cs index 3abddaa..9746c0d 100644 --- a/src/SmartCode/BuildContext.cs +++ b/src/SmartCode/BuildContext.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; using System.Text; +using System.Threading; +using System.Threading.Tasks; using SmartCode.Configuration; namespace SmartCode { public class BuildContext { + public Project Project { get; set; } public IDataSource DataSource { get; set; } public IPluginManager PluginManager { get; set; } @@ -26,5 +29,9 @@ public void SetItem(string key, object item) { Items[key] = item; } + + public IList DependOn { get; set; } + //public Task BuildTask { get; set; } + public CountdownEvent CountDown { get; } = new CountdownEvent(1); } } diff --git a/src/SmartCode/Configuration/Build.cs b/src/SmartCode/Configuration/Build.cs index 72a75aa..f00f859 100644 --- a/src/SmartCode/Configuration/Build.cs +++ b/src/SmartCode/Configuration/Build.cs @@ -13,7 +13,7 @@ public class Build /// public String Type { get; set; } public String Module { get; set; } - public TemplateEngine TemplateEngine { get; set; } + public TemplateEngine TemplateEngine { get; set; } public Output Output { get; set; } public IEnumerable IncludeTables { get; set; } public IEnumerable IgnoreTables { get; set; } @@ -21,6 +21,10 @@ public class Build public bool? IgnoreView { get; set; } public NamingConverter NamingConverter { get; set; } /// + /// 依赖于 + /// + public IEnumerable DependOn { get; set; } + /// /// 自定义构建参数 /// public IDictionary Parameters { get; set; } diff --git a/src/SmartCode/Configuration/Project.cs b/src/SmartCode/Configuration/Project.cs index ed9d7d2..92deb0b 100644 --- a/src/SmartCode/Configuration/Project.cs +++ b/src/SmartCode/Configuration/Project.cs @@ -11,6 +11,7 @@ public class Project public String ConfigPath { get; set; } public String Module { get; set; } public String Author { get; set; } + public bool AllowParallel { get; set; } = false; public ProjectMode? Mode { get; set; } public DataSource DataSource { get; set; } public TemplateEngine TemplateEngine { get; set; } = TemplateEngine.Default;