diff --git a/Src/CSharpier.Cli/CommandLineFormatter.cs b/Src/CSharpier.Cli/CommandLineFormatter.cs
index d2b22e8ad..0fca3208e 100644
--- a/Src/CSharpier.Cli/CommandLineFormatter.cs
+++ b/Src/CSharpier.Cli/CommandLineFormatter.cs
@@ -1,7 +1,9 @@
using System;
using System.Diagnostics;
using System.IO.Abstractions;
-using System.Linq;
+using System.Reflection;
+using System.Xml.Linq;
+using System.Xml.XPath;
using CSharpier.Utilities;
using Microsoft.Extensions.Logging;
@@ -94,6 +96,17 @@ await FormatPhysicalFile(
}
else if (fileSystem.Directory.Exists(directoryOrFile))
{
+ if (
+ HasMismatchedCliAndMsBuildVersions.Check(
+ directoryOrFile,
+ fileSystem,
+ logger
+ )
+ )
+ {
+ return 1;
+ }
+
var tasks = fileSystem.Directory
.EnumerateFiles(directoryOrFile, "*.cs", SearchOption.AllDirectories)
.Select(FormatFile)
diff --git a/Src/CSharpier.Cli/HasMismatchedCliAndMsBuildVersions.cs b/Src/CSharpier.Cli/HasMismatchedCliAndMsBuildVersions.cs
new file mode 100644
index 000000000..f0bd277e2
--- /dev/null
+++ b/Src/CSharpier.Cli/HasMismatchedCliAndMsBuildVersions.cs
@@ -0,0 +1,55 @@
+using System.IO.Abstractions;
+using System.Xml.Linq;
+using System.Xml.XPath;
+using Microsoft.Extensions.Logging;
+
+namespace CSharpier.Cli;
+
+public static class HasMismatchedCliAndMsBuildVersions
+{
+ public static bool Check(string directory, IFileSystem fileSystem, ILogger logger)
+ {
+ var csProjPaths = fileSystem.Directory
+ .EnumerateFiles(directory, "*.csproj", SearchOption.AllDirectories)
+ .ToArray();
+
+ var versionOfDotnetTool = typeof(CommandLineFormatter).Assembly.GetName().Version!.ToString(
+ 3
+ );
+
+ foreach (var pathToCsProj in csProjPaths)
+ {
+ // this could potentially use the Microsoft.CodeAnalysis.Project class, but that was
+ // proving difficult to use
+ var csProjXElement = XElement.Load(fileSystem.File.OpenRead(pathToCsProj));
+ var csharpierMsBuildElement = csProjXElement
+ .XPathSelectElements("//PackageReference[@Include='CSharpier.MsBuild']")
+ .FirstOrDefault();
+ if (csharpierMsBuildElement == null)
+ {
+ continue;
+ }
+
+ var versionOfMsBuildPackage = csharpierMsBuildElement.Attribute("Version")?.Value;
+ if (versionOfMsBuildPackage == null)
+ {
+ logger.LogError(
+ $"The csproj at {pathToCsProj} uses an unknown version of CSharpier.MsBuild"
+ + $" which is a mismatch with version {versionOfDotnetTool}"
+ );
+ return true;
+ }
+
+ if (versionOfDotnetTool != versionOfMsBuildPackage)
+ {
+ logger.LogError(
+ $"The csproj at {pathToCsProj} uses version {versionOfMsBuildPackage} of CSharpier.MsBuild"
+ + $" which is a mismatch with version {versionOfDotnetTool}"
+ );
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/Src/CSharpier.Tests/CommandLineFormatterTests.cs b/Src/CSharpier.Tests/CommandLineFormatterTests.cs
index 5fdfa3833..937066116 100644
--- a/Src/CSharpier.Tests/CommandLineFormatterTests.cs
+++ b/Src/CSharpier.Tests/CommandLineFormatterTests.cs
@@ -75,6 +75,91 @@ public void Format_Writes_File_With_Directory_Path()
this.GetFileContent(unformattedFilePath).Should().Be(FormattedClassContent);
}
+ [TestCase("0.9.0", false)]
+ [TestCase("9999.0.0", false)]
+ [TestCase("current", true)]
+ public void Works_With_MSBuild_Version_Checking(string version, bool shouldPass)
+ {
+ var currentVersion = typeof(CommandLineFormatter).Assembly.GetName().Version!.ToString(3);
+
+ var versionToTest = version == "current" ? currentVersion : version;
+
+ WhenAFileExists(
+ "Test.csproj",
+ $@"
+
+
+
+
+"
+ );
+
+ var result = this.Format();
+
+ if (shouldPass)
+ {
+ result.ExitCode.Should().Be(0);
+ result.ErrorLines.Should().BeEmpty();
+ }
+ else
+ {
+ result.ExitCode.Should().Be(1);
+ result.ErrorLines
+ .First()
+ .Should()
+ .EndWith(
+ $@"Test.csproj uses version {version} of CSharpier.MsBuild which is a mismatch with version {currentVersion}"
+ );
+ }
+ }
+
+ [Test]
+ public void Works_With_MSBuild_Version_Checking_When_No_Version_Specified()
+ {
+ var currentVersion = typeof(CommandLineFormatter).Assembly.GetName().Version!.ToString(3);
+
+ WhenAFileExists(
+ "Test.csproj",
+ $@"
+
+
+
+
+"
+ );
+
+ var result = this.Format();
+
+ result.ExitCode.Should().Be(1);
+ result.ErrorLines
+ .First()
+ .Should()
+ .EndWith(
+ $"Test.csproj uses an unknown version of CSharpier.MsBuild which is a mismatch with version {currentVersion}"
+ );
+ }
+
+ [Test]
+ public void Works_With_MSBuild_Version_Checking_When_No_Version_Included()
+ {
+ var currentVersion = typeof(CommandLineFormatter).Assembly.GetName().Version!.ToString(3);
+
+ WhenAFileExists(
+ "Test.csproj",
+ $@"
+
+
+
+
+"
+ );
+
+ var result = this.Format();
+
+ result.ExitCode.Should().Be(0);
+ result.ErrorLines.Should().BeEmpty();
+ }
+
[Test]
public void Format_Writes_File_With_File_Path()
{
@@ -357,6 +442,7 @@ public void Empty_Config_Files_Should_Log_Warning(string configFileName)
result.Lines
.First()
+ .Replace("\\", "/")
.Should()
.Be($"Warning The configuration file at {configPath} was empty.");
}