mirror of https://github.com/SixLabors/ImageSharp
10 changed files with 337 additions and 97 deletions
@ -1,37 +1,2 @@ |
|||||
|
|
||||
|
|
||||
@echo Off |
@echo Off |
||||
ECHO Starting build |
call build\build.cmd |
||||
|
|
||||
call build\config.cmd |
|
||||
|
|
||||
ECHO Restoring packages |
|
||||
for %%s in (%projects%) do dotnet restore %%s |
|
||||
|
|
||||
call build\update-versions.cmd |
|
||||
|
|
||||
set buildRoot="%~dp0" |
|
||||
SET cli=dotnet pack --configuration Release --output "artifacts\bin\ImageSharp" |
|
||||
where gitversion |
|
||||
if not "%errorlevel%"=="0" ( |
|
||||
REM gitversion was not availible lets make a local build |
|
||||
SET cli=%cli% --version-suffix "local-build" |
|
||||
) |
|
||||
|
|
||||
ECHO Building packages |
|
||||
for %%s in (%projects%) do %cli% %%s |
|
||||
|
|
||||
REM reset local version numbers |
|
||||
call build\reset-versions.cmd |
|
||||
|
|
||||
:success |
|
||||
ECHO successfully built project |
|
||||
REM exit 0 |
|
||||
goto end |
|
||||
|
|
||||
:failure |
|
||||
ECHO failed to build. |
|
||||
REM exit -1 |
|
||||
goto end |
|
||||
|
|
||||
:end |
|
||||
@ -0,0 +1,252 @@ |
|||||
|
using Microsoft.DotNet.ProjectModel; |
||||
|
using System; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using NuGet.Versioning; |
||||
|
using System.Collections.Generic; |
||||
|
using LibGit2Sharp; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Text; |
||||
|
|
||||
|
namespace ConsoleApplication |
||||
|
{ |
||||
|
public class Program |
||||
|
{ |
||||
|
const string fallbackTag = "CI"; |
||||
|
|
||||
|
public static void Main(string[] args) |
||||
|
{ |
||||
|
var resetmode = args.Contains("reset"); |
||||
|
|
||||
|
// find the project root where glbal.json lives
|
||||
|
var root = ProjectRootResolver.ResolveRootDirectory("."); |
||||
|
//lets find the repo
|
||||
|
var repo = new LibGit2Sharp.Repository(root); |
||||
|
|
||||
|
//lets find all the project.json files in the src folder (don't care about versioning tests)
|
||||
|
var projectFiles = Directory.EnumerateFiles(Path.Combine(root, "src"), Project.FileName, SearchOption.AllDirectories); |
||||
|
|
||||
|
//open them and convert them to source projects
|
||||
|
var projects = projectFiles.Select(x => ProjectReader.GetProject(x)) |
||||
|
.Select(x => new SourceProject(x, repo.Info.WorkingDirectory)) |
||||
|
.ToList(); |
||||
|
if (resetmode) |
||||
|
{ |
||||
|
if (File.Exists("build-inner.bak")) |
||||
|
{ |
||||
|
File.Copy("build-inner.bak", "build-inner.cmd", true); |
||||
|
File.Delete("build-inner.bak"); |
||||
|
} |
||||
|
|
||||
|
//revert the project.json change be reverting it but skipp all the git stuff as its not needed
|
||||
|
foreach (var p in projects) |
||||
|
{ |
||||
|
if (File.Exists($"{p.FullProjectFilePath}.bak")) |
||||
|
{ |
||||
|
File.Copy($"{p.FullProjectFilePath}.bak", p.FullProjectFilePath, true); |
||||
|
File.Delete($"{p.FullProjectFilePath}.bak"); |
||||
|
} |
||||
|
Console.WriteLine($"{p.Name} {p.Version.ToFullString()}"); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
// populate the dependency chains
|
||||
|
projects.ForEach(x => x.PopulateDependencies(projects)); |
||||
|
|
||||
|
|
||||
|
foreach (var p in projects) |
||||
|
{ |
||||
|
foreach (var c in repo.Commits) |
||||
|
{ |
||||
|
// lets apply each commit to the projects looking to see if they effect it or a
|
||||
|
// dependency and detect if the commit was one that sent the current version
|
||||
|
if (!p.ApplyCommit(c, repo)) |
||||
|
{ |
||||
|
// if it did create the version then stop looking this one wins
|
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// lets build version friendly commit
|
||||
|
string branch = repo.Head.FriendlyName; |
||||
|
branch = branch.Replace("/", "-").Replace("--", "-"); |
||||
|
if (branch == "master") |
||||
|
{ |
||||
|
branch = ""; |
||||
|
} |
||||
|
|
||||
|
var sb = new StringBuilder(); |
||||
|
foreach (var p in projects) |
||||
|
{ |
||||
|
//we skip the build number and standard CI prefix on first commits
|
||||
|
var newVersion = p.CalculateVersionNumber(branch); |
||||
|
File.Copy(p.FullProjectFilePath, $"{p.FullProjectFilePath}.bak", true); |
||||
|
dynamic projectFile = JsonConvert.DeserializeObject(File.ReadAllText(p.FullProjectFilePath)); |
||||
|
|
||||
|
projectFile.version = $"{newVersion}-*"; |
||||
|
File.WriteAllText(p.FullProjectFilePath, JsonConvert.SerializeObject(projectFile, Formatting.Indented)); |
||||
|
|
||||
|
Console.WriteLine($"{p.Name} {newVersion}"); |
||||
|
|
||||
|
sb.AppendLine($@"dotnet pack --configuration Release --output ""artifacts\bin\ImageSharp"" ""{p.ProjectFilePath}"""); |
||||
|
} |
||||
|
|
||||
|
File.Copy("build-inner.cmd", "build-inner.bak", true); |
||||
|
File.WriteAllText("build-inner.cmd", sb.ToString()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
//find project root
|
||||
|
public static string GetProjectRoot() |
||||
|
{ |
||||
|
var path = Path.GetFullPath("."); |
||||
|
do |
||||
|
{ |
||||
|
var jsonPath = Path.Combine(path, "global.json"); |
||||
|
if (File.Exists(jsonPath)) |
||||
|
{ |
||||
|
return path; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
path = Path.GetDirectoryName(path); |
||||
|
} |
||||
|
} while (!string.IsNullOrWhiteSpace(path)); |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public class SourceProject |
||||
|
{ |
||||
|
private readonly IEnumerable<string> dependencies; |
||||
|
|
||||
|
public string ProjectDirectory { get; } |
||||
|
|
||||
|
public NuGetVersion Version { get; } |
||||
|
|
||||
|
public List<SourceProject> DependentProjects { get; private set; } |
||||
|
public string Name { get; private set; } |
||||
|
public string ProjectFilePath { get; private set; } |
||||
|
|
||||
|
private int commitCount = 0; |
||||
|
public string FullProjectFilePath { get; private set; } |
||||
|
|
||||
|
public SourceProject(Project project, string root) |
||||
|
{ |
||||
|
this.Name = project.Name; |
||||
|
this.ProjectDirectory = project.ProjectDirectory.Substring(root.Length); |
||||
|
this.ProjectFilePath = project.ProjectFilePath.Substring(root.Length); |
||||
|
this.FullProjectFilePath = project.ProjectFilePath; |
||||
|
this.Version = project.Version; |
||||
|
this.dependencies = project.Dependencies.Select(x => x.Name); |
||||
|
} |
||||
|
|
||||
|
public void PopulateDependencies(IEnumerable<SourceProject> projects) |
||||
|
{ |
||||
|
DependentProjects = projects.Where(x => dependencies.Contains(x.Name)).ToList(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private bool MatchPath(string path) |
||||
|
{ |
||||
|
if(path.StartsWith(this.ProjectDirectory, StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
if (DependentProjects.Any()) |
||||
|
{ |
||||
|
return DependentProjects.Any(x => x.MatchPath(path)); |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
internal bool ApplyCommitInternal(Commit commit, TreeChanges changes, Repository repo) |
||||
|
{ |
||||
|
commitCount++; |
||||
|
|
||||
|
//return false if this is a version number root
|
||||
|
var projectFileChange = changes.Where(x => x.Path?.Equals(this.ProjectFilePath, StringComparison.OrdinalIgnoreCase) == true).FirstOrDefault(); |
||||
|
if(projectFileChange != null) |
||||
|
{ |
||||
|
if(projectFileChange.Status == ChangeKind.Added) |
||||
|
{ |
||||
|
// the version must have been set here
|
||||
|
return false; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var blob = repo.Lookup<Blob>(projectFileChange.Oid); |
||||
|
using (var s = blob.GetContentStream()) |
||||
|
{ |
||||
|
var project = new ProjectReader().ReadProject(s, this.Name, this.FullProjectFilePath, null); |
||||
|
if(project.Version != this.Version) |
||||
|
{ |
||||
|
//version changed
|
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// version must have been the same lets carry on
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
internal bool ApplyCommit(Commit commit, Repository repo) |
||||
|
{ |
||||
|
foreach (var parent in commit.Parents) |
||||
|
{ |
||||
|
var changes = repo.Diff.Compare<TreeChanges>(parent.Tree, commit.Tree); |
||||
|
|
||||
|
foreach (TreeEntryChanges change in changes) |
||||
|
{ |
||||
|
if (!string.IsNullOrWhiteSpace(change.OldPath)) |
||||
|
{ |
||||
|
if (MatchPath(change.OldPath)) |
||||
|
{ |
||||
|
return ApplyCommitInternal(commit, changes, repo); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(change.Path)) |
||||
|
{ |
||||
|
if (MatchPath(change.Path)) |
||||
|
{ |
||||
|
return ApplyCommitInternal(commit, changes, repo); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
internal string CalculateVersionNumber(string branch) |
||||
|
{ |
||||
|
var version = this.Version.ToFullString(); |
||||
|
if (this.commitCount == 1 && branch == "") //master only
|
||||
|
{ |
||||
|
if (this.Version.IsPrerelease) |
||||
|
{ |
||||
|
//prerelease always needs the build counter just not on a branch name
|
||||
|
return $"{version}-{this.commitCount:000000}"; |
||||
|
} |
||||
|
//only 1 commit (the changing one) we will skip appending suffix
|
||||
|
return version; |
||||
|
} |
||||
|
|
||||
|
if (branch == "") |
||||
|
{ |
||||
|
branch = fallbackTag; |
||||
|
} |
||||
|
|
||||
|
return $"{version}-{branch}-{this.commitCount:000000}"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
"profiles": { |
||||
|
"build": { |
||||
|
"commandName": "Project" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
@echo Off |
||||
|
set buildRoot="%cd%" |
||||
|
|
||||
|
ECHO restoring packages |
||||
|
dotnet restore |
||||
|
|
||||
|
ECHO Updating version numbers and generating build script |
||||
|
cd %~dp0 |
||||
|
dotnet run -- update |
||||
|
cd %buildRoot% |
||||
|
|
||||
|
ECHO Building package |
||||
|
call %~dp0build-inner.cmd |
||||
|
|
||||
|
ECHO Reset version numbers |
||||
|
cd %~dp0 |
||||
|
dotnet run -- reset |
||||
|
cd %buildRoot% |
||||
@ -0,0 +1,25 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<PropertyGroup> |
||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> |
||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
||||
|
</PropertyGroup> |
||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> |
||||
|
<PropertyGroup Label="Globals"> |
||||
|
<ProjectGuid>575a5002-dd9f-4335-aa47-1dd87fa13645</ProjectGuid> |
||||
|
<RootNamespace>build</RootNamespace> |
||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> |
||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> |
||||
|
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup> |
||||
|
<SchemaVersion>2.0</SchemaVersion> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
|
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" /> |
||||
|
</ItemGroup> |
||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> |
||||
|
</Project> |
||||
@ -0,0 +1,22 @@ |
|||||
|
{ |
||||
|
"version": "1.0.0-*", |
||||
|
"buildOptions": { |
||||
|
"debugType": "portable", |
||||
|
"emitEntryPoint": true |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"Microsoft.DotNet.ProjectModel": "1.0.0-rc3-003121", |
||||
|
"LibGit2Sharp": "0.23.0" |
||||
|
}, |
||||
|
"frameworks": { |
||||
|
"net46": { |
||||
|
//"dependencies": { |
||||
|
// "Microsoft.NETCore.App": { |
||||
|
// "type": "platform", |
||||
|
// "version": "1.0.0" |
||||
|
// } |
||||
|
//}, |
||||
|
//"imports": "dnxcore50" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,25 +1,8 @@ |
|||||
|
|
||||
|
|
||||
@echo Off |
@echo Off |
||||
REM include project configs |
|
||||
call %~dp0\config.cmd |
|
||||
|
|
||||
set buildRoot="%cd%" |
set buildRoot="%cd%" |
||||
|
cd %~dp0 |
||||
|
|
||||
ECHO Reseting build version numbers |
dotnet run -- reset |
||||
for %%s in (%projects%) do ( |
|
||||
cd %%s |
|
||||
ECHO %GitVersion_NuGetVersion% |
|
||||
dotnet version "1.0.0-*" |
|
||||
cd %buildRoot% |
|
||||
) |
|
||||
|
|
||||
:success |
|
||||
REM exit 0 |
|
||||
goto end |
|
||||
|
|
||||
:failure |
|
||||
REM exit -1 |
|
||||
goto end |
|
||||
|
|
||||
:end |
cd %buildRoot% |
||||
@ -1,41 +0,0 @@ |
|||||
|
|
||||
|
|
||||
@echo Off |
|
||||
REM include project configs |
|
||||
call %~dp0\config.cmd |
|
||||
|
|
||||
REM gitversion not already been set in this build |
|
||||
if "%GitVersion_NuGetVersion%" == "" ( |
|
||||
rem can I call gitversion |
|
||||
where gitversion |
|
||||
if "%errorlevel%"=="0" ( |
|
||||
REM call gitversion and then recall this build script with the envArgs set |
|
||||
ECHO calculating correct version number |
|
||||
|
|
||||
REM call this file from itself with the args set |
|
||||
gitversion /output buildserver /exec "%~dp0\update-versions.cmd" |
|
||||
|
|
||||
REM we looped skip to the end |
|
||||
goto end |
|
||||
) |
|
||||
) |
|
||||
|
|
||||
set buildRoot="%cd%" |
|
||||
|
|
||||
ECHO Updating build version numbers |
|
||||
for %%s in (%projects%) do ( |
|
||||
cd %%s |
|
||||
ECHO %GitVersion_NuGetVersion% |
|
||||
dotnet version %GitVersion_NuGetVersion% |
|
||||
cd %buildRoot% |
|
||||
) |
|
||||
|
|
||||
:success |
|
||||
REM exit 0 |
|
||||
goto end |
|
||||
|
|
||||
:failure |
|
||||
REM exit -1 |
|
||||
goto end |
|
||||
|
|
||||
:end |
|
||||
Loading…
Reference in new issue