Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save dima1034/b870b70ca27d76d67fd207065b62c5c5 to your computer and use it in GitHub Desktop.

Select an option

Save dima1034/b870b70ca27d76d67fd207065b62c5c5 to your computer and use it in GitHub Desktop.

Revisions

  1. @Antaris Antaris created this gist Aug 12, 2016.
    79 changes: 79 additions & 0 deletions DotNetCoreVersionExtensions.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@
    namespace Cake.DotNetVersion
    {
    using System;
    using System.Collections.Generic;
    using Cake.Core;
    using Cake.Core.Annotations;
    using Cake.Core.IO;

    /// <summary>
    /// Contains functionality required to updating project file versions.
    /// </summary>
    [CakeAliasCategory("DotNetCoreVersion")]
    public static class DotNetCoreVersionExtensions
    {
    [CakeMethodAlias]
    public static void DotNetCoreVersion(this ICakeContext context, string version)
    {
    var settings = new DotNetCoreVersionSettings
    {
    Files = context.Globber.GetFiles("/**/project.json"),
    Version = version
    };

    DotNetCoreVersion(context, settings);
    }

    [CakeMethodAlias]
    public static void DotNetCoreVersion(this ICakeContext context, FilePath file, string version)
    {
    var settings = new DotNetCoreVersionSettings
    {
    File = file,
    Version = version
    };

    DotNetCoreVersion(context, settings);
    }

    [CakeMethodAlias]
    public static void DotNetCoreVersion(this ICakeContext context, IEnumerable<FilePath> files, string version)
    {
    var settings = new DotNetCoreVersionSettings
    {
    Files = files,
    Version = version
    };

    DotNetCoreVersion(context, settings);
    }

    [CakeMethodAlias]
    public static void DotNetCoreVersion(this ICakeContext context, DotNetCoreVersionSettings settings)
    {
    if (context == null)
    {
    throw new ArgumentNullException(nameof(context));
    }

    if (settings == null)
    {
    throw new ArgumentNullException(nameof(settings));
    }

    if (settings.File == null && settings.Files == null)
    {
    throw new ArgumentException("You must provide a file or set of file paths to process.");
    }

    if (string.IsNullOrEmpty(settings.Version))
    {
    throw new ArgumentException("You must provide a version to set.");
    }

    var runner = new DotNetCoreVersionRunner(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools);

    runner.Run(settings);
    }
    }
    }
    81 changes: 81 additions & 0 deletions DotNetVersionRunner.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,81 @@
    namespace Cake.DotNetVersion
    {
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using Cake.Core;
    using Cake.Core.IO;
    using Cake.Core.Tooling;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;

    /// <summary>
    /// Applies a version to a set of project.json files.
    /// </summary>
    public class DotNetCoreVersionRunner : Tool<DotNetCoreVersionSettings>
    {
    /// <summary>
    /// Initialises a new instance of <see cref="DotNetCoreVersionRunner"/>
    /// </summary>
    /// <param name="fileSystem">The Cake file system.</param>
    public DotNetCoreVersionRunner(IFileSystem fileSystem, ICakeEnvironment environment, IProcessRunner processRunner, IToolLocator toolLocator)
    : base(fileSystem, environment, processRunner, toolLocator)
    {
    }

    public void Run(DotNetCoreVersionSettings settings)
    {
    if (settings == null)
    {
    throw new ArgumentNullException(nameof(settings));
    }

    if (settings.Files != null)
    {
    foreach (var file in settings.Files)
    {
    RunCore(file, settings.Version);
    }
    }
    else if (settings.File != null)
    {
    RunCore(settings.File, settings.Version);
    }
    }

    protected override IEnumerable<string> GetToolExecutableNames()
    {
    return new string[0];
    }

    protected override string GetToolName()
    {
    return "DotNetCoreVersion";
    }

    private void RunCore(FilePath filePath, string version)
    {
    JObject project;

    using (var file = new FileStream(filePath.FullPath, FileMode.Open))
    using (var stream = new StreamReader(file))
    using (var json = new JsonTextReader(stream))
    {
    project = JObject.Load(json);
    }

    var versionAttr = project.Property("version");
    if (versionAttr == null)
    {
    project.Add("version", new JValue(version));
    }
    else
    {
    versionAttr.Value = version;
    }

    File.WriteAllText(filePath.FullPath, project.ToString(), Encoding.UTF8);
    }
    }
    }
    27 changes: 27 additions & 0 deletions DotNetVersionSettings.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    namespace Cake.DotNetVersion
    {
    using System.Collections.Generic;
    using Cake.Core.IO;
    using Cake.Core.Tooling;

    /// <summary>
    /// Contains settings used by the version tool.
    /// </summary>
    public class DotNetCoreVersionSettings : ToolSettings
    {
    /// <summary>
    /// Gets or sets the collection of project files to update.
    /// </summary>
    public IEnumerable<FilePath> Files { get; set; }

    /// <summary>
    /// Gets or sets the single file path to update.
    /// </summary>
    public FilePath File { get; set; }

    /// <summary>
    /// Gets or sets the version to set.
    /// </summary>
    public string Version { get; set; }
    }
    }
    146 changes: 146 additions & 0 deletions build.cake
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,146 @@
    #addin "Cake.Powershell"
    #r "tools/AddIns/Cake.DotNetCoreVersion/Cake.DotNetCoreVersion.dll"

    //////////////////////////////////////////////////////////////////////
    // ARGUMENTS
    //////////////////////////////////////////////////////////////////////

    var target = Argument("target", "Default");
    var configuration = Argument("configuration", "Release");

    string version = null;
    string semanticVersion = null;
    string prerelease = null;

    //////////////////////////////////////////////////////////////////////
    // TASKS
    //////////////////////////////////////////////////////////////////////

    Task("Clean")
    .Does(() =>
    {
    CleanDirectory("./artifacts/");
    CleanDirectory("./test-results/");
    });

    Task("Restore")
    .Does(() =>
    {
    DotNetCoreRestore();
    });

    Task("Version")
    .Does(() =>
    {
    if (Bamboo.IsRunningOnBamboo)
    {
    // MA - We are running a CI build - so need make sure we execute the script with -local = $false
    StartPowershellFile("./version.ps1", args =>
    {
    args.Append("local", "$false");
    args.Append("branch", EnvironmentVariable("bamboo_planRepository_branchName"));
    });
    }
    else
    {
    StartPowershellFile("./version.ps1", args => args.Append("local", "$true"));
    }

    string[] lines = System.IO.File.ReadAllLines("./version.props");
    foreach (string line in lines)
    {
    if (line.StartsWith("version"))
    {
    version = line.Substring("version=".Length).Trim();
    }
    else if (line.StartsWith("semanticVersion"))
    {
    semanticVersion = line.Substring("semanticVersion=".Length).Trim();
    }
    else if (line.StartsWith("prerelease"))
    {
    prerelease = line.Substring("prerelease=".Length).Trim();
    }
    }

    Console.WriteLine("Version: {0}", version);
    Console.WriteLine("SemanticVersion: {0}", semanticVersion);
    Console.WriteLine("PreRelease: {0}", prerelease);

    DotNetCoreVersion(new DotNetCoreVersionSettings
    {
    Files = GetFiles("**/project.json"),
    Version = semanticVersion
    });
    });

    Task("Build")
    .Does(() =>
    {
    // MA - Build the libraries
    DotNetCoreBuild("./src/**/project.json", new DotNetCoreBuildSettings
    {
    Configuration = configuration
    });

    // MA - Build the test libraries
    DotNetCoreBuild("./tests/**/project.json", new DotNetCoreBuildSettings
    {
    Configuration = configuration
    });
    });

    Task("Test")
    .WithCriteria(() => HasArgument("test"))
    .Does(() =>
    {
    var tests = GetFiles("./tests/**/project.json");
    foreach (var test in tests)
    {
    string projectFolder = System.IO.Path.GetDirectoryName(test.FullPath);
    string projectName = projectFolder.Substring(projectFolder.LastIndexOf('\\') + 1);
    string resultsFile = "./test-results/" + projectName + ".xml";

    DotNetCoreTest(test.FullPath, new DotNetCoreTestSettings
    {
    ArgumentCustomization = args => args.Append("-xml " + resultsFile)
    });

    // MA - Transform the result XML into NUnit-compatible XML for the build server.
    XmlTransform("./tools/NUnitXml.xslt", "./test-results/" + projectName + ".xml", "./test-results/NUnit." + projectName + ".xml");
    }
    });

    Task("Pack")
    .WithCriteria(() => HasArgument("pack"))
    .Does(() =>
    {
    var projects = GetFiles("./src/**/project.json");
    foreach (var project in projects)
    {
    // MA - Pack the libraries
    DotNetCorePack(project.FullPath, new DotNetCorePackSettings
    {
    Configuration = configuration,
    OutputDirectory = "./artifacts/"
    });
    }
    });

    //////////////////////////////////////////////////////////////////////
    // TASK TARGETS
    //////////////////////////////////////////////////////////////////////

    Task("Default")
    .IsDependentOn("Version")
    .IsDependentOn("Clean")
    .IsDependentOn("Restore")
    .IsDependentOn("Build")
    .IsDependentOn("Test")
    .IsDependentOn("Pack");

    //////////////////////////////////////////////////////////////////////
    // EXECUTION
    //////////////////////////////////////////////////////////////////////

    RunTarget(target);
    3 changes: 3 additions & 0 deletions build.props
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    versionMajor=1
    versionMinor=0
    versionRev=0
    96 changes: 96 additions & 0 deletions version.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@

    [CmdletBinding()]
    Param(
    [bool] $local = $true,
    [string] $branch = $null
    )

    function ReadBuildProps
    {
    $buildProps = ConvertFrom-StringData (Get-Content ./build.props -raw)
    $buildObject = New-Object PSObject -Property $buildProps | Select-Object versionMajor, versionMinor, versionRev
    return $buildObject
    }

    function ReadBranchName
    {
    $branchName = (& git rev-parse --abbrev-ref HEAD).Trim()
    return $branchName
    }

    function ReadCommitCount
    {
    $count = (& git rev-list --all --count).Trim()
    return $count
    }

    function CreateVersion
    (
    [string] $major,
    [string] $minor,
    [string] $rev,
    [string] $branch,
    [int] $commits,
    [bool] $local = $true
    )
    {
    $version = [string]::Concat($major, ".", $minor, ".", $rev)
    $prerelease = $null

    $branch = $branch.Replace('/', '-')

    if ($branch -ne "release")
    {
    if ($local)
    {
    $prerelease = $branch
    }
    else
    {
    $prerelease = "$($branch)-$($commits)"
    }
    }

    if ($prerelease -ne $null)
    {
    $semVer = [string]::Concat($version, "-", $prerelease)
    }
    else
    {
    $semVer = $version
    }

    return @{
    Version = $version
    SemanticVersion = $semVer
    PreRelease = $prerelease
    }
    }

    function WriteVersion
    (
    [string] $version,
    [string] $semanticVersion,
    [string] $prerelease
    )
    {
    Set-Content ./version.props "version=$($version)`nsemanticVersion=$($semanticVersion)`nprerelease=$($prerelease)"
    }

    function ResolveVersion
    (
    [bool] $local = $true
    )
    {
    $parts = ReadBuildProps
    if (!$branch)
    {
    $branch = ReadBranchName
    }
    $count = ReadCommitCount
    $version = CreateVersion -major $parts.versionMajor -minor $parts.versionMinor -rev $parts.versionRev -branch $branch -commits $count -local $local

    WriteVersion -version $version.Version -semanticVersion $version.SemanticVersion -prerelease $version.PreRelease
    }

    ResolveVersion -local $local