From 805c57ec397db096c907b3f6ad17c82b6aac1730 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Thu, 15 Sep 2016 23:03:29 +0200 Subject: [PATCH] Script to update nuspecs, projects, and other references to a new version --- build.cake | 75 +++++++++++++--- cake/UtilsMSBuild.cake | 199 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+), 14 deletions(-) diff --git a/build.cake b/build.cake index e5440ec2..8c605b26 100644 --- a/build.cake +++ b/build.cake @@ -46,21 +46,9 @@ Task ("externals") // LIBS - the managed C# libraries //////////////////////////////////////////////////////////////////////////////////////////////////// -Task ("libs-base") - .Does (() => -{ - // set the SHA on the assembly info - var sha = EnvironmentVariable ("GIT_COMMIT") ?? string.Empty; - if (!string.IsNullOrEmpty (sha) && sha.Length >= 6) { - sha = sha.Substring (0, 6); - Information ("Setting Git SHA to {0}.", sha); - ReplaceTextInFiles ("./binding/SkiaSharp/Properties/SkiaSharpAssemblyInfo.cs", "{GIT_SHA}", sha); - } -}); - Task ("libs") .IsDependentOn ("externals") - .IsDependentOn ("libs-base") + .IsDependentOn ("set-versions") .Does (() => { // set the SHA on the assembly info @@ -306,7 +294,7 @@ Task ("views-forms") //////////////////////////////////////////////////////////////////////////////////////////////////// Task ("docs") - .IsDependentOn ("libs-base") + .IsDependentOn ("set-versions") .IsDependentOn ("externals-genapi") .Does (() => { @@ -402,6 +390,65 @@ Task ("component") // MoveFiles (yamlDir.FullPath.TrimEnd ('/') + "/*.xam", "./output/"); }); +//////////////////////////////////////////////////////////////////////////////////////////////////// +// VERSIONS - update all packages and references to the new version +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Task ("set-versions") + .Does (() => +{ + // set the SHA on the assembly info + var sha = EnvironmentVariable ("GIT_COMMIT") ?? string.Empty; + if (!string.IsNullOrEmpty (sha) && sha.Length >= 6) { + sha = sha.Substring (0, 6); + } else { + sha = "{GIT_SHA}"; + } + + // the versions + var version = "1.54.0.0"; + var fileVersion = "1.54.1.0"; + var versions = new Dictionary { + { "SkiaSharp", "1.54.1" }, + { "SkiaSharp.Views", "1.54.1-beta1" }, + { "SkiaSharp.Views.Forms", "1.54.1-beta1" }, + }; + + var files = new List (); + var add = new Action (glob => { + files.AddRange (GetFiles (glob).Select (p => MakeAbsolute (p).ToString ())); + }); + // nuspecs + add ("./nuget/*.nuspec"); + // packages files + add ("./source/*/*/packages.config"); + add ("./source/*/*/project.json"); + // project files + add ("./source/*/*/*.nuget.targets"); + add ("./source/*/*/*.csproj"); + // sample packages files + add ("./samples/**/packages.config"); + add ("./samples/**/project.json"); + // sample project files + add ("./samples/**/*.nuget.targets"); + add ("./samples/**/*.csproj"); + // update + foreach (var file in files) { + UpdateSkiaSharpVersion (file, versions); + } + + // assembly infos + UpdateAssemblyInfo ( + "./binding/SkiaSharp/Properties/SkiaSharpAssemblyInfo.cs", + version, fileVersion, sha); + UpdateAssemblyInfo ( + "./source/SkiaSharp.Views/SkiaSharp.Views/Properties/SkiaSharpViewsAssemblyInfo.cs", + version, fileVersion, sha); + UpdateAssemblyInfo ( + "./source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Shared/SkiaSharpViewsFormsAssemblyInfo.cs", + version, fileVersion, sha); +}); + //////////////////////////////////////////////////////////////////////////////////////////////////// // CLEAN - remove all the build artefacts //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/cake/UtilsMSBuild.cake b/cake/UtilsMSBuild.cake index 56af4f94..19fb9b12 100644 --- a/cake/UtilsMSBuild.cake +++ b/cake/UtilsMSBuild.cake @@ -108,3 +108,202 @@ var RedirectBuildOutputs = new Action ((projectFilePath) => { xdoc.Save (projectFile); }); + +var UpdateSkiaSharpVersion = new Action> ((path, versions) => { + path = MakeAbsolute (path); + var fn = System.IO.Path.GetFileName (path.ToString ()); + var ext = System.IO.Path.GetExtension (path.ToString ()); + + var ProjectJsonRegex = new Regex (@"(?
^\s*\"")(?.*)(?\""\:\s*\"")(?.*)(?\"".*$)");
+    var TargetsRegex = new Regex (@"(?
^.*\$\(NuGetPackageRoot\)\\)(?.*?)(?\\)(?.*?)(?\\.*)");
+    var HintRegex = new Regex (@"(?
^.*packages\\)(?.*?)(?\.)(?[\d\.]+(\-.*?){0,1})(?\\.*)");
+
+    if (fn == "project.json") {
+        // replace the NuGet v3 project.json
+
+        var modified = false;
+        var lines = FileReadLines (path);
+        // regex for `"id": "version",`
+        for (var i = 0; i < lines.Length; i++) {
+            // check if this line matches anything
+            var match = ProjectJsonRegex.Match (lines [i]);
+            if (match.Success) {
+                var id = match.Groups ["id"].Value;
+                // check to see what it matches
+                string version;
+                if (versions.TryGetValue (id, out version) && 
+                    version != match.Groups ["version"].Value) {
+                    // replace with the new version
+                    lines[i] = match.Result ("${pre}" + id + "${mid}" + version + "${post}");
+                    modified = true;
+                }
+            }
+        }
+        if (modified) {
+            FileWriteLines (path, lines);
+        }
+    } else if (fn == "packages.config") {
+        // replace the NuGet v2 packages.config
+
+        var modified = false;
+        var xdoc = XDocument.Load (path.ToString ());
+        foreach (var package in xdoc.Root.Elements ("package")) {
+            var id = package.Attribute ("id");
+            var oldVersion = package.Attribute ("version");
+            if (id != null && oldVersion != null) {
+                string version;
+                if (versions.TryGetValue (id.Value, out version) && 
+                    version != oldVersion.Value) {
+                    // replace with the new version
+                    oldVersion.Value = version;
+                    modified = true;
+                }
+            }
+        }
+        if (modified) {
+            xdoc.Save (path.ToString ());
+        }
+    } else if (ext == ".nuspec") {
+        // replace NuSpec
+
+        var modified = false;
+        var xdoc = XDocument.Load (path.ToString ());
+        var metadata = xdoc.Root.Elements ("metadata");
+        var dependencies = metadata
+            .Elements ("dependencies")
+            .Elements ("dependency");
+        var groupDependencies = metadata
+            .Elements ("dependencies")
+            .Elements ("group")
+            .Elements ("dependency");
+        foreach (var package in dependencies.Union (groupDependencies)) {
+            var id = package.Attribute ("id");
+            var oldVersion = package.Attribute ("version");
+            if (id != null && oldVersion != null) {
+                string version;
+                if (versions.TryGetValue (id.Value, out version) && 
+                    version != oldVersion.Value) {
+                    // replace with the new version
+                    oldVersion.Value = version;
+                    modified = true;
+                }
+            }
+        }
+        var xId = metadata.Elements ("id").FirstOrDefault ();
+        var xVersion = metadata.Elements ("version").FirstOrDefault ();
+        if (xId != null && xVersion != null) {
+            string version;
+            if (versions.TryGetValue (xId.Value, out version) && 
+                version != xVersion.Value) {
+                // replace with the new version
+                xVersion.Value = version;
+                modified = true;
+            }
+        }
+        if (modified) {
+            xdoc.Save (path.ToString ());
+        }
+    } else if (fn.EndsWith (".nuget.targets")) {
+        // replace NuGet v3 targets
+
+        var modified = false;
+        var xdoc = XDocument.Load (path.ToString ());
+        var imports = xdoc.Root
+            .Elements (MSBuildNS + "ImportGroup")
+            .Elements (MSBuildNS + "Import");
+        foreach (var package in imports) {
+            var proj = package.Attribute ("Project");
+            var cond = package.Attribute ("Condition");
+            if (proj != null) {
+                var projMatch = TargetsRegex.Match (proj.Value);
+                var id = projMatch.Groups ["id"].Value;
+                var oldVersion = projMatch.Groups ["version"].Value;
+                string version;
+                if (versions.TryGetValue (id, out version) && 
+                    version != oldVersion) {
+                    // replace with the new version
+                    proj.Value = projMatch.Result ("${pre}" + id + "${mid}" + version + "${post}");
+                    if (cond != null) {
+                        var condMatch = TargetsRegex.Match (cond.Value);
+                        cond.Value = condMatch.Result ("${pre}" + id + "${mid}" + version + "${post}");
+                    }
+                    modified = true;
+                }
+            }
+        }
+        if (modified) {
+            xdoc.Save (path.ToString ());
+        }
+    } else if (ext == ".csproj") {
+        // replace C# projects
+
+        var modified = false;
+        var replace = new Func ((text) => {
+            var match = HintRegex.Match (text);
+            var id = match.Groups ["id"].Value;
+            var oldVersion = match.Groups ["version"].Value;
+            string version;
+            if (versions.TryGetValue (id, out version) && 
+                version != oldVersion) {
+                // replace with the new version
+                modified = true;
+                text = match.Result ("${pre}" + id + "${mid}" + version + "${post}");
+            }
+            return text;
+        });
+        var xdoc = XDocument.Load (path.ToString ());
+        var references = xdoc.Root
+            .Elements (MSBuildNS + "ItemGroup")
+            .Elements (MSBuildNS + "Reference");
+        foreach (var package in references) {
+            var hint = package.Element (MSBuildNS + "HintPath");
+            if (hint != null) {
+                hint.Value = replace (hint.Value);
+            }
+        }
+        var imports = xdoc.Root
+            .Elements (MSBuildNS + "Import");
+        foreach (var package in imports) {
+            var proj = package.Attribute ("Project");
+            if (proj != null) {
+                proj.Value = replace (proj.Value);
+            }
+            var cond = package.Attribute ("Condition");
+            if (cond != null) {
+                cond.Value = replace (cond.Value);
+            }
+        }
+        var errors = xdoc.Root
+            .Elements (MSBuildNS + "Target")
+            .Elements (MSBuildNS + "Error");
+        foreach (var package in errors) {
+            var cond = package.Attribute ("Condition");
+            if (cond != null) {
+                cond.Value = replace (cond.Value);
+            }
+            var text = package.Attribute ("Text");
+            if (text != null) {
+                text.Value = replace (text.Value);
+            }
+        }
+        if (modified) {
+            xdoc.Save (path.ToString ());
+        }
+    }
+});
+
+var UpdateAssemblyInfo = new Action ((path, assembly, version, sha) => {
+    var info = ParseAssemblyInfo (path);
+    var settings = new AssemblyInfoSettings {
+        Version = assembly,
+        FileVersion = version,
+        InformationalVersion = version + "-" + sha,
+        Company = info.Company,
+        Copyright = info.Copyright,
+        Description = info.Description,
+        Product = info.Product,
+        Title = info.Title,
+        Trademark = info.Trademark,
+    };
+    CreateAssemblyInfo (path, settings);
+});
\ No newline at end of file