Browse Source

implemented build status generator

pull/5418/head
İsmail ÇAĞDAŞ 6 years ago
parent
commit
29b9dac0a2
  1. 84
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultBuildStatusGenerator.cs
  2. 50
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultChangedProjectFinder.cs
  3. 15
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultDotNetProjectBuilder.cs
  4. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectBuildConfig.cs
  5. 51
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemRepositoryBuildStatusStore.cs
  6. 13
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IBuildStatusGenerator.cs
  7. 51
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IRepositoryBuildStatusStore.cs
  8. 90
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BuildCommand.cs

84
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<DotNetProjectInfo> changedProjects,
List<string> 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<DotNetProjectInfo> changedProjects,
List<string> 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);
}
}
}
}

50
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); return FindBySlnFile(buildConfig.GitRepository, buildConfig.SlFilePath);
} }
private List<DotNetProjectInfo> FindByRepository(DotNetProjectBuildConfig buildConfig) private List<DotNetProjectInfo> FindByRepository(DotNetProjectBuildConfig buildConfig)
{ {
var changedProjectList = new List<DotNetProjectInfo>(); var changedProjectList = new List<DotNetProjectInfo>();
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; return changedProjectList;
} }
@ -72,7 +80,8 @@ namespace Volo.Abp.Cli.Build
AddProjectDependencies(gitRepository, project, changedProjectList); AddProjectDependencies(gitRepository, project, changedProjectList);
} }
private void AddProjectDependencies(GitRepository gitRepository, DotNetProjectInfo project, List<DotNetProjectInfo> changedProjectList) private void AddProjectDependencies(GitRepository gitRepository, DotNetProjectInfo project,
List<DotNetProjectInfo> changedProjectList)
{ {
var projectNode = XElement.Load(project.CsProjPath); var projectNode = XElement.Load(project.CsProjPath);
var referenceNodes = projectNode.Descendants("ItemGroup").Descendants("ProjectReference"); var referenceNodes = projectNode.Descendants("ItemGroup").Descendants("ProjectReference");
@ -92,7 +101,7 @@ namespace Volo.Abp.Cli.Build
{ {
continue; continue;
} }
var repositoryName = gitRepository.FindRepositoryOf(referenceProjectInfo.FullName); var repositoryName = gitRepository.FindRepositoryOf(referenceProjectInfo.FullName);
var referenceProject = new DotNetProjectInfo(repositoryName, referenceProjectInfo.FullName); var referenceProject = new DotNetProjectInfo(repositoryName, referenceProjectInfo.FullName);
changedProjectList.Add(referenceProject); changedProjectList.Add(referenceProject);
@ -104,23 +113,34 @@ namespace Volo.Abp.Cli.Build
private void FindChangedFiles( private void FindChangedFiles(
GitRepository repository, GitRepository repository,
GitRepositoryBuildStatus repositoryBuildStatus, GitRepositoryBuildStatus repositoryBuildStatus,
List<DotNetProjectInfo> changedProjectList) List<DotNetProjectInfo> changedProjectList,
bool forceBuild)
{ {
if (repositoryBuildStatus.CommitId.IsNullOrEmpty()) if (forceBuild || repositoryBuildStatus.CommitId.IsNullOrEmpty())
{ {
AddAllCsProjFiles(repository, changedProjectList); AddAllCsProjFiles(repository, changedProjectList);
} }
else else
{ {
AddChangedCsProjFiles(repository, changedProjectList, repositoryBuildStatus); AddChangedCsProjFiles(
repository,
changedProjectList,
repositoryBuildStatus,
false
);
} }
if (repository.DependingRepositories.Any()) if (repository.DependingRepositories.Any())
{ {
foreach (var dependingRepository in repository.DependingRepositories) foreach (var dependingRepository in repository.DependingRepositories)
{ {
var dependingRepositoryBuildStatus = repositoryBuildStatus.GetChild(dependingRepository.Name); var dependingRepositoryBuildStatus = repositoryBuildStatus?.GetChild(dependingRepository.Name);
FindChangedFiles(dependingRepository, dependingRepositoryBuildStatus, changedProjectList); FindChangedFiles(
dependingRepository,
dependingRepositoryBuildStatus,
changedProjectList,
forceBuild
);
} }
} }
} }
@ -144,7 +164,8 @@ namespace Volo.Abp.Cli.Build
private void AddChangedCsProjFiles( private void AddChangedCsProjFiles(
GitRepository repository, GitRepository repository,
List<DotNetProjectInfo> changedFiles, List<DotNetProjectInfo> changedFiles,
GitRepositoryBuildStatus status) GitRepositoryBuildStatus status,
bool forceBuild)
{ {
using (var repo = new Repository(string.Concat(repository.RootPath, @"\.git"))) 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) foreach (var subRepository in repository.DependingRepositories)
{ {
var subRepositoryBuildStatus = status.GetChild(subRepository.Name); var subRepositoryBuildStatus = status.GetChild(subRepository.Name);
FindChangedFiles(subRepository, subRepositoryBuildStatus, changedFiles); FindChangedFiles(
subRepository,
subRepositoryBuildStatus,
changedFiles,
forceBuild
);
} }
} }
} }

15
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultDotNetProjectBuilder.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing;
using System.Linq; using System.Linq;
using Volo.Abp.Cli.Utils; using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -53,7 +54,7 @@ namespace Volo.Abp.Cli.Build
{ {
Console.WriteLine("Building...: dotnet build " + project.CsProjPath + " " + arguments); Console.WriteLine("Building...: dotnet build " + project.CsProjPath + " " + arguments);
CmdHelper.RunCmdAndGetOutput( var output = CmdHelper.RunCmdAndGetOutput(
"dotnet build " + project.CsProjPath + " " + arguments, "dotnet build " + project.CsProjPath + " " + arguments,
out int buildStatus out int buildStatus
); );
@ -61,12 +62,22 @@ namespace Volo.Abp.Cli.Build
if (buildStatus == 0) if (buildStatus == 0)
{ {
builtProjects.Add(project.CsProjPath); builtProjects.Add(project.CsProjPath);
WriteOutput(output, ConsoleColor.Green);
} }
else else
{ {
// TODO: throw exception and stop build process. WriteOutput(output, ConsoleColor.Red);
Console.WriteLine("Build failed for :" + project.CsProjPath); 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;
}
} }
} }

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectBuildConfig.cs

@ -7,5 +7,7 @@
public string SlFilePath { get; set; } public string SlFilePath { get; set; }
public GitRepository GitRepository { get; set; } public GitRepository GitRepository { get; set; }
public bool ForceBuild { get; set; }
} }
} }

51
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<GitRepositoryBuildStatus>(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);
}
}
}
}

13
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<DotNetProjectInfo> changedProjects,
List<string> buildSucceededProjects
);
}
}

51
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/IRepositoryBuildStatusStore.cs

@ -1,9 +1,4 @@
using System.IO; namespace Volo.Abp.Cli.Build
using Newtonsoft.Json;
using Volo.Abp.DependencyInjection;
using Volo.Abp.IO;
namespace Volo.Abp.Cli.Build
{ {
public interface IRepositoryBuildStatusStore public interface IRepositoryBuildStatusStore
{ {
@ -11,48 +6,4 @@ namespace Volo.Abp.Cli.Build
void Set(string buildNamePrefix, GitRepositoryBuildStatus status); 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<GitRepositoryBuildStatus>(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);
}
}
}
} }

90
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BuildCommand.cs

@ -2,10 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using LibGit2Sharp;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Volo.Abp.Cli.Args; using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Build; using Volo.Abp.Cli.Build;
@ -27,6 +25,8 @@ namespace Volo.Abp.Cli.Commands
public IDotNetProjectBuildConfigReader DotNetProjectBuildConfigReader { get; set; } public IDotNetProjectBuildConfigReader DotNetProjectBuildConfigReader { get; set; }
public IBuildStatusGenerator BuildStatusGenerator { get; set; }
public Task ExecuteAsync(CommandLineArgs commandLineArgs) public Task ExecuteAsync(CommandLineArgs commandLineArgs)
{ {
var sw = new Stopwatch(); var sw = new Stopwatch();
@ -52,8 +52,11 @@ namespace Volo.Abp.Cli.Commands
Options.BuildName.Long Options.BuildName.Long
); );
var forceBuild = commandLineArgs.Options.ContainsKey(Options.ForceBuild.Long);
var buildConfig = DotNetProjectBuildConfigReader.Read(workingDirectory ?? Directory.GetCurrentDirectory()); var buildConfig = DotNetProjectBuildConfigReader.Read(workingDirectory ?? Directory.GetCurrentDirectory());
buildConfig.BuildName = buildName; buildConfig.BuildName = buildName;
buildConfig.ForceBuild = forceBuild;
var changedProjectFiles = ChangedProjectFinder.Find(buildConfig); var changedProjectFiles = ChangedProjectFinder.Find(buildConfig);
@ -67,7 +70,7 @@ namespace Volo.Abp.Cli.Commands
dotnetBuildArguments ?? "" dotnetBuildArguments ?? ""
); );
var buildStatus = GenerateBuildStatus( var buildStatus = BuildStatusGenerator.Generate(
buildConfig.GitRepository, buildConfig.GitRepository,
changedProjectFiles, changedProjectFiles,
buildSucceededProjects buildSucceededProjects
@ -81,82 +84,6 @@ namespace Volo.Abp.Cli.Commands
return Task.CompletedTask; return Task.CompletedTask;
} }
private GitRepositoryBuildStatus GenerateBuildStatus(
GitRepository gitRepository,
List<DotNetProjectInfo> changedProjects,
List<string> 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<DotNetProjectInfo> changedProjects,
List<string> 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() public string GetUsageInfo()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -205,6 +132,11 @@ namespace Volo.Abp.Cli.Commands
public const string Short = "n"; public const string Short = "n";
public const string Long = "build-name"; public const string Long = "build-name";
} }
public static class ForceBuild
{
public const string Long = "force";
}
} }
} }
} }

Loading…
Cancel
Save