Browse Source

sort project dependencies using the main changed project list

pull/5418/head
İsmail ÇAĞDAŞ 6 years ago
parent
commit
4039e78b3e
  1. 79
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultChangedProjectFinder.cs
  2. 50
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectDependencyFiller.cs
  3. 13
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectInfo.cs
  4. 62
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BuildCommand.cs

79
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DefaultChangedProjectFinder.cs

@ -116,7 +116,7 @@ namespace Volo.Abp.Cli.Build
List<DotNetProjectInfo> changedProjectList, List<DotNetProjectInfo> changedProjectList,
bool forceBuild) bool forceBuild)
{ {
if (forceBuild || repositoryBuildStatus.CommitId.IsNullOrEmpty()) if (forceBuild || repositoryBuildStatus == null || repositoryBuildStatus.CommitId.IsNullOrEmpty())
{ {
AddAllCsProjFiles(repository, changedProjectList); AddAllCsProjFiles(repository, changedProjectList);
} }
@ -143,13 +143,6 @@ namespace Volo.Abp.Cli.Build
); );
} }
} }
// Filter ignored directories
foreach (var ignoredDirectory in repository.IgnoredDirectories)
{
changedProjectList = changedProjectList.Where(e => !e.CsProjPath.StartsWith(Path.Combine(repository.RootPath, ignoredDirectory)))
.ToList();
}
} }
private void AddAllCsProjFiles(GitRepository repository, List<DotNetProjectInfo> changedFiles) private void AddAllCsProjFiles(GitRepository repository, List<DotNetProjectInfo> changedFiles)
@ -160,6 +153,14 @@ namespace Volo.Abp.Cli.Build
SearchOption.AllDirectories SearchOption.AllDirectories
).ToList(); ).ToList();
// Filter ignored directories
foreach (var ignoredDirectory in repository.IgnoredDirectories)
{
allCsProjFiles = allCsProjFiles.Where(e =>
!e.StartsWith(Path.Combine(repository.RootPath, ignoredDirectory)))
.ToList();
}
foreach (var file in allCsProjFiles) foreach (var file in allCsProjFiles)
{ {
changedFiles.Add( changedFiles.Add(
@ -187,14 +188,25 @@ namespace Volo.Abp.Cli.Build
.Select(e => e) .Select(e => e)
.ToList(); .ToList();
foreach (var file in files) var affectedCsProjFiles = FindAffectedCsProjFiles(repository.RootPath, files);
foreach (var file in affectedCsProjFiles)
{ {
var csProjPath = Path.Combine(repository.RootPath, file.Path); var csProjPath = Path.Combine(repository.RootPath, file);
if (status.SucceedProjects.Any(p => p.CsProjPath == csProjPath && p.CommitId == "1")) if (status.SucceedProjects.Any(p => p.CsProjPath == csProjPath && p.CommitId == "1"))
{ {
continue; continue;
} }
// Filter ignored directories
foreach (var ignoredDirectory in repository.IgnoredDirectories)
{
if (csProjPath.StartsWith(Path.Combine(repository.RootPath, ignoredDirectory)))
{
continue;
}
}
changedFiles.Add( changedFiles.Add(
new DotNetProjectInfo(repository.Name, csProjPath) new DotNetProjectInfo(repository.Name, csProjPath)
); );
@ -217,5 +229,52 @@ namespace Volo.Abp.Cli.Build
} }
} }
} }
private List<string> FindAffectedCsProjFiles(string repositoryPath, List<PatchEntryChanges> files)
{
var affectedProjectFiles = new List<string>();
foreach (var file in files)
{
var filePath = Path.Combine(repositoryPath, file.Path);
if (filePath.EndsWith(".csproj"))
{
affectedProjectFiles.Add(filePath);
}
if (!filePath.EndsWith(".cs"))
{
continue;
}
var classFile = new FileInfo(filePath);
var csProjPath = FindBelongingProjectPathOfClass(classFile.Directory?.FullName);
if (csProjPath.IsNullOrEmpty() || affectedProjectFiles.Contains(csProjPath))
{
continue;
}
affectedProjectFiles.Add(csProjPath);
}
return affectedProjectFiles;
}
private string FindBelongingProjectPathOfClass(string directoryPath)
{
var files = Directory.GetFiles(directoryPath, "*.csproj", SearchOption.TopDirectoryOnly);
if (files.Length == 1)
{
return files.First();
}
var directoryInfo = new DirectoryInfo(directoryPath);
if (directoryInfo.Parent == null)
{
return null;
}
return FindBelongingProjectPathOfClass(directoryInfo.Parent.FullName);
}
} }
} }

50
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectDependencyFiller.cs

@ -36,58 +36,8 @@ namespace Volo.Abp.Cli.Build
var referenceProjectInfo = new FileInfo(Path.Combine(file.Directory.FullName, relativePath)); var referenceProjectInfo = new FileInfo(Path.Combine(file.Directory.FullName, relativePath));
var referenceProject = new DotNetProjectInfo(project.RepositoryName, referenceProjectInfo.FullName); var referenceProject = new DotNetProjectInfo(project.RepositoryName, referenceProjectInfo.FullName);
project.Dependencies.Add(referenceProject); project.Dependencies.Add(referenceProject);
} }
} }
private void GetProjectsOfRepository(GitRepository repository, List<string> projectPaths)
{
Logger.LogInformation("repo name:" + repository.Name);
Logger.LogInformation("directoryPath:" + repository.RootPath);
GetProjectsOfADirectory(repository.RootPath, projectPaths, new List<string>());
if (!repository.DependingRepositories.Any())
{
return;
}
foreach (var dependantRepository in repository.DependingRepositories)
{
GetProjectsOfRepository(dependantRepository, projectPaths);
}
}
private void GetProjectsOfADirectory(
string directoryPath,
List<string> projectPaths,
List<string> ignoredDirectories)
{
Logger.LogInformation("directoryPath:" + directoryPath);
var files = Directory.GetFiles(directoryPath, "*.csproj", SearchOption.AllDirectories)
.Select(f => f)
.ToList();
// foreach (var ignoredDirectory in ignoredDirectories)
// {
// files = files.Where(e => !e.StartsWith(Path.Combine(directoryPath, ignoredDirectory)))
// .ToList();
// }
projectPaths.AddRange(files);
// foreach (var projectFile in files)
// {
// var projectNode = XElement.Load(projectFile);
// if (projectNode.Attribute("Sdk") == null)
// {
// continue;
// }
//
// projectPaths.Add(projectFile);
// }
}
} }
} }

13
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/DotNetProjectInfo.cs

@ -19,4 +19,17 @@ namespace Volo.Abp.Cli.Build
Dependencies = new List<DotNetProjectInfo>(); Dependencies = new List<DotNetProjectInfo>();
} }
} }
public class DotNetProjectInfoEqualityComparer : EqualityComparer<DotNetProjectInfo>
{
public override bool Equals(DotNetProjectInfo x, DotNetProjectInfo y)
{
return (x == null && y == null) || (x != null && y != null && x.CsProjPath == y.CsProjPath);
}
public override int GetHashCode(DotNetProjectInfo obj)
{
return obj == null ? 0 : obj.CsProjPath.GetHashCode();
}
}
} }

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

@ -2,6 +2,7 @@
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 Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -51,7 +52,7 @@ namespace Volo.Abp.Cli.Commands
Options.BuildName.Short, Options.BuildName.Short,
Options.BuildName.Long Options.BuildName.Long
); );
var forceBuild = commandLineArgs.Options.ContainsKey(Options.ForceBuild.Long); var forceBuild = commandLineArgs.Options.ContainsKey(Options.ForceBuild.Long);
var buildConfig = DotNetProjectBuildConfigReader.Read(workingDirectory ?? Directory.GetCurrentDirectory()); var buildConfig = DotNetProjectBuildConfigReader.Read(workingDirectory ?? Directory.GetCurrentDirectory());
@ -62,7 +63,10 @@ namespace Volo.Abp.Cli.Commands
DotNetProjectDependencyFiller.Fill(changedProjectFiles); DotNetProjectDependencyFiller.Fill(changedProjectFiles);
var sortedProjects = changedProjectFiles.SortByDependencies(p => p.Dependencies); var sortedProjects = SortByDependencies(
changedProjectFiles,
new DotNetProjectInfoEqualityComparer()
);
var buildSucceededProjects = DotNetProjectBuilder.Build( var buildSucceededProjects = DotNetProjectBuilder.Build(
sortedProjects, sortedProjects,
@ -84,6 +88,60 @@ namespace Volo.Abp.Cli.Commands
return Task.CompletedTask; return Task.CompletedTask;
} }
private List<DotNetProjectInfo> SortByDependencies(
List<DotNetProjectInfo> source,
IEqualityComparer<DotNetProjectInfo> comparer = null)
{
/* See: http://www.codeproject.com/Articles/869059/Topological-sorting-in-Csharp
* http://en.wikipedia.org/wiki/Topological_sorting
*/
var sorted = new List<DotNetProjectInfo>();
var visited = new Dictionary<DotNetProjectInfo, bool>(comparer);
foreach (var item in source)
{
SortByDependenciesVisit(source, item, sorted, visited);
}
return sorted;
}
private void SortByDependenciesVisit(
List<DotNetProjectInfo> source,
DotNetProjectInfo item,
List<DotNetProjectInfo> sorted,
Dictionary<DotNetProjectInfo, bool> visited)
{
bool inProcess;
var alreadyVisited = visited.TryGetValue(item, out inProcess);
if (alreadyVisited)
{
if (inProcess)
{
throw new ArgumentException("Cyclic dependency found! Item: " + item);
}
}
else
{
visited[item] = true;
var dependencies = item.Dependencies;
if (dependencies != null)
{
foreach (var dependency in dependencies)
{
var dependencyItem = source.FirstOrDefault(e => e.CsProjPath == dependency.CsProjPath);
SortByDependenciesVisit(source, dependencyItem, sorted, visited);
}
}
visited[item] = false;
sorted.Add(item);
}
}
public string GetUsageInfo() public string GetUsageInfo()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();

Loading…
Cancel
Save