/
PackagesLockFileBuilder.cs
130 lines (106 loc) · 5.94 KB
/
PackagesLockFileBuilder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NuGet.Common;
using NuGet.LibraryModel;
using NuGet.Packaging.Core;
using NuGet.ProjectModel;
using NuGet.Shared;
namespace NuGet.Commands
{
public class PackagesLockFileBuilder
{
public PackagesLockFile CreateNuGetLockFile(LockFile assetsFile)
{
var lockFile = new PackagesLockFile(GetPackagesLockFileVersion(assetsFile));
var libraryLookup = assetsFile.Libraries.Where(e => e.Type == LibraryType.Package)
.ToDictionary(e => new PackageIdentity(e.Name, e.Version));
foreach (var target in assetsFile.Targets)
{
var nuGettarget = new PackagesLockFileTarget()
{
TargetFramework = target.TargetFramework,
RuntimeIdentifier = target.RuntimeIdentifier
};
var framework = assetsFile.PackageSpec.TargetFrameworks.FirstOrDefault(
f => EqualityUtility.EqualsWithNullCheck(f.FrameworkName, target.TargetFramework));
IEnumerable<LockFileTargetLibrary> libraries = target.Libraries;
// check if this is RID-based graph then only add those libraries which differ from original TFM.
if (!string.IsNullOrEmpty(target.RuntimeIdentifier))
{
var onlyTFM = assetsFile.Targets.First(t => EqualityUtility.EqualsWithNullCheck(t.TargetFramework, target.TargetFramework));
libraries = target.Libraries.Where(lib => !onlyTFM.Libraries.Any(tfmLib => tfmLib.Equals(lib)));
}
foreach (var library in libraries.Where(e => e.Type == LibraryType.Package))
{
var identity = new PackageIdentity(library.Name, library.Version);
var dependency = new LockFileDependency()
{
Id = library.Name,
ResolvedVersion = library.Version,
ContentHash = libraryLookup[identity].Sha512,
Dependencies = library.Dependencies
};
var framework_dep = framework?.Dependencies.FirstOrDefault(
dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Name, library.Name));
CentralPackageVersion centralPackageVersion = null;
framework?.CentralPackageVersions.TryGetValue(library.Name, out centralPackageVersion);
if (framework_dep != null)
{
dependency.Type = PackageDependencyType.Direct;
dependency.RequestedVersion = framework_dep.LibraryRange.VersionRange;
}
// The dgspec has a list of the direct dependencies and changes in the direct dependencies will invalidate the lock file
// A dgspec does not have information about transitive dependencies
// At the restore time the transitive dependencies could be pinned from central package version management file
// By marking them will allow to evaluate when to invalidate the packages.lock.json
// in cases that a central transitive version is updated, removed or added the lock file will be invalidated
else if (centralPackageVersion != null)
{
// This is a transitive dependency that is in the list of central dependencies.
dependency.Type = PackageDependencyType.CentralTransitive;
dependency.RequestedVersion = centralPackageVersion.VersionRange;
}
else
{
dependency.Type = PackageDependencyType.Transitive;
}
nuGettarget.Dependencies.Add(dependency);
}
var projectFullPaths = assetsFile.Libraries
.Where(l => l.Type == LibraryType.Project || l.Type == LibraryType.ExternalProject)
.ToDictionary(l => new PackageIdentity(l.Name, l.Version), l => l.MSBuildProject);
foreach (var projectReference in libraries.Where(e => e.Type == LibraryType.Project || e.Type == LibraryType.ExternalProject))
{
var projectIdentity = new PackageIdentity(projectReference.Name, projectReference.Version);
var projectFullPath = projectFullPaths[projectIdentity];
var id = PathUtility.GetStringComparerBasedOnOS().Equals(Path.GetFileNameWithoutExtension(projectFullPath), projectReference.Name)
? projectReference.Name.ToLowerInvariant()
: projectReference.Name;
var dependency = new LockFileDependency()
{
Id = id,
Dependencies = projectReference.Dependencies,
Type = PackageDependencyType.Project
};
nuGettarget.Dependencies.Add(dependency);
}
nuGettarget.Dependencies = nuGettarget.Dependencies.OrderBy(d => d.Type).ToList();
lockFile.Targets.Add(nuGettarget);
}
return lockFile;
}
private int GetPackagesLockFileVersion(LockFile assetsFile)
{
// Increase the version only for the projects opted-in central version management
if (assetsFile.PackageSpec.RestoreMetadata.CentralPackageVersionsEnabled)
{
return PackagesLockFileFormat.PackagesLockFileVersion;
}
return PackagesLockFileFormat.Version;
}
}
}