提交 91e93714 编写于 作者: J Jared Parsons 提交者: GitHub

Merge pull request #14746 from jaredpar/fix-build

BuildBoss updates
{
"exclude": [
"src\\Workspaces\\CoreTest\\TestFiles",
"src\\Setup\\Templates"
"Binaries"
"targets": [
"Roslyn.sln",
"src\\Samples\\Samples.sln"
]
}
......@@ -123,7 +123,7 @@ echo Running RepoUtil
REM Verify the state of our project.jsons
echo Running BuildBoss
.\Binaries\%BuildConfiguration%\Exes\BuildBoss\BuildBoss.exe %RoslynRoot% || goto :BuildFailed
.\Binaries\%BuildConfiguration%\Exes\BuildBoss\BuildBoss.exe Roslyn.sln src\Samples\Samples.sln || goto :BuildFailed
REM Ensure caller sees successful exit.
exit /b 0
......
......@@ -28,6 +28,8 @@
<Compile Include="ProjectType.cs" />
<Compile Include="ProjectUtil.cs" />
<Compile Include="SharedUtil.cs" />
<Compile Include="ProjectData.cs" />
<Compile Include="SolutionUtil.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
......@@ -37,4 +39,4 @@
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="..\..\..\build\Targets\VSL.Imports.targets" />
</Project>
</Project>
\ No newline at end of file
......@@ -10,9 +10,9 @@ namespace BuildBoss
public sealed class BuildBossConfig
{
/// <summary>
/// The set of projects and paths to exclude.
/// The solutions targetted by this scan
/// </summary>
[JsonProperty(PropertyName = "exclude")]
public string[] Exclude { get; set; }
[JsonProperty(PropertyName = "targets")]
public string[] Targets { get; set; }
}
}
......@@ -13,52 +13,72 @@ internal static class Program
{
internal static int Main(string[] args)
{
string sourcePath;
string configPath;
if (!ParseArgs(args, out sourcePath, out configPath))
{
string configFile;
string basePath;
List<string> solutionFilePaths;
if (!ParseCommandLine(args, out configFile, out basePath, out solutionFilePaths))
{
Usage();
return 1;
}
var config = JsonConvert.DeserializeObject<BuildBossConfig>(File.ReadAllText(configPath));
if (configFile != null)
{
var config = JsonConvert.DeserializeObject<BuildBossConfig>(File.ReadAllText(configFile));
foreach (var target in config.Targets)
{
solutionFilePaths.Add(Path.IsPathRooted(target)
? target
: Path.Combine(basePath, target));
}
}
var allGood = true;
var list = new List<string>();
foreach (var solutionFilePath in solutionFilePaths)
{
allGood &= ProcessSolution(solutionFilePath);
}
foreach (var projectPath in Directory.EnumerateFiles(sourcePath, "*proj", SearchOption.AllDirectories))
return allGood ? 0 : 1;
}
private static bool ProcessSolution(string solutionFilePath)
{
var solutionPath = Path.GetDirectoryName(solutionFilePath);
var projectDataList = SolutionUtil.ParseProjects(solutionFilePath);
var allGood = true;
var count = 0;
foreach (var projectData in projectDataList)
{
var relativePath = GetRelativePath(sourcePath, projectPath);
if (Exclude(config, relativePath))
if (projectData.IsFolder)
{
continue;
}
var doc = XDocument.Load(projectPath);
var projectType = GetProjectType(projectPath);
var util = new ProjectUtil(projectType, projectPath, doc);
var textWriter = new StringWriter();
if (!util.CheckAll(textWriter))
{
Console.WriteLine($"Checking {relativePath} failed");
Console.WriteLine(textWriter.ToString());
list.Add(relativePath);
allGood = false;
}
var projectFilePath = Path.Combine(solutionPath, projectData.RelativeFilePath);
allGood &= ProcessProject(projectFilePath, projectData);
count++;
}
return allGood ? 0 : 1;
var result = allGood ? "passed" : "FAILED";
Console.WriteLine($"Processing {Path.GetFileName(solutionFilePath)} ... {result} ({count} projects processed)");
return allGood;
}
private static ProjectType GetProjectType(string path)
private static bool ProcessProject(string projectFilePath, ProjectData projectData)
{
switch (Path.GetExtension(path))
var doc = XDocument.Load(projectFilePath);
var projectType = projectData.ProjectType;
var util = new ProjectUtil(projectType, projectFilePath, doc);
var textWriter = new StringWriter();
if (!util.CheckAll(textWriter))
{
case ".csproj": return ProjectType.CSharp;
case ".vbproj": return ProjectType.Basic;
case ".shproj": return ProjectType.Shared;
default:
return ProjectType.Unknown;
Console.WriteLine($"Checking {projectData.RelativeFilePath} failed");
Console.WriteLine(textWriter.ToString());
return false;
}
return true;
}
private static string GetRelativePath(string basePath, string fullPath)
......@@ -77,58 +97,51 @@ private static string GetRelativePath(string basePath, string fullPath)
return path;
}
private static bool Exclude(BuildBossConfig config, string projectRelativePath)
{
foreach (var exclude in config.Exclude)
{
if (projectRelativePath.StartsWith(exclude, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private static bool ParseArgs(string[] args, out string sourcePath, out string configPath)
private static bool ParseCommandLine(string[] args, out string configFile, out string basePath, out List<string> solutionFilePaths)
{
configPath = null;
sourcePath = null;
configFile = null;
basePath = AppContext.BaseDirectory;
solutionFilePaths = new List<string>();
var i = 0;
while (i < args.Length)
{
var current = args[i];
if (current == "-config")
{
if (i + 1 >= args.Length)
{
Console.WriteLine("The -config option requires a parameter");
return false;
}
configPath = args[i + 1];
i += 2;
}
else
switch (current.ToLower())
{
break;
case "-config":
if (i + 1 >= args.Length)
{
Console.WriteLine("config requires an argument");
return false;
}
configFile = args[i + 1];
i += 2;
break;
case "-basepath":
if (i + 1 >= args.Length)
{
Console.WriteLine("basePath requise and argument");
return false;
}
basePath = args[i + 1];
i += 2;
break;
default:
solutionFilePaths.Add(current);
i++;
break;
}
}
if (i + 1 != args.Length)
{
return false;
}
sourcePath = args[i];
configPath = configPath ?? Path.Combine(sourcePath, @"build\config\BuildBossData.json");
return true;
}
private static void Usage()
{
Console.WriteLine($"BuildBoss [-config <config path>] <source path>");
Console.WriteLine($"BuildBoss [-config <config file path] [-basePath <base path>] <solution paths>");
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BuildBoss
{
/// <summary>
/// All of the project information contained in a solution file.
/// </summary>
internal struct ProjectData
{
internal string RelativeFilePath { get; }
internal string Name { get; }
internal Guid Guid { get; }
internal Guid TypeGuid { get; }
internal bool IsFolder => TypeGuid == ProjectDataUtil.FolderProjectType;
internal ProjectType ProjectType => ProjectDataUtil.GetProjectType(RelativeFilePath);
internal ProjectData(
string relativeFilePath,
string name,
Guid guid,
Guid typeGuid)
{
RelativeFilePath = relativeFilePath;
Name = name;
Guid = guid;
TypeGuid = typeGuid;
}
public override string ToString() => Name;
}
internal static class ProjectDataUtil
{
internal static readonly Guid FolderProjectType = new Guid("{2150E333-8FDC-42A3-9474-1A3956D46DE8}");
internal static ProjectType GetProjectType(string path)
{
switch (Path.GetExtension(path))
{
case ".csproj": return ProjectType.CSharp;
case ".vbproj": return ProjectType.Basic;
case ".shproj": return ProjectType.Shared;
default:
return ProjectType.Unknown;
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BuildBoss
{
internal static class SolutionUtil
{
internal static List<ProjectData> ParseProjects(string solutionPath)
{
using (var reader = new StreamReader(solutionPath))
{
var list = new List<ProjectData>();
while (true)
{
var line = reader.ReadLine();
if (line == null)
{
break;
}
if (!line.StartsWith("Project"))
{
continue;
}
list.Add(ParseProjectLine(line));
}
return list;
}
}
private static ProjectData ParseProjectLine(string line)
{
var index = 0;
var typeGuid = ParseStringLiteral(line, ref index);
var name = ParseStringLiteral(line, ref index);
var filePath = ParseStringLiteral(line, ref index);
var guid = ParseStringLiteral(line, ref index);
return new ProjectData(
relativeFilePath: filePath,
name: name,
guid: Guid.Parse(guid),
typeGuid: Guid.Parse(typeGuid));
}
private static string ParseStringLiteral(string line, ref int index)
{
var start = line.IndexOf('"', index);
if (start < 0)
{
goto error;
}
start++;
var end = line.IndexOf('"', start);
if (end < 0)
{
goto error;
}
index = end + 1;
return line.Substring(start, end - start);
error:
throw new Exception($"Invalid project line {line}");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册