diff options
Diffstat (limited to 'src/Microsoft.NuGet.Build.Tasks/ResolveNuGetPackageAssets.cs')
-rw-r--r-- | src/Microsoft.NuGet.Build.Tasks/ResolveNuGetPackageAssets.cs | 80 |
1 files changed, 62 insertions, 18 deletions
diff --git a/src/Microsoft.NuGet.Build.Tasks/ResolveNuGetPackageAssets.cs b/src/Microsoft.NuGet.Build.Tasks/ResolveNuGetPackageAssets.cs index 3e12fb0..f4a7f17 100644 --- a/src/Microsoft.NuGet.Build.Tasks/ResolveNuGetPackageAssets.cs +++ b/src/Microsoft.NuGet.Build.Tasks/ResolveNuGetPackageAssets.cs @@ -369,7 +369,7 @@ namespace Microsoft.NuGet.Build.Tasks if (Path.GetExtension(file).Equals(".dll", StringComparison.OrdinalIgnoreCase)) { string path; - if (TryGetFile(package.Id, package.Version, file, out path)) + if (TryGetFile(package.Id, package.Version, package.RelativePackagePath, file, out path)) { var analyzer = new TaskItem(path); @@ -441,16 +441,16 @@ namespace Microsoft.NuGet.Build.Tasks } } - private bool TryGetFile(string packageName, string packageVersion, string file, out string path) + private bool TryGetFile(string packageName, string packageVersion, string packageRelativePath, string file, out string path) { if (IsFileValid(file, "C#", "VB")) { - path = GetPath(packageName, packageVersion, file); + path = GetPath(packageName, packageVersion, packageRelativePath, file); return true; } else if (IsFileValid(file, "VB", "C#")) { - path = GetPath(packageName, packageVersion, file); + path = GetPath(packageName, packageVersion, packageRelativePath, file); return true; } @@ -469,9 +469,9 @@ namespace Microsoft.NuGet.Build.Tasks !file.Split('/').Any(x => x.Equals(unExpectedLanguage, StringComparison.OrdinalIgnoreCase))); } - private string GetPath(string packageName, string packageVersion, string file) + private string GetPath(string packageName, string packageVersion, string packageRelativePath, string file) { - return Path.Combine(GetNuGetPackagePath(packageName, packageVersion), file.Replace('/', '\\')); + return Path.Combine(GetNuGetPackagePath(packageName, packageVersion, packageRelativePath), file.Replace('/', '\\')); } /// <summary> @@ -854,24 +854,54 @@ namespace Microsoft.NuGet.Build.Tasks } var projectFileDependencyGroups = (JObject)lockFile["projectFileDependencyGroups"]; + var allPackageNames = GetAllPackageNames(lockFile); if (targetMoniker != null) { var targetSpecificDependencies = (JArray)projectFileDependencyGroups[targetMoniker]; if (targetSpecificDependencies != null) { - AddReferencedPackages(targetSpecificDependencies); + AddReferencedPackages(targetSpecificDependencies, allPackageNames); } } var universalDependencies = (JArray)projectFileDependencyGroups[""]; if (universalDependencies != null) { - AddReferencedPackages(universalDependencies); + AddReferencedPackages(universalDependencies, allPackageNames); } } - private void AddReferencedPackages(JArray packageDependencies) + /// <summary> + /// Returns the set of all the package names (not including version numbers) + /// in the "libraries" section of the assets/lock file. Note that this includes + /// only proper packages; projects are specifically excluded. + /// </summary> + private static SortedSet<string> GetAllPackageNames(JObject lockFile) + { + var allPackageNames = new SortedSet<string>(); + var libraries = (JObject)lockFile["libraries"]; + foreach (var library in libraries) + { + var libraryObject = (JObject)library.Value; + string type = (string)libraryObject["type"]; + if (type != null && + type.Equals("project", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + SplitPackageName(library.Key, out string name, out string version); + allPackageNames.Add(name); + } + + return allPackageNames; + } + + /// <summary> + /// Given a set of dependencies, identities the packages and adds their names to <see cref="_referencedPackages"/>. + /// </summary> + private void AddReferencedPackages(JArray packageDependencies, SortedSet<string> allPackageNames) { foreach (var packageDependency in packageDependencies.Select(v => (string)v)) { @@ -881,21 +911,30 @@ namespace Microsoft.NuGet.Build.Tasks ? packageDependency.Substring(0, firstSpace) : packageDependency; - _referencedPackages.Add(new TaskItem(packageName)); + if (allPackageNames.Contains(packageName)) + { + _referencedPackages.Add(new TaskItem(packageName)); + } } } - private string GetNuGetPackagePath(string packageId, string packageVersion) + private string GetNuGetPackagePath(string packageId, string packageVersion, string packageRelativePath) { + string relativePathToUse = String.IsNullOrEmpty(packageRelativePath) + ? Path.Combine(packageId, packageVersion) + : packageRelativePath.Replace('/', Path.DirectorySeparatorChar); + + string hashFileName = $"{packageId.ToLowerInvariant()}.{packageVersion.ToLowerInvariant()}.nupkg.sha512"; + foreach (var packagesFolder in _packageFolders) { - string packagePath = Path.Combine(packagesFolder, packageId, packageVersion); + string packageFullPath = Path.Combine(packagesFolder, relativePathToUse); // The proper way to check if a package is available is to look for the hash file, since that's the last // file written as a part of the restore process. If it's not there, it means something failed part way through. - if (_fileExists(Path.Combine(packagePath, $"{packageId}.{packageVersion}.nupkg.sha512"))) + if (_fileExists(Path.Combine(packageFullPath, hashFileName))) { - return packagePath; + return packageFullPath; } } @@ -906,9 +945,7 @@ namespace Microsoft.NuGet.Build.Tasks { foreach (var package in target) { - var nameParts = package.Key.Split('/'); - var id = nameParts[0]; - var version = nameParts[1]; + SplitPackageName(package.Key, out string id, out string version); var libraryObject = (JObject)lockFile["libraries"][package.Key]; @@ -926,13 +963,20 @@ namespace Microsoft.NuGet.Build.Tasks } else { - fullPackagePathGenerator = () => GetNuGetPackagePath(id, version); + fullPackagePathGenerator = () => GetNuGetPackagePath(id, version, (string)libraryObject["path"]); } yield return new NuGetPackageObject(id, version, fullPackagePathGenerator, (JObject)package.Value, libraryObject); } } + private static void SplitPackageName(string key, out string id, out string version) + { + var nameParts = key.Split('/'); + id = nameParts[0]; + version = nameParts[1]; + } + private string GetAbsolutePathFromProjectRelativePath(string path) { return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Path.GetFullPath(ProjectLockFile)), path)); |