From 1d515310a1fb07407762dc67e21b738a373bcfc9 Mon Sep 17 00:00:00 2001
From: 0x6d61726b <0x6d61726b@gmail.com>
Date: Sat, 17 Oct 2020 20:41:40 +0200
Subject: [PATCH 1/8] Implemented resolving of AssemblyMetadata attributes
---
NetRevisionTask/AssemblyInfoHelper.cs | 26 ++++++++++++++++---
NetRevisionTask/NetRevisionTask.csproj | 2 +-
NetRevisionTask/Tasks/PatchAssemblyInfo.cs | 8 +++++-
.../Unclassified.NetRevisionTask.targets | 4 ++-
README.md | 5 ++++
5 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/NetRevisionTask/AssemblyInfoHelper.cs b/NetRevisionTask/AssemblyInfoHelper.cs
index 9ea7573..7cfbce7 100644
--- a/NetRevisionTask/AssemblyInfoHelper.cs
+++ b/NetRevisionTask/AssemblyInfoHelper.cs
@@ -78,6 +78,7 @@ public AssemblyInfoHelper(string projectDir, bool throwOnMissingFile, ILogger lo
/// Indicates whether only the last number is replaced by the revision number.
/// Indicates whether the copyright year is replaced.
/// Indicates whether the final informational version string is displayed.
+ /// Indicates whether the AssemblyMetadata attribute is processed.
/// The name of the patched AssemblyInfo file.
public string PatchFile(
string patchedFileDir,
@@ -87,7 +88,8 @@ public string PatchFile(
bool informationalAttribute,
bool revOnly,
bool copyrightAttribute,
- bool echo)
+ bool echo,
+ bool metadataAttribute)
{
logger?.Trace($@"Patching file ""{fileName}""...");
ReadFileLines(FullFileName);
@@ -111,7 +113,7 @@ public string PatchFile(
}
// Process all lines in the file
- ResolveAllLines(rf, simpleAttributes, informationalAttribute, revOnly, copyrightAttribute, echo);
+ ResolveAllLines(rf, simpleAttributes, informationalAttribute, revOnly, copyrightAttribute, echo, metadataAttribute);
// Write all lines to the file
string patchedFileName = Path.Combine(patchedFileDir, "Nrt" + Path.GetFileName(fileName));
@@ -250,7 +252,8 @@ private void WriteFileLines(string patchedFileName)
/// Indicates whether only the last number is replaced by the revision number.
/// Indicates whether the copyright year is replaced.
/// Indicates whether the final informational version string is displayed.
- private void ResolveAllLines(RevisionFormatter rf, bool simpleAttributes, bool informationalAttribute, bool revOnly, bool copyrightAttribute, bool echo)
+ /// Indicates whether the AssemblyMetadata attribute is processed.
+ private void ResolveAllLines(RevisionFormatter rf, bool simpleAttributes, bool informationalAttribute, bool revOnly, bool copyrightAttribute, bool echo, bool metadataAttribute)
{
// Preparing a truncated dotted-numeric version if we may need it
string truncVersion = null;
@@ -385,6 +388,23 @@ private void ResolveAllLines(RevisionFormatter rf, bool simpleAttributes, bool i
logger?.Trace($@" Replaced ""{match.Groups[2].Value}"" with ""{copyrightText}"".");
}
}
+
+ if (metadataAttribute)
+ {
+ // Replace the value part of AssemblyMetadata with the resolved string of what
+ // was already there. Format: [assembly: AssemblyMetadata("Key", "Value")]
+ match = Regex.Match(
+ lines[i],
+ @"^(\s*\" + attrStart + @"\s*assembly\s*:\s*AssemblyMetadata\s*\(\s*"")(.*?)(""\s*,\s*"")(.*?)(""\s*\)\s*\" + attrEnd + @".*)$",
+ RegexOptions.IgnoreCase);
+ if (match.Success)
+ {
+ string metadataText = rf.Resolve(match.Groups[4].Value);
+ lines[i] = match.Groups[1].Value + match.Groups[2].Value + match.Groups[3].Value + metadataText + match.Groups[5].Value;
+ logger?.Success("Found AssemblyMetadata attribute.");
+ logger?.Trace($@" Replaced [{match.Groups[2].Value}] => ""{match.Groups[4].Value}"" with ""{metadataText}"".");
+ }
+ }
}
}
diff --git a/NetRevisionTask/NetRevisionTask.csproj b/NetRevisionTask/NetRevisionTask.csproj
index 5139811..794a064 100644
--- a/NetRevisionTask/NetRevisionTask.csproj
+++ b/NetRevisionTask/NetRevisionTask.csproj
@@ -8,7 +8,7 @@
tasks
- 0.3
+ 0.4
true
diff --git a/NetRevisionTask/Tasks/PatchAssemblyInfo.cs b/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
index 154be36..849be5e 100644
--- a/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
+++ b/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
@@ -93,6 +93,11 @@ public class PatchAssemblyInfo : MSBuildTask
///
public bool ShowRevision { get; set; }
+ ///
+ /// Gets or sets a value indicating whether the AssemblyMetadata attribute is processed.
+ ///
+ public bool ResolveMetadata { get; set; }
+
#endregion Properties
#region Task output properties
@@ -157,7 +162,8 @@ public override bool Execute()
ResolveInformationalAttribute,
RevisionNumberOnly,
ResolveCopyright,
- ShowRevision);
+ ShowRevision,
+ ResolveMetadata);
}
catch (FormatException ex)
{
diff --git a/NetRevisionTask/build/Unclassified.NetRevisionTask.targets b/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
index 2520eda..14e485a 100644
--- a/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
+++ b/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
@@ -13,6 +13,7 @@
true
true
true
+ true
v[0-9]*
true
@@ -66,7 +67,8 @@
ResolveInformationalAttribute="$(NrtResolveInformationalAttribute)"
RevisionNumberOnly="$(NrtRevisionNumberOnly)"
ResolveCopyright="$(NrtResolveCopyright)"
- ShowRevision="$(NrtShowRevision)">
+ ShowRevision="$(NrtShowRevision)"
+ ResolveMetadata="$(NrtResolveMetadata)">
diff --git a/README.md b/README.md
index 545e92d..433825b 100644
--- a/README.md
+++ b/README.md
@@ -68,6 +68,7 @@ Example:
true
git
true
+ true
The following MSBuild properties are supported:
@@ -104,6 +105,10 @@ Specifies the name of the VCS that is expected to be found in the project direct
Specifies whether the determined revision ID is printed during the build with higher importance than normal, so it can be seen more easily. When patching the AssemblyInfo file, it is also displayed to the console.
+**NrtResolveMetadata**: boolean, default: true.
+
+Specifies whether the value component of the `AssemblyMetadata` (`AssemblyMetadataAttribute`) is resolved.
+
### Revision format
You can customise the format of the resulting version with a revision format string that defines how information about the commit or revision is formatted into the final revision ID. It is a plain string that contains placeholders in `{curly braces}`. Each placeholder is a simple data field or encodes a time value using a scheme and optional configuration arguments.
From f0fd6b978c65e332da80ba0ac669f8af250b696e Mon Sep 17 00:00:00 2001
From: 0x6d61726b <0x6d61726b@gmail.com>
Date: Sat, 17 Oct 2020 20:45:57 +0200
Subject: [PATCH 2/8] Update BuildTime if a new version is requested (v0.3
implemention keeps build time constant until Visual Studio Solution is
reloaded)
---
NetRevisionTask/Common.cs | 2 +-
NetRevisionTask/RevisionFormatter.cs | 10 +++++++---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/NetRevisionTask/Common.cs b/NetRevisionTask/Common.cs
index ffbfda6..769c6c9 100644
--- a/NetRevisionTask/Common.cs
+++ b/NetRevisionTask/Common.cs
@@ -26,7 +26,7 @@ public static (bool success, string version, string informationalVersion, string
revisionFormat = data.GetDefaultRevisionFormat(logger);
}
- var rf = new RevisionFormatter { RevisionData = data, RemoveTagV = removeTagV };
+ var rf = new RevisionFormatter { RevisionData = data, RemoveTagV = removeTagV, BuildTime = DateTimeOffset.Now };
try
{
return (true, rf.ResolveShort(revisionFormat), rf.Resolve(revisionFormat), rf.Resolve(copyright));
diff --git a/NetRevisionTask/RevisionFormatter.cs b/NetRevisionTask/RevisionFormatter.cs
index 90d72a4..96e155e 100644
--- a/NetRevisionTask/RevisionFormatter.cs
+++ b/NetRevisionTask/RevisionFormatter.cs
@@ -11,7 +11,7 @@ internal class RevisionFormatter
{
#region Static data
- private static readonly DateTimeOffset buildTime = DateTimeOffset.Now;
+ private static DateTimeOffset buildTime = DateTimeOffset.Now;
///
/// Alphabet for the base-28 encoding. This uses the digits 0–9 and all characters a–z that
@@ -50,9 +50,13 @@ internal class RevisionFormatter
public bool RemoveTagV { get; set; }
///
- /// Gets the build time.
+ /// Gets or sets the build time.
///
- public DateTimeOffset BuildTime => buildTime;
+ public DateTimeOffset BuildTime
+ {
+ get => buildTime;
+ set => buildTime = value;
+ }
#endregion Data properties
From ddd988dc7eb8d12fb3e8323c338aa7b36a689035 Mon Sep 17 00:00:00 2001
From: 0x6d61726b <0x6d61726b@gmail.com>
Date: Sat, 17 Oct 2020 20:52:45 +0200
Subject: [PATCH 3/8] Build configuration name format strings {bconf}, {BCONF}
and {bconf::[} added
---
NetRevisionTask/Api.cs | 12 ++++++++----
NetRevisionTask/Common.cs | 5 +++--
NetRevisionTask/RevisionFormatter.cs | 11 +++++++++++
NetRevisionTask/Tasks/PatchAssemblyInfo.cs | 8 +++++++-
NetRevisionTask/Tasks/SetVersion.cs | 8 +++++++-
.../build/Unclassified.NetRevisionTask.targets | 6 ++++--
README.md | 6 ++++++
7 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/NetRevisionTask/Api.cs b/NetRevisionTask/Api.cs
index 8481cd5..fbd1d2b 100644
--- a/NetRevisionTask/Api.cs
+++ b/NetRevisionTask/Api.cs
@@ -13,13 +13,15 @@ public static string GetVersion(
string revisionFormat = null,
string tagMatch = "v[0-9]*",
bool removeTagV = true,
- string copyright = null)
+ string copyright = null,
+ string configurationName = null)
{
if (string.IsNullOrEmpty(projectDir))
projectDir = Directory.GetCurrentDirectory();
var logger = new ConsoleLogger();
- var result = Common.GetVersion(projectDir, requiredVcs, revisionFormat, tagMatch, removeTagV, copyright ?? "", logger, true);
+ var result = Common.GetVersion(projectDir, requiredVcs, revisionFormat, tagMatch, removeTagV, copyright ?? "", logger, true,
+ configurationName);
if (!result.success)
{
return null;
@@ -33,13 +35,15 @@ public static string GetShortVersion(
string revisionFormat = null,
string tagMatch = "v[0-9]*",
bool removeTagV = true,
- string copyright = null)
+ string copyright = null,
+ string configurationName = null)
{
if (string.IsNullOrEmpty(projectDir))
projectDir = Directory.GetCurrentDirectory();
var logger = new ConsoleLogger();
- var result = Common.GetVersion(projectDir, requiredVcs, revisionFormat, tagMatch, removeTagV, copyright ?? "", logger, true);
+ var result = Common.GetVersion(projectDir, requiredVcs, revisionFormat, tagMatch, removeTagV, copyright ?? "", logger, true,
+ configurationName);
if (!result.success)
{
return null;
diff --git a/NetRevisionTask/Common.cs b/NetRevisionTask/Common.cs
index 769c6c9..eefd897 100644
--- a/NetRevisionTask/Common.cs
+++ b/NetRevisionTask/Common.cs
@@ -8,7 +8,8 @@ namespace NetRevisionTask
internal class Common
{
public static (bool success, string version, string informationalVersion, string copyright)
- GetVersion(string projectDir, string requiredVcs, string revisionFormat, string tagMatch, bool removeTagV, string copyright, ILogger logger, bool warnOnMissing)
+ GetVersion(string projectDir, string requiredVcs, string revisionFormat, string tagMatch, bool removeTagV, string copyright, ILogger logger, bool warnOnMissing,
+ string configurationName)
{
// Analyse working directory
RevisionData data = ProcessDirectory(projectDir, requiredVcs, tagMatch, logger);
@@ -26,7 +27,7 @@ public static (bool success, string version, string informationalVersion, string
revisionFormat = data.GetDefaultRevisionFormat(logger);
}
- var rf = new RevisionFormatter { RevisionData = data, RemoveTagV = removeTagV, BuildTime = DateTimeOffset.Now };
+ var rf = new RevisionFormatter { RevisionData = data, RemoveTagV = removeTagV, BuildTime = DateTimeOffset.Now, ConfigurationName = configurationName };
try
{
return (true, rf.ResolveShort(revisionFormat), rf.Resolve(revisionFormat), rf.Resolve(copyright));
diff --git a/NetRevisionTask/RevisionFormatter.cs b/NetRevisionTask/RevisionFormatter.cs
index 96e155e..5e09a0c 100644
--- a/NetRevisionTask/RevisionFormatter.cs
+++ b/NetRevisionTask/RevisionFormatter.cs
@@ -58,6 +58,11 @@ public DateTimeOffset BuildTime
set => buildTime = value;
}
+ ///
+ /// Gets the value of the build configuration name.
+ ///
+ public string ConfigurationName { get; set; }
+
#endregion Data properties
#region Format resolving
@@ -146,6 +151,12 @@ public string Resolve(string format)
format = format.Replace("{copyright}", copyright);
format = Regex.Replace(format, @"\{copyright:([0-9]+?)-?\}", m => (m.Groups[1].Value != copyright ? m.Groups[1].Value + "–" : "") + copyright);
+ // Build Configuration
+ format = format.Replace("{bconf}", ConfigurationName);
+ format = format.Replace("{BCONF}", ConfigurationName.ToUpperInvariant());
+ format = Regex.Replace(format, @"\{bconf:(.*?):(.+?)\}", m => ConfigurationName != m.Groups[2].Value ? m.Groups[1].Value + ConfigurationName : "");
+ format = Regex.Replace(format, @"\{BCONF:(.*?):(.+?)\}", m => ConfigurationName != m.Groups[2].Value ? m.Groups[1].Value + ConfigurationName.ToUpperInvariant() : "");
+
// Return revision ID
return format;
}
diff --git a/NetRevisionTask/Tasks/PatchAssemblyInfo.cs b/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
index 849be5e..657b880 100644
--- a/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
+++ b/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
@@ -98,6 +98,11 @@ public class PatchAssemblyInfo : MSBuildTask
/// ]
public bool ResolveMetadata { get; set; }
+ ///
+ /// Gets or sets the value of the build configuration name.
+ ///
+ public string ConfigurationName { get; set; }
+
#endregion Properties
#region Task output properties
@@ -149,7 +154,8 @@ public override bool Execute()
RevisionFormat = data.GetDefaultRevisionFormat(logger);
}
- var rf = new RevisionFormatter { RevisionData = data, RemoveTagV = RemoveTagV };
+ var rf = new RevisionFormatter { RevisionData = data, RemoveTagV = RemoveTagV,
+ ConfigurationName = ConfigurationName };
try
{
var aih = new AssemblyInfoHelper(ProjectDir, true, logger);
diff --git a/NetRevisionTask/Tasks/SetVersion.cs b/NetRevisionTask/Tasks/SetVersion.cs
index 39a58fb..2463339 100644
--- a/NetRevisionTask/Tasks/SetVersion.cs
+++ b/NetRevisionTask/Tasks/SetVersion.cs
@@ -69,6 +69,11 @@ public class SetVersion : MSBuildTask
///
public bool ShowRevision { get; set; }
+ ///
+ /// Gets the value of the build configuration name.
+ ///
+ public string ConfigurationName { get; set; }
+
#endregion Properties
#region Task output properties
@@ -110,7 +115,8 @@ public override bool Execute()
logger = new TaskLogger(Log);
logger.Trace($"NetRevisionTask: SetVersion ({targetFramework})");
- var result = Common.GetVersion(ProjectDir, RequiredVcs, RevisionFormat, TagMatch, RemoveTagV, Copyright ?? "", logger, !GenerateAssemblyInfo);
+ var result = Common.GetVersion(ProjectDir, RequiredVcs, RevisionFormat, TagMatch, RemoveTagV, Copyright ?? "", logger, !GenerateAssemblyInfo,
+ ConfigurationName);
if (!result.success)
{
return false;
diff --git a/NetRevisionTask/build/Unclassified.NetRevisionTask.targets b/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
index 14e485a..71bf204 100644
--- a/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
+++ b/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
@@ -32,7 +32,8 @@
RemoveTagV="$(NrtRemoveTagV)"
ResolveCopyright="$(NrtResolveCopyright)"
Copyright="$(Copyright)"
- ShowRevision="$(NrtShowRevision)">
+ ShowRevision="$(NrtShowRevision)"
+ ConfigurationName="$(ConfigurationName)">
@@ -68,7 +69,8 @@
RevisionNumberOnly="$(NrtRevisionNumberOnly)"
ResolveCopyright="$(NrtResolveCopyright)"
ShowRevision="$(NrtShowRevision)"
- ResolveMetadata="$(NrtResolveMetadata)">
+ ResolveMetadata="$(NrtResolveMetadata)"
+ ConfigurationName="$(ConfigurationName)">
diff --git a/README.md b/README.md
index 433825b..5c5581e 100644
--- a/README.md
+++ b/README.md
@@ -171,6 +171,12 @@ The following data field placeholders are supported:
**`{copyright:-}`**: Abbreviation for the copyright year range, starting at ``. The following dash is optional but recommended for clearer understanding.
+**`{bconf}`**: Build configuration.
+
+**`{BCONF}`**: Build configuration, in upper case.
+
+**`{bconf::[}`, `{BCONF::][}`**: Build configuration, if not `][` or empty, separated by ``, otherwise empty.
+
Schemes convert a commit or build time to a compact string representation. They can be used to assign incrementing versions if no revision number is provided by the VCS. First, select from the build, commit or authoring time with `{b:…}`, `{c:…}` or `{a:…}`. This is followed by the scheme name. There are 4 types of schemes.
The following time schemes are supported:
From ba26cab31779a81b19a01742a22011c380c05d46 Mon Sep 17 00:00:00 2001
From: 0x6d61726b <0x6d61726b@gmail.com>
Date: Sat, 17 Oct 2020 20:57:03 +0200
Subject: [PATCH 4/8] Implemented regex match pattern to trigger a build error
if the repository contains modified (dirty)
---
NetRevisionTask/Api.cs | 10 +++---
NetRevisionTask/Common.cs | 32 ++++++++++++++++++-
NetRevisionTask/Tasks/PatchAssemblyInfo.cs | 12 +++++++
NetRevisionTask/Tasks/SetVersion.cs | 8 ++++-
.../Unclassified.NetRevisionTask.targets | 6 ++--
README.md | 5 +++
6 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/NetRevisionTask/Api.cs b/NetRevisionTask/Api.cs
index fbd1d2b..dd6b547 100644
--- a/NetRevisionTask/Api.cs
+++ b/NetRevisionTask/Api.cs
@@ -14,14 +14,15 @@ public static string GetVersion(
string tagMatch = "v[0-9]*",
bool removeTagV = true,
string copyright = null,
- string configurationName = null)
+ string configurationName = null,
+ string errorOnModifiedRepoPattern = null)
{
if (string.IsNullOrEmpty(projectDir))
projectDir = Directory.GetCurrentDirectory();
var logger = new ConsoleLogger();
var result = Common.GetVersion(projectDir, requiredVcs, revisionFormat, tagMatch, removeTagV, copyright ?? "", logger, true,
- configurationName);
+ configurationName, errorOnModifiedRepoPattern);
if (!result.success)
{
return null;
@@ -36,14 +37,15 @@ public static string GetShortVersion(
string tagMatch = "v[0-9]*",
bool removeTagV = true,
string copyright = null,
- string configurationName = null)
+ string configurationName = null,
+ string errorOnModifiedRepoPattern = null)
{
if (string.IsNullOrEmpty(projectDir))
projectDir = Directory.GetCurrentDirectory();
var logger = new ConsoleLogger();
var result = Common.GetVersion(projectDir, requiredVcs, revisionFormat, tagMatch, removeTagV, copyright ?? "", logger, true,
- configurationName);
+ configurationName, errorOnModifiedRepoPattern);
if (!result.success)
{
return null;
diff --git a/NetRevisionTask/Common.cs b/NetRevisionTask/Common.cs
index eefd897..3ae2263 100644
--- a/NetRevisionTask/Common.cs
+++ b/NetRevisionTask/Common.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using System.Text.RegularExpressions;
using NetRevisionTask.VcsProviders;
namespace NetRevisionTask
@@ -9,7 +10,7 @@ internal class Common
{
public static (bool success, string version, string informationalVersion, string copyright)
GetVersion(string projectDir, string requiredVcs, string revisionFormat, string tagMatch, bool removeTagV, string copyright, ILogger logger, bool warnOnMissing,
- string configurationName)
+ string configurationName, string configurationNameErrorPattern)
{
// Analyse working directory
RevisionData data = ProcessDirectory(projectDir, requiredVcs, tagMatch, logger);
@@ -18,6 +19,10 @@ public static (bool success, string version, string informationalVersion, string
logger.Error($@"The required version control system ""{requiredVcs}"" is not available or not used in the project directory.");
return (false, null, null, null);
}
+ if (TriggerErrorIfRepoModified(logger, data, configurationNameErrorPattern, configurationName))
+ {
+ return (false, null, null, null);
+ }
if (string.IsNullOrEmpty(revisionFormat))
{
revisionFormat = GetRevisionFormat(projectDir, logger, warnOnMissing);
@@ -147,5 +152,30 @@ public static string GetRevisionFormat(string projectDir, ILogger logger, bool w
}
return revisionFormat;
}
+
+ ///
+ /// Determines if a modified repository that matches the given pattern triggers a build error.
+ ///
+ /// The data about the current revision of the source directory.
+ /// The match pattern that shall trigger the error.
+ /// The name of the build configuration.
+ /// True if an error shall be triggered, false otherwise.
+ public static bool TriggerErrorIfRepoModified(ILogger logger, RevisionData data, string cfgNameMatchPattern, string cfgName)
+ {
+ if (!string.IsNullOrEmpty(cfgNameMatchPattern) && !string.IsNullOrEmpty(cfgName))
+ {
+ if (data.IsModified)
+ {
+ var match = Regex.Match(cfgName, $@"^{cfgNameMatchPattern}$", RegexOptions.IgnoreCase);
+ if (match.Success)
+ {
+ logger.Error($@"The ""{cfgName}"" configuration does not allow builds with a modified {data.VcsProvider.Name} repository.");
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
}
}
diff --git a/NetRevisionTask/Tasks/PatchAssemblyInfo.cs b/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
index 657b880..082224a 100644
--- a/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
+++ b/NetRevisionTask/Tasks/PatchAssemblyInfo.cs
@@ -103,6 +103,12 @@ public class PatchAssemblyInfo : MSBuildTask
///
public string ConfigurationName { get; set; }
+ ///
+ /// Gets or sets the value of the build configuration RegEx pattern that triggers an error
+ /// on match if the repository is modified.
+ ///
+ public string ErrorOnModifiedRepoPattern { get; set; }
+
#endregion Properties
#region Task output properties
@@ -154,6 +160,12 @@ public override bool Execute()
RevisionFormat = data.GetDefaultRevisionFormat(logger);
}
+ // check whether a modified repository triggers a build error
+ if (Common.TriggerErrorIfRepoModified(logger, data, ErrorOnModifiedRepoPattern, ConfigurationName))
+ {
+ return false;
+ }
+
var rf = new RevisionFormatter { RevisionData = data, RemoveTagV = RemoveTagV,
ConfigurationName = ConfigurationName };
try
diff --git a/NetRevisionTask/Tasks/SetVersion.cs b/NetRevisionTask/Tasks/SetVersion.cs
index 2463339..979171b 100644
--- a/NetRevisionTask/Tasks/SetVersion.cs
+++ b/NetRevisionTask/Tasks/SetVersion.cs
@@ -74,6 +74,12 @@ public class SetVersion : MSBuildTask
///
public string ConfigurationName { get; set; }
+ ///
+ /// Gets or sets the value of the build configuration RegEx pattern that triggers an error
+ /// on match if the repository is modified.
+ ///
+ public string ErrorOnModifiedRepoPattern { get; set; }
+
#endregion Properties
#region Task output properties
@@ -116,7 +122,7 @@ public override bool Execute()
logger.Trace($"NetRevisionTask: SetVersion ({targetFramework})");
var result = Common.GetVersion(ProjectDir, RequiredVcs, RevisionFormat, TagMatch, RemoveTagV, Copyright ?? "", logger, !GenerateAssemblyInfo,
- ConfigurationName);
+ ConfigurationName, ErrorOnModifiedRepoPattern);
if (!result.success)
{
return false;
diff --git a/NetRevisionTask/build/Unclassified.NetRevisionTask.targets b/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
index 71bf204..216d204 100644
--- a/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
+++ b/NetRevisionTask/build/Unclassified.NetRevisionTask.targets
@@ -33,7 +33,8 @@
ResolveCopyright="$(NrtResolveCopyright)"
Copyright="$(Copyright)"
ShowRevision="$(NrtShowRevision)"
- ConfigurationName="$(ConfigurationName)">
+ ConfigurationName="$(ConfigurationName)"
+ ErrorOnModifiedRepoPattern="$(NrtErrorOnModifiedRepoPattern)">
@@ -70,7 +71,8 @@
ResolveCopyright="$(NrtResolveCopyright)"
ShowRevision="$(NrtShowRevision)"
ResolveMetadata="$(NrtResolveMetadata)"
- ConfigurationName="$(ConfigurationName)">
+ ConfigurationName="$(ConfigurationName)"
+ ErrorOnModifiedRepoPattern="$(NrtErrorOnModifiedRepoPattern)">
diff --git a/README.md b/README.md
index 5c5581e..3ffa4f0 100644
--- a/README.md
+++ b/README.md
@@ -69,6 +69,7 @@ Example:
git
true
true
+ .*Release.*
The following MSBuild properties are supported:
@@ -109,6 +110,10 @@ Specifies whether the determined revision ID is printed during the build with hi
Specifies whether the value component of the `AssemblyMetadata` (`AssemblyMetadataAttribute`) is resolved.
+**NrtErrorOnModifiedRepoPattern**: string, default: “”.
+
+Specifies a case-insensitive Regex pattern string matching the build configuration string to trigger a build error if the repository contains modifications. If the string is empty, the functionality is disabled.
+
### Revision format
You can customise the format of the resulting version with a revision format string that defines how information about the commit or revision is formatted into the final revision ID. It is a plain string that contains placeholders in `{curly braces}`. Each placeholder is a simple data field or encodes a time value using a scheme and optional configuration arguments.
From ad5ab2bbe09f478cb9aaffdef995807b45278fc3 Mon Sep 17 00:00:00 2001
From: 0x6d61726b <0x6d61726b@gmail.com>
Date: Sat, 24 Oct 2020 23:28:25 +0200
Subject: [PATCH 5/8] {bconf::][} and {BCONF::][} changed to
support case-insensitive Regex match for ][
---
NetRevisionTask/RevisionFormatter.cs | 4 ++--
README.md | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/NetRevisionTask/RevisionFormatter.cs b/NetRevisionTask/RevisionFormatter.cs
index 5e09a0c..7462297 100644
--- a/NetRevisionTask/RevisionFormatter.cs
+++ b/NetRevisionTask/RevisionFormatter.cs
@@ -154,8 +154,8 @@ public string Resolve(string format)
// Build Configuration
format = format.Replace("{bconf}", ConfigurationName);
format = format.Replace("{BCONF}", ConfigurationName.ToUpperInvariant());
- format = Regex.Replace(format, @"\{bconf:(.*?):(.+?)\}", m => ConfigurationName != m.Groups[2].Value ? m.Groups[1].Value + ConfigurationName : "");
- format = Regex.Replace(format, @"\{BCONF:(.*?):(.+?)\}", m => ConfigurationName != m.Groups[2].Value ? m.Groups[1].Value + ConfigurationName.ToUpperInvariant() : "");
+ format = Regex.Replace(format, @"\{bconf:(.*?):(.+?)\}", m => !Regex.IsMatch(ConfigurationName, $@"^{m.Groups[2].Value}$", RegexOptions.IgnoreCase) ? m.Groups[1].Value + ConfigurationName : "");
+ format = Regex.Replace(format, @"\{BCONF:(.*?):(.+?)\}", m => !Regex.IsMatch(ConfigurationName, $@"^{m.Groups[2].Value}$", RegexOptions.IgnoreCase) ? m.Groups[1].Value + ConfigurationName.ToUpperInvariant() : "");
// Return revision ID
return format;
diff --git a/README.md b/README.md
index 3ffa4f0..a8029e1 100644
--- a/README.md
+++ b/README.md
@@ -112,7 +112,7 @@ Specifies whether the value component of the `AssemblyMetadata` (`AssemblyMetada
**NrtErrorOnModifiedRepoPattern**: string, default: “”.
-Specifies a case-insensitive Regex pattern string matching the build configuration string to trigger a build error if the repository contains modifications. If the string is empty, the functionality is disabled.
+Specifies a case-insensitive RegEx pattern string matching the build configuration string to trigger a build error if the repository contains modifications. If the string is empty, the functionality is disabled.
### Revision format
@@ -180,7 +180,7 @@ The following data field placeholders are supported:
**`{BCONF}`**: Build configuration, in upper case.
-**`{bconf::][}`, `{BCONF::][}`**: Build configuration, if not `][` or empty, separated by ``, otherwise empty.
+**`{bconf::][}`, `{BCONF::][}`**: Build configuration, if not matching case-insensitive RegEx `][` pattern, separated by ``, otherwise empty.
Schemes convert a commit or build time to a compact string representation. They can be used to assign incrementing versions if no revision number is provided by the VCS. First, select from the build, commit or authoring time with `{b:…}`, `{c:…}` or `{a:…}`. This is followed by the scheme name. There are 4 types of schemes.
From 56485af6aa71506574e6ecf6e77b6fa8129bd62a Mon Sep 17 00:00:00 2001
From: 0x6d61726b <0x6d61726b@gmail.com>
Date: Thu, 12 Nov 2020 20:36:36 +0100
Subject: [PATCH 6/8] Apply default revision 'v0.0.0.0' when repository is not
yet tagged to avoid error message "Revision ID cannot be truncated to
dotted-numeric"
---
NetRevisionTask/NetRevisionTask.csproj | 2 +-
NetRevisionTask/RevisionFormatter.cs | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/NetRevisionTask/NetRevisionTask.csproj b/NetRevisionTask/NetRevisionTask.csproj
index 794a064..951e9b4 100644
--- a/NetRevisionTask/NetRevisionTask.csproj
+++ b/NetRevisionTask/NetRevisionTask.csproj
@@ -8,7 +8,7 @@
tasks
- 0.4
+ 0.4.1
true
diff --git a/NetRevisionTask/RevisionFormatter.cs b/NetRevisionTask/RevisionFormatter.cs
index 7462297..f223ecc 100644
--- a/NetRevisionTask/RevisionFormatter.cs
+++ b/NetRevisionTask/RevisionFormatter.cs
@@ -111,6 +111,11 @@ public string Resolve(string format)
}
string tagName = RevisionData.Tag;
+ if (string.IsNullOrEmpty(tagName))
+ {
+ // default value when no tag exists in repository
+ tagName = "v0.0.0.0";
+ }
if (RemoveTagV && Regex.IsMatch(tagName, "^v[0-9]"))
{
tagName = tagName.Substring(1);
From 297564bf6f20af5518431994c3208ce4f7e3f774 Mon Sep 17 00:00:00 2001
From: 0x6d61726b <0x6d61726b@gmail.com>
Date: Sat, 19 Dec 2020 22:36:04 +0100
Subject: [PATCH 7/8] Fixed ArgumentNullException on ConfigurationName
---
NetRevisionTask/NetRevisionTask.csproj | 2 +-
NetRevisionTask/RevisionFormatter.cs | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/NetRevisionTask/NetRevisionTask.csproj b/NetRevisionTask/NetRevisionTask.csproj
index 951e9b4..9ba0bbe 100644
--- a/NetRevisionTask/NetRevisionTask.csproj
+++ b/NetRevisionTask/NetRevisionTask.csproj
@@ -8,7 +8,7 @@
tasks
- 0.4.1
+ 0.4.2
true
diff --git a/NetRevisionTask/RevisionFormatter.cs b/NetRevisionTask/RevisionFormatter.cs
index f223ecc..e7d4ee9 100644
--- a/NetRevisionTask/RevisionFormatter.cs
+++ b/NetRevisionTask/RevisionFormatter.cs
@@ -157,6 +157,10 @@ public string Resolve(string format)
format = Regex.Replace(format, @"\{copyright:([0-9]+?)-?\}", m => (m.Groups[1].Value != copyright ? m.Groups[1].Value + "–" : "") + copyright);
// Build Configuration
+ if (ConfigurationName == null)
+ {
+ ConfigurationName = string.Empty;
+ }
format = format.Replace("{bconf}", ConfigurationName);
format = format.Replace("{BCONF}", ConfigurationName.ToUpperInvariant());
format = Regex.Replace(format, @"\{bconf:(.*?):(.+?)\}", m => !Regex.IsMatch(ConfigurationName, $@"^{m.Groups[2].Value}$", RegexOptions.IgnoreCase) ? m.Groups[1].Value + ConfigurationName : "");
From 885c758e56a9201f7aa0211cd443d82dce3e07ec Mon Sep 17 00:00:00 2001
From: 0x6d61726b <0x6d61726b@gmail.com>
Date: Sat, 19 Dec 2020 22:39:12 +0100
Subject: [PATCH 8/8] Fixed whitespace/tab intents
---
NetRevisionTask/RevisionFormatter.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/NetRevisionTask/RevisionFormatter.cs b/NetRevisionTask/RevisionFormatter.cs
index e7d4ee9..c72d0d1 100644
--- a/NetRevisionTask/RevisionFormatter.cs
+++ b/NetRevisionTask/RevisionFormatter.cs
@@ -158,7 +158,7 @@ public string Resolve(string format)
// Build Configuration
if (ConfigurationName == null)
- {
+ {
ConfigurationName = string.Empty;
}
format = format.Replace("{bconf}", ConfigurationName);
]