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

PackageVersion property for .NET Core projects #1146

Merged
merged 1 commit into from
Jan 25, 2017
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -29,6 +29,8 @@ namespace NuGet.SolutionRestoreManager
[Export(typeof(IVsSolutionRestoreService))]
public sealed class VsSolutionRestoreService : IVsSolutionRestoreService
{
private const string PackageVersion = nameof(PackageVersion);
private const string Version = nameof(Version);
private const string IncludeAssets = "IncludeAssets";
private const string ExcludeAssets = "ExcludeAssets";
private const string PrivateAssets = "PrivateAssets";
Expand Down Expand Up @@ -108,6 +110,12 @@ public Task<bool> NominateProjectAsync(string projectUniqueName, IVsProjectResto
return restoreTask;
}
catch (Exception e)
when (e is InvalidOperationException || e is ArgumentException || e is FormatException)
{
_logger.LogError(e.ToString());
return Task.FromResult(false);
}
catch (Exception e)
{
_logger.LogError(e.ToString());
throw;
Expand Down Expand Up @@ -196,6 +204,7 @@ private static PackageSpec ToPackageSpec(ProjectNames projectNames, IVsProjectRe
var packageSpec = new PackageSpec(tfis)
{
Name = projectNames.ShortName,
Version = GetPackageVersion(projectRestoreInfo.TargetFrameworks),
FilePath = projectFullPath,
RestoreMetadata = new ProjectRestoreMetadata
{
Expand All @@ -220,6 +229,29 @@ private static PackageSpec ToPackageSpec(ProjectNames projectNames, IVsProjectRe
return packageSpec;
}

private static NuGetVersion GetPackageVersion(IVsTargetFrameworks tfms)
{
// $(PackageVersion) property if set overrides the $(Version)
var versionPropertyValue =
GetNonEvaluatedPropertyOrNull(tfms, PackageVersion)
?? GetNonEvaluatedPropertyOrNull(tfms, Version);

return versionPropertyValue != null
? NuGetVersion.Parse(versionPropertyValue)
: PackageSpec.DefaultVersion;
}

// Trying to fetch a property value from tfm property bags.
// If defined the property should have identical values in all of the occurances.
private static string GetNonEvaluatedPropertyOrNull(IVsTargetFrameworks tfms, string propertyName)
{
return tfms
.Cast<IVsTargetFrameworkInfo>()
.Select(tfm => GetPropertyValueOrNull(tfm.Properties, propertyName))
.Distinct()
.SingleOrDefault();
Copy link
Member

Choose a reason for hiding this comment

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

I would say this is the most correct, but will it be too difficult for the user to figure out if this silently returns null and 1.0.0 is used as the project version?

}

private static RuntimeGraph GetRuntimeGraph(IVsProjectRestoreInfo projectRestoreInfo)
{
var runtimes = projectRestoreInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,24 @@ namespace NuGet.SolutionRestoreManager.Test
/// Helper class providing a method of building <see cref="IVsProjectRestoreInfo"/>
/// out of <see cref="PackageSpec"/>.
/// </summary>
internal static class ProjectRestoreInfoBuilder
internal class ProjectRestoreInfoBuilder
{
private readonly VsProjectRestoreInfo _pri;

private ProjectRestoreInfoBuilder(VsProjectRestoreInfo pri)
{
_pri = pri;
}

/// <summary>
/// Creates project restore info object to be consumed by <see cref="IVsSolutionRestoreService"/>.
/// </summary>
/// <param name="packageSpec">Source project restore object</param>
/// <returns>Desired project restore object</returns>
public static VsProjectRestoreInfo Build(
public static ProjectRestoreInfoBuilder FromPackageSpec(
PackageSpec packageSpec,
string baseIntermediatePath,
bool crossTargeting,
IEnumerable<LibraryRange> tools)
bool crossTargeting)
{
if (packageSpec == null)
{
Expand All @@ -36,18 +42,24 @@ public static VsProjectRestoreInfo Build(
return null;
}

var projectProperties = new VsProjectProperties { };

if (packageSpec.Version != null)
{
projectProperties = new VsProjectProperties
{
{ "PackageVersion", packageSpec.Version.ToString() }
};
}

var targetFrameworks = new VsTargetFrameworks(
packageSpec
.TargetFrameworks
.Select(ToTargetFrameworkInfo));
.Select(tfm => ToTargetFrameworkInfo(tfm, projectProperties)));

var pri = new VsProjectRestoreInfo(
baseIntermediatePath,
targetFrameworks)
{
ToolReferences = new VsReferenceItems(
(tools ?? Enumerable.Empty<LibraryRange>()).Select(ToToolReference))
};
targetFrameworks);

if (crossTargeting)
{
Expand All @@ -57,32 +69,61 @@ public static VsProjectRestoreInfo Build(
.Select(tfm => tfm.FrameworkName.GetShortFolderName()));
}

return pri;
return new ProjectRestoreInfoBuilder(pri);
}

private static VsTargetFrameworkInfo ToTargetFrameworkInfo(TargetFrameworkInformation tfm)
public ProjectRestoreInfoBuilder WithTool(string name, string version)
{
var packageReferences = new VsReferenceItems(
tfm.Dependencies
.Where(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.Package)
.Select(ToPackageReference));

var projectReferences = new VsReferenceItems(
tfm.Dependencies
.Where(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.ExternalProject)
.Select(ToProjectReference));

var projectProperties = new VsProjectProperties(
new VsProjectProperty(
var properties = new VsReferenceProperties
{
{ "Version", version }
};

_pri.ToolReferences = new VsReferenceItems
{
new VsReferenceItem(name, properties)
};

return this;
}

public ProjectRestoreInfoBuilder WithTargetFrameworkInfo(
IVsTargetFrameworkInfo tfi)
{
(_pri.TargetFrameworks as VsTargetFrameworks).Add(tfi);

return this;
}

public VsProjectRestoreInfo Build() => _pri;

private static VsTargetFrameworkInfo ToTargetFrameworkInfo(
TargetFrameworkInformation tfm,
IEnumerable<IVsProjectProperty> globalProperties)
{
var packageReferences = tfm
.Dependencies
.Where(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.Package)
.Select(ToPackageReference);

var projectReferences = tfm
.Dependencies
.Where(d => d.LibraryRange.TypeConstraint == LibraryDependencyTarget.ExternalProject)
.Select(ToProjectReference);

var projectProperties = new VsProjectProperties
{
{
"PackageTargetFallback",
string.Join(";", tfm.Imports.Select(x => x.GetShortFolderName())))
);
string.Join(";", tfm.Imports.Select(x => x.GetShortFolderName()))
}
};

return new VsTargetFrameworkInfo(
tfm.FrameworkName.ToString(),
packageReferences,
projectReferences,
projectProperties);
projectProperties.Concat(globalProperties));
}

private static IVsReferenceItem ToPackageReference(LibraryDependency library)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,10 @@ public VsProjectProperties(IEnumerable<IVsProjectProperty> collection) : base(co
public VsProjectProperties(params IVsProjectProperty[] collection) : base(collection) { }

protected override string GetKeyForItem(IVsProjectProperty value) => value.Name;

public void Add(string propertyName, string propertyValue)
{
Add(new VsProjectProperty(propertyName, propertyValue));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace NuGet.SolutionRestoreManager.Test
/// </summary>
internal class VsProjectRestoreInfo : IVsProjectRestoreInfo
{
public String BaseIntermediatePath { get; }
public string BaseIntermediatePath { get; }

public string OriginalTargetFrameworks { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,10 @@ public VsReferenceProperties() : base() { }
public VsReferenceProperties(IEnumerable<IVsReferenceProperty> collection) : base(collection) { }

protected override String GetKeyForItem(IVsReferenceProperty value) => value.Name;

public void Add(string propertyName, string propertyValue)
{
Add(new VsReferenceProperty(propertyName, propertyValue));
}
}
}
Loading