diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..4eb7559fce --- /dev/null +++ b/.editorconfig @@ -0,0 +1,29 @@ +; EditorConfig to support per-solution formatting. +; Use the EditorConfig VS add-in to make this work. +; http://editorconfig.org/ + +; This is the default for the codeline. +root = true + +[*] +indent_style = space +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{cs}] +indent_size = 4 +dotnet_sort_system_directives_first = true:warning + +[*.{xml,config,*proj,nuspec,props,resx,targets,yml,tasks}] +indent_size = 2 + +[*.json] +indent_size = 2 + +[*.{ps1,psm1}] +indent_size = 4 + +[*.sh] +indent_size = 4 +end_of_line = lf diff --git a/.gitignore b/.gitignore index a0129822f5..9efbb61c7e 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ node_modules .deps global.json korebuild-lock.txt +*.binlog diff --git a/build/Repositories.props b/build/Repositories.props index 25e5478021..866f06c5ae 100644 --- a/build/Repositories.props +++ b/build/Repositories.props @@ -2,6 +2,7 @@ dev + true diff --git a/build/RepositoryBuild.targets b/build/RepositoryBuild.targets index 660030d6c8..636e016708 100644 --- a/build/RepositoryBuild.targets +++ b/build/RepositoryBuild.targets @@ -30,7 +30,7 @@ $(RepositoryBuildArguments) '/p:Universe_Version=$(Version)' $(RepositoryBuildArguments) '/p:Universe_LineupBuildDir=$(LineupBuildDir)' - $(RepositoryBuildArguments) '/p:Universe_DependencyLineupDir=$(_DependencyLineupDir)' + $(RepositoryBuildArguments) '/p:Universe_AdditionalRestoreSources=$(IntermediateMirrorPackageDir)' $(RepositoryBuildArguments) '/p:Universe_IntermediateDir=$(IntermediateDir)' $(RepositoryBuildArguments) '/p:CustomBeforeKoreBuildProps=$(MSBuildThisFileDirectory)repobuild\BeforeKoreBuild.props' $(RepositoryBuildArguments) '/p:CustomAfterKoreBuildTargets=$(MSBuildThisFileDirectory)repobuild\AfterKoreBuild.targets' @@ -59,8 +59,6 @@ - - @@ -72,15 +70,6 @@ SourceFiles="@(RepositoryMSBuildArtifacts)" DestinationFolder="$(ArtifactsDir)msbuild\$(RepositoryToBuild)\%(RecursiveDir)" /> - - - - diff --git a/build/artifacts.props b/build/artifacts.props new file mode 100644 index 0000000000..799feba584 --- /dev/null +++ b/build/artifacts.props @@ -0,0 +1,239 @@ + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/dependencies.props b/build/dependencies.props index 6e179d808c..6e3273a926 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -1,12 +1,75 @@ - + + + + + + + + + + false + + false + + true + + + + - https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json + https://dotnet.myget.org/f/dotnet-core/api/v3/index.json - + + + + + + https://dotnet.myget.org/f/dotnet-corefxlab/api/v3/index.json + + + + + + + + + + + + + + + + + + + + + https://dotnet.myget.org/F/roslyn/api/v3/index.json + + + + + + + + + + + + + + + + https://dotnet.myget.org/F/aspnetcoremodule/api/v3/index.json + + + + @@ -15,13 +78,14 @@ - - - - + + + + + - + @@ -43,32 +107,32 @@ - + - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + @@ -130,7 +194,7 @@ - + diff --git a/build/lineups/Internal.AspNetCore.Partners.Lineup.nuspec b/build/lineups/Internal.AspNetCore.Partners.Lineup.nuspec new file mode 100644 index 0000000000..66ebb614e0 --- /dev/null +++ b/build/lineups/Internal.AspNetCore.Partners.Lineup.nuspec @@ -0,0 +1,17 @@ + + + + Internal.AspNetCore.Partners.Lineup + $version$ + Microsoft + This package used to unify external dependency versions. Internal use only. + + + + + + + + diff --git a/lineups/Internal.AspNetCore.Universe.Lineup.nuspec b/build/lineups/Internal.AspNetCore.Universe.Lineup.nuspec similarity index 78% rename from lineups/Internal.AspNetCore.Universe.Lineup.nuspec rename to build/lineups/Internal.AspNetCore.Universe.Lineup.nuspec index 2ca7e0c78f..7ffbde205a 100644 --- a/lineups/Internal.AspNetCore.Universe.Lineup.nuspec +++ b/build/lineups/Internal.AspNetCore.Universe.Lineup.nuspec @@ -4,7 +4,7 @@ Internal.AspNetCore.Universe.Lineup $version$ Microsoft - This package used to unify dependency versions across all Universe repos. Internal use only. + This package used to unify ASP.NET Core package versions across all Universe repos. Internal use only. diff --git a/build/push.targets b/build/push.targets new file mode 100644 index 0000000000..a766f7d43c --- /dev/null +++ b/build/push.targets @@ -0,0 +1,23 @@ + + + + + + <_PackagesToPush Include="$(BuildDir)*.nupkg" /> + <_PackagesToPush Include="$(ArtifactsDir)mirror\*.nupkg" /> + <_LineupPackagesToPush Include="$(BuildDir)*.nupkg" /> + + + + + + + diff --git a/build/repo.props b/build/repo.props index 2e230882b2..40b83474b9 100644 --- a/build/repo.props +++ b/build/repo.props @@ -1,13 +1,10 @@ - + true - $(VersionPrefix) - $(Version)-$(VersionSuffix) - $(Version)-$(BuildNumber) diff --git a/build/repo.targets b/build/repo.targets index f02189a663..d2858b0671 100644 --- a/build/repo.targets +++ b/build/repo.targets @@ -2,8 +2,6 @@ - https://dotnet.myget.org/F/aspnetcore-volatile-dev/api/v2/package - $(ArtifactsDir)lineups\ <_CloneRepositoryRoot>$(RepositoryRoot).r\ <_DependencyBuildDirectory>$(RepositoryRoot).deps\build\ @@ -20,75 +18,84 @@ <_RepositoryBuildTargets Condition="'$(_RepositoryBuildTargets)'=='' AND '$(CompileOnly)'=='true'">/t:Package /t:VerifyPackages <_RepositoryBuildTargets Condition="'$(_RepositoryBuildTargets)'==''">/t:Verify - $(PrepareDependsOn);CleanUniverseArtifacts - $(CleanDependsOn);CleanUniverseArtifacts - $(BuildDependsOn);CloneRepositories;BuildRepositories + + $(IntermediateDir)mirror\ + + $(IntermediateDir)ext\ + + $(PrepareDependsOn);VerifyPackageArtifactConfig;CleanArtifacts;CleanUniverseArtifacts + $(RestoreDependsOn);RestoreExternalDependencies + $(CleanDependsOn);CleanArtifacts;CleanUniverseArtifacts + $(CompileDependsOn);CloneRepositories;BuildRepositories + $(PackageDependsOn);CopyPackagesByCategory + $(VerifyDependsOn);VerifyCoherentVersions - - + + - - - <_DependencyPackageFiles Include="$(_DependencyPackagesDirectory)*.nupkg" - Exclude="$(_DependencyPackagesDirectory)*.symbols.nupkg" - Condition=" '$(_DependencyPackagesDirectory)' != '' " /> - <_DependencyLineupFiles Include="$(_DependencyLineupDir)*.nupkg" - Exclude="$(_DependencyLineupDir)Internal.AspNetCore.Universe.Lineup.*.nupkg" - Condition=" '$(_DependencyLineupDir)' != '' " /> - - - - - - - - - + + - - - <_Dependency Remove="@(_Dependency)" /> + + + + - - <_Dependency Include="@(PackagesProduced)" /> - <_Dependency Include="@(ExternalDependency)" Exclude="@(_Dependency)" /> - - <_Dependency Include="@(ArtifactDependency)" Exclude="@(_Dependency);@(DependencyLineupDependency)" /> - + + + - + + + + + Dependencies="@(ExternalDependency->WithMetadataValue('Lineup', 'true'))"> - - - + + + + + + + <_RepositoriesToInclude Include="$(KOREBUILD_REPOSITORY_INCLUDE)" /> + + Update="@(Repository)" + Condition="'@(Repository)'=='@(_RepositoriesToInclude)' AND '%(Identity)'!=''" + Build="true" /> - + @@ -166,12 +175,14 @@ Condition="'$(GateBranchExitCode)'!='0'" WorkingDirectory="$(_CloneRepositoryRoot)" EnvironmentVariables="GIT_TERMINAL_PROMPT=0" + IgnoreStandardErrorWarningFormat="true" Timeout="180000" /> @@ -183,7 +194,8 @@ + ContinueOnError="WarnAndContinue" + Condition="%(Repository.Build)"> @@ -213,12 +225,11 @@ - @@ -227,16 +238,46 @@ NuGetConfigPath="$(_CloneRepositoryRoot)%(Repository.Identity)\NuGet.config" SourceName="Dependencies" SourceUri="$(_DependencyPackagesDirectory)" - Condition="Exists('$(_DependencyPackagesDirectory)')" /> + Condition="Exists('$(_DependencyPackagesDirectory)') AND %(Repository.Build)" /> + + + + + <_MirroredPackageFiles Include="$(IntermediateMirrorPackageDir)*.nupkg" /> + + + + + + + + + + + + + + + + + $(BuildDir)$(_RepositoryListFileName) diff --git a/build/repobuild/AfterKoreBuild.targets b/build/repobuild/AfterKoreBuild.targets index 6db507685d..c482209e13 100644 --- a/build/repobuild/AfterKoreBuild.targets +++ b/build/repobuild/AfterKoreBuild.targets @@ -2,5 +2,6 @@ + diff --git a/build/repobuild/BeforeKoreBuild.props b/build/repobuild/BeforeKoreBuild.props index 26bd1c6b92..f7fbcf8abd 100644 --- a/build/repobuild/BeforeKoreBuild.props +++ b/build/repobuild/BeforeKoreBuild.props @@ -5,6 +5,9 @@ $([MSBuild]::NormalizeDirectory($(Universe_IntermediateDir)))packages\ $(PolicyRestoreAdditionalSources);$(Universe_LineupBuildDir) - $(PolicyRestoreAdditionalSources);$(Universe_DependencyLineupDir) + + + + diff --git a/build/tasks/CalculateBuildGraph.cs b/build/tasks/CalculateBuildGraph.cs index 1dc3abfecf..0c574f41dd 100644 --- a/build/tasks/CalculateBuildGraph.cs +++ b/build/tasks/CalculateBuildGraph.cs @@ -35,9 +35,6 @@ namespace RepoTasks [Output] public ITaskItem[] RepositoriesToBuildInOrder { get; set; } - [Output] - public ITaskItem[] PackagesProduced { get; set; } - public override bool Execute() { var graphSpecProvider = new DependencyGraphSpecProvider(PackageSpecsDirectory.Trim()); @@ -74,17 +71,6 @@ namespace RepoTasks .Select(r => r.repository) .ToArray(); - var packages = new List(); - foreach (var project in repositories.SelectMany(p => p.Projects)) - { - var pkg = new TaskItem(project.Name); - var version = project.Version ?? DefaultPackageVersion; - pkg.SetMetadata("Version", version); - packages.Add(pkg); - } - - PackagesProduced = packages.ToArray(); - return true; } } diff --git a/build/tasks/CopyPackagesToSplitFolders.cs b/build/tasks/CopyPackagesToSplitFolders.cs new file mode 100644 index 0000000000..682e50806c --- /dev/null +++ b/build/tasks/CopyPackagesToSplitFolders.cs @@ -0,0 +1,110 @@ +// 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.IO; +using System.Text; +using Microsoft.Build.Framework; +using NuGet.Packaging; +using NuGet.Packaging.Core; +using RepoTasks.ProjectModel; + +namespace RepoTasks +{ + public class CopyPackagesToSplitFolders : Microsoft.Build.Utilities.Task + { + /// + /// The item group containing the nuget packages to split in different folders. + /// + [Required] + public ITaskItem[] Packages { get; set; } + + [Required] + public ITaskItem[] Files { get; set; } + + /// + /// The folder where packages should be copied. Subfolders will be created based on package category. + /// + [Required] + public string DestinationFolder { get; set; } + + public bool Overwrite { get; set; } + + public override bool Execute() + { + if (Files?.Length == 0) + { + Log.LogError("No packages were found."); + return false; + } + + var expectedPackages = PackageCollection.FromItemGroup(Packages); + + Directory.CreateDirectory(DestinationFolder); + + foreach (var file in Files) + { + PackageIdentity identity; + using (var reader = new PackageArchiveReader(file.ItemSpec)) + { + identity = reader.GetIdentity(); + } + + if (!expectedPackages.TryGetCategory(identity.Id, out var category)) + { + Log.LogError($"Unexpected package artifact with id: {identity.Id}"); + continue; + } + + string destDir; + switch (category) + { + case PackageCategory.Unknown: + throw new InvalidOperationException($"Package {identity} does not have a recognized package category."); + case PackageCategory.Shipping: + destDir = Path.Combine(DestinationFolder, "ship"); + break; + case PackageCategory.NoShip: + destDir = Path.Combine(DestinationFolder, "noship"); + break; + case PackageCategory.ShipOob: + destDir = Path.Combine(DestinationFolder, "shipoob"); + break; + case PackageCategory.Mirror: + destDir = Path.Combine(DestinationFolder, "mirror"); + break; + default: + throw new NotImplementedException(); + } + + Directory.CreateDirectory(destDir); + + var destFile = Path.Combine(destDir, Path.GetFileName(file.ItemSpec)); + + if (!Overwrite && File.Exists(destFile)) + { + Log.LogError($"File already exists in {destFile}"); + continue; + } + + Log.LogMessage($"Copying {file.ItemSpec} to {destFile}"); + File.Copy(file.ItemSpec, destFile, Overwrite); + expectedPackages.Remove(identity.Id); + } + + if (expectedPackages.Count != 0) + { + var error = new StringBuilder(); + foreach (var key in expectedPackages.Keys) + { + error.Append(" - ").AppendLine(key); + } + + Log.LogError($"Expected the following packages, but they were not found:" + error.ToString()); + return false; + } + + return !Log.HasLoggedErrors; + } + } +} diff --git a/build/tasks/ProjectModel/PackageCategory.cs b/build/tasks/ProjectModel/PackageCategory.cs new file mode 100644 index 0000000000..e3869319f0 --- /dev/null +++ b/build/tasks/ProjectModel/PackageCategory.cs @@ -0,0 +1,15 @@ +// 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. + + +namespace RepoTasks.ProjectModel +{ + public enum PackageCategory + { + Unknown = 0, + Shipping, + NoShip, + ShipOob, + Mirror, + } +} diff --git a/build/tasks/ProjectModel/PackageCollection.cs b/build/tasks/ProjectModel/PackageCollection.cs new file mode 100644 index 0000000000..56b998969a --- /dev/null +++ b/build/tasks/ProjectModel/PackageCollection.cs @@ -0,0 +1,69 @@ +// 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 Microsoft.Build.Framework; + +namespace RepoTasks.ProjectModel +{ + public class PackageCollection + { + private readonly IDictionary _packages = new Dictionary(StringComparer.OrdinalIgnoreCase); + + private PackageCollection() + { + } + + public bool TryGetCategory(string packageId, out PackageCategory category) => _packages.TryGetValue(packageId, out category); + + public void Remove(string packageId) => _packages.Remove(packageId); + + public int Count => _packages.Count; + + public IEnumerable Keys => _packages.Keys; + + public static PackageCollection FromItemGroup(ITaskItem[] items) + { + var list = new PackageCollection(); + if (items == null) + { + return list; + } + + foreach (var item in items) + { + PackageCategory category; + switch (item.GetMetadata("Category")?.ToLowerInvariant()) + { + case "ship": + category = PackageCategory.Shipping; + break; + case "noship": + category = PackageCategory.NoShip; + break; + case "shipoob": + category = PackageCategory.ShipOob; + break; + case "mirror": + category = PackageCategory.Mirror; + break; + default: + category = PackageCategory.Unknown; + break; + } + + if (list._packages.ContainsKey(item.ItemSpec)) + { + throw new InvalidDataException($"Duplicate package id detected: {item.ItemSpec}"); + } + + list._packages.Add(item.ItemSpec, category); + } + + return list; + } + } +} diff --git a/build/tasks/ProjectModel/PackageInfo.cs b/build/tasks/ProjectModel/PackageInfo.cs new file mode 100644 index 0000000000..463fab690a --- /dev/null +++ b/build/tasks/ProjectModel/PackageInfo.cs @@ -0,0 +1,42 @@ +// 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 NuGet.Frameworks; +using NuGet.Packaging; +using NuGet.Versioning; + +namespace RepoTasks.ProjectModel +{ + internal class PackageInfo + { + public PackageInfo(string id, + NuGetVersion version, + IReadOnlyList dependencyGroups, + string source, + string packageType = "Dependency") + { + if (string.IsNullOrEmpty(id)) + { + throw new ArgumentException(nameof(id)); + } + + Id = id; + Version = version ?? throw new ArgumentNullException(nameof(version)); + PackageType = packageType; + Source = source; + DependencyGroups = dependencyGroups ?? Array.Empty(); + } + + public string Id { get; } + public NuGetVersion Version { get; } + public string PackageType { get; } + /// + /// Can be a https feed or a file path. May be null. + /// + public string Source { get; } + public IReadOnlyList DependencyGroups { get; } + } +} diff --git a/build/tasks/ReadPackageDependencies.cs b/build/tasks/ReadPackageDependencies.cs deleted file mode 100644 index 315cb45271..0000000000 --- a/build/tasks/ReadPackageDependencies.cs +++ /dev/null @@ -1,44 +0,0 @@ -// 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; -using System.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Packaging; - -namespace RepoTasks -{ - public class ReadPackageDependencies : Task - { - [Required] - public ITaskItem[] PackageFiles { get; set; } - - [Output] - public ITaskItem[] PackageDefinitions { get; set; } - - public override bool Execute() - { - PackageDefinitions = PackageFiles.SelectMany(item => - { - using (var package = new PackageArchiveReader(item.ItemSpec)) - { - var identity = package.GetIdentity(); - var metadata = new NuspecReader(package.GetNuspec()); - var groups = metadata.GetDependencyGroups()?.ToList(); - if (groups == null) - { - return Enumerable.Empty(); - } - - return groups.SelectMany(g => - g.Packages.Select(p => new TaskItem(p.Id, new Hashtable { ["Version"] = p.VersionRange.MinVersion.ToString() }))); - } - }) - .ToArray(); - - return true; - } - } -} diff --git a/build/tasks/ReadPackageIdentity.cs b/build/tasks/ReadPackageIdentity.cs deleted file mode 100644 index 354a226422..0000000000 --- a/build/tasks/ReadPackageIdentity.cs +++ /dev/null @@ -1,37 +0,0 @@ -// 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; -using NuGet.Packaging; - -namespace RepoTasks -{ - public class ReadPackageIdentity : Task - { - [Required] - public ITaskItem[] PackageFiles { get; set; } - - [Output] - public ITaskItem[] PackageDefinitions { get; set; } - - public override bool Execute() - { - PackageDefinitions = PackageFiles.Select(item => - { - using (var package = new PackageArchiveReader(item.ItemSpec)) - { - var identity = package.GetIdentity(); - var packageItem = new TaskItem(identity.Id); - packageItem.SetMetadata("Version", identity.Version.ToString()); - return packageItem; - } - }) - .ToArray(); - - return true; - } - } -} diff --git a/build/tasks/RepoTasks.tasks b/build/tasks/RepoTasks.tasks index d4759ca827..7d33d0ad09 100644 --- a/build/tasks/RepoTasks.tasks +++ b/build/tasks/RepoTasks.tasks @@ -4,7 +4,7 @@ + - - + diff --git a/build/tasks/VerifyCoherentVersions.cs b/build/tasks/VerifyCoherentVersions.cs new file mode 100644 index 0000000000..f0e92a7d47 --- /dev/null +++ b/build/tasks/VerifyCoherentVersions.cs @@ -0,0 +1,137 @@ +// 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 System.Text; +using Microsoft.Build.Framework; +using NuGet.Frameworks; +using NuGet.Packaging; +using NuGet.Packaging.Core; +using NuGet.Versioning; +using RepoTasks.ProjectModel; + +namespace RepoTasks +{ + public class VerifyCoherentVersions : Microsoft.Build.Utilities.Task + { + [Required] + public ITaskItem[] PackageFiles { get; set; } + + [Required] + public ITaskItem[] ExternalDependencies { get; set; } + + public override bool Execute() + { + var packageLookup = new Dictionary(StringComparer.OrdinalIgnoreCase); + var dependencyMap = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + foreach (var dep in ExternalDependencies) + { + if (!dependencyMap.TryGetValue(dep.ItemSpec, out var list)) + { + dependencyMap[dep.ItemSpec] = list = new List(); + } + var externalDep = new ExternalDependency + { + Version = dep.GetMetadata("Version"), + IsPrivate = bool.TryParse(dep.GetMetadata("Private"), out var isPrivate) && isPrivate, + }; + list.Add(externalDep); + } + + foreach (var file in PackageFiles) + { + PackageInfo package; + using (var reader = new PackageArchiveReader(file.ItemSpec)) + { + var identity = reader.GetIdentity(); + var metadata = new PackageBuilder(reader.GetNuspec(), basePath: null); + package = new PackageInfo(identity.Id, identity.Version, + source: Path.GetDirectoryName(file.ItemSpec), + dependencyGroups: metadata.DependencyGroups.ToArray()); + } + + if (packageLookup.TryGetValue(package.Id, out var existingPackage)) + { + throw new Exception("Multiple copies of the following package were found: " + + Environment.NewLine + + existingPackage + + Environment.NewLine + + package); + } + + packageLookup[package.Id] = package; + } + + foreach (var packageInfo in packageLookup.Values) + { + Visit(packageLookup, dependencyMap, packageInfo); + } + + Log.LogMessage(MessageImportance.High, $"Verified {PackageFiles.Length} package(s) have coherent versions"); + return !Log.HasLoggedErrors; + } + + private class ExternalDependency + { + public string Version { get; set; } + public bool IsPrivate { get; set; } + } + + private void Visit( + IReadOnlyDictionary packageLookup, + IReadOnlyDictionary> dependencyMap, + PackageInfo packageInfo) + { + Log.LogMessage(MessageImportance.Low, $"Processing package {packageInfo.Id}"); + try + { + foreach (var dependencySet in packageInfo.DependencyGroups) + { + foreach (var dependency in dependencySet.Packages) + { + PackageInfo dependencyPackageInfo; + var depVersion = dependency.VersionRange.MinVersion.ToString(); + if (dependencyMap.TryGetValue(dependency.Id, out var externalDependencies)) + { + var matchedVersion = externalDependencies.FirstOrDefault(d => depVersion.Equals(d.Version)); + + if (matchedVersion == null) + { + var versions = string.Join(" or ", externalDependencies.Select(d => d.Version)); + Log.LogError($"Package {packageInfo.Id} has an external dependency on the wrong version of {dependency.Id}. " + + $"It uses {depVersion} but only {versions} is allowed."); + } + else if (matchedVersion.IsPrivate) + { + Log.LogError($"Package {packageInfo.Id} has an external dependency on {dependency.Id}/{depVersion} which is marked as Private=true."); + } + continue; + } + else if (!packageLookup.TryGetValue(dependency.Id, out dependencyPackageInfo)) + { + Log.LogError($"Package {packageInfo.Id} has an undefined external dependency on {dependency.Id}/{depVersion}"); + continue; + } + + if (dependencyPackageInfo.Version != dependency.VersionRange.MinVersion) + { + // For any dependency in the universe + // Add a mismatch if the min version doesn't work out + // (we only really care about >= minVersion) + Log.LogError($"{packageInfo.Id} depends on {dependency.Id} " + + $"{dependency.VersionRange} ({dependencySet.TargetFramework}) when the latest build is {depVersion}."); + } + } + } + } + catch (Exception ex) + { + Log.LogError($"Unexpected error while attempting to verify package {packageInfo.Id}.\r\n{ex}"); + } + } + } +} diff --git a/version.xml b/version.props similarity index 51% rename from version.xml rename to version.props index 3c05022b7d..834077241d 100644 --- a/version.xml +++ b/version.props @@ -1,8 +1,7 @@ - - dev 2.1.0 preview1 + $(VersionSuffix)-$(BuildNumber)