-
Notifications
You must be signed in to change notification settings - Fork 692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Repeatable build using Project lock file implementation #2342
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -363,7 +363,11 @@ private async Task<PackageSpec> GetPackageSpecAsync(ISettings settings) | |
ProjectWideWarningProperties = WarningProperties.GetWarningProperties( | ||
treatWarningsAsErrors: _vsProjectAdapter.TreatWarningsAsErrors, | ||
noWarn: _vsProjectAdapter.NoWarn, | ||
warningsAsErrors: _vsProjectAdapter.WarningsAsErrors) | ||
warningsAsErrors: _vsProjectAdapter.WarningsAsErrors), | ||
RestoreLockProperties = new RestoreLockProperties( | ||
await _vsProjectAdapter.GetRestorePackagesWithLockFileAsync(), | ||
await _vsProjectAdapter.GetNuGetLockFilePathAsync(), | ||
await _vsProjectAdapter.IsRestoreLockedAsync()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might be repeating the same conversation that we've had before, but do we really want this? What's the precedence order if you use a reevaluate switch from the UI? I'm not arguing for or against yet, I'm just trying to understand the behavior. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is This flag is mentioned in the spec with explanation. If you think this is not clear then may be we can ask Anand to make it more clear. - https://github.com/NuGet/Home/wiki/Enable-repeatable-package-restore-using-lock-file |
||
} | ||
}; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -119,7 +119,8 @@ Copyright (c) .NET Foundation. All rights reserved. | |
RestoreRecursive="$(RestoreRecursive)" | ||
RestoreForce="$(RestoreForce)" | ||
HideWarningsAndErrors="$(HideWarningsAndErrors)" | ||
Interactive="$(NuGetInteractive)"/> | ||
Interactive="$(NuGetInteractive)" | ||
ReevaluateRestoreGraph="$(ReevaluateRestoreGraph)"/> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spec: This is not documented anywhere in the specs. This is the reevaluate lock file, hose everything (well almost) right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the implementation part of And yes, it just skip existing lock file and re-evaluate all the dependencies. |
||
</Target> | ||
|
||
<!-- | ||
|
@@ -657,6 +658,9 @@ Copyright (c) .NET Foundation. All rights reserved. | |
<TreatWarningsAsErrors>$(TreatWarningsAsErrors)</TreatWarningsAsErrors> | ||
<WarningsAsErrors>$(WarningsAsErrors)</WarningsAsErrors> | ||
<NoWarn>$(NoWarn)</NoWarn> | ||
<RestorePackagesWithLockFile>$(RestorePackagesWithLockFile)</RestorePackagesWithLockFile> | ||
<NuGetLockFilePath>$(NuGetLockFilePath)</NuGetLockFilePath> | ||
<RestoreLockedMode>$(RestoreLockedMode)</RestoreLockedMode> | ||
</_RestoreGraphEntry> | ||
</ItemGroup> | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// 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.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(); | ||
|
||
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)); | ||
|
||
var 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))).ToList(); | ||
} | ||
|
||
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, | ||
Sha512 = libraryLookup[identity].Sha512, | ||
Dependencies = library.Dependencies | ||
}; | ||
|
||
var framework_dep = framework?.Dependencies.FirstOrDefault( | ||
dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Name, library.Name)); | ||
|
||
if (framework_dep != null) | ||
{ | ||
dependency.Type = PackageDependencyType.Direct; | ||
dependency.RequestedVersion = framework_dep.LibraryRange.VersionRange; | ||
} | ||
else | ||
{ | ||
dependency.Type = PackageDependencyType.Transitive; | ||
} | ||
|
||
nuGettarget.Dependencies.Add(dependency); | ||
} | ||
|
||
foreach (var projectReference in libraries.Where(e => e.Type == LibraryType.Project || e.Type == LibraryType.ExternalProject)) | ||
{ | ||
var dependency = new LockFileDependency() | ||
{ | ||
Id = projectReference.Name, | ||
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; | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -154,8 +154,7 @@ private RestoreSummaryRequest Create( | |
// Project.json is special cased to put assets file and generated .props and targets in the project folder | ||
RestoreOutputPath = project.PackageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson ? rootPath : project.PackageSpec.RestoreMetadata.OutputPath, | ||
DependencyGraphSpec = projectDgSpec, | ||
MSBuildProjectExtensionsPath = projectPackageSpec.RestoreMetadata.OutputPath, | ||
ParentId = restoreArgs.ParentId | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is the ParentId removed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is being done through |
||
MSBuildProjectExtensionsPath = projectPackageSpec.RestoreMetadata.OutputPath | ||
}; | ||
|
||
var restoreLegacyPackagesDirectory = project.PackageSpec?.RestoreMetadata?.LegacyPackagesDirectory | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you going to change these as well to align with the eventual NuGetLockFile name change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, these are fine since the MSBuild property name itself is
NuGetLockFilePath