Skip to content
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

Use MSBuildProjectExtensionsPath for RestoreOutputPath #2056

Closed
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,13 @@ private static string[] SplitArgs(string unsplitArguments)
{
if (string.IsNullOrWhiteSpace(unsplitArguments))
{
return new string[0];
return Array.Empty<string>();
}

var ptrToSplitArgs = CommandLineToArgvW(unsplitArguments, out int numberOfArgs);
if (ptrToSplitArgs == IntPtr.Zero)
{
return new string[0];
return Array.Empty<string>();
}

try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public override async Task<string> GetAssetsFilePathAsync()
public override async Task<string> GetCacheFilePathAsync()
{
await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();
return NoOpRestoreUtilities.GetProjectCacheFilePath(cacheRoot: GetBaseIntermediatePath(), projectPath: _projectFullPath);
return NoOpRestoreUtilities.GetProjectCacheFilePath(cacheRoot: GetMSBuildProjectExtensionsPath(), projectPath: _projectFullPath);
}

public override async Task<string> GetAssetsFilePathOrNullAsync()
Expand All @@ -91,7 +91,7 @@ private async Task<string> GetAssetsFilePathAsync(bool shouldThrow)
{
await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();

var baseIntermediatePath = GetBaseIntermediatePath(shouldThrow);
var baseIntermediatePath = GetMSBuildProjectExtensionsPath(shouldThrow);

if (baseIntermediatePath == null)
{
Expand Down Expand Up @@ -164,25 +164,25 @@ public override async Task<bool> UninstallPackageAsync(

#endregion

private string GetBaseIntermediatePath(bool shouldThrow = true)
private string GetMSBuildProjectExtensionsPath(bool shouldThrow = true)
{
ThreadHelper.ThrowIfNotOnUIThread();

var baseIntermediatePath = _vsProjectAdapter.BaseIntermediateOutputPath;
var msbuildProjectExtensionsPath = _vsProjectAdapter.MSBuildProjectExtensionsPath;

if (string.IsNullOrEmpty(baseIntermediatePath))
if (string.IsNullOrEmpty(msbuildProjectExtensionsPath))
{
if (shouldThrow)
{
throw new InvalidDataException(string.Format(
Strings.BaseIntermediateOutputPathNotFound,
Strings.MSBuildProjectExtensionsPathNotFound,
_vsProjectAdapter.ProjectDirectory));
}

return null;
}

return baseIntermediatePath;
return msbuildProjectExtensionsPath;
}

private string GetPackagesPath(ISettings settings)
Expand Down Expand Up @@ -337,7 +337,7 @@ private async Task<PackageSpec> GetPackageSpecAsync(ISettings settings)
RestoreMetadata = new ProjectRestoreMetadata
{
ProjectStyle = ProjectStyle.PackageReference,
OutputPath = GetBaseIntermediatePath(),
OutputPath = GetMSBuildProjectExtensionsPath(),
ProjectPath = _projectFullPath,
ProjectName = projectName,
ProjectUniqueName = _projectFullPath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ internal class VsProjectAdapter : IVsProjectAdapter

#region Properties

public string BaseIntermediateOutputPath
public string MSBuildProjectExtensionsPath
{
get
{
var baseIntermediateOutputPath = BuildProperties.GetPropertyValue(ProjectBuildProperties.BaseIntermediateOutputPath);
var msbuildProjectExtensionsPath = BuildProperties.GetPropertyValue(ProjectBuildProperties.MSBuildProjectExtensionsPath);

if (string.IsNullOrEmpty(baseIntermediateOutputPath))
if (string.IsNullOrEmpty(msbuildProjectExtensionsPath))
{
return null;
}

return Path.Combine(ProjectDirectory, baseIntermediateOutputPath);
return Path.Combine(ProjectDirectory, msbuildProjectExtensionsPath);
}
}

Expand Down Expand Up @@ -278,7 +278,7 @@ public async Task<string[]> GetProjectTypeGuidsAsync()
return new string[] { _projectTypeGuid };
}

return new string[0];
return Array.Empty<string>();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,23 @@ public VsProjectJsonNuGetProject(
ProjectServices = projectServices;
}

protected override async Task<string> GetBaseIntermediatePathAsync()
protected override async Task<string> GetMSBuildProjectExtensionsPathAsync()
{
var baseIntermediatePath = await ProjectServices.BuildProperties.GetPropertyValueAsync(ProjectBuildProperties.BaseIntermediateOutputPath);
var msbuildProjectExtensionsPath = await ProjectServices.BuildProperties.GetPropertyValueAsync(ProjectBuildProperties.MSBuildProjectExtensionsPath);

if (string.IsNullOrEmpty(baseIntermediatePath))
if (string.IsNullOrEmpty(msbuildProjectExtensionsPath))
{
throw new InvalidDataException(string.Format(
Strings.BaseIntermediateOutputPathNotFound,
Strings.MSBuildProjectExtensionsPathNotFound,
MSBuildProjectPath));
}

return UriUtility.GetAbsolutePathFromFile(MSBuildProjectPath, baseIntermediatePath);
return UriUtility.GetAbsolutePathFromFile(MSBuildProjectPath, msbuildProjectExtensionsPath);
}

public override async Task<string> GetCacheFilePathAsync()
{
return NoOpRestoreUtilities.GetProjectCacheFilePath(await GetBaseIntermediatePathAsync(), MSBuildProjectPath);
return NoOpRestoreUtilities.GetProjectCacheFilePath(await GetMSBuildProjectExtensionsPathAsync(), MSBuildProjectPath);
}

protected override async Task UpdateInternalTargetFrameworkAsync()
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@
<data name="ProjectNotLoaded_RestoreFailed" xml:space="preserve">
<value>The operation failed as details for project {0} could not be loaded.</value>
</data>
<data name="BaseIntermediateOutputPathNotFound" xml:space="preserve">
<value>The BaseIntermediateOutputPath MSBuild property could not be found for project '{0}'.</value>
<data name="MSBuildProjectExtensionsPathNotFound" xml:space="preserve">
<value>The MSBuildProjectExtensionsPath MSBuild property could not be found for project '{0}'.</value>
<comment>{0} is the full path to the project.</comment>
</data>
<data name="ProjectCouldNotBeCastedToBuildPropertyStorage" xml:space="preserve">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public interface IVsProjectAdapter
string AssetTargetFallback { get; }

/// <summary>
/// BaseIntermediateOutputPath project property (e.g. c:\projFoo\obj)
/// MSBuildProjectExtensionsPath project property (e.g. c:\projFoo\obj)
/// </summary>
string BaseIntermediateOutputPath { get; }
string MSBuildProjectExtensionsPath { get; }

IProjectBuildProperties BuildProperties { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static string[] GetProjectTypeGuids(IVsHierarchy hierarchy, string defaul
return new[] { defaultType };
}

return new string[0];
return Array.Empty<string>();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public string ActivePackageSource

public string[] GetPackageSources()
{
return new string[0];
return Array.Empty<string>();
}

public string DefaultProject
Expand All @@ -60,7 +60,7 @@ public void SetDefaultProjectIndex(int index)

public string[] GetAvailableProjects()
{
return new string[0];
return Array.Empty<string>();
}

public void SetDefaultRunspace()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>
<PropertyGroup>
<PackageOutputPath Condition=" '$(PackageOutputPath)' == '' ">$(OutputPath)</PackageOutputPath>
<RestoreOutputPath Condition=" '$(RestoreOutputPath)' == '' " >$(BaseIntermediateOutputPath)</RestoreOutputPath>
<RestoreOutputPath Condition=" '$(RestoreOutputPath)' == '' " >$(MSBuildProjectExtensionsPath)</RestoreOutputPath>
</PropertyGroup>

<ConvertToAbsolutePath Paths="$(NuspecOutputPath)">
Expand Down
4 changes: 2 additions & 2 deletions src/NuGet.Core/NuGet.Build.Tasks/GetRestoreSettingsTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public override bool Execute()
// Sources
var currentSources = RestoreSettingsUtils.GetValue(
() => RestoreSourcesOverride?.Select(MSBuildRestoreUtility.FixSourcePath).Select(e => GetGlobalAbsolutePath(e)).ToArray(),
() => MSBuildRestoreUtility.ContainsClearKeyword(RestoreSources) ? new string[0] : null,
() => MSBuildRestoreUtility.ContainsClearKeyword(RestoreSources) ? Array.Empty<string>() : null,
() => RestoreSources?.Select(MSBuildRestoreUtility.FixSourcePath).Select(e => UriUtility.GetAbsolutePathFromFile(ProjectUniqueName, e)).ToArray(),
() => (new PackageSourceProvider(settings)).LoadPackageSources().Where(e => e.IsEnabled).Select(e => e.Source).ToArray());

Expand All @@ -148,7 +148,7 @@ public override bool Execute()
// Fallback folders
var currentFallbackFolders = RestoreSettingsUtils.GetValue(
() => RestoreFallbackFoldersOverride?.Select(e => GetGlobalAbsolutePath(e)).ToArray(),
() => MSBuildRestoreUtility.ContainsClearKeyword(RestoreFallbackFolders) ? new string[0] : null,
() => MSBuildRestoreUtility.ContainsClearKeyword(RestoreFallbackFolders) ? Array.Empty<string>() : null,
() => RestoreFallbackFolders?.Select(e => UriUtility.GetAbsolutePathFromFile(ProjectUniqueName, e)).ToArray(),
() => SettingsUtility.GetFallbackPackageFolders(settings).ToArray());

Expand Down
29 changes: 28 additions & 1 deletion src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,25 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>
</Target>

<!--
============================================================
EnableIntermediateOutputPathMismatchWarning
If using PackageReference, enable an MSBuild warning if BaseIntermediateOutputPath is set to something different
than MSBuildProjectExtensionsPath, because it may be unexpected that the assets and related files wouldn't be written
to the BaseIntermediateOutputPath.
============================================================
-->

<Target Name="EnableIntermediateOutputPathMismatchWarning" DependsOnTargets="_GetRestoreProjectStyle"
BeforeTargets="_CheckForInvalidConfigurationAndPlatform"
Condition="'$(RestoreProjectStyle)' == 'PackageReference'">

<PropertyGroup Condition="'$(EnableBaseIntermediateOutputPathMismatchWarning)' == ''">
<EnableBaseIntermediateOutputPathMismatchWarning>true</EnableBaseIntermediateOutputPathMismatchWarning>
</PropertyGroup>

</Target>

<!--
============================================================
_GetRestoreTargetFrameworksOutput
Expand Down Expand Up @@ -569,7 +588,15 @@ Copyright (c) .NET Foundation. All rights reserved.
Returns="@(_RestoreGraphEntry)">

<!-- Determine the restore output path -->
<PropertyGroup Condition=" '$(PackageReferenceCompatibleProjectStyle)' == 'true' OR '$(RestoreProjectStyle)' == 'ProjectJson' ">
<PropertyGroup Condition=" '$(PackageReferenceCompatibleProjectStyle)' == 'true' ">
<!-- NuGet writes .props and .targets files to the RestoreOutputPath for PackageReference projects. MSBuild common
targets import these via the MSBuildProjectExtensionsPath, so that's what the RestoreOutputPath should be. -->
<RestoreOutputPath Condition=" '$(RestoreOutputPath)' == '' " >$(MSBuildProjectExtensionsPath)</RestoreOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(RestoreProjectStyle)' == 'ProjectJson' ">
<!-- For project.json projects, only the assets file cache goes in the RestoreOutputPath. The assets file and the
generated .props and .targets go in the project folder. So in that case use the BaseIntermediateOutputPath,
so that the assets file cache will respect a BaseIntermediateOutputPath set in the project body. -->
<RestoreOutputPath Condition=" '$(RestoreOutputPath)' == '' " >$(BaseIntermediateOutputPath)</RestoreOutputPath>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now different between VS and commandline for Project.Json?
One cache file goes BaseIntermediate, the other one goes to MsBuildExtensionsOutputPath.

Why not use MSBuildProjectExtensionsPath here as well?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't mean to make it inconsistent, so if it is that should be fixed.

But the idea is that for project.json, the generated props and targets go in the project folder and are imported via other means, so the whole reason we needed to switch to MSBuildProjectExtensionsPath doesn't exist. So we might as well continue to use BaseIntermediateOutputPath so that we don't change where the assets cache goes if BaseIntermediateOutputPath has been overridden.

Copy link
Member

@nkolev92 nkolev92 Mar 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid.

I think I'll just change what we read in VS for PJ then.

Other than that, this change, looks fine to me.

I'll get someone else to review it and merge it to a feature branch, and fix the tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the issue if we change it for project.json as well? at least that way, it will be a consistent behavior across project formats...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jainaashish
We can do either one.
The argument would be, no need to risk changing the experience in PJ, because it's not fixing a bug there.

I personally don't care too much either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the time when we're still supporting pj for legacy projects, I'd recommend we keep the code same across formats instead of making it conditional.

</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// 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 Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
Expand Down Expand Up @@ -28,8 +29,8 @@ public override bool Execute()
var log = new MSBuildLogger(Log);

// item -> string
var all = AllProjects?.Select(e => e.ItemSpec).ToArray() ?? new string[0];
var valid = ValidProjects?.Select(e => e.ItemSpec).ToArray() ?? new string[0];
var all = AllProjects?.Select(e => e.ItemSpec).ToArray() ?? Array.Empty<string>();
var valid = ValidProjects?.Select(e => e.ItemSpec).ToArray() ?? Array.Empty<string>();

// log inputs
BuildTasksUtility.LogInputParam(log, nameof(AllProjects), all);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,10 @@ private RestoreSummaryRequest Create(
{
// Set properties from the restore metadata
ProjectStyle = project.PackageSpec.RestoreMetadata.ProjectStyle,
// 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,
AssetsCachePath = projectPackageSpec.RestoreMetadata.OutputPath,
DependencyGraphSpec = projectDgSpec,
BaseIntermediateOutputPath = projectPackageSpec.RestoreMetadata.OutputPath,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set msbuildextensionspath here.

ParentId = restoreArgs.ParentId
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,15 @@ public RestoreRequest(
public ProjectStyle ProjectStyle { get; set; } = ProjectStyle.Unknown;

/// <summary>
/// Restore output path
/// RestoreOutputPath, which is where the restore output (assets file and generated props and targets) will go
/// </summary>
public string RestoreOutputPath { get; set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bring this back.


/// <summary>
/// Base Intermediate output path
/// AssetsCachePath, which is where the no-op restore cache will go
/// </summary>
public string BaseIntermediateOutputPath { get; set; }
public string AssetsCachePath { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also a NuGet restore artifact just like assets file or target file, so I think this should also go in the same location.



/// <summary>
/// Compatibility options
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal static bool IsNoOpSupported(RestoreRequest request)
}

/// <summary>
/// The cache file path is $(BaseIntermediateOutputPath)\$(project).nuget.cache
/// The cache file path is $(project).nuget.cache in the AssetsCachePath folder
/// </summary>
private static string GetBuildIntegratedProjectCacheFilePath(RestoreRequest request)
{
Expand All @@ -35,7 +35,7 @@ private static string GetBuildIntegratedProjectCacheFilePath(RestoreRequest requ
|| request.ProjectStyle == ProjectStyle.PackageReference
|| request.ProjectStyle == ProjectStyle.Standalone)
{
var cacheRoot = request.BaseIntermediateOutputPath ?? request.RestoreOutputPath;
Copy link
Member

@nkolev92 nkolev92 Mar 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since MsbuildExtensionsPath will always be set, it breaks this logic here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks project.json.

Don't remove RestoreOutputPath as from restoreRequest as the assets/lock and msbuild properties go to the project directory, but the cache file still goes into obj.

var cacheRoot = request.AssetsCachePath;
return request.Project.RestoreMetadata.CacheFilePath = GetProjectCacheFilePath(cacheRoot, request.Project.RestoreMetadata.ProjectPath);
}

Expand Down
2 changes: 1 addition & 1 deletion src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace NuGet.Common
{
/// <summary>
/// This enum is used to quantify NuGet error and wanring codes.
/// This enum is used to quantify NuGet error and warning codes.
/// Format - NUxyzw where NU is the profix indicating NuGet and xyzw is a 4 digit code
///
/// Numbers - xyzw
Expand Down
4 changes: 2 additions & 2 deletions src/NuGet.Core/NuGet.Common/MsBuildStringUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static string[] Split(string s, params char[] chars)
.ToArray();
}

return new string[0];
return Array.Empty<string>();
}

/// <summary>
Expand All @@ -59,7 +59,7 @@ public static string[] TrimAndExcludeNullOrEmpty(string[] strings)
{
if (strings == null)
{
return new string[0];
return Array.Empty<string>();
}

return strings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace NuGet.ProjectManagement
/// </summary>
public static class ProjectBuildProperties
{
public const string BaseIntermediateOutputPath = "BaseIntermediateOutputPath";
public const string MSBuildProjectExtensionsPath = "MSBuildProjectExtensionsPath";
public const string PackageTargetFallback = "PackageTargetFallback";
public const string AssetTargetFallback = "AssetTargetFallback";
public const string PackageVersion = "PackageVersion";
Expand Down
Loading