diff --git a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs
index d9a98a5bc..01d4f9e0c 100644
--- a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs
+++ b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs
@@ -183,9 +183,12 @@ namespace NuGet.ProjectModel
Targets = ReadObject(cursor[TargetsProperty] as JObject, ReadTarget),
ProjectFileDependencyGroups = ReadObject(cursor[ProjectFileDependencyGroupsProperty] as JObject, ReadProjectFileDependencyGroup),
PackageFolders = ReadObject(cursor[PackageFoldersProperty] as JObject, ReadFileItem),
- PackageSpec = ReadPackageSpec(cursor[PackageSpecProperty] as JObject),
- LogMessages = ReadArray(cursor[LogsProperty] as JArray, ReadLogMessage)
+ PackageSpec = ReadPackageSpec(cursor[PackageSpecProperty] as JObject)
};
+
+ lockFile.LogMessages = ReadLogMessageArray(cursor[LogsProperty] as JArray,
+ lockFile?.PackageSpec?.RestoreMetadata?.ProjectPath);
+
return lockFile;
}
@@ -218,7 +221,8 @@ namespace NuGet.ProjectModel
{
if(lockFile.LogMessages.Count > 0)
{
- json[LogsProperty] = WriteLogMessages(lockFile.LogMessages);
+ var projectPath = lockFile.PackageSpec?.RestoreMetadata?.ProjectPath;
+ json[LogsProperty] = WriteLogMessages(lockFile.LogMessages, projectPath);
}
}
@@ -309,7 +313,7 @@ namespace NuGet.ProjectModel
///
/// IAssetsLogMessage representing the log message.
/// JObject containg the json representation of the log message.
- private static JObject WriteLogMessage(IAssetsLogMessage logMessage)
+ private static JObject WriteLogMessage(IAssetsLogMessage logMessage, string projectPath)
{
var logJObject = new JObject()
{
@@ -322,8 +326,11 @@ namespace NuGet.ProjectModel
logJObject[LogMessageProperties.WARNING_LEVEL] = logMessage.WarningLevel.ToString();
}
- if (logMessage.FilePath != null)
+ if (logMessage.FilePath != null &&
+ (projectPath == null || !PathUtility.GetStringComparerBasedOnOS().Equals(logMessage.FilePath, projectPath)))
{
+ // Do not write the file path if it is the same as the project path.
+ // This prevents duplicate information in the lock file.
logJObject[LogMessageProperties.FILE_PATH] = logMessage.FilePath;
}
@@ -372,7 +379,7 @@ namespace NuGet.ProjectModel
///
/// JObject containg the json representation of the log message.
/// IAssetsLogMessage representing the log message.
- private static IAssetsLogMessage ReadLogMessage(JObject json)
+ private static IAssetsLogMessage ReadLogMessage(JObject json, string projectPath)
{
AssetsLogMessage assetsLogMessage = null;
@@ -412,6 +419,10 @@ namespace NuGet.ProjectModel
{
assetsLogMessage.FilePath = filePathJson.Value();
}
+ else
+ {
+ assetsLogMessage.FilePath = projectPath;
+ }
if (startLineNumberJson != null)
{
@@ -443,17 +454,12 @@ namespace NuGet.ProjectModel
return assetsLogMessage;
}
- private static IAssetsLogMessage ReadLogMessage(JToken json)
- {
- return ReadLogMessage(json as JObject);
- }
-
- private static JArray WriteLogMessages(IEnumerable logMessages)
+ private static JArray WriteLogMessages(IEnumerable logMessages, string projectPath)
{
var logMessageArray = new JArray();
foreach(var logMessage in logMessages)
{
- logMessageArray.Add(WriteLogMessage(logMessage));
+ logMessageArray.Add(WriteLogMessage(logMessage, projectPath));
}
return logMessageArray;
}
@@ -696,6 +702,25 @@ namespace NuGet.ProjectModel
return items;
}
+ private static IList ReadLogMessageArray(JArray json, string projectPath)
+ {
+ if (json == null)
+ {
+ return new List();
+ }
+
+ var items = new List();
+ foreach (var child in json)
+ {
+ var logMessage = ReadLogMessage(child as JObject, projectPath);
+ if (logMessage != null)
+ {
+ items.Add(logMessage);
+ }
+ }
+ return items;
+ }
+
private static IList ReadPathArray(JArray json, Func readItem)
{
return ReadArray(json, readItem).Select(f => GetPathWithForwardSlashes(f)).ToList();
diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs
index 692085705..0967a8932 100644
--- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs
+++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs
@@ -800,6 +800,134 @@ namespace NuGet.ProjectModel.Test
Assert.Equal(expected, output);
}
+ [Fact]
+ public void LockFileFormat_WritesErrorMessageWithFilePathSameAsProjectPath()
+ {
+
+ // Arrange
+ var lockFileContent = @"{
+ ""version"": 3,
+ ""targets"": {
+ "".NETPlatform,Version=v5.0"": {
+ ""System.Runtime/4.0.20-beta-22927"": {
+ ""type"": ""package"",
+ ""dependencies"": {
+ ""Frob"": ""4.0.20""
+ },
+ ""compile"": {
+ ""ref/dotnet/System.Runtime.dll"": {}
+ }
+ }
+ }
+ },
+ ""libraries"": {
+ ""System.Runtime/4.0.20-beta-22927"": {
+ ""sha512"": ""sup3rs3cur3"",
+ ""type"": ""package"",
+ ""files"": [
+ ""System.Runtime.nuspec""
+ ]
+ }
+ },
+ ""projectFileDependencyGroups"": {
+ """": [
+ ""System.Runtime [4.0.10-beta-*, )""
+ ],
+ "".NETPlatform,Version=v5.0"": []
+ },
+ ""project"": {
+ ""restore"": {
+ ""projectPath"": ""kung\\fu\\fighting.csproj""
+ }
+ },
+ ""logs"": [
+ {
+ ""code"": ""NU1000"",
+ ""level"": ""Error"",
+ ""startLineNumber"": 11,
+ ""startColumnNumber"": 2,
+ ""endLineNumber"": 11,
+ ""endColumnNumber"": 10,
+ ""message"": ""test log message"",
+ ""libraryId"": ""nuget.versioning"",
+ ""targetGraphs"": [
+ ""net46"",
+ ""netcoreapp1.0"",
+ ""netstandard1.6""
+ ]
+ }
+ ]
+}";
+ var lockFile = new LockFile()
+ {
+ Version = 3
+ };
+
+ var target = new LockFileTarget()
+ {
+ TargetFramework = FrameworkConstants.CommonFrameworks.DotNet
+ };
+
+ var targetLib = new LockFileTargetLibrary()
+ {
+ Name = "System.Runtime",
+ Version = NuGetVersion.Parse("4.0.20-beta-22927"),
+ Type = LibraryType.Package
+ };
+
+ targetLib.Dependencies.Add(new Packaging.Core.PackageDependency("Frob",
+ new VersionRange(NuGetVersion.Parse("4.0.20"))));
+ targetLib.CompileTimeAssemblies.Add(new LockFileItem("ref/dotnet/System.Runtime.dll"));
+ target.Libraries.Add(targetLib);
+ lockFile.Targets.Add(target);
+
+ var lib = new LockFileLibrary()
+ {
+ Name = "System.Runtime",
+ Version = NuGetVersion.Parse("4.0.20-beta-22927"),
+ Type = LibraryType.Package,
+ Sha512 = "sup3rs3cur3"
+ };
+ lib.Files.Add("System.Runtime.nuspec");
+ lockFile.Libraries.Add(lib);
+
+ lockFile.ProjectFileDependencyGroups.Add(
+ new ProjectFileDependencyGroup("", new string[] { "System.Runtime [4.0.10-beta-*, )" }));
+ lockFile.ProjectFileDependencyGroups.Add(
+ new ProjectFileDependencyGroup(FrameworkConstants.CommonFrameworks.DotNet.DotNetFrameworkName, new string[0]));
+
+ lockFile.PackageSpec = new PackageSpec(new List())
+ {
+ RestoreMetadata = new ProjectRestoreMetadata()
+ {
+ ProjectPath = "kung\\fu\\fighting.csproj"
+ }
+ };
+
+ lockFile.LogMessages = new List
+ {
+ new AssetsLogMessage(LogLevel.Error, NuGetLogCode.NU1000, "test log message")
+ {
+ FilePath = @"kung\fu\fighting.csproj",
+ ProjectPath = @"kung\fu\fighting.csproj",
+ TargetGraphs = new List{ "net46", "netcoreapp1.0", "netstandard1.6" },
+ StartLineNumber = 11,
+ StartColumnNumber = 2,
+ EndLineNumber = 11,
+ EndColumnNumber = 10,
+ LibraryId = "nuget.versioning"
+ }
+ };
+
+ // Act
+ var lockFileFormat = new LockFileFormat();
+ var output = JObject.Parse(lockFileFormat.Render(lockFile)).ToString();
+ var expected = JObject.Parse(lockFileContent).ToString();
+
+ // Assert
+ Assert.Equal(expected, output);
+ }
+
[Fact]
public void LockFileFormat_ReadsMinimalErrorMessage()
{
@@ -957,6 +1085,7 @@ namespace NuGet.ProjectModel.Test
[Fact]
public void LockFileFormat_ReadsWarningMessage()
{
+
// Arrange
var lockFileContent = @"{
""version"": 3,
@@ -1128,5 +1257,161 @@ namespace NuGet.ProjectModel.Test
Assert.Equal(1, lockFileObj.LogMessages.Where(m => m.Code == NuGetLogCode.NU1001).Count());
}
+ [Fact]
+ public void LockFileFormat_ReadsLogMessageWithSameFilePathAndProjectPath()
+ {
+ // Arrange
+ var lockFileContent = @"{
+ ""version"": 3,
+ ""targets"": {
+ "".NETPlatform,Version=v5.0"": {
+ ""System.Runtime/4.0.20-beta-22927"": {
+ ""type"": ""package"",
+ ""dependencies"": {
+ ""Frob"": ""4.0.20""
+ },
+ ""compile"": {
+ ""ref/dotnet/System.Runtime.dll"": {}
+ }
+ }
+ }
+ },
+ ""libraries"": {
+ ""System.Runtime/4.0.20-beta-22927"": {
+ ""sha512"": ""sup3rs3cur3"",
+ ""type"": ""package"",
+ ""files"": [
+ ""System.Runtime.nuspec""
+ ]
+ }
+ },
+ ""projectFileDependencyGroups"": {
+ """": [
+ ""System.Runtime [4.0.10-beta-*, )""
+ ],
+ "".NETPlatform,Version=v5.0"": []
+ },
+ ""project"": {
+ ""restore"": {
+ ""projectPath"": ""kung\\fu\\fighting.csproj""
+ }
+ },
+ ""logs"": [
+ {
+ ""code"": ""NU1000"",
+ ""level"": ""Error"",
+ ""message"": ""test log message"",
+ ""filePath"": ""kung\\fu\\fighting.csproj""
+ }
+ ]
+}";
+ LockFile lockFileObj = null;
+ IAssetsLogMessage logMessage = null;
+ using (var lockFile = new TempFile())
+ {
+
+ File.WriteAllText(lockFile, lockFileContent);
+
+ // Act
+ var reader = new LockFileFormat();
+ lockFileObj = reader.Read(lockFile);
+ logMessage = lockFileObj?.LogMessages?.First();
+ }
+
+
+ // Assert
+ Assert.NotNull(lockFileObj);
+ Assert.NotNull(logMessage);
+ Assert.Equal(1, lockFileObj.LogMessages.Count());
+ Assert.Equal(LogLevel.Error, logMessage.Level);
+ Assert.Equal(NuGetLogCode.NU1000, logMessage.Code);
+ Assert.NotNull(logMessage.FilePath);
+ Assert.Equal("kung\\fu\\fighting.csproj", logMessage.FilePath);
+ Assert.Equal(-1, logMessage.StartLineNumber);
+ Assert.Equal(-1, logMessage.EndLineNumber);
+ Assert.Equal(-1, logMessage.StartColumnNumber);
+ Assert.Equal(-1, logMessage.EndColumnNumber);
+ Assert.NotNull(logMessage.TargetGraphs);
+ Assert.Equal(0, logMessage.TargetGraphs.Count);
+ Assert.Equal("test log message", logMessage.Message);
+ }
+
+ [Fact]
+ public void LockFileFormat_ReadsLogMessageWithNoFilePath()
+ {
+ // Arrange
+ var lockFileContent = @"{
+ ""version"": 3,
+ ""targets"": {
+ "".NETPlatform,Version=v5.0"": {
+ ""System.Runtime/4.0.20-beta-22927"": {
+ ""type"": ""package"",
+ ""dependencies"": {
+ ""Frob"": ""4.0.20""
+ },
+ ""compile"": {
+ ""ref/dotnet/System.Runtime.dll"": {}
+ }
+ }
+ }
+ },
+ ""libraries"": {
+ ""System.Runtime/4.0.20-beta-22927"": {
+ ""sha512"": ""sup3rs3cur3"",
+ ""type"": ""package"",
+ ""files"": [
+ ""System.Runtime.nuspec""
+ ]
+ }
+ },
+ ""projectFileDependencyGroups"": {
+ """": [
+ ""System.Runtime [4.0.10-beta-*, )""
+ ],
+ "".NETPlatform,Version=v5.0"": []
+ },
+ ""project"": {
+ ""restore"": {
+ ""projectPath"": ""kung\\fu\\fighting.csproj""
+ }
+ },
+ ""logs"": [
+ {
+ ""code"": ""NU1000"",
+ ""level"": ""Error"",
+ ""message"": ""test log message""
+ }
+ ]
+}";
+ LockFile lockFileObj = null;
+ IAssetsLogMessage logMessage = null;
+ using (var lockFile = new TempFile())
+ {
+
+ File.WriteAllText(lockFile, lockFileContent);
+
+ // Act
+ var reader = new LockFileFormat();
+ lockFileObj = reader.Read(lockFile);
+ logMessage = lockFileObj?.LogMessages?.First();
+ }
+
+
+ // Assert
+ Assert.NotNull(lockFileObj);
+ Assert.NotNull(logMessage);
+ Assert.Equal(1, lockFileObj.LogMessages.Count());
+ Assert.Equal(LogLevel.Error, logMessage.Level);
+ Assert.Equal(NuGetLogCode.NU1000, logMessage.Code);
+ Assert.NotNull(logMessage.FilePath);
+ Assert.Equal("kung\\fu\\fighting.csproj", logMessage.FilePath);
+ Assert.Equal(-1, logMessage.StartLineNumber);
+ Assert.Equal(-1, logMessage.EndLineNumber);
+ Assert.Equal(-1, logMessage.StartColumnNumber);
+ Assert.Equal(-1, logMessage.EndColumnNumber);
+ Assert.NotNull(logMessage.TargetGraphs);
+ Assert.Equal(0, logMessage.TargetGraphs.Count);
+ Assert.Equal("test log message", logMessage.Message);
+ }
}
}