From 29b9dac0a251ba6efade09cb9ad8fca3b912312f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20=C3=87A=C4=9EDA=C5=9E?= Date: Tue, 1 Sep 2020 15:29:06 +0300 Subject: [PATCH] implemented build status generator --- .../Cli/Build/DefaultBuildStatusGenerator.cs | 84 +++++++++++++++++ .../Cli/Build/DefaultChangedProjectFinder.cs | 50 ++++++++--- .../Cli/Build/DefaultDotNetProjectBuilder.cs | 15 +++- .../Abp/Cli/Build/DotNetProjectBuildConfig.cs | 2 + .../FileSystemRepositoryBuildStatusStore.cs | 51 +++++++++++ .../Abp/Cli/Build/IBuildStatusGenerator.cs | 13 +++ .../Cli/Build/IRepositoryBuildStatusStore.cs | 51 +---------- .../Volo/Abp/Cli/Commands/BuildCommand.cs | 90 +++---------------- 8 files changed, 213 insertions(+), 143 deletions(-) create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultBuildStatusGenerator.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemRepositoryBuildStatusStore.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IBuildStatusGenerator.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultBuildStatusGenerator.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultBuildStatusGenerator.cs new file mode 100644 index 0000000000..a1b90ff47e --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultBuildStatusGenerator.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using System.Linq; +using LibGit2Sharp; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Cli.Build +{ + public class DefaultBuildStatusGenerator : IBuildStatusGenerator, ITransientDependency + { + public GitRepositoryBuildStatus Generate(GitRepository gitRepository, List changedProjects, + List buildSucceededProjects) + { + using (var repo = new Repository(string.Concat(gitRepository.RootPath, @"\.git"))) + { + var lastCommitId = repo.Head.Tip.Id.ToString(); + var status = new GitRepositoryBuildStatus( + gitRepository.Name, + repo.Head.FriendlyName + ) + { + CommitId = lastCommitId + }; + + status.SucceedProjects = changedProjects.Where(p => + p.RepositoryName == gitRepository.Name && + buildSucceededProjects.Contains(p.CsProjPath) + ) + .Select(e => new DotNetProjectBuildStatus() + { + CsProjPath = e.CsProjPath, + CommitId = lastCommitId + }).ToList(); + + foreach (var dependingRepository in gitRepository.DependingRepositories) + { + GenerateBuildStatusInternal(dependingRepository, changedProjects, buildSucceededProjects, status); + } + + return status; + } + } + + private void GenerateBuildStatusInternal( + GitRepository gitRepository, + List changedProjects, + List buildSucceededProjects, + GitRepositoryBuildStatus status) + { + using (var repo = new Repository(string.Concat(gitRepository.RootPath, @"\.git"))) + { + var lastCommitId = repo.Head.Tip.Id.ToString(); + var dependingRepositoryStatus = new GitRepositoryBuildStatus( + gitRepository.Name, + repo.Head.FriendlyName + ) + { + CommitId = lastCommitId + }; + + dependingRepositoryStatus.SucceedProjects = changedProjects.Where(p => + p.RepositoryName == gitRepository.Name && + buildSucceededProjects.Contains(p.CsProjPath) + ) + .Select(e => new DotNetProjectBuildStatus() + { + CsProjPath = e.CsProjPath, + CommitId = lastCommitId + }).ToList(); + + foreach (var dependingRepository in gitRepository.DependingRepositories) + { + GenerateBuildStatusInternal( + dependingRepository, + changedProjects, + buildSucceededProjects, + dependingRepositoryStatus + ); + } + + status.DependingRepositories.Add(dependingRepositoryStatus); + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultChangedProjectFinder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultChangedProjectFinder.cs index 7eaec1f8f3..cf1dbeeb32 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultChangedProjectFinder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultChangedProjectFinder.cs @@ -26,13 +26,21 @@ namespace Volo.Abp.Cli.Build return FindBySlnFile(buildConfig.GitRepository, buildConfig.SlFilePath); } - + private List FindByRepository(DotNetProjectBuildConfig buildConfig) { var changedProjectList = new List(); - var gitRepositoryBuildStatus = _repositoryBuildStatusStore.Get(buildConfig.BuildName, buildConfig.GitRepository); + var gitRepositoryBuildStatus = _repositoryBuildStatusStore.Get( + buildConfig.BuildName, + buildConfig.GitRepository + ); - FindChangedFiles(buildConfig.GitRepository, gitRepositoryBuildStatus, changedProjectList); + FindChangedFiles( + buildConfig.GitRepository, + gitRepositoryBuildStatus, + changedProjectList, + buildConfig.ForceBuild + ); return changedProjectList; } @@ -72,7 +80,8 @@ namespace Volo.Abp.Cli.Build AddProjectDependencies(gitRepository, project, changedProjectList); } - private void AddProjectDependencies(GitRepository gitRepository, DotNetProjectInfo project, List changedProjectList) + private void AddProjectDependencies(GitRepository gitRepository, DotNetProjectInfo project, + List changedProjectList) { var projectNode = XElement.Load(project.CsProjPath); var referenceNodes = projectNode.Descendants("ItemGroup").Descendants("ProjectReference"); @@ -92,7 +101,7 @@ namespace Volo.Abp.Cli.Build { continue; } - + var repositoryName = gitRepository.FindRepositoryOf(referenceProjectInfo.FullName); var referenceProject = new DotNetProjectInfo(repositoryName, referenceProjectInfo.FullName); changedProjectList.Add(referenceProject); @@ -104,23 +113,34 @@ namespace Volo.Abp.Cli.Build private void FindChangedFiles( GitRepository repository, GitRepositoryBuildStatus repositoryBuildStatus, - List changedProjectList) + List changedProjectList, + bool forceBuild) { - if (repositoryBuildStatus.CommitId.IsNullOrEmpty()) + if (forceBuild || repositoryBuildStatus.CommitId.IsNullOrEmpty()) { AddAllCsProjFiles(repository, changedProjectList); } else { - AddChangedCsProjFiles(repository, changedProjectList, repositoryBuildStatus); + AddChangedCsProjFiles( + repository, + changedProjectList, + repositoryBuildStatus, + false + ); } if (repository.DependingRepositories.Any()) { foreach (var dependingRepository in repository.DependingRepositories) { - var dependingRepositoryBuildStatus = repositoryBuildStatus.GetChild(dependingRepository.Name); - FindChangedFiles(dependingRepository, dependingRepositoryBuildStatus, changedProjectList); + var dependingRepositoryBuildStatus = repositoryBuildStatus?.GetChild(dependingRepository.Name); + FindChangedFiles( + dependingRepository, + dependingRepositoryBuildStatus, + changedProjectList, + forceBuild + ); } } } @@ -144,7 +164,8 @@ namespace Volo.Abp.Cli.Build private void AddChangedCsProjFiles( GitRepository repository, List changedFiles, - GitRepositoryBuildStatus status) + GitRepositoryBuildStatus status, + bool forceBuild) { using (var repo = new Repository(string.Concat(repository.RootPath, @"\.git"))) { @@ -180,7 +201,12 @@ namespace Volo.Abp.Cli.Build foreach (var subRepository in repository.DependingRepositories) { var subRepositoryBuildStatus = status.GetChild(subRepository.Name); - FindChangedFiles(subRepository, subRepositoryBuildStatus, changedFiles); + FindChangedFiles( + subRepository, + subRepositoryBuildStatus, + changedFiles, + forceBuild + ); } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultDotNetProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultDotNetProjectBuilder.cs index eea3d85c9f..a5473d1e14 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultDotNetProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultDotNetProjectBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Drawing; using System.Linq; using Volo.Abp.Cli.Utils; using Volo.Abp.DependencyInjection; @@ -53,7 +54,7 @@ namespace Volo.Abp.Cli.Build { Console.WriteLine("Building...: dotnet build " + project.CsProjPath + " " + arguments); - CmdHelper.RunCmdAndGetOutput( + var output = CmdHelper.RunCmdAndGetOutput( "dotnet build " + project.CsProjPath + " " + arguments, out int buildStatus ); @@ -61,12 +62,22 @@ namespace Volo.Abp.Cli.Build if (buildStatus == 0) { builtProjects.Add(project.CsProjPath); + WriteOutput(output, ConsoleColor.Green); } else { - // TODO: throw exception and stop build process. + WriteOutput(output, ConsoleColor.Red); Console.WriteLine("Build failed for :" + project.CsProjPath); + throw new Exception("Build failed!"); } } + + private void WriteOutput(string text, ConsoleColor color) + { + var currentConsoleColor = Console.ForegroundColor; + Console.ForegroundColor = color; + Console.WriteLine(text); + Console.ForegroundColor = currentConsoleColor; + } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectBuildConfig.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectBuildConfig.cs index 18e23d2125..9a9da0766a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectBuildConfig.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectBuildConfig.cs @@ -7,5 +7,7 @@ public string SlFilePath { get; set; } public GitRepository GitRepository { get; set; } + + public bool ForceBuild { get; set; } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemRepositoryBuildStatusStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemRepositoryBuildStatusStore.cs new file mode 100644 index 0000000000..339ea13374 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemRepositoryBuildStatusStore.cs @@ -0,0 +1,51 @@ +using System.IO; +using Newtonsoft.Json; +using Volo.Abp.DependencyInjection; +using Volo.Abp.IO; + +namespace Volo.Abp.Cli.Build +{ + public class FileSystemRepositoryBuildStatusStore : IRepositoryBuildStatusStore, ITransientDependency + { + // TODO: change this ? + private string BaseBuildStatusStorePath = @"C:\Users\ismai\.abp\build"; + + public GitRepositoryBuildStatus Get(string buildNamePrefix, GitRepository repository) + { + if (!Directory.Exists(BaseBuildStatusStorePath)) + { + Directory.CreateDirectory(BaseBuildStatusStorePath); + } + + var buildStatusFile = Path.Combine(BaseBuildStatusStorePath, repository.GetUniqueName(buildNamePrefix)) + ".json"; + + if (!File.Exists(buildStatusFile)) + { + // TODO: this is wrong + return new GitRepositoryBuildStatus(repository.Name, repository.BranchName); + } + + var buildStatusText = File.ReadAllText(buildStatusFile); + return JsonConvert.DeserializeObject(buildStatusText); + } + + public void Set(string buildNamePrefix, GitRepositoryBuildStatus status) + { + if (!Directory.Exists(BaseBuildStatusStorePath)) + { + Directory.CreateDirectory(BaseBuildStatusStorePath); + } + + var buildStatusFile = Path.Combine(BaseBuildStatusStorePath, status.GetUniqueName(buildNamePrefix)) + ".json"; + if (File.Exists(buildStatusFile)) + { + FileHelper.DeleteIfExists(buildStatusFile); + } + + using (var file = File.CreateText(buildStatusFile)) + { + new JsonSerializer {Formatting = Formatting.Indented}.Serialize(file, status); + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IBuildStatusGenerator.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IBuildStatusGenerator.cs new file mode 100644 index 0000000000..bfd8d0a2ee --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IBuildStatusGenerator.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Cli.Build +{ + public interface IBuildStatusGenerator + { + GitRepositoryBuildStatus Generate( + GitRepository gitRepository, + List changedProjects, + List buildSucceededProjects + ); + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IRepositoryBuildStatusStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IRepositoryBuildStatusStore.cs index 655c6ef236..c71f007f9d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IRepositoryBuildStatusStore.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IRepositoryBuildStatusStore.cs @@ -1,9 +1,4 @@ -using System.IO; -using Newtonsoft.Json; -using Volo.Abp.DependencyInjection; -using Volo.Abp.IO; - -namespace Volo.Abp.Cli.Build +namespace Volo.Abp.Cli.Build { public interface IRepositoryBuildStatusStore { @@ -11,48 +6,4 @@ namespace Volo.Abp.Cli.Build void Set(string buildNamePrefix, GitRepositoryBuildStatus status); } - - public class FileSystemRepositoryBuildStatusStore : IRepositoryBuildStatusStore, ITransientDependency - { - // TODO: change this ? - private string BaseBuildStatusStorePath = @"C:\Users\ismai\.abp\build"; - - public GitRepositoryBuildStatus Get(string buildNamePrefix, GitRepository repository) - { - if (!Directory.Exists(BaseBuildStatusStorePath)) - { - Directory.CreateDirectory(BaseBuildStatusStorePath); - } - - var buildStatusFile = Path.Combine(BaseBuildStatusStorePath, repository.GetUniqueName(buildNamePrefix)) + ".json"; - - if (!File.Exists(buildStatusFile)) - { - // TODO: this is wrong - return new GitRepositoryBuildStatus(repository.Name, repository.BranchName); - } - - var buildStatusText = File.ReadAllText(buildStatusFile); - return JsonConvert.DeserializeObject(buildStatusText); - } - - public void Set(string buildNamePrefix, GitRepositoryBuildStatus status) - { - if (!Directory.Exists(BaseBuildStatusStorePath)) - { - Directory.CreateDirectory(BaseBuildStatusStorePath); - } - - var buildStatusFile = Path.Combine(BaseBuildStatusStorePath, status.GetUniqueName(buildNamePrefix)) + ".json"; - if (File.Exists(buildStatusFile)) - { - FileHelper.DeleteIfExists(buildStatusFile); - } - - using (var file = File.CreateText(buildStatusFile)) - { - new JsonSerializer {Formatting = Formatting.Indented}.Serialize(file, status); - } - } - } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BuildCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BuildCommand.cs index fce49dcf65..b77bad8a55 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BuildCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BuildCommand.cs @@ -2,10 +2,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; -using LibGit2Sharp; using Microsoft.Extensions.Logging; using Volo.Abp.Cli.Args; using Volo.Abp.Cli.Build; @@ -27,6 +25,8 @@ namespace Volo.Abp.Cli.Commands public IDotNetProjectBuildConfigReader DotNetProjectBuildConfigReader { get; set; } + public IBuildStatusGenerator BuildStatusGenerator { get; set; } + public Task ExecuteAsync(CommandLineArgs commandLineArgs) { var sw = new Stopwatch(); @@ -52,8 +52,11 @@ namespace Volo.Abp.Cli.Commands Options.BuildName.Long ); + var forceBuild = commandLineArgs.Options.ContainsKey(Options.ForceBuild.Long); + var buildConfig = DotNetProjectBuildConfigReader.Read(workingDirectory ?? Directory.GetCurrentDirectory()); buildConfig.BuildName = buildName; + buildConfig.ForceBuild = forceBuild; var changedProjectFiles = ChangedProjectFinder.Find(buildConfig); @@ -67,7 +70,7 @@ namespace Volo.Abp.Cli.Commands dotnetBuildArguments ?? "" ); - var buildStatus = GenerateBuildStatus( + var buildStatus = BuildStatusGenerator.Generate( buildConfig.GitRepository, changedProjectFiles, buildSucceededProjects @@ -81,82 +84,6 @@ namespace Volo.Abp.Cli.Commands return Task.CompletedTask; } - private GitRepositoryBuildStatus GenerateBuildStatus( - GitRepository gitRepository, - List changedProjects, - List buildSucceededProjects) - { - using (var repo = new Repository(string.Concat(gitRepository.RootPath, @"\.git"))) - { - var lastCommitId = repo.Head.Tip.Id.ToString(); - var status = new GitRepositoryBuildStatus( - gitRepository.Name, - repo.Head.FriendlyName - ) - { - CommitId = lastCommitId - }; - - status.SucceedProjects = changedProjects.Where(p => - p.RepositoryName == gitRepository.Name && - buildSucceededProjects.Contains(p.CsProjPath) - ) - .Select(e => new DotNetProjectBuildStatus() - { - CsProjPath = e.CsProjPath, - CommitId = lastCommitId - }).ToList(); - - foreach (var dependingRepository in gitRepository.DependingRepositories) - { - GenerateBuildStatusInternal(dependingRepository, changedProjects, buildSucceededProjects, status); - } - - return status; - } - } - - private void GenerateBuildStatusInternal( - GitRepository gitRepository, - List changedProjects, - List buildSucceededProjects, - GitRepositoryBuildStatus status) - { - using (var repo = new Repository(string.Concat(gitRepository.RootPath, @"\.git"))) - { - var lastCommitId = repo.Head.Tip.Id.ToString(); - var dependingRepositoryStatus = new GitRepositoryBuildStatus( - gitRepository.Name, - repo.Head.FriendlyName - ) - { - CommitId = lastCommitId - }; - - dependingRepositoryStatus.SucceedProjects = changedProjects.Where(p => - p.RepositoryName == gitRepository.Name && - buildSucceededProjects.Contains(p.CsProjPath) - ) - .Select(e => new DotNetProjectBuildStatus() - { - CsProjPath = e.CsProjPath, - CommitId = lastCommitId - }).ToList(); - - foreach (var dependingRepository in gitRepository.DependingRepositories) - { - GenerateBuildStatusInternal( - dependingRepository, - changedProjects, - buildSucceededProjects, - dependingRepositoryStatus - ); - } - - status.DependingRepositories.Add(dependingRepositoryStatus); - } - } - public string GetUsageInfo() { var sb = new StringBuilder(); @@ -205,6 +132,11 @@ namespace Volo.Abp.Cli.Commands public const string Short = "n"; public const string Long = "build-name"; } + + public static class ForceBuild + { + public const string Long = "force"; + } } } }